Files
StoreWeb/Modules/Store.Users
2026-10-29 11:34:35 +08:00
..
2026-10-23 19:01:28 +08:00
2026-10-29 11:34:35 +08:00
2026-10-29 11:34:35 +08:00
2026-10-23 19:01:28 +08:00
2026-10-23 19:01:28 +08:00
2026-10-29 11:34:35 +08:00
2026-10-29 11:34:35 +08:00
2026-10-29 11:34:35 +08:00

用户模块

参考旧版 D:/Works/KJD_WebService/KJD_WebService/BLL/WXXD/WXUserManage.cs,沿用用户、积分、余额、充值备注等旧表。接口采用 JSON DTO 和现有 Bearer Token 身份,不接受旧版拼接参数或客户端提供的操作者身份。

文件与职责

  • 文件:../Store.Users.Contracts/Dtos/*.cs、Dtos/ShopRenewRequest.cs:非空、长度、数值范围、日期顺序、金额精度和二维码格式。null 更新字段保留原值,空字符串可清空可选文本。
  • 文件:Services/UserAccessPolicy.cs:集中定义管理员、主账号、子账号的操作范围。
  • 文件:Services/UserManagementService.cs:账户增删改查、密码和流水查询。
  • 文件:Services/UserManagementService.TopUp.cs:充值备注和公共代理二维码。
  • 文件:Services/UserFundsService.cs:资金事务、按主键顺序锁定账户、权限校验、请求去重和流水写入。
  • 文件:Commands/ShopRenewCommand.cs、Behaviors/*.cs:续费输入验证 → 事务 → 当前身份、账户归属及积分检查 → 店铺归属 → 扣费及延长有效期。
  • 文件:Repositories/UserRepository.cs:子账号的有效 OEM、费用和积分用户权限继承。
  • 文件:Services/UserPassword.cs:兼容旧明文密码;新建和修改密码保存带盐哈希。

权限规则

身份从登录上下文和数据库读取,管理员为 SaLevel == UserAdminLevel.SuperAdmin;普通主账号必须 GroupId == UserGroup.MainAccount 且无父账号。父账号缺失的子账号不会自动获得主账号权限。

操作 管理员 普通主账号 普通子账号
查询账户、资金流水 任意账户 本人和直属非管理员子账号 本人
创建主账号 允许 不允许 不允许
创建子账号 指定任意主账号 仅挂在本人名下 不允许
修改资料、删除账户 任意账户 本人和直属非管理员子账号 不允许
重置密码 任意账户,包括本人,无需原密码 子账号免原密码,本人需原密码 本人需原密码
积分充值、余额调整 任意账户 不允许 不允许
积分转移 向其他任意账户转出本人的积分 向直属非管理员子账号转出本人的积分 不允许
店铺续费、提交充值备注 任意账户 本人和直属非管理员子账号 本人
处理充值备注 任意账户 本人和直属非管理员子账号 不允许
管理员级别、计费配置、公共充值二维码 允许 不允许 不允许

管理员不受账户归属限制,仍须满足账户存在、余额充足等业务条件。删除要求无余额、无积分、无子账号、无店铺关联;本人满足条件也可删除,成功后注销会话。普通主账号不能向子账号授予自己没有的权限,不能通过管理具有管理员身份的子账号取得管理员权限。

校验与业务边界

DTO 用 [Required] 声明非空,使用数据注解和 IValidatableObject 声明输入规则。Service 入口统一调用 RequestValidator.Validate,续费通过 ValidationBehavior 调用 DTO 校验,保证内部调用也执行输入检查。Service 和后续管道只保留数据库状态、主子关系、权限、资金与店铺归属判断,不再重复校验必填字段。

账户登录名保持稳定,避免破坏店铺和历史流水关联。新建账户的主/子身份由接口决定,GroupId 必须与该身份一致。管理员创建子账号可指定 ParentUserName,普通主账号只能指定本人。查询列表先限定可见范围,再应用筛选与分页;不能用筛选条件扩大权限。

续费命令只接收 ShopRenewRequest,不再接收 OperatorName。管道从 ICurrentUser 读取实际操作者,目标账户省略时默认为本人。店铺必须属于目标账户,扣除目标账户积分,流水记录真实操作者。续费保留旧规则:每月最少 30 积分,在当前有效期和当前时间中较晚者的基础上延长。

资金请求的 Amount 为正数且最多两位小数;积分支持“充值”“转移”,余额支持“充值”“消费”。积分转入仍计入累计充值。资金和流水在同一事务提交;同一目标和资金类型下,重复 RequestId 拒绝再次记账。重试必须复用请求号。充值备注的处理不自动增加余额或积分。

接口与运行

所有用户接口要求 Bearer Token,采用 POST,路由为 v{version}/user/[action]。资料和资金操作使用 JSON 请求体;GetUser、DelUser、GetTopUpQrcode 使用查询参数。分页从 1 开始,默认每页 50 条,最大 200 条。

dotnet build Modules/Store.Users/Store.Users.csproj
dotnet build Store.API/Store.Api.csproj
dotnet run --project Store.API/Store.Api.csproj

连接现有 MySQL 前确认账户表用户名唯一、密码列可容纳 Identity 哈希、资金相关表支持事务。应用不自动创建或修改旧表。旧系统直接比较明文密码的登录接口不能识别新哈希,需随调用方迁移。

使用 dotnet test Tests/Store.Users.Tests/Store.Users.Tests.csproj 验证参数、权限、密码、资金和 HTTP 接口。SQLite 测试不能替代真实 MySQL 的并发与表结构联调。旧文件中的 E57 令牌、销售助手 Cookie、淘宝买手不属于本模块范围。可以继续使用“代码审查”检查实现质量。