From efd5fce9a78073f272fb77851de98e6f098fa09b Mon Sep 17 00:00:00 2001 From: tamakyi Date: Mon, 19 Oct 2026 00:07:22 +0800 Subject: [PATCH] restrict v10 --- .workbuddy/memory/2026-10-18.md | 29 +++++++++++++++++++++++++++++ dev/devcheck-e2e.py | 6 +++--- internal/form/auth.go | 3 +++ internal/i18n/dict_en.go | 19 ++++++++++++------- internal/i18n/dict_ja.go | 19 ++++++++++++------- internal/i18n/dict_zh_cn.go | 19 ++++++++++++------- internal/i18n/dict_zh_tw.go | 19 ++++++++++++------- templates/auth/register.html | 7 +++++++ templates/base/footer.html | 1 + templates/user/question-list.html | 2 +- 10 files changed, 92 insertions(+), 32 deletions(-) diff --git a/.workbuddy/memory/2026-10-18.md b/.workbuddy/memory/2026-10-18.md index 10cd47f..b228cf8 100644 --- a/.workbuddy/memory/2026-10-18.md +++ b/.workbuddy/memory/2026-10-18.md @@ -391,3 +391,32 @@ admin6 当前处于 L2(到期次日),必要时 `unrestrict` 解除。 已把 `rules.html` 加进清单,编译 EXIT=0、`go test ./templates/` 通过。 ⚠️ 以后新增**顶层**模板必须改 embed 指令;子目录下的文件已被目录项覆盖。 MEMORY.md 里那条错误认知已纠正。 + +### /rules 修复后验证:四语言全通过 + +`rules=200`(39KB);标题依次为「社区规则与内容边界 / 社群規則與內容界線 / +Community rules and content boundaries / コミュニティルールとコンテンツの境界」; +处置梯度段落存在。 + +发现规则页**没有任何入口**(页脚原本全是外链,无站内链接),已加 +`` 到 `templates/base/footer.html` + `site.footer.rules`(四语言)。 +编译 EXIT=0、checktpl OK、i18n 与 templates 测试全绿。**需再部署一次生效**。 + +补充(用户要求):处置条幅里「如有疑问请通过页脚找站长联系」后面再挂一个 `/rules` 链接, +用 `·` 分隔(`qlist.restrictionRulesLink`,四语言)。模板压成单行避免多余空白。 +编译 EXIT=0、checktpl OK。仍需部署。 + +## 规则页扩展 + 注册强制同意(用户要求) + +- **规则分两类**(关键设计):`rules.forbidden` 重写为 + 「一、严重违规(直接删内容 + 按情节封禁,**不适用分级**)」6 条(涉政/暴恐/色情涉未成年/违禁品赌博诈骗/侵害未成年人/隐私), + 「二、社区冲突(**按影响面分级**)」4 条(挂人、辱骂、群体对立、垃圾广告)。 + `rules.enforce` 相应说明「分级只适用于社区冲突;严重违规不走分级,涉法配合有关部门」。 + 四语言同步。这样避免「挂人只停分发、涉政也停分发」的错误预期。 +- **注册强制同意**:`form.Register` 加 `AgreeRules string`(`form:"agree_rules" valid:"required"`, + msg `form.register.agreeRules`);注册页在 language 之后加 checkbox + `/rules` 链接(`target="_blank" rel="noopener"`)。 + **服务端校验是必须的**:前端 required 可绕过,而这个勾选是「用户已知悉规则」的唯一凭证。 +- 顺带同步 `dev/devcheck-e2e.py` 的三处注册 POST,加 `"agree_rules": "1"`,否则 e2e 注册步骤会全部失败。 + +验证:`go build ./...` EXIT=0;checktpl OK;i18n 与 templates 测试全绿。 +未用 modal 而用新标签页:规则正文很长,iframe 弹窗体验差且要重复维护内容。 diff --git a/dev/devcheck-e2e.py b/dev/devcheck-e2e.py index d7afee3..5659037 100644 --- a/dev/devcheck-e2e.py +++ b/dev/devcheck-e2e.py @@ -268,7 +268,7 @@ def main(): r = c.post("/register", { "email": args.reuse_email, "domain": domain, "name": "TBCheck", "password": pwd, "repeat_password": pwd, - "g-recaptcha-response": captcha(c), "language": "zh-CN", + "g-recaptcha-response": captcha(c), "language": "zh-CN", "agree_rules": "1", "_csrf": csrf_of(r.body), }) step("以既有邮箱重新注册(已停用则应被明确拒绝并提示找站长)", is_deactivated_rejected(r), @@ -284,7 +284,7 @@ def main(): reg = pub.post("/register", { "email": email, "domain": domain, "name": "TB%s" % ts, "password": pwd, "repeat_password": pwd, - "g-recaptcha-response": captcha(pub), "language": "zh-CN", + "g-recaptcha-response": captcha(pub), "language": "zh-CN", "agree_rules": "1", "_csrf": csrf_of(r.body), }) step("注册", reg.status == 302, "HTTP %s -> %s %s" % (reg.status, reg.loc, reg.alert())) @@ -330,7 +330,7 @@ def main(): r = pub2.post("/register", { "email": email, "domain": domain, "name": "TB%sb" % ts, "password": pwd, "repeat_password": pwd, - "g-recaptcha-response": captcha(pub2), "language": "zh-CN", + "g-recaptcha-response": captcha(pub2), "language": "zh-CN", "agree_rules": "1", "_csrf": csrf_of(r.body), }) step("停用后同邮箱重注册被明确拒绝并提示找站长(核心回归)", is_deactivated_rejected(r), diff --git a/internal/form/auth.go b/internal/form/auth.go index 4614ac5..a3bb35b 100644 --- a/internal/form/auth.go +++ b/internal/form/auth.go @@ -12,6 +12,9 @@ type Register struct { RepeatPassword string `valid:"required;equal:Password" label:"重复密码" msg:"form.register.repeatPassword"` Recaptcha string `form:"g-recaptcha-response" valid:"required" label:"Recaptcha" msg:"form.register.recaptcha"` Language string `form:"language" label:"界面语言"` // 可选:注册时选择界面语言,留空使用站点默认 + // AgreeRules 注册时勾选「已阅读并同意社区规则」。 + // 服务端必须校验:前端的 required 可以被绕过,而这个勾选是「用户已知悉规则」的唯一凭证。 + AgreeRules string `form:"agree_rules" valid:"required" label:"同意社区规则" msg:"form.register.agreeRules"` } type Login struct { diff --git a/internal/i18n/dict_en.go b/internal/i18n/dict_en.go index 4c9197c..f86929e 100644 --- a/internal/i18n/dict_en.go +++ b/internal/i18n/dict_en.go @@ -47,6 +47,7 @@ var enDict = map[string]string{ "site.footer.drive": "Drive", "site.footer.status": "Status", "site.footer.nav": "Links", + "site.footer.rules": "Rules", "site.maintenance": "The site is under maintenance. Please come back later ~", // Auth @@ -322,6 +323,8 @@ var enDict = map[string]string{ "auth.register.confirm": "Confirm password", "auth.register.language": "Language", "auth.register.languageDefault": "Use site default", + "auth.register.agreePrefix": "I have read and agree to the ", + "auth.register.agreeLink": "community rules", "auth.register.success": "Registration successful, welcome to TamaBox!", // Explore page extras @@ -441,19 +444,20 @@ var enDict = map[string]string{ "report.errFailed": "Failed to submit report, please try again later", // 箱主侧举报标记(只给数量,不给举报人 IP) - "qlist.reported": "%d reports", - "qlist.reportedShort": "!%d", - "qlist.reportFilter": "Reports", - "qlist.reportedOnly": "Reported only", - "qlist.restrictionBanner": "This box is under moderation (%s). Some features are limited until %s. Contact the site owner if you have questions.", + "qlist.reported": "%d reports", + "qlist.reportedShort": "!%d", + "qlist.reportFilter": "Reports", + "qlist.reportedOnly": "Reported only", + "qlist.restrictionBanner": "This box is under moderation (%s). Some features are limited until %s. Contact the site owner if you have questions.", + "qlist.restrictionRulesLink": "See community rules", // 社区规则页(处置依据,公开可访问) "rules.title": "Community rules and content boundaries", "rules.intro": "This is an anonymous question box for collecting questions and answers. It is not a callout board, and it should not become a battlefield for group conflicts.\n\nThe rules below are about one thing: you may dislike a work or a group of people, but you may not use this site to organize attacks on specific individuals.", "rules.forbiddenTitle": "Not allowed", - "rules.forbidden": "1. Callouts / blacklists / exposing accounts\n Naming or pointing to an identifiable person (nickname, alias, profile, work tag) with a derogatory label, or urging others to avoid or attack them.\n\n2. Harassment and insults\n Including coded nicknames with insulting judgments (for example referring to someone as an animal or an object).\n\n3. Inciting group conflict\n Rallying one group against another along faction, stance, or identity lines.\n\n4. Exposing private information\n Real name, address, contact details, school, or employer.", + "rules.forbidden": "1. Severe violations - content is removed immediately and the account may be banned, with no graded handling\n\n 1. Politically sensitive content, or content that endangers national security, undermines social stability, or attacks state institutions or leaders.\n 2. Violence, terrorism, or encouraging self-harm or harm to others.\n 3. Pornography, obscenity, or sexual content involving minors.\n 4. Trade in prohibited goods, gambling, fraud, pyramid schemes, or illegal fundraising.\n 5. Infringing the rights of minors or soliciting minors.\n 6. Exposing private information: real name, address, contact details, ID numbers, school or employer.\n\n2. Community conflicts - handled in graded steps (see the next section)\n\n 7. Callouts / blacklists / exposing accounts: pointing to an identifiable person (nickname, alias, profile, work tag) with a derogatory label, or urging others to avoid or attack them.\n 8. Harassment and insults, including coded nicknames with insulting judgments (for example referring to someone as an animal or an object).\n 9. Inciting group conflict by rallying one group against another along faction, stance, or identity lines.\n 10. Spam, flooding, or bulk account creation.", "rules.enforceTitle": "What happens after a violation", - "rules.enforce": "Actions scale with reach, from light to heavy:\n\n· Stop distribution: content no longer appears in Explore and cannot generate a share card\n· Narrow publishing: new answers are private by default\n· Freeze publishing: answering and publishing are suspended, but receiving still works\n· Suspend the page: the whole box is temporarily unavailable\n· Ban: data removed, email released\n\nEvery action has an expiry date and lifts automatically. Content that has been handled is not pursued again.", + "rules.enforce": "Graded handling applies to community conflicts only:\n\n· Stop distribution: the content no longer appears in Explore and cannot generate a share card\n· Narrow publishing: new answers are private by default\n· Freeze publishing: answering and publishing are suspended, but receiving still works\n· Suspend the page: the whole box is temporarily unavailable\n· Ban: data removed, email released\n\nEvery action has an expiry date and lifts automatically. Content that has been handled is not pursued again.\n\nSevere violations skip the grading entirely: once confirmed, the content is removed at once and the account\nis limited or banned according to severity. Where laws are involved, we cooperate with the authorities as required.", "rules.reportedTitle": "If your content was reported", "rules.reported": "Your dashboard will show \"reported N times\". Deleting the content or setting it private closes the related reports automatically.\n\nThe notice does not mean the platform has judged you. If you believe a report is malicious, you may leave it unhandled, but please make sure the content itself does not attack a specific person.", "rules.attackedTitle": "If you are being attacked", @@ -904,5 +908,6 @@ var enDict = map[string]string{ "form.register.name": "Nickname is required and must be at most 20 characters", "form.register.password": "Please set a password of 8–30 characters", "form.register.recaptcha": "Unable to load the CAPTCHA. Please refresh the page or switch your network and try again", + "form.register.agreeRules": "Please read and accept the community rules first", "form.register.repeatPassword": "The two passwords do not match", } diff --git a/internal/i18n/dict_ja.go b/internal/i18n/dict_ja.go index 9e8f1b2..4086564 100644 --- a/internal/i18n/dict_ja.go +++ b/internal/i18n/dict_ja.go @@ -47,6 +47,7 @@ var jaDict = map[string]string{ "site.footer.drive": "ドライブ", "site.footer.status": "ステータス", "site.footer.nav": "リンク", + "site.footer.rules": "ルール", "site.maintenance": "メンテナンス中です。しばらくお待ちください~", // 認証 @@ -322,6 +323,8 @@ var jaDict = map[string]string{ "auth.register.confirm": "パスワード(確認)", "auth.register.language": "表示言語", "auth.register.languageDefault": "サイト既定に従う", + "auth.register.agreePrefix": "コミュニティルールを読み、同意します:", + "auth.register.agreeLink": "コミュニティルール", "auth.register.success": "登録が完了しました。狼の質問箱へようこそ!", // 探索ページ補足 @@ -441,19 +444,20 @@ var jaDict = map[string]string{ "report.errFailed": "報告の送信に失敗しました。しばらくしてからお試しください", // 箱主侧举报标记(只给数量,不给举报人 IP) - "qlist.reported": "%d 件の報告", - "qlist.reportedShort": "報%d", - "qlist.reportFilter": "報告", - "qlist.reportedOnly": "報告ありのみ", - "qlist.restrictionBanner": "この質問箱は現在プラットフォームによる制限期間中です(%s)。一部機能が制限され、%s に自動解除されます。ご不明な点はフッターの「管理人に連絡」からお問い合わせください。", + "qlist.reported": "%d 件の報告", + "qlist.reportedShort": "報%d", + "qlist.reportFilter": "報告", + "qlist.reportedOnly": "報告ありのみ", + "qlist.restrictionBanner": "この質問箱は現在プラットフォームによる制限期間中です(%s)。一部機能が制限され、%s に自動解除されます。ご不明な点はフッターの「管理人に連絡」からお問い合わせください。", + "qlist.restrictionRulesLink": "コミュニティルールを見る", // 社区规则页(处置依据,公开可访问) "rules.title": "コミュニティルールとコンテンツの境界", "rules.intro": "ここは匿名質問箱で、質問と回答を集めるための場所です。晒しの壁ではなく、集団同士の争いの場でもありません。\n\n以下のルールはひとつのことだけを定めます。ある作品や集団が好きでないのは自由ですが、特定の個人への攻撃をこのサイトで組織することはできません。", "rules.forbiddenTitle": "禁止される内容", - "rules.forbidden": "1. 晒し / 避雷(ブラックリスト)/ アカウントの暴露\n 特定できる個人(ニックネーム、蔑称、プロフィール、作品タグ)を指し、貶す評価を添える、または他者に回避や攻撃を呼びかけるもの。\n\n2. 誹謗中傷・暴言\n 隠語で他人を指し、侮辱的な評価を添えるもの(動物や物に喩えるなどを含む)。\n\n3. 集団対立の扇動\n 界隈・立場・属性を単位として、一方の集団を他方への攻撃に駆り立てるもの。\n\n4. 個人情報の暴露\n 本名、住所、連絡先、学校や勤務先。", + "rules.forbidden": "一、重大な違反 ― コンテンツは直ちに削除し、状況に応じて利用停止(段階的措置は適用しません)\n\n1. 政治的敏感事項、国の安全を害するもの、社会の安定を損なうもの、国家制度や指導者を攻撃する内容。\n2. 暴力、テロリズム、自傷や他者への危害を唆すもの。\n3. ポルノ、低俗、未成年者に関わる性的な内容。\n4. 禁止物品の取引、賭博、詐欺、ネットワークビジネス、違法な資金集め。\n5. 未成年者の権利を侵害するもの、未成年者を誘引するもの。\n6. 他者のプライバシー侵害:本名、住所、連絡先、身分証番号、学校や勤務先。\n\n二、コミュニティ内の対立 ― 影響範囲に応じて段階的に措置(次節参照)\n\n7. 晒し / 避雷 / アカウントの暴露:特定できる個人(ニックネーム、蔑称、プロフィール、作品タグ)を指し、貶す評価を添える、または他者に回避や攻撃を呼びかけるもの。\n8. 誹謗中傷・暴言:隠語で他人を指し侮辱的な評価を添えるもの(動物や物に喩える場合を含む)。\n9. 集団対立の扇動:界隈・立場・属性を単位に、一方の集団を他方への攻撃に駆り立てるもの。\n10. スパム、連投、大量のアカウント作成。", "rules.enforceTitle": "違反が認められた場合", - "rules.enforce": "影響範囲に応じて軽い順に:\n\n· 配信停止:探索ページに出なくなり、共有カードも生成できません\n· 公開の縮小:新しい回答は既定で非公開になります\n· 投稿の凍結:回答と公開の機能を停止(受信は可能)\n· ページの停止:質問箱全体が一時的に閲覧できなくなります\n· 利用停止:データを削除し、メールアドレスを解放\n\nいずれも期限付きで、期限が来ると自動的に解除されます。処理済みの内容が繰り返し問われることはありません。", + "rules.enforce": "段階的措置は「コミュニティ内の対立」にのみ適用されます:\n\n· 配信停止:探索ページに出なくなり、共有カードも生成できません\n· 公開の縮小:新しい回答は既定で非公開になります\n· 投稿の凍結:回答と公開の機能を停止(受信は可能)\n· ページの停止:質問箱全体が一時的に閲覧できなくなります\n· 利用停止:データを削除し、メールアドレスを解放\n\nいずれも期限付きで、期限が来ると自動的に解除されます。処理済みの内容が繰り返し問われることはありません。\n\n「重大な違反」は段階的措置の対象外です。確認でき次第、コンテンツを直ちに削除し、\n状況に応じてアカウントを制限または停止します。法令に関わる部分は、所管機関に協力します。", "rules.reportedTitle": "自分のコンテンツが通報された場合", "rules.reported": "管理画面に「N 件の報告」と表示されます。その内容を削除するか非公開にすると、関連する報告は自動的に閉じられます。\n\nこの通知は、プラットフォームが違反と判断したという意味ではありません。悪意ある通報だと思う場合は対応しなくても構いませんが、内容そのものが特定の個人を攻撃していないことを確認してください。", "rules.attackedTitle": "攻撃を受けている場合", @@ -904,5 +908,6 @@ var jaDict = map[string]string{ "form.register.name": "ニックネームは必須で、20文字以内である必要があります", "form.register.password": "8〜30文字のパスワードを設定してください", "form.register.recaptcha": "CAPTCHAを読み込めません。ページを再読み込みするか、ネットワークを変更してお試しください", + "form.register.agreeRules": "コミュニティルールをお読みのうえ同意してください", "form.register.repeatPassword": "入力した2つのパスワードが一致しません", } diff --git a/internal/i18n/dict_zh_cn.go b/internal/i18n/dict_zh_cn.go index 631a4d6..3b67bf6 100644 --- a/internal/i18n/dict_zh_cn.go +++ b/internal/i18n/dict_zh_cn.go @@ -47,6 +47,7 @@ var zhCNDict = map[string]string{ "site.footer.drive": "盘", "site.footer.status": "监控板", "site.footer.nav": "导航页", + "site.footer.rules": "社区规则", "site.maintenance": "本站正在维护中,请稍后再来~", // 认证 @@ -322,6 +323,8 @@ var zhCNDict = map[string]string{ "auth.register.confirm": "确认密码", "auth.register.language": "界面语言", "auth.register.languageDefault": "跟随站点默认", + "auth.register.agreePrefix": "我已阅读并同意", + "auth.register.agreeLink": "社区规则", "auth.register.success": "注册成功,欢迎来到 狼的提问箱!", // 探索页补充 @@ -441,19 +444,20 @@ var zhCNDict = map[string]string{ "report.errFailed": "举报提交失败,请稍后再试", // 箱主侧举报标记(只给数量,不给举报人 IP) - "qlist.reported": "被举报 %d 次", - "qlist.reportedShort": "报%d", - "qlist.reportFilter": "举报", - "qlist.reportedOnly": "仅被举报", - "qlist.restrictionBanner": "本箱当前处于平台限制期(%s),部分功能受限,至 %s 自动解除。如有疑问请通过页脚「找站长」联系。", + "qlist.reported": "被举报 %d 次", + "qlist.reportedShort": "报%d", + "qlist.reportFilter": "举报", + "qlist.reportedOnly": "仅被举报", + "qlist.restrictionBanner": "本箱当前处于平台限制期(%s),部分功能受限,至 %s 自动解除。如有疑问请通过页脚「找站长」联系。", + "qlist.restrictionRulesLink": "查看社区规则", // 社区规则页(处置依据,公开可访问) "rules.title": "社区规则与内容边界", "rules.intro": "这是一个匿名提问箱,用来收集提问与回答。它不是挂人墙,也不该成为群体冲突的战场。\n\n下面的规则只针对一件事:你可以不喜欢某个作品或某群人,但不能用这个站点组织对具体的人的攻击。", "rules.forbiddenTitle": "明确禁止的内容", - "rules.forbidden": "1. 挂人 / 避雷 / 曝光他人账号\n 指向可识别的个人(昵称、代称、主页、作品标签),并带有贬损定性,或号召他人规避、攻击。\n\n2. 人身攻击与辱骂\n 包括用黑话代称他人并附加侮辱性评价(例如用动物、物件指代某个人)。\n\n3. 挑起群体对立\n 以粉籍、立场、属性为单位,鼓动一群人去攻击另一群人。\n\n4. 曝光私人信息\n 真实姓名、住址、联系方式、学校或工作单位。", + "rules.forbidden": "一、严重违规 —— 直接删除内容并按情节封禁,不适用分级处置\n\n1. 涉及政治敏感、危害国家安全、破坏社会稳定、攻击国家制度或领导人的内容。\n2. 暴力、恐怖主义、教唆自伤或伤害他人。\n3. 色情、低俗、涉及未成年人的性相关内容。\n4. 违禁品交易、赌博、诈骗、传销、非法集资。\n5. 侵犯未成年人权益、诱导未成年人。\n6. 侵犯他人隐私:真实姓名、住址、联系方式、证件号码、学校或工作单位。\n\n二、社区冲突 —— 按影响面分级处置(见下一节)\n\n7. 挂人 / 避雷 / 曝光他人账号:指向可识别的个人(昵称、代称、主页、作品标签),并带有贬损定性,或号召他人规避、攻击。\n8. 人身攻击与辱骂:包括用黑话代称他人并附加侮辱性评价(例如用动物、物件指代某个人)。\n9. 挑起群体对立:以粉籍、立场、属性为单位,鼓动一群人攻击另一群人。\n10. 垃圾广告、刷屏、批量注册。", "rules.enforceTitle": "被认定后会怎么处理", - "rules.enforce": "处理按影响面从轻到重:\n\n· 停止分发:内容不再出现在探索页,也不能生成分享卡\n· 收窄公开:新回答默认不公开\n· 冻结发布:暂停回答与公开功能,仍可收信\n· 暂停页面:整个提问箱暂时不可访问\n· 封禁:删除数据、释放邮箱\n\n所有处置都有期限,到期自动解除。已经处理过的内容不会被反复追责。", + "rules.enforce": "分级处置只适用于「社区冲突」类问题:\n\n· 停止分发:内容不再出现在探索页,也不能生成分享卡\n· 收窄公开:新回答默认不公开\n· 冻结发布:暂停回答与公开功能,仍可收信\n· 暂停页面:整个提问箱暂时不可访问\n· 封禁:删除数据、释放邮箱\n\n所有处置都有期限,到期自动解除。已经处理过的内容不会被反复追责。\n\n「严重违规」不走分级:一经确认,内容立即删除,账号按情节直接限制或封禁;\n涉及违法犯罪的部分,会依法配合有关部门处理。", "rules.reportedTitle": "如果你的内容被举报了", "rules.reported": "后台列表会显示「被举报 N 次」。删除该内容或设为私密后,相关举报会自动关闭。\n\n这条提醒不代表平台已经判定你违规。如果你认为举报是恶意的,可以选择不处理,但请确保内容本身没有攻击具体的人。", "rules.attackedTitle": "如果你被攻击了", @@ -904,5 +908,6 @@ var zhCNDict = map[string]string{ "form.register.name": "昵称不能为空,且不超过 20 个字符", "form.register.password": "请设置 8 至 30 位的密码", "form.register.recaptcha": "无法加载人机验证,请刷新页面或切换网络后重试", + "form.register.agreeRules": "请先阅读并同意社区规则", "form.register.repeatPassword": "两次输入的密码不一致", } diff --git a/internal/i18n/dict_zh_tw.go b/internal/i18n/dict_zh_tw.go index 62b0c43..4602fdd 100644 --- a/internal/i18n/dict_zh_tw.go +++ b/internal/i18n/dict_zh_tw.go @@ -47,6 +47,7 @@ var zhTWDict = map[string]string{ "site.footer.drive": "盤", "site.footer.status": "監控板", "site.footer.nav": "導航頁", + "site.footer.rules": "社群規則", "site.maintenance": "本站正在維護中,請稍後再來~", // 認證 @@ -322,6 +323,8 @@ var zhTWDict = map[string]string{ "auth.register.confirm": "確認密碼", "auth.register.language": "介面語言", "auth.register.languageDefault": "跟隨站點預設", + "auth.register.agreePrefix": "我已閱讀並同意", + "auth.register.agreeLink": "社群規則", "auth.register.success": "註冊成功,歡迎來到 狼的提問箱!", // 探索頁補充 @@ -441,19 +444,20 @@ var zhTWDict = map[string]string{ "report.errFailed": "檢舉提交失敗,請稍後再試", // 箱主侧举报标记(只给数量,不给举报人 IP) - "qlist.reported": "被檢舉 %d 次", - "qlist.reportedShort": "檢%d", - "qlist.reportFilter": "檢舉", - "qlist.reportedOnly": "僅被檢舉", - "qlist.restrictionBanner": "本箱目前處於平台限制期(%s),部分功能受限,至 %s 自動解除。如有疑問請透過頁尾「找站長」聯絡。", + "qlist.reported": "被檢舉 %d 次", + "qlist.reportedShort": "檢%d", + "qlist.reportFilter": "檢舉", + "qlist.reportedOnly": "僅被檢舉", + "qlist.restrictionBanner": "本箱目前處於平台限制期(%s),部分功能受限,至 %s 自動解除。如有疑問請透過頁尾「找站長」聯絡。", + "qlist.restrictionRulesLink": "檢視社群規則", // 社区规则页(处置依据,公开可访问) "rules.title": "社群規則與內容界線", "rules.intro": "這是一個匿名提問箱,用來收集提問與回答。它不是掛人牆,也不該成為群體衝突的戰場。\n\n下面的規則只針對一件事:你可以不喜歡某個作品或某群人,但不能用這個站點組織對具體的人的攻擊。", "rules.forbiddenTitle": "明確禁止的內容", - "rules.forbidden": "1. 掛人 / 避雷 / 曝光他人帳號\n 指向可辨識的個人(暱稱、代稱、主頁、作品標籤),並帶有貶損定性,或號召他人規避、攻擊。\n\n2. 人身攻擊與辱罵\n 包括用黑話代稱他人並附加侮辱性評價(例如用動物、物件指代某個人)。\n\n3. 挑起群體對立\n 以粉籍、立場、屬性為單位,鼓動一群人去攻擊另一群人。\n\n4. 曝光私人資訊\n 真實姓名、住址、聯絡方式、學校或工作單位。", + "rules.forbidden": "一、嚴重違規 —— 直接刪除內容並按情節封禁,不適用分級處置\n\n1. 涉及政治敏感、危害國家安全、破壞社會穩定、攻擊國家制度或領導人的內容。\n2. 暴力、恐怖主義、教唆自傷或傷害他人。\n3. 色情、低俗、涉及未成年人的性相關內容。\n4. 違禁品交易、賭博、詐騙、傳銷、非法集資。\n5. 侵犯未成年人權益、誘導未成年人。\n6. 侵犯他人隱私:真實姓名、住址、聯絡方式、證件號碼、學校或工作單位。\n\n二、社群衝突 —— 按影響面分級處置(見下一節)\n\n7. 掛人 / 避雷 / 曝光他人帳號:指向可辨識的個人(暱稱、代稱、主頁、作品標籤),並帶有貶損定性,或號召他人規避、攻擊。\n8. 人身攻擊與辱罵:包括用黑話代稱他人並附加侮辱性評價(例如用動物、物件指代某個人)。\n9. 挑起群體對立:以粉籍、立場、屬性為單位,鼓動一群人攻擊另一群人。\n10. 垃圾廣告、洗版、批次註冊。", "rules.enforceTitle": "被認定後會怎麼處理", - "rules.enforce": "處理按影響面從輕到重:\n\n· 停止分發:內容不再出現在探索頁,也不能產生分享卡\n· 收窄公開:新回答預設不公開\n· 凍結發佈:暫停回答與公開功能,仍可收信\n· 暫停頁面:整個提問箱暫時無法存取\n· 封禁:刪除資料、釋放信箱\n\n所有處置都有期限,到期自動解除。已經處理過的內容不會被反覆追責。", + "rules.enforce": "分級處置只適用於「社群衝突」類問題:\n\n· 停止分發:內容不再出現在探索頁,也不能產生分享卡\n· 收窄公開:新回答預設不公開\n· 凍結發佈:暫停回答與公開功能,仍可收信\n· 暫停頁面:整個提問箱暫時無法存取\n· 封禁:刪除資料、釋放信箱\n\n所有處置都有期限,到期自動解除。已經處理過的內容不會被反覆追責。\n\n「嚴重違規」不走分級:一經確認,內容立即刪除,帳號按情節直接限制或封禁;\n涉及違法犯罪的部分,會依法配合有關部門處理。", "rules.reportedTitle": "如果你的內容被檢舉了", "rules.reported": "後台列表會顯示「被檢舉 N 次」。刪除該內容或設為私密後,相關檢舉會自動關閉。\n\n這則提醒不代表平台已經判定你違規。如果你認為檢舉是惡意的,可以選擇不處理,但請確保內容本身沒有攻擊具體的人。", "rules.attackedTitle": "如果你被攻擊了", @@ -904,5 +908,6 @@ var zhTWDict = map[string]string{ "form.register.name": "暱稱不能為空,且不超過 20 個字元", "form.register.password": "請設定 8 至 30 位的密碼", "form.register.recaptcha": "無法人機驗證,請重新整理頁面或更換網路後重試", + "form.register.agreeRules": "請先閱讀並同意社群規則", "form.register.repeatPassword": "兩次輸入的密碼不一致", } diff --git a/templates/auth/register.html b/templates/auth/register.html index 2c0045e..9f31d39 100644 --- a/templates/auth/register.html +++ b/templates/auth/register.html @@ -46,6 +46,13 @@ {{ end }} + +
+ {{t .LangCode "auth.register.agreeLink"}} + +
{{ if eq .CaptchaType "math" }} diff --git a/templates/base/footer.html b/templates/base/footer.html index 3f3a6a6..4e9fdaf 100644 --- a/templates/base/footer.html +++ b/templates/base/footer.html @@ -1,6 +1,7 @@


Powered by NekoBox | {{ ICP }}
{{t .LangCode "site.footer.runtime"}}:
+ {{t .LangCode "site.footer.rules"}} | {{t .LangCode "site.footer.admin"}} | {{t .LangCode "site.footer.notice"}} diff --git a/templates/user/question-list.html b/templates/user/question-list.html index 31f74b7..6b5f09d 100644 --- a/templates/user/question-list.html +++ b/templates/user/question-list.html @@ -177,7 +177,7 @@ {{ if .RestrictionLevel }}

-
{{t .LangCode "qlist.restrictionBanner" .RestrictionLevel .RestrictionExpiresAt}}
+
{{t .LangCode "qlist.restrictionBanner" .RestrictionLevel .RestrictionExpiresAt}} · {{t .LangCode "qlist.restrictionRulesLink"}}
{{ end }}