From 4f80a691d1719c9ff94fbd95752f2867f7aa8cc4 Mon Sep 17 00:00:00 2001 From: Zhou Weidong <502333560@qq.com> Date: Fri, 23 Oct 2026 16:45:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(app-version):=20=E5=8A=A0=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=88=9B=E5=BB=BA=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AppVersionAdminController.java | 13 ++++++++ .../system/service/AppVersionService.java | 24 ++++++++++++++ sql/patch-2026-10-23-app-version-fix.sql | 32 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 sql/patch-2026-10-23-app-version-fix.sql diff --git a/fruitshorts-admin-api/src/main/java/com/fruitshorts/admin/controller/AppVersionAdminController.java b/fruitshorts-admin-api/src/main/java/com/fruitshorts/admin/controller/AppVersionAdminController.java index 434c421..165b4e2 100644 --- a/fruitshorts-admin-api/src/main/java/com/fruitshorts/admin/controller/AppVersionAdminController.java +++ b/fruitshorts-admin-api/src/main/java/com/fruitshorts/admin/controller/AppVersionAdminController.java @@ -12,6 +12,8 @@ import com.fruitshorts.system.vo.AppVersionSaveReqVO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Size; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; @@ -56,6 +58,17 @@ public class AppVersionAdminController { return Result.ok(appVersionService.create(req)); } + @Operation(summary = "批量新建版本(一次事务)") + @PostMapping("/batch") + @PreAuthorize("@ss.hasPermission('app-version:create')") + @OperationLog(module = "版本管理", action = "批量新建版本") + public Result> batchCreate( + @NotEmpty(message = "请至少传一条") + @Size(max = 16, message = "单次不超过 16 条") + @Valid @RequestBody java.util.List<@Valid AppVersionSaveReqVO> reqs) { + return Result.ok(appVersionService.batchCreate(reqs)); + } + @Operation(summary = "编辑版本") @PutMapping("/{id}") @PreAuthorize("@ss.hasPermission('app-version:update')") diff --git a/fruitshorts-module-system/src/main/java/com/fruitshorts/system/service/AppVersionService.java b/fruitshorts-module-system/src/main/java/com/fruitshorts/system/service/AppVersionService.java index 1f4172a..0f2a775 100644 --- a/fruitshorts-module-system/src/main/java/com/fruitshorts/system/service/AppVersionService.java +++ b/fruitshorts-module-system/src/main/java/com/fruitshorts/system/service/AppVersionService.java @@ -64,6 +64,30 @@ public class AppVersionService { return v.getId(); } + /** 批量新建:一次事务全插或全回滚。 */ + @Transactional(rollbackFor = Exception.class) + public List batchCreate(List reqs) { + if (reqs == null || reqs.isEmpty()) { + throw new ServiceException(ErrorCode.BAD_REQUEST, "请至少传一条"); + } + if (reqs.size() > 16) { + throw new ServiceException(ErrorCode.BAD_REQUEST, "单次不超过 16 条"); + } + LocalDateTime now = LocalDateTime.now(); + List ids = new java.util.ArrayList<>(); + for (AppVersionSaveReqVO req : reqs) { + String platform = normalizePlatform(req.getPlatform()); + checkDuplicate(platform, req.getVersionCode(), null); + AppVersion v = new AppVersion(); + applyFields(v, req, platform); + v.setStatus(1); + v.setReleasedAt(now); + versionMapper.insert(v); + ids.add(v.getId()); + } + return ids; + } + @Transactional(rollbackFor = Exception.class) public void update(Long id, AppVersionSaveReqVO req) { String platform = normalizePlatform(req.getPlatform()); diff --git a/sql/patch-2026-10-23-app-version-fix.sql b/sql/patch-2026-10-23-app-version-fix.sql new file mode 100644 index 0000000..17e5a4f --- /dev/null +++ b/sql/patch-2026-10-23-app-version-fix.sql @@ -0,0 +1,32 @@ +-- Author: fruit.com.cn +-- 修正 App 版本管理的菜单与权限: +-- 1) 删除误加的 BUTTON 类型菜单 40-44(项目其他模块都只在 permission_code 里挂权限点, +-- 不在 sys_menu 里建按钮行,否则前端菜单渲染会多出无用条目) +-- 2) 在 sys_permission 里加 app-version 完整权限点 +-- 3) 给超级管理员(role_id=1)授权这些权限点 + +-- 1) 删除多余的 BUTTON 菜单 +DELETE FROM sys_role_menu WHERE menu_id IN (40, 41, 42, 43, 44); +DELETE FROM sys_menu WHERE id IN (40, 41, 42, 43, 44); + +-- 2) 权限点(code 唯一约束兜底) +INSERT INTO sys_permission (id, code, name, group_name, type, sort) VALUES + (50000101, 'app-version:list', '版本管理-查看', 'App 版本', 'BUTTON', 1), + (50000102, 'app-version:create', '版本管理-新增', 'App 版本', 'BUTTON', 2), + (50000103, 'app-version:update', '版本管理-编辑', 'App 版本', 'BUTTON', 3), + (50000104, 'app-version:delete', '版本管理-删除', 'App 版本', 'BUTTON', 4) +ON CONFLICT (code) DO NOTHING; + +-- 3) 超管授权(id 按现有 MAX+1 顺延) +INSERT INTO sys_role_permission (id, role_id, permission_id) +SELECT 50001, 1, p.id FROM sys_permission p WHERE p.code = 'app-version:list' +ON CONFLICT DO NOTHING; +INSERT INTO sys_role_permission (id, role_id, permission_id) +SELECT 50002, 1, p.id FROM sys_permission p WHERE p.code = 'app-version:create' +ON CONFLICT DO NOTHING; +INSERT INTO sys_role_permission (id, role_id, permission_id) +SELECT 50003, 1, p.id FROM sys_permission p WHERE p.code = 'app-version:update' +ON CONFLICT DO NOTHING; +INSERT INTO sys_role_permission (id, role_id, permission_id) +SELECT 50004, 1, p.id FROM sys_permission p WHERE p.code = 'app-version:delete' +ON CONFLICT DO NOTHING;