Skip to content

Commit e8b4b4c

Browse files
committed
feat(membership): 为会员系统添加管理员功能并重构响应处理
- 添加管理员VIP管理页面和相关API接口 - 实现管理员分页查询、新增免费VIP、更新VIP信息等功能 - 添加管理员退款和延长VIP到期时间功能 - 重构响应处理方法,统一使用renderSuccess和renderError - 添加解析参数和解析用户ID的工具方法 - 优化文章查询逻辑,移除不必要的列表大小限制 - 完善会员开通时的奖励背包发放机制 - 添加会员状态管理和过期处理逻辑 - 引入RepositoryException和UserRepository依赖 - 优化会员数据模型和服务层交互逻辑
1 parent ddd54a0 commit e8b4b4c

File tree

18 files changed

+2336
-190
lines changed

18 files changed

+2336
-190
lines changed

AGENTS.md

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,61 @@
1-
## 项目约定
1+
## 用户关键要求
22
- 所有文件不要直接修改 `.css`,而是修改 `.scss`,然后执行 `yarn run build` 生成新的 CSS。js同理,请修改js,而不是min.js,然后同样是通过 `yarn run build` 编译min.js
33
- 在 WSL 中执行 Maven 时,优先复用 Windows 本地仓库:`-Dmaven.repo.local=/mnt/c/.m2/repository`(对应 Windows 的 `C:\.m2\repository`),可避免依赖下载时的 SSL 握手失败;Java 版本固定使用 25。
44
- 如果你的更改涉及到操作数据库,请注意在引用Repository类的时候不要加上包名org.b3log.latke.repository,如果没有请直接import,另外除了查询以外,增、删、改 所有写入的操作都需要用Transaction进行完整的事务commit,否则会无法正常写入。
55
- 涉及到前端的更改,请不要只修改classic(PC端)皮肤,mobile(移动端)皮肤也要同步修改
66
- 涉及到新增 Repository(新增表/集合)时,除了 SQL 建表外,必须同步更新 `src/main/resources/repository.json`,并且 Repository 的 `super("...")`/模型常量中不要写 `symphony_` 前缀(框架会根据 `jdbc.tablePrefix` 自动加前缀)。
77
- 除非用户提到代码编译有问题或者主动要求你进行编译,否则不要使用mvn编译java,这个过程会浪费用户的时间,除非你觉得非常有必要,并且询问用户且被同意
8+
- 每次遇到新的项目架构关键信息,对后续项目AI使用有帮助的,请主动维护AGENTS.md,注意每次维护不要过度细节,只要让AI正确理解就可以了,防止prompt token过长
89

9-
## 项目基本结构
10-
- 后端 Java 代码:`src/main/java/org/b3log/symphony`
11-
- 入口:`Server.java`
12-
- `processor`:路由/控制层(Web/API)
13-
- `service`:业务逻辑
14-
- `repository`:数据访问
15-
- `model`:领域模型
16-
- `util`:通用工具
17-
- 资源与配置:`src/main/resources`
18-
- 配置:`symphony.properties``latke.properties``log4j2.xml``lang_*.properties`
19-
- 静态资源:`images/``js/``css/``scss/`
20-
- 模板皮肤:`skins/`(classic / mobile,Freemarker `.ftl`
21-
- 前端静态输出:`src/main/webapp/css``src/main/webapp/js`
22-
- 构建工具:后端 Maven(`pom.xml`);前端资源 Gulp(`gulpfile.js``package.json`
10+
## 协作目标
11+
- `AGENTS.md` 保持精简,只保留会影响决策的长期约定;新增内容优先补充“关键链路”,避免堆砌背景信息。
2312

24-
## 项目基本功能
25-
- 用户与权限:登录/注册、角色权限、MFA、个人设置(User/Role/MFA/Settings)
26-
- 内容与互动:帖子/长文、评论、投票、关注、转发(Article/Comment/Vote/Follow/Forward)
27-
- 话题与聚合:标签、领域(Domain)、城市聚合(Tag/Domain/City)
28-
- 动态与通知:轻量动态(Breezemoon)、站内通知、活动、里程碑、举报(Breezemoon/Notification/Activity/Milestone/Report)
29-
- 运营与积分:勋章、会员、积分与奖励、邀请码、优惠券(Medal/Membership/Point/Reward/Invitecode/Coupon)
30-
- 其他能力:聊天/聊天室、文件上传、搜索、统计、商城、微信支付(Chat/Chatroom/Upload/Search/Statistic/Shop/WeChatPay)
31-
- AI 能力:`AIProviderFactory`(OpenAI 兼容 / 通义千问)
13+
## 开发硬约束
14+
- 前端改动只改源码:`.scss` 与非 `min.js`;执行 `yarn run build` 生成产物;`classic``mobile` 皮肤需同步修改。
15+
- WSL 执行 Maven 优先使用:`-Dmaven.repo.local=/mnt/c/.m2/repository`;Java 固定 25。
16+
- 未经用户明确要求,不主动执行 `mvn` 编译。
17+
- 涉及数据库写操作(增/删/改)必须使用 `Transaction` 并完整 `commit`
18+
- `Repository` 相关类直接 `import`,不要在代码里写 `org.b3log.latke.repository` 全限定名。
19+
- 新增 Repository(新表/集合)时:同步更新 `src/main/resources/repository.json``super("...")`/模型常量不要写 `symphony_` 前缀。
20+
- 安全基线(已审计):防扫描验证码链路核心在 `BeforeRequestHandler` + `AnonymousViewCheckMidware#handle` + `CaptchaProcessor#validateCaptcha``LoginCheckMidware#handle` 负责登录态校验(含 apiKey),两套逻辑都不可被绕过。
21+
- 访问控制基线(已审计):当前未登录可访问并不只首页/文章/登录/注册,还包含验证码页、`/about``/download``/privacy``/agreement` 及部分公开 API;匿名可访问范围还受 `symphony.properties``anonymous.viewSkips` 影响。
22+
- 新增页面/路由默认要求登录(优先挂 `loginCheck::handle`);若业务必须匿名访问,必须显式接入 `anonymousViewCheckMidware::handle` 并评审风险,不能裸放。
23+
- 新增或改造登录/入口逻辑必须做回归:未登录拦截、登录后放行、黑名单 IP 跳转 `/test``/validateCaptcha` 解封、开发模式关闭风控后行为一致。
24+
- `loginCheck::handle` 默认兼容 `Sessions` + `apiKey`(query 参数与 JSON body),并写入 `context.attr(User.USER)`;后续处理逻辑优先从该 attr 取当前用户。
25+
- `apiCheck::handle` 同样支持 `apiKey` 并写入 `context.attr(User.USER)`,但未登录返回 JSON `{"result":"Unauthorized"}`;适合纯 API 场景。
26+
- `permissionMidware::check` 只做权限判断,不负责写入 `context.attr(User.USER)`;若处理方法还需要当前用户信息,必须自行取用户(或叠加 `loginCheck`)。
27+
- 处理方法取当前用户推荐顺序:`context.attr(User.USER)` -> `Sessions.getUser()` -> `ApiProcessor.getUserByKey(...)`;不要只依赖 `Sessions.getUser()`
28+
- 接口设计安全约束:前后端新增/改造接口时,必须同时评估常见漏洞(越权、未鉴权访问、CSRF、XSS、注入、SSRF、批量请求滥用、敏感信息泄露)。
29+
- 字符串输入必须做限制与校验:长度上限、空白处理、字符白名单/黑名单、格式校验(如用户名/URL/JSON)、必要的转义或编码;禁止直接信任前端传参。
30+
- 涉及业务规则(可用字符、最大长度、是否允许 HTML/Markdown、过滤策略)不明确时,先与用户确认规则再实现,避免误伤或放漏。
31+
32+
## 目录速览
33+
- 后端:`src/main/java/org/b3log/symphony`(入口 `Server.java`,核心分层 `processor/service/repository/model/util`)。
34+
- 资源:`src/main/resources`(配置、静态资源、`skins` 模板)。
35+
- 前端编译输出:`src/main/webapp/css``src/main/webapp/js`
36+
- 构建:后端 Maven(`pom.xml`),前端 Gulp(`gulpfile.js``package.json`)。
37+
38+
## 关键链路(持续维护)
39+
- 勋章管理页:`/admin/medal`
40+
- 后端:`src/main/java/org/b3log/symphony/processor/MedalProcessor.java``showAdminMedal``register`
41+
- 前端:`src/main/resources/js/medal.js`
42+
- 模板:`src/main/resources/skins/classic/admin/medal.ftl``src/main/resources/skins/mobile/admin/medal.ftl`
43+
- 管理 API:`/api/medal/admin/list``/api/medal/admin/search``/api/medal/admin/grant``/api/medal/admin/revoke``/api/medal/admin/owners`
44+
- 会员状态 API:`GET /api/membership/{userId}``MembershipProcessor#getUserMembershipStatus`
45+
- VIP 管理页:`/admin/vip``MembershipProcessor#showAdminVipManagePage`,classic/mobile 同路径模板 `admin/vip.ftl`)。
46+
- VIP 管理 API(仅 `adminRole`):`/api/admin/vip/list``/api/admin/vip/add``/api/admin/vip/update``/api/admin/vip/refund``/api/admin/vip/extend`
47+
- VIP 管理服务关键方法位于 `MembershipMgmtService`:免费新增(不扣积分)、手工维护、按剩余天数退款并失效。
48+
- VIP 按天退款成功后会复用“系统转账通知”(`Notification.DATA_TYPE_C_POINT_TRANSFER`)给用户发送站内通知。
49+
- 积分变更统一走 `PointtransferMgmtService`:独立流程用 `transfer(...)`(方法内自带事务);若外层已有事务,必须用 `transferInCurrentTransaction(...)` 避免事务冲突。
50+
- 发积分/扣积分约定:发积分用 `fromId=Pointtransfer.ID_C_SYS``toId=userId`;扣积分用 `fromId=userId``toId=Pointtransfer.ID_C_SYS`(常用类型 `Pointtransfer.TRANSFER_TYPE_C_ABUSE_DEDUCT`)。
51+
- 需要给用户发“系统转账通知”时:在转账成功拿到 `transferId` 后,调用 `NotificationMgmtService#addPointTransferNotification`,并设置 `Notification.NOTIFICATION_USER_ID``Notification.NOTIFICATION_DATA_ID=transferId`
52+
- VIP 管理页配置项不再手填 JSON:前端依据等级 `benefits` 模板自动生成可视化表单,再序列化为 `configJson` 提交。
53+
- VIP 管理页样式需注意 `home.css``.form--admin label { flex: 1; }` 会影响布局;配置项行在 `vip-admin.scss` 中需显式改为整行(label/builder 100%)并对 checkbox 使用类型选择器,避免控件被放大。
54+
- 有效期字段:勋章 `expireTime`(毫秒,`0`=永久);会员 `expiresAt`(可回填勋章到期)。
55+
- 首页最新文章链路:`IndexProcessor#loadIndexData` 通过 `ArticleQueryService#getIndexRecentArticles(fetchSize, page)` 组装 classic/mobile 首页“最新文章”;第一页置顶插入与数量行为在该方法维护。
56+
- 路由总入口:`Router#requestMapping` + 各 Processor `register()`;新增路由先决定使用 `loginCheck` / `apiCheck` / `permission` / `anonymousViewCheck` 哪条链路。
57+
- `LoginCheckMidware#handle`:未登录统一 401(特殊 URI `/gen` 返回空 SVG);支持 `Sessions``apiKey` 两种登录态来源。
58+
- 新接口若需“页面登录态 + apiKey 调用”双兼容,路由层优先挂 `loginCheck::handle`,处理方法再读取 `context.attr(User.USER)`;避免只挂 `permission` 导致拿不到当前用户对象。
59+
- `AnonymousViewCheckMidware#handle`:匿名访问触发验证码(2 小时首次访问 + 每 5 次访问),并结合 `anonymous.viewSkips`、文章匿名开关、匿名访问次数 Cookie 限制。
60+
- `Server` 启动逻辑:`DEVELOPMENT` 模式会关闭 `Firewall``AnonymousViewCheck`(验证码盾),联调时不要误判“线上无校验”。
61+
- 历史遗留:部分接口未在路由层挂登录中间件而在方法内鉴权(如 `MedalProcessor#requireAdmin/requireLogin``UserProcessor` 的 goldFingerKey 系列);新增接口不要复用该模式,优先路由层显式鉴权。

0 commit comments

Comments
 (0)