feat: 创作者账号体系(后台开号 → 登录即进创作者中心)+ 创作者中心菜单只给创作者

为什么:创作者此前根本无法登录 —— creator.admin_user_id 只有实体字段、没有任何接口会写它,
C 端申请入驻也没做,等于整条账号链路缺入口。这批先把"后台手工建主体 → 审核 → 开号 → 登录落地"打通;
同时按用户口径收窄菜单:只要不是创作者,就不显示创作者中心。

- 手工建主体:POST /admin/creators(编号可传可自动生成 CR+日期+序号)+ 审核页「新增创作者」
- 开通账号:POST /admin/creators/{id}/account —— 仅 approved 可开(否则 200003)、已开通幂等返回
  (created=false、不回明文)、用户名默认 creator.code 小写且冲突报 200001、随机 10 位初始密码一次性返回、
  建 sys_admin_user + 绑 creator.admin_user_id + 授 creator 角色
- 重置密码:POST /admin/creators/{id}/account/reset-password(同样一次性明文,旧密码立即失效)
- 首登强制改密:sys_admin_user 加 must_change_password 列(幂等 ALTER;不新建表、不复用 two_factor 是因为
  这个标记要能直接驱动登录响应与前端拦截),开号/重置置 1,自助改密后清 0
- 菜单收窄:26-30 从超管收回(sys_role_menu delete);另外发现超管的菜单是"全量兜底"、根本不看角色-菜单表,
  光收授权无效,所以加 sys_menu.super_admin_visible,这几条置 0 —— 超管侧边栏不再出现创作者中心
  (代看代码保留,只是没有入口了,见回执)
- 权限点 creator:account(只授超管);creator:list 之外的读接口未变

实测:未审核开号 200003 / 重复开号幂等 / 用户名冲突 200001 / 重置后旧密码失效新密码可登录 /
新账号只能看到自己的作品;创作者登录直接落 /creator-center/workspace 并弹出首登改密。
This commit is contained in:
Vicky committed 2026-10-15 16:00:42 +08:00
1 parent efeb9fcfaf
commit 414d9fd482
15 files changed
+377 -8

No files matched your search

@@ -5,14 +5,20 @@ import com.fruitshorts.common.pojo.Result;
import com.fruitshorts.creator.dal.entity.Creator;
import com.fruitshorts.creator.dal.entity.CreatorDocument;
import com.fruitshorts.creator.service.CreatorService;
import com.fruitshorts.creator.service.CreatorAccountService;
import com.fruitshorts.creator.vo.CreatorAccountOpenReqVO;
import com.fruitshorts.creator.vo.CreatorAccountRespVO;
import com.fruitshorts.creator.vo.CreatorSaveReqVO;
import com.fruitshorts.creator.vo.CreatorAuditReqVO;
import com.fruitshorts.creator.vo.CreatorQueryReqVO;
import com.fruitshorts.framework.log.OperationLog;
import com.fruitshorts.framework.security.SecurityUtils;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -27,6 +33,7 @@ import java.util.List;
public class CreatorAdminController {
private final CreatorService creatorService;
private final CreatorAccountService creatorAccountService;
@GetMapping("/page")
@PreAuthorize("@ss.hasPermission('creator:list')")
@@ -53,4 +60,29 @@ public class CreatorAdminController {
public Result<Creator> audit(@PathVariable Long id, @RequestBody CreatorAuditReqVO req) {
return Result.ok(creatorService.audit(id, req, SecurityUtils.getUserId()));
}
/** 手工录入创作者主体(C 端申请入驻还没实现,先用它打通链路)。 */
@PostMapping
@PreAuthorize("@ss.hasPermission('creator:audit')")
@OperationLog(module = "创作者管理", action = "新增创作者")
public Result<Long> create(@Valid @RequestBody CreatorSaveReqVO req) {
return Result.ok(creatorService.create(req));
}
/** 开通创作者账号:仅审核通过可开;已开通则幂等返回,不重复建号。 */
@PostMapping("/{id}/account")
@PreAuthorize("@ss.hasPermission('creator:account')")
@OperationLog(module = "创作者管理", action = "开通创作者账号")
public Result<CreatorAccountRespVO> openAccount(@PathVariable Long id,
@RequestBody(required = false) CreatorAccountOpenReqVO req) {
return Result.ok(creatorAccountService.open(id, req == null ? null : req.getUsername()));
}
/** 重置创作者账号密码:一次性明文返回,旧密码立即失效。 */
@PostMapping("/{id}/account/reset-password")
@PreAuthorize("@ss.hasPermission('creator:account')")
@OperationLog(module = "创作者管理", action = "重置创作者密码")
public Result<CreatorAccountRespVO> resetAccountPassword(@PathVariable Long id) {
return Result.ok(creatorAccountService.resetPassword(id));
}
}