From 35cc034af10b3d38de9f7fc26100f7bf324a03dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Sat, 28 Mar 2026 21:33:42 +0800 Subject: [PATCH] =?UTF-8?q?feat(generator):=20=E6=B7=BB=E5=8A=A0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=94=9F=E6=88=90=E5=B7=A5=E5=85=B7=E5=8F=8A=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=AE=9E=E4=BD=93=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 AppGenerator 代码生成工具类,支持多平台模板生成 - 生成 app_credential 应用密钥凭证的完整CRUD功能模块 - 生成 app_event 应用操作动态的完整CRUD功能模块 - 添加对应的 Entity、Controller、Service、Mapper 和 Param 类 - 配置多平台模板支持(Vue、UniApp、移动端页面) - 实现 app.config.ts 自动更新功能 - 优化后端实现指南文档说明 --- docs/ai/后端实现指南.md | 3 +- ...t_mp_customer_step1_4_approval_columns.sql | 24 ++ .../controller/AppCredentialController.java | 129 ++++++ .../app/controller/AppEventController.java | 129 ++++++ .../app/controller/AppUserController.java | 129 ++++++ .../app/controller/AppVersionController.java | 129 ++++++ .../gxwebsoft/app/entity/AppCredential.java | 80 ++++ .../com/gxwebsoft/app/entity/AppEvent.java | 76 ++++ .../com/gxwebsoft/app/entity/AppUser.java | 67 +++ .../com/gxwebsoft/app/entity/AppVersion.java | 85 ++++ .../app/mapper/AppCredentialMapper.java | 37 ++ .../gxwebsoft/app/mapper/AppEventMapper.java | 37 ++ .../gxwebsoft/app/mapper/AppUserMapper.java | 37 ++ .../app/mapper/AppVersionMapper.java | 37 ++ .../app/mapper/xml/AppCredentialMapper.xml | 78 ++++ .../app/mapper/xml/AppEventMapper.xml | 72 ++++ .../app/mapper/xml/AppUserMapper.xml | 63 +++ .../app/mapper/xml/AppVersionMapper.xml | 81 ++++ .../app/param/AppCredentialParam.java | 71 ++++ .../gxwebsoft/app/param/AppEventParam.java | 68 ++++ .../com/gxwebsoft/app/param/AppUserParam.java | 58 +++ .../gxwebsoft/app/param/AppVersionParam.java | 78 ++++ .../app/service/AppCredentialService.java | 42 ++ .../app/service/AppEventService.java | 42 ++ .../gxwebsoft/app/service/AppUserService.java | 42 ++ .../app/service/AppVersionService.java | 42 ++ .../impl/AppCredentialServiceImpl.java | 47 +++ .../app/service/impl/AppEventServiceImpl.java | 47 +++ .../app/service/impl/AppUserServiceImpl.java | 47 +++ .../service/impl/AppVersionServiceImpl.java | 47 +++ .../com/gxwebsoft/generator/AppGenerator.java | 384 ++++++++++++++++++ 31 files changed, 2307 insertions(+), 1 deletion(-) create mode 100644 docs/sql/credit_mp_customer_step1_4_approval_columns.sql create mode 100644 src/main/java/com/gxwebsoft/app/controller/AppCredentialController.java create mode 100644 src/main/java/com/gxwebsoft/app/controller/AppEventController.java create mode 100644 src/main/java/com/gxwebsoft/app/controller/AppUserController.java create mode 100644 src/main/java/com/gxwebsoft/app/controller/AppVersionController.java create mode 100644 src/main/java/com/gxwebsoft/app/entity/AppCredential.java create mode 100644 src/main/java/com/gxwebsoft/app/entity/AppEvent.java create mode 100644 src/main/java/com/gxwebsoft/app/entity/AppUser.java create mode 100644 src/main/java/com/gxwebsoft/app/entity/AppVersion.java create mode 100644 src/main/java/com/gxwebsoft/app/mapper/AppCredentialMapper.java create mode 100644 src/main/java/com/gxwebsoft/app/mapper/AppEventMapper.java create mode 100644 src/main/java/com/gxwebsoft/app/mapper/AppUserMapper.java create mode 100644 src/main/java/com/gxwebsoft/app/mapper/AppVersionMapper.java create mode 100644 src/main/java/com/gxwebsoft/app/mapper/xml/AppCredentialMapper.xml create mode 100644 src/main/java/com/gxwebsoft/app/mapper/xml/AppEventMapper.xml create mode 100644 src/main/java/com/gxwebsoft/app/mapper/xml/AppUserMapper.xml create mode 100644 src/main/java/com/gxwebsoft/app/mapper/xml/AppVersionMapper.xml create mode 100644 src/main/java/com/gxwebsoft/app/param/AppCredentialParam.java create mode 100644 src/main/java/com/gxwebsoft/app/param/AppEventParam.java create mode 100644 src/main/java/com/gxwebsoft/app/param/AppUserParam.java create mode 100644 src/main/java/com/gxwebsoft/app/param/AppVersionParam.java create mode 100644 src/main/java/com/gxwebsoft/app/service/AppCredentialService.java create mode 100644 src/main/java/com/gxwebsoft/app/service/AppEventService.java create mode 100644 src/main/java/com/gxwebsoft/app/service/AppUserService.java create mode 100644 src/main/java/com/gxwebsoft/app/service/AppVersionService.java create mode 100644 src/main/java/com/gxwebsoft/app/service/impl/AppCredentialServiceImpl.java create mode 100644 src/main/java/com/gxwebsoft/app/service/impl/AppEventServiceImpl.java create mode 100644 src/main/java/com/gxwebsoft/app/service/impl/AppUserServiceImpl.java create mode 100644 src/main/java/com/gxwebsoft/app/service/impl/AppVersionServiceImpl.java create mode 100644 src/test/java/com/gxwebsoft/generator/AppGenerator.java diff --git a/docs/ai/后端实现指南.md b/docs/ai/后端实现指南.md index c4bde09..e9f7e38 100644 --- a/docs/ai/后端实现指南.md +++ b/docs/ai/后端实现指南.md @@ -9,7 +9,8 @@ ### 1. 修改 credit_mp_customer 表结构 ```sql --- 为第5-7步添加字段(第1-4步字段已存在) +-- 为第5-7步添加字段(第1-4步基础字段已存在;如未包含审核时间/审核人字段,请先补齐 step1-4 的 approved_at/approved_by) +-- 参考:docs/sql/credit_mp_customer_step1_4_approval_columns.sql -- 第5步:合同签订 ALTER TABLE credit_mp_customer ADD COLUMN follow_step5_submitted TINYINT DEFAULT 0 COMMENT '是否已提交'; ALTER TABLE credit_mp_customer ADD COLUMN follow_step5_submitted_at VARCHAR(255) COMMENT '提交时间'; diff --git a/docs/sql/credit_mp_customer_step1_4_approval_columns.sql b/docs/sql/credit_mp_customer_step1_4_approval_columns.sql new file mode 100644 index 0000000..9dbbe0f --- /dev/null +++ b/docs/sql/credit_mp_customer_step1_4_approval_columns.sql @@ -0,0 +1,24 @@ +-- 修复:审核接口(updateStepApproval)会写入 follow_step{1..4}_approved_at / follow_step{1..4}_approved_by +-- 若数据库缺少这些列,会触发:Unknown column 'follow_step1_approved_at' in 'field list' +-- +-- 建议先检查: +-- SHOW COLUMNS FROM credit_mp_customer LIKE 'follow_step%_approved%'; +-- +-- 然后按需执行下面的 ALTER TABLE(如果你的 MySQL 版本支持,也可以改为 ADD COLUMN IF NOT EXISTS)。 + +-- 第1步:案件受理 +ALTER TABLE credit_mp_customer ADD COLUMN follow_step1_approved_at VARCHAR(255) NULL COMMENT '第1步审核时间'; +ALTER TABLE credit_mp_customer ADD COLUMN follow_step1_approved_by BIGINT NULL COMMENT '第1步审核人ID'; + +-- 第2步:材料准备 +ALTER TABLE credit_mp_customer ADD COLUMN follow_step2_approved_at VARCHAR(255) NULL COMMENT '第2步审核时间'; +ALTER TABLE credit_mp_customer ADD COLUMN follow_step2_approved_by BIGINT NULL COMMENT '第2步审核人ID'; + +-- 第3步:案件办理 +ALTER TABLE credit_mp_customer ADD COLUMN follow_step3_approved_at VARCHAR(255) NULL COMMENT '第3步审核时间'; +ALTER TABLE credit_mp_customer ADD COLUMN follow_step3_approved_by BIGINT NULL COMMENT '第3步审核人ID'; + +-- 第4步:送达签收 +ALTER TABLE credit_mp_customer ADD COLUMN follow_step4_approved_at VARCHAR(255) NULL COMMENT '第4步审核时间'; +ALTER TABLE credit_mp_customer ADD COLUMN follow_step4_approved_by BIGINT NULL COMMENT '第4步审核人ID'; + diff --git a/src/main/java/com/gxwebsoft/app/controller/AppCredentialController.java b/src/main/java/com/gxwebsoft/app/controller/AppCredentialController.java new file mode 100644 index 0000000..17e68da --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/controller/AppCredentialController.java @@ -0,0 +1,129 @@ +package com.gxwebsoft.app.controller; + +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.app.service.AppCredentialService; +import com.gxwebsoft.app.entity.AppCredential; +import com.gxwebsoft.app.param.AppCredentialParam; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.BatchParam; +import com.gxwebsoft.common.core.annotation.OperationLog; +import com.gxwebsoft.common.system.entity.User; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 应用密钥凭证控制器 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Tag(name = "应用密钥凭证管理") +@RestController +@RequestMapping("/api/app/app-credential") +public class AppCredentialController extends BaseController { + @Resource + private AppCredentialService appCredentialService; + + @PreAuthorize("hasAuthority('app:appCredential:list')") + @Operation(summary = "分页查询应用密钥凭证") + @GetMapping("/page") + public ApiResult> page(AppCredentialParam param) { + // 使用关联查询 + return success(appCredentialService.pageRel(param)); + } + + @PreAuthorize("hasAuthority('app:appCredential:list')") + @Operation(summary = "查询全部应用密钥凭证") + @GetMapping() + public ApiResult> list(AppCredentialParam param) { + // 使用关联查询 + return success(appCredentialService.listRel(param)); + } + + @PreAuthorize("hasAuthority('app:appCredential:list')") + @Operation(summary = "根据id查询应用密钥凭证") + @GetMapping("/{id}") + public ApiResult get(@PathVariable("id") Integer id) { + // 使用关联查询 + return success(appCredentialService.getByIdRel(id)); + } + + @PreAuthorize("hasAuthority('app:appCredential:save')") + @OperationLog + @Operation(summary = "添加应用密钥凭证") + @PostMapping() + public ApiResult save(@RequestBody AppCredential appCredential) { + // 记录当前登录用户id + User loginUser = getLoginUser(); + if (loginUser != null) { + appCredential.setUserId(loginUser.getUserId()); + } + if (appCredentialService.save(appCredential)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('app:appCredential:update')") + @OperationLog + @Operation(summary = "修改应用密钥凭证") + @PutMapping() + public ApiResult update(@RequestBody AppCredential appCredential) { + if (appCredentialService.updateById(appCredential)) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('app:appCredential:remove')") + @OperationLog + @Operation(summary = "删除应用密钥凭证") + @DeleteMapping("/{id}") + public ApiResult remove(@PathVariable("id") Integer id) { + if (appCredentialService.removeById(id)) { + return success("删除成功"); + } + return fail("删除失败"); + } + + @PreAuthorize("hasAuthority('app:appCredential:save')") + @OperationLog + @Operation(summary = "批量添加应用密钥凭证") + @PostMapping("/batch") + public ApiResult saveBatch(@RequestBody List list) { + if (appCredentialService.saveBatch(list)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('app:appCredential:update')") + @OperationLog + @Operation(summary = "批量修改应用密钥凭证") + @PutMapping("/batch") + public ApiResult removeBatch(@RequestBody BatchParam batchParam) { + if (batchParam.update(appCredentialService, "id")) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('app:appCredential:remove')") + @OperationLog + @Operation(summary = "批量删除应用密钥凭证") + @DeleteMapping("/batch") + public ApiResult removeBatch(@RequestBody List ids) { + if (appCredentialService.removeByIds(ids)) { + return success("删除成功"); + } + return fail("删除失败"); + } + +} diff --git a/src/main/java/com/gxwebsoft/app/controller/AppEventController.java b/src/main/java/com/gxwebsoft/app/controller/AppEventController.java new file mode 100644 index 0000000..84a7413 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/controller/AppEventController.java @@ -0,0 +1,129 @@ +package com.gxwebsoft.app.controller; + +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.app.service.AppEventService; +import com.gxwebsoft.app.entity.AppEvent; +import com.gxwebsoft.app.param.AppEventParam; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.BatchParam; +import com.gxwebsoft.common.core.annotation.OperationLog; +import com.gxwebsoft.common.system.entity.User; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 应用操作动态控制器 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Tag(name = "应用操作动态管理") +@RestController +@RequestMapping("/api/app/app-event") +public class AppEventController extends BaseController { + @Resource + private AppEventService appEventService; + + @PreAuthorize("hasAuthority('app:appEvent:list')") + @Operation(summary = "分页查询应用操作动态") + @GetMapping("/page") + public ApiResult> page(AppEventParam param) { + // 使用关联查询 + return success(appEventService.pageRel(param)); + } + + @PreAuthorize("hasAuthority('app:appEvent:list')") + @Operation(summary = "查询全部应用操作动态") + @GetMapping() + public ApiResult> list(AppEventParam param) { + // 使用关联查询 + return success(appEventService.listRel(param)); + } + + @PreAuthorize("hasAuthority('app:appEvent:list')") + @Operation(summary = "根据id查询应用操作动态") + @GetMapping("/{id}") + public ApiResult get(@PathVariable("id") Integer id) { + // 使用关联查询 + return success(appEventService.getByIdRel(id)); + } + + @PreAuthorize("hasAuthority('app:appEvent:save')") + @OperationLog + @Operation(summary = "添加应用操作动态") + @PostMapping() + public ApiResult save(@RequestBody AppEvent appEvent) { + // 记录当前登录用户id + User loginUser = getLoginUser(); + if (loginUser != null) { + appEvent.setUserId(loginUser.getUserId()); + } + if (appEventService.save(appEvent)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('app:appEvent:update')") + @OperationLog + @Operation(summary = "修改应用操作动态") + @PutMapping() + public ApiResult update(@RequestBody AppEvent appEvent) { + if (appEventService.updateById(appEvent)) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('app:appEvent:remove')") + @OperationLog + @Operation(summary = "删除应用操作动态") + @DeleteMapping("/{id}") + public ApiResult remove(@PathVariable("id") Integer id) { + if (appEventService.removeById(id)) { + return success("删除成功"); + } + return fail("删除失败"); + } + + @PreAuthorize("hasAuthority('app:appEvent:save')") + @OperationLog + @Operation(summary = "批量添加应用操作动态") + @PostMapping("/batch") + public ApiResult saveBatch(@RequestBody List list) { + if (appEventService.saveBatch(list)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('app:appEvent:update')") + @OperationLog + @Operation(summary = "批量修改应用操作动态") + @PutMapping("/batch") + public ApiResult removeBatch(@RequestBody BatchParam batchParam) { + if (batchParam.update(appEventService, "id")) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('app:appEvent:remove')") + @OperationLog + @Operation(summary = "批量删除应用操作动态") + @DeleteMapping("/batch") + public ApiResult removeBatch(@RequestBody List ids) { + if (appEventService.removeByIds(ids)) { + return success("删除成功"); + } + return fail("删除失败"); + } + +} diff --git a/src/main/java/com/gxwebsoft/app/controller/AppUserController.java b/src/main/java/com/gxwebsoft/app/controller/AppUserController.java new file mode 100644 index 0000000..3a7f660 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/controller/AppUserController.java @@ -0,0 +1,129 @@ +package com.gxwebsoft.app.controller; + +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.app.service.AppUserService; +import com.gxwebsoft.app.entity.AppUser; +import com.gxwebsoft.app.param.AppUserParam; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.BatchParam; +import com.gxwebsoft.common.core.annotation.OperationLog; +import com.gxwebsoft.common.system.entity.User; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 应用成员控制器 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Tag(name = "应用成员管理") +@RestController +@RequestMapping("/api/app/app-user") +public class AppUserController extends BaseController { + @Resource + private AppUserService appUserService; + + @PreAuthorize("hasAuthority('app:appUser:list')") + @Operation(summary = "分页查询应用成员") + @GetMapping("/page") + public ApiResult> page(AppUserParam param) { + // 使用关联查询 + return success(appUserService.pageRel(param)); + } + + @PreAuthorize("hasAuthority('app:appUser:list')") + @Operation(summary = "查询全部应用成员") + @GetMapping() + public ApiResult> list(AppUserParam param) { + // 使用关联查询 + return success(appUserService.listRel(param)); + } + + @PreAuthorize("hasAuthority('app:appUser:list')") + @Operation(summary = "根据id查询应用成员") + @GetMapping("/{id}") + public ApiResult get(@PathVariable("id") Integer id) { + // 使用关联查询 + return success(appUserService.getByIdRel(id)); + } + + @PreAuthorize("hasAuthority('app:appUser:save')") + @OperationLog + @Operation(summary = "添加应用成员") + @PostMapping() + public ApiResult save(@RequestBody AppUser appUser) { + // 记录当前登录用户id + User loginUser = getLoginUser(); + if (loginUser != null) { + appUser.setUserId(loginUser.getUserId()); + } + if (appUserService.save(appUser)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('app:appUser:update')") + @OperationLog + @Operation(summary = "修改应用成员") + @PutMapping() + public ApiResult update(@RequestBody AppUser appUser) { + if (appUserService.updateById(appUser)) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('app:appUser:remove')") + @OperationLog + @Operation(summary = "删除应用成员") + @DeleteMapping("/{id}") + public ApiResult remove(@PathVariable("id") Integer id) { + if (appUserService.removeById(id)) { + return success("删除成功"); + } + return fail("删除失败"); + } + + @PreAuthorize("hasAuthority('app:appUser:save')") + @OperationLog + @Operation(summary = "批量添加应用成员") + @PostMapping("/batch") + public ApiResult saveBatch(@RequestBody List list) { + if (appUserService.saveBatch(list)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('app:appUser:update')") + @OperationLog + @Operation(summary = "批量修改应用成员") + @PutMapping("/batch") + public ApiResult removeBatch(@RequestBody BatchParam batchParam) { + if (batchParam.update(appUserService, "id")) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('app:appUser:remove')") + @OperationLog + @Operation(summary = "批量删除应用成员") + @DeleteMapping("/batch") + public ApiResult removeBatch(@RequestBody List ids) { + if (appUserService.removeByIds(ids)) { + return success("删除成功"); + } + return fail("删除失败"); + } + +} diff --git a/src/main/java/com/gxwebsoft/app/controller/AppVersionController.java b/src/main/java/com/gxwebsoft/app/controller/AppVersionController.java new file mode 100644 index 0000000..c5e8ad2 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/controller/AppVersionController.java @@ -0,0 +1,129 @@ +package com.gxwebsoft.app.controller; + +import com.gxwebsoft.common.core.web.BaseController; +import com.gxwebsoft.app.service.AppVersionService; +import com.gxwebsoft.app.entity.AppVersion; +import com.gxwebsoft.app.param.AppVersionParam; +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.BatchParam; +import com.gxwebsoft.common.core.annotation.OperationLog; +import com.gxwebsoft.common.system.entity.User; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 应用版本发布记录控制器 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Tag(name = "应用版本发布记录管理") +@RestController +@RequestMapping("/api/app/app-version") +public class AppVersionController extends BaseController { + @Resource + private AppVersionService appVersionService; + + @PreAuthorize("hasAuthority('app:appVersion:list')") + @Operation(summary = "分页查询应用版本发布记录") + @GetMapping("/page") + public ApiResult> page(AppVersionParam param) { + // 使用关联查询 + return success(appVersionService.pageRel(param)); + } + + @PreAuthorize("hasAuthority('app:appVersion:list')") + @Operation(summary = "查询全部应用版本发布记录") + @GetMapping() + public ApiResult> list(AppVersionParam param) { + // 使用关联查询 + return success(appVersionService.listRel(param)); + } + + @PreAuthorize("hasAuthority('app:appVersion:list')") + @Operation(summary = "根据id查询应用版本发布记录") + @GetMapping("/{id}") + public ApiResult get(@PathVariable("id") Integer id) { + // 使用关联查询 + return success(appVersionService.getByIdRel(id)); + } + + @PreAuthorize("hasAuthority('app:appVersion:save')") + @OperationLog + @Operation(summary = "添加应用版本发布记录") + @PostMapping() + public ApiResult save(@RequestBody AppVersion appVersion) { + // 记录当前登录用户id + User loginUser = getLoginUser(); + if (loginUser != null) { + appVersion.setUserId(loginUser.getUserId()); + } + if (appVersionService.save(appVersion)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('app:appVersion:update')") + @OperationLog + @Operation(summary = "修改应用版本发布记录") + @PutMapping() + public ApiResult update(@RequestBody AppVersion appVersion) { + if (appVersionService.updateById(appVersion)) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('app:appVersion:remove')") + @OperationLog + @Operation(summary = "删除应用版本发布记录") + @DeleteMapping("/{id}") + public ApiResult remove(@PathVariable("id") Integer id) { + if (appVersionService.removeById(id)) { + return success("删除成功"); + } + return fail("删除失败"); + } + + @PreAuthorize("hasAuthority('app:appVersion:save')") + @OperationLog + @Operation(summary = "批量添加应用版本发布记录") + @PostMapping("/batch") + public ApiResult saveBatch(@RequestBody List list) { + if (appVersionService.saveBatch(list)) { + return success("添加成功"); + } + return fail("添加失败"); + } + + @PreAuthorize("hasAuthority('app:appVersion:update')") + @OperationLog + @Operation(summary = "批量修改应用版本发布记录") + @PutMapping("/batch") + public ApiResult removeBatch(@RequestBody BatchParam batchParam) { + if (batchParam.update(appVersionService, "id")) { + return success("修改成功"); + } + return fail("修改失败"); + } + + @PreAuthorize("hasAuthority('app:appVersion:remove')") + @OperationLog + @Operation(summary = "批量删除应用版本发布记录") + @DeleteMapping("/batch") + public ApiResult removeBatch(@RequestBody List ids) { + if (appVersionService.removeByIds(ids)) { + return success("删除成功"); + } + return fail("删除失败"); + } + +} diff --git a/src/main/java/com/gxwebsoft/app/entity/AppCredential.java b/src/main/java/com/gxwebsoft/app/entity/AppCredential.java new file mode 100644 index 0000000..2384db5 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/entity/AppCredential.java @@ -0,0 +1,80 @@ +package com.gxwebsoft.app.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.TableLogic; +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 应用密钥凭证 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:43 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Schema(name = "AppCredential对象", description = "应用密钥凭证") +public class AppCredential implements Serializable { + private static final long serialVersionUID = 1L; + + @Schema(description = "自增ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @Schema(description = "关联应用ID") + private Long websiteId; + + @Schema(description = "凭证名称,如生产环境密钥") + private String name; + + @Schema(description = "App ID(公开)") + private String appId; + + @Schema(description = "App Secret(加密存储)") + private String appSecret; + + @Schema(description = "凭证类型: server/client/webhook") + private String type; + + @Schema(description = "权限范围,空格分隔") + private String scopes; + + @Schema(description = "到期时间,NULL=永不过期") + private LocalDateTime expireTime; + + @Schema(description = "最后使用时间") + private LocalDateTime lastUsedAt; + + private String remark; + + @Schema(description = "排序(数字越小越靠前)") + private Integer sortNumber; + + @Schema(description = "状态, 0正常, 1冻结") + private Integer status; + + @Schema(description = "是否删除, 0否, 1是") + @TableLogic + private Integer deleted; + + @Schema(description = "用户ID") + private Integer userId; + + @Schema(description = "租户id") + private Integer tenantId; + + @Schema(description = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + @Schema(description = "修改时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updateTime; + +} diff --git a/src/main/java/com/gxwebsoft/app/entity/AppEvent.java b/src/main/java/com/gxwebsoft/app/entity/AppEvent.java new file mode 100644 index 0000000..b3fb88c --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/entity/AppEvent.java @@ -0,0 +1,76 @@ +package com.gxwebsoft.app.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 应用操作动态 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Schema(name = "AppEvent对象", description = "应用操作动态") +public class AppEvent implements Serializable { + private static final long serialVersionUID = 1L; + + @Schema(description = "自增ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @Schema(description = "关联应用ID") + private Long websiteId; + + @Schema(description = "事件类型: created/published/updated/domain_bound/member_added/status_changed") + private String eventType; + + @Schema(description = "事件标题,如已发布") + private String title; + + @Schema(description = "详细描述") + private String content; + + @Schema(description = "操作人用户ID") + private Long operatorId; + + @Schema(description = "操作人名称(冗余)") + private String operator; + + @Schema(description = "关联ID,如版本ID") + private Long refId; + + @Schema(description = "关联类型") + private String refType; + + @Schema(description = "扩展数据") + private String extra; + + @Schema(description = "排序(数字越小越靠前)") + private Integer sortNumber; + + @Schema(description = "状态, 0正常, 1冻结") + private Integer status; + + @Schema(description = "用户ID") + private Integer userId; + + @Schema(description = "租户id") + private Integer tenantId; + + @Schema(description = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + @Schema(description = "修改时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updateTime; + +} diff --git a/src/main/java/com/gxwebsoft/app/entity/AppUser.java b/src/main/java/com/gxwebsoft/app/entity/AppUser.java new file mode 100644 index 0000000..a5d3ad3 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/entity/AppUser.java @@ -0,0 +1,67 @@ +package com.gxwebsoft.app.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 应用成员 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Schema(name = "AppUser对象", description = "应用成员") +public class AppUser implements Serializable { + private static final long serialVersionUID = 1L; + + @Schema(description = "自增ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @Schema(description = "关联应用ID") + private Long websiteId; + + @Schema(description = "用户ID") + private Integer userId; + + @Schema(description = "用户名(冗余)") + private String username; + + @Schema(description = "头像(冗余)") + private String avatar; + + @Schema(description = "角色: owner/admin/developer/viewer") + private String role; + + @Schema(description = "邀请人用户ID") + private Long inviteBy; + + @Schema(description = "加入时间") + private LocalDateTime inviteTime; + + @Schema(description = "排序(数字越小越靠前)") + private Integer sortNumber; + + @Schema(description = "状态, 0正常, 1冻结") + private Integer status; + + @Schema(description = "租户id") + private Integer tenantId; + + @Schema(description = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + @Schema(description = "修改时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updateTime; + +} diff --git a/src/main/java/com/gxwebsoft/app/entity/AppVersion.java b/src/main/java/com/gxwebsoft/app/entity/AppVersion.java new file mode 100644 index 0000000..6442e8b --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/entity/AppVersion.java @@ -0,0 +1,85 @@ +package com.gxwebsoft.app.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 应用版本发布记录 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Schema(name = "AppVersion对象", description = "应用版本发布记录") +public class AppVersion implements Serializable { + private static final long serialVersionUID = 1L; + + @Schema(description = "自增ID") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @Schema(description = "关联应用ID") + private Long websiteId; + + @Schema(description = "版本号,如 1.0.0") + private String versionNo; + + @Schema(description = "版本名称") + private String versionName; + + @Schema(description = "版本更新说明") + private String changelog; + + @Schema(description = "安装包地址") + private String packageUrl; + + @Schema(description = "包大小(字节)") + private Long packageSize; + + @Schema(description = "包MD5/SHA256") + private String packageHash; + + @Schema(description = "环境: development/staging/production") + private String env; + + @Schema(description = "状态 0=构建中 1=已发布 2=已回滚 3=构建失败") + private Integer status; + + @Schema(description = "是否为当前版本") + private Boolean isCurrent; + + @Schema(description = "发布人用户ID") + private Long publishBy; + + @Schema(description = "发布时间") + private LocalDateTime publishTime; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "排序(数字越小越靠前)") + private Integer sortNumber; + + @Schema(description = "用户ID") + private Integer userId; + + @Schema(description = "租户id") + private Integer tenantId; + + @Schema(description = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + @Schema(description = "修改时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updateTime; + +} diff --git a/src/main/java/com/gxwebsoft/app/mapper/AppCredentialMapper.java b/src/main/java/com/gxwebsoft/app/mapper/AppCredentialMapper.java new file mode 100644 index 0000000..4ab3599 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/mapper/AppCredentialMapper.java @@ -0,0 +1,37 @@ +package com.gxwebsoft.app.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.gxwebsoft.app.entity.AppCredential; +import com.gxwebsoft.app.param.AppCredentialParam; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 应用密钥凭证Mapper + * + * @author 科技小王子 + * @since 2026-03-28 21:29:43 + */ +public interface AppCredentialMapper extends BaseMapper { + + /** + * 分页查询 + * + * @param page 分页对象 + * @param param 查询参数 + * @return List + */ + List selectPageRel(@Param("page") IPage page, + @Param("param") AppCredentialParam param); + + /** + * 查询全部 + * + * @param param 查询参数 + * @return List + */ + List selectListRel(@Param("param") AppCredentialParam param); + +} diff --git a/src/main/java/com/gxwebsoft/app/mapper/AppEventMapper.java b/src/main/java/com/gxwebsoft/app/mapper/AppEventMapper.java new file mode 100644 index 0000000..c1fe3ca --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/mapper/AppEventMapper.java @@ -0,0 +1,37 @@ +package com.gxwebsoft.app.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.gxwebsoft.app.entity.AppEvent; +import com.gxwebsoft.app.param.AppEventParam; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 应用操作动态Mapper + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +public interface AppEventMapper extends BaseMapper { + + /** + * 分页查询 + * + * @param page 分页对象 + * @param param 查询参数 + * @return List + */ + List selectPageRel(@Param("page") IPage page, + @Param("param") AppEventParam param); + + /** + * 查询全部 + * + * @param param 查询参数 + * @return List + */ + List selectListRel(@Param("param") AppEventParam param); + +} diff --git a/src/main/java/com/gxwebsoft/app/mapper/AppUserMapper.java b/src/main/java/com/gxwebsoft/app/mapper/AppUserMapper.java new file mode 100644 index 0000000..a2cca59 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/mapper/AppUserMapper.java @@ -0,0 +1,37 @@ +package com.gxwebsoft.app.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.gxwebsoft.app.entity.AppUser; +import com.gxwebsoft.app.param.AppUserParam; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 应用成员Mapper + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +public interface AppUserMapper extends BaseMapper { + + /** + * 分页查询 + * + * @param page 分页对象 + * @param param 查询参数 + * @return List + */ + List selectPageRel(@Param("page") IPage page, + @Param("param") AppUserParam param); + + /** + * 查询全部 + * + * @param param 查询参数 + * @return List + */ + List selectListRel(@Param("param") AppUserParam param); + +} diff --git a/src/main/java/com/gxwebsoft/app/mapper/AppVersionMapper.java b/src/main/java/com/gxwebsoft/app/mapper/AppVersionMapper.java new file mode 100644 index 0000000..187b1a6 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/mapper/AppVersionMapper.java @@ -0,0 +1,37 @@ +package com.gxwebsoft.app.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.gxwebsoft.app.entity.AppVersion; +import com.gxwebsoft.app.param.AppVersionParam; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 应用版本发布记录Mapper + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +public interface AppVersionMapper extends BaseMapper { + + /** + * 分页查询 + * + * @param page 分页对象 + * @param param 查询参数 + * @return List + */ + List selectPageRel(@Param("page") IPage page, + @Param("param") AppVersionParam param); + + /** + * 查询全部 + * + * @param param 查询参数 + * @return List + */ + List selectListRel(@Param("param") AppVersionParam param); + +} diff --git a/src/main/java/com/gxwebsoft/app/mapper/xml/AppCredentialMapper.xml b/src/main/java/com/gxwebsoft/app/mapper/xml/AppCredentialMapper.xml new file mode 100644 index 0000000..0c2c0c0 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/mapper/xml/AppCredentialMapper.xml @@ -0,0 +1,78 @@ + + + + + + + SELECT a.* + FROM app_credential a + + + AND a.id = #{param.id} + + + AND a.website_id LIKE CONCAT('%', #{param.websiteId}, '%') + + + AND a.name LIKE CONCAT('%', #{param.name}, '%') + + + AND a.app_id LIKE CONCAT('%', #{param.appId}, '%') + + + AND a.app_secret LIKE CONCAT('%', #{param.appSecret}, '%') + + + AND a.type LIKE CONCAT('%', #{param.type}, '%') + + + AND a.scopes LIKE CONCAT('%', #{param.scopes}, '%') + + + AND a.expire_time LIKE CONCAT('%', #{param.expireTime}, '%') + + + AND a.last_used_at LIKE CONCAT('%', #{param.lastUsedAt}, '%') + + + AND a.remark LIKE CONCAT('%', #{param.remark}, '%') + + + AND a.sort_number = #{param.sortNumber} + + + AND a.status = #{param.status} + + + AND a.deleted = #{param.deleted} + + + AND a.deleted = 0 + + + AND a.user_id = #{param.userId} + + + AND a.create_time >= #{param.createTimeStart} + + + AND a.create_time <= #{param.createTimeEnd} + + + AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') + ) + + + + + + + + + + + diff --git a/src/main/java/com/gxwebsoft/app/mapper/xml/AppEventMapper.xml b/src/main/java/com/gxwebsoft/app/mapper/xml/AppEventMapper.xml new file mode 100644 index 0000000..ef63c66 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/mapper/xml/AppEventMapper.xml @@ -0,0 +1,72 @@ + + + + + + + SELECT a.* + FROM app_event a + + + AND a.id = #{param.id} + + + AND a.website_id LIKE CONCAT('%', #{param.websiteId}, '%') + + + AND a.event_type LIKE CONCAT('%', #{param.eventType}, '%') + + + AND a.title LIKE CONCAT('%', #{param.title}, '%') + + + AND a.content LIKE CONCAT('%', #{param.content}, '%') + + + AND a.operator_id LIKE CONCAT('%', #{param.operatorId}, '%') + + + AND a.operator LIKE CONCAT('%', #{param.operator}, '%') + + + AND a.ref_id LIKE CONCAT('%', #{param.refId}, '%') + + + AND a.ref_type LIKE CONCAT('%', #{param.refType}, '%') + + + AND a.extra LIKE CONCAT('%', #{param.extra}, '%') + + + AND a.sort_number = #{param.sortNumber} + + + AND a.status = #{param.status} + + + AND a.user_id = #{param.userId} + + + AND a.create_time >= #{param.createTimeStart} + + + AND a.create_time <= #{param.createTimeEnd} + + + AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') + ) + + + + + + + + + + + diff --git a/src/main/java/com/gxwebsoft/app/mapper/xml/AppUserMapper.xml b/src/main/java/com/gxwebsoft/app/mapper/xml/AppUserMapper.xml new file mode 100644 index 0000000..e52506a --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/mapper/xml/AppUserMapper.xml @@ -0,0 +1,63 @@ + + + + + + + SELECT a.* + FROM app_user a + + + AND a.id = #{param.id} + + + AND a.website_id LIKE CONCAT('%', #{param.websiteId}, '%') + + + AND a.user_id LIKE CONCAT('%', #{param.userId}, '%') + + + AND a.username LIKE CONCAT('%', #{param.username}, '%') + + + AND a.avatar LIKE CONCAT('%', #{param.avatar}, '%') + + + AND a.role LIKE CONCAT('%', #{param.role}, '%') + + + AND a.invite_by LIKE CONCAT('%', #{param.inviteBy}, '%') + + + AND a.invite_time LIKE CONCAT('%', #{param.inviteTime}, '%') + + + AND a.sort_number = #{param.sortNumber} + + + AND a.status = #{param.status} + + + AND a.create_time >= #{param.createTimeStart} + + + AND a.create_time <= #{param.createTimeEnd} + + + AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') + ) + + + + + + + + + + + diff --git a/src/main/java/com/gxwebsoft/app/mapper/xml/AppVersionMapper.xml b/src/main/java/com/gxwebsoft/app/mapper/xml/AppVersionMapper.xml new file mode 100644 index 0000000..23dc680 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/mapper/xml/AppVersionMapper.xml @@ -0,0 +1,81 @@ + + + + + + + SELECT a.* + FROM app_version a + + + AND a.id = #{param.id} + + + AND a.website_id LIKE CONCAT('%', #{param.websiteId}, '%') + + + AND a.version_no LIKE CONCAT('%', #{param.versionNo}, '%') + + + AND a.version_name LIKE CONCAT('%', #{param.versionName}, '%') + + + AND a.changelog LIKE CONCAT('%', #{param.changelog}, '%') + + + AND a.package_url LIKE CONCAT('%', #{param.packageUrl}, '%') + + + AND a.package_size LIKE CONCAT('%', #{param.packageSize}, '%') + + + AND a.package_hash LIKE CONCAT('%', #{param.packageHash}, '%') + + + AND a.env LIKE CONCAT('%', #{param.env}, '%') + + + AND a.status = #{param.status} + + + AND a.is_current = #{param.isCurrent} + + + AND a.publish_by LIKE CONCAT('%', #{param.publishBy}, '%') + + + AND a.publish_time LIKE CONCAT('%', #{param.publishTime}, '%') + + + AND a.remark LIKE CONCAT('%', #{param.remark}, '%') + + + AND a.sort_number = #{param.sortNumber} + + + AND a.user_id = #{param.userId} + + + AND a.create_time >= #{param.createTimeStart} + + + AND a.create_time <= #{param.createTimeEnd} + + + AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') + ) + + + + + + + + + + + diff --git a/src/main/java/com/gxwebsoft/app/param/AppCredentialParam.java b/src/main/java/com/gxwebsoft/app/param/AppCredentialParam.java new file mode 100644 index 0000000..cd53d0b --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/param/AppCredentialParam.java @@ -0,0 +1,71 @@ +package com.gxwebsoft.app.param; + +import java.math.BigDecimal; +import com.gxwebsoft.common.core.annotation.QueryField; +import com.gxwebsoft.common.core.annotation.QueryType; +import com.gxwebsoft.common.core.web.BaseParam; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 应用密钥凭证查询参数 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:43 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(name = "AppCredentialParam对象", description = "应用密钥凭证查询参数") +public class AppCredentialParam extends BaseParam { + private static final long serialVersionUID = 1L; + + @Schema(description = "自增ID") + @QueryField(type = QueryType.EQ) + private Long id; + + @Schema(description = "关联应用ID") + private Long websiteId; + + @Schema(description = "凭证名称,如生产环境密钥") + private String name; + + @Schema(description = "App ID(公开)") + private String appId; + + @Schema(description = "App Secret(加密存储)") + private String appSecret; + + @Schema(description = "凭证类型: server/client/webhook") + private String type; + + @Schema(description = "权限范围,空格分隔") + private String scopes; + + @Schema(description = "到期时间,NULL=永不过期") + private String expireTime; + + @Schema(description = "最后使用时间") + private String lastUsedAt; + + private String remark; + + @Schema(description = "排序(数字越小越靠前)") + @QueryField(type = QueryType.EQ) + private Integer sortNumber; + + @Schema(description = "状态, 0正常, 1冻结") + @QueryField(type = QueryType.EQ) + private Integer status; + + @Schema(description = "是否删除, 0否, 1是") + @QueryField(type = QueryType.EQ) + private Integer deleted; + + @Schema(description = "用户ID") + @QueryField(type = QueryType.EQ) + private Integer userId; + +} diff --git a/src/main/java/com/gxwebsoft/app/param/AppEventParam.java b/src/main/java/com/gxwebsoft/app/param/AppEventParam.java new file mode 100644 index 0000000..64b2e2a --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/param/AppEventParam.java @@ -0,0 +1,68 @@ +package com.gxwebsoft.app.param; + +import java.math.BigDecimal; +import com.gxwebsoft.common.core.annotation.QueryField; +import com.gxwebsoft.common.core.annotation.QueryType; +import com.gxwebsoft.common.core.web.BaseParam; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 应用操作动态查询参数 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(name = "AppEventParam对象", description = "应用操作动态查询参数") +public class AppEventParam extends BaseParam { + private static final long serialVersionUID = 1L; + + @Schema(description = "自增ID") + @QueryField(type = QueryType.EQ) + private Long id; + + @Schema(description = "关联应用ID") + private Long websiteId; + + @Schema(description = "事件类型: created/published/updated/domain_bound/member_added/status_changed") + private String eventType; + + @Schema(description = "事件标题,如已发布") + private String title; + + @Schema(description = "详细描述") + private String content; + + @Schema(description = "操作人用户ID") + private Long operatorId; + + @Schema(description = "操作人名称(冗余)") + private String operator; + + @Schema(description = "关联ID,如版本ID") + private Long refId; + + @Schema(description = "关联类型") + private String refType; + + @Schema(description = "扩展数据") + private String extra; + + @Schema(description = "排序(数字越小越靠前)") + @QueryField(type = QueryType.EQ) + private Integer sortNumber; + + @Schema(description = "状态, 0正常, 1冻结") + @QueryField(type = QueryType.EQ) + private Integer status; + + @Schema(description = "用户ID") + @QueryField(type = QueryType.EQ) + private Integer userId; + +} diff --git a/src/main/java/com/gxwebsoft/app/param/AppUserParam.java b/src/main/java/com/gxwebsoft/app/param/AppUserParam.java new file mode 100644 index 0000000..d9578f0 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/param/AppUserParam.java @@ -0,0 +1,58 @@ +package com.gxwebsoft.app.param; + +import java.math.BigDecimal; +import com.gxwebsoft.common.core.annotation.QueryField; +import com.gxwebsoft.common.core.annotation.QueryType; +import com.gxwebsoft.common.core.web.BaseParam; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 应用成员查询参数 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(name = "AppUserParam对象", description = "应用成员查询参数") +public class AppUserParam extends BaseParam { + private static final long serialVersionUID = 1L; + + @Schema(description = "自增ID") + @QueryField(type = QueryType.EQ) + private Long id; + + @Schema(description = "关联应用ID") + private Long websiteId; + + @Schema(description = "用户ID") + private Long userId; + + @Schema(description = "用户名(冗余)") + private String username; + + @Schema(description = "头像(冗余)") + private String avatar; + + @Schema(description = "角色: owner/admin/developer/viewer") + private String role; + + @Schema(description = "邀请人用户ID") + private Long inviteBy; + + @Schema(description = "加入时间") + private String inviteTime; + + @Schema(description = "排序(数字越小越靠前)") + @QueryField(type = QueryType.EQ) + private Integer sortNumber; + + @Schema(description = "状态, 0正常, 1冻结") + @QueryField(type = QueryType.EQ) + private Integer status; + +} diff --git a/src/main/java/com/gxwebsoft/app/param/AppVersionParam.java b/src/main/java/com/gxwebsoft/app/param/AppVersionParam.java new file mode 100644 index 0000000..a986bc0 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/param/AppVersionParam.java @@ -0,0 +1,78 @@ +package com.gxwebsoft.app.param; + +import java.math.BigDecimal; +import com.gxwebsoft.common.core.annotation.QueryField; +import com.gxwebsoft.common.core.annotation.QueryType; +import com.gxwebsoft.common.core.web.BaseParam; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 应用版本发布记录查询参数 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@JsonInclude(JsonInclude.Include.NON_NULL) +@Schema(name = "AppVersionParam对象", description = "应用版本发布记录查询参数") +public class AppVersionParam extends BaseParam { + private static final long serialVersionUID = 1L; + + @Schema(description = "自增ID") + @QueryField(type = QueryType.EQ) + private Long id; + + @Schema(description = "关联应用ID") + private Long websiteId; + + @Schema(description = "版本号,如 1.0.0") + private String versionNo; + + @Schema(description = "版本名称") + private String versionName; + + @Schema(description = "版本更新说明") + private String changelog; + + @Schema(description = "安装包地址") + private String packageUrl; + + @Schema(description = "包大小(字节)") + private Long packageSize; + + @Schema(description = "包MD5/SHA256") + private String packageHash; + + @Schema(description = "环境: development/staging/production") + private String env; + + @Schema(description = "状态 0=构建中 1=已发布 2=已回滚 3=构建失败") + @QueryField(type = QueryType.EQ) + private Integer status; + + @Schema(description = "是否为当前版本") + @QueryField(type = QueryType.EQ) + private Boolean isCurrent; + + @Schema(description = "发布人用户ID") + private Long publishBy; + + @Schema(description = "发布时间") + private String publishTime; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "排序(数字越小越靠前)") + @QueryField(type = QueryType.EQ) + private Integer sortNumber; + + @Schema(description = "用户ID") + @QueryField(type = QueryType.EQ) + private Integer userId; + +} diff --git a/src/main/java/com/gxwebsoft/app/service/AppCredentialService.java b/src/main/java/com/gxwebsoft/app/service/AppCredentialService.java new file mode 100644 index 0000000..6a426ce --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/service/AppCredentialService.java @@ -0,0 +1,42 @@ +package com.gxwebsoft.app.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.app.entity.AppCredential; +import com.gxwebsoft.app.param.AppCredentialParam; + +import java.util.List; + +/** + * 应用密钥凭证Service + * + * @author 科技小王子 + * @since 2026-03-28 21:29:43 + */ +public interface AppCredentialService extends IService { + + /** + * 分页关联查询 + * + * @param param 查询参数 + * @return PageResult + */ + PageResult pageRel(AppCredentialParam param); + + /** + * 关联查询全部 + * + * @param param 查询参数 + * @return List + */ + List listRel(AppCredentialParam param); + + /** + * 根据id查询 + * + * @param id 自增ID + * @return AppCredential + */ + AppCredential getByIdRel(Integer id); + +} diff --git a/src/main/java/com/gxwebsoft/app/service/AppEventService.java b/src/main/java/com/gxwebsoft/app/service/AppEventService.java new file mode 100644 index 0000000..34d8d89 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/service/AppEventService.java @@ -0,0 +1,42 @@ +package com.gxwebsoft.app.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.app.entity.AppEvent; +import com.gxwebsoft.app.param.AppEventParam; + +import java.util.List; + +/** + * 应用操作动态Service + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +public interface AppEventService extends IService { + + /** + * 分页关联查询 + * + * @param param 查询参数 + * @return PageResult + */ + PageResult pageRel(AppEventParam param); + + /** + * 关联查询全部 + * + * @param param 查询参数 + * @return List + */ + List listRel(AppEventParam param); + + /** + * 根据id查询 + * + * @param id 自增ID + * @return AppEvent + */ + AppEvent getByIdRel(Integer id); + +} diff --git a/src/main/java/com/gxwebsoft/app/service/AppUserService.java b/src/main/java/com/gxwebsoft/app/service/AppUserService.java new file mode 100644 index 0000000..82706e9 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/service/AppUserService.java @@ -0,0 +1,42 @@ +package com.gxwebsoft.app.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.app.entity.AppUser; +import com.gxwebsoft.app.param.AppUserParam; + +import java.util.List; + +/** + * 应用成员Service + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +public interface AppUserService extends IService { + + /** + * 分页关联查询 + * + * @param param 查询参数 + * @return PageResult + */ + PageResult pageRel(AppUserParam param); + + /** + * 关联查询全部 + * + * @param param 查询参数 + * @return List + */ + List listRel(AppUserParam param); + + /** + * 根据id查询 + * + * @param id 自增ID + * @return AppUser + */ + AppUser getByIdRel(Integer id); + +} diff --git a/src/main/java/com/gxwebsoft/app/service/AppVersionService.java b/src/main/java/com/gxwebsoft/app/service/AppVersionService.java new file mode 100644 index 0000000..8a56e0e --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/service/AppVersionService.java @@ -0,0 +1,42 @@ +package com.gxwebsoft.app.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.gxwebsoft.common.core.web.PageResult; +import com.gxwebsoft.app.entity.AppVersion; +import com.gxwebsoft.app.param.AppVersionParam; + +import java.util.List; + +/** + * 应用版本发布记录Service + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +public interface AppVersionService extends IService { + + /** + * 分页关联查询 + * + * @param param 查询参数 + * @return PageResult + */ + PageResult pageRel(AppVersionParam param); + + /** + * 关联查询全部 + * + * @param param 查询参数 + * @return List + */ + List listRel(AppVersionParam param); + + /** + * 根据id查询 + * + * @param id 自增ID + * @return AppVersion + */ + AppVersion getByIdRel(Integer id); + +} diff --git a/src/main/java/com/gxwebsoft/app/service/impl/AppCredentialServiceImpl.java b/src/main/java/com/gxwebsoft/app/service/impl/AppCredentialServiceImpl.java new file mode 100644 index 0000000..3028fde --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/service/impl/AppCredentialServiceImpl.java @@ -0,0 +1,47 @@ +package com.gxwebsoft.app.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.gxwebsoft.app.mapper.AppCredentialMapper; +import com.gxwebsoft.app.service.AppCredentialService; +import com.gxwebsoft.app.entity.AppCredential; +import com.gxwebsoft.app.param.AppCredentialParam; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.PageResult; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 应用密钥凭证Service实现 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:43 + */ +@Service +public class AppCredentialServiceImpl extends ServiceImpl implements AppCredentialService { + + @Override + public PageResult pageRel(AppCredentialParam param) { + PageParam page = new PageParam<>(param); + page.setDefaultOrder("sort_number asc, create_time desc"); + List list = baseMapper.selectPageRel(page, param); + return new PageResult<>(list, page.getTotal()); + } + + @Override + public List listRel(AppCredentialParam param) { + List list = baseMapper.selectListRel(param); + // 排序 + PageParam page = new PageParam<>(); + page.setDefaultOrder("sort_number asc, create_time desc"); + return page.sortRecords(list); + } + + @Override + public AppCredential getByIdRel(Integer id) { + AppCredentialParam param = new AppCredentialParam(); + param.setId(id); + return param.getOne(baseMapper.selectListRel(param)); + } + +} diff --git a/src/main/java/com/gxwebsoft/app/service/impl/AppEventServiceImpl.java b/src/main/java/com/gxwebsoft/app/service/impl/AppEventServiceImpl.java new file mode 100644 index 0000000..91c147a --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/service/impl/AppEventServiceImpl.java @@ -0,0 +1,47 @@ +package com.gxwebsoft.app.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.gxwebsoft.app.mapper.AppEventMapper; +import com.gxwebsoft.app.service.AppEventService; +import com.gxwebsoft.app.entity.AppEvent; +import com.gxwebsoft.app.param.AppEventParam; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.PageResult; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 应用操作动态Service实现 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Service +public class AppEventServiceImpl extends ServiceImpl implements AppEventService { + + @Override + public PageResult pageRel(AppEventParam param) { + PageParam page = new PageParam<>(param); + page.setDefaultOrder("sort_number asc, create_time desc"); + List list = baseMapper.selectPageRel(page, param); + return new PageResult<>(list, page.getTotal()); + } + + @Override + public List listRel(AppEventParam param) { + List list = baseMapper.selectListRel(param); + // 排序 + PageParam page = new PageParam<>(); + page.setDefaultOrder("sort_number asc, create_time desc"); + return page.sortRecords(list); + } + + @Override + public AppEvent getByIdRel(Integer id) { + AppEventParam param = new AppEventParam(); + param.setId(id); + return param.getOne(baseMapper.selectListRel(param)); + } + +} diff --git a/src/main/java/com/gxwebsoft/app/service/impl/AppUserServiceImpl.java b/src/main/java/com/gxwebsoft/app/service/impl/AppUserServiceImpl.java new file mode 100644 index 0000000..2f2fb01 --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/service/impl/AppUserServiceImpl.java @@ -0,0 +1,47 @@ +package com.gxwebsoft.app.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.gxwebsoft.app.mapper.AppUserMapper; +import com.gxwebsoft.app.service.AppUserService; +import com.gxwebsoft.app.entity.AppUser; +import com.gxwebsoft.app.param.AppUserParam; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.PageResult; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 应用成员Service实现 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Service +public class AppUserServiceImpl extends ServiceImpl implements AppUserService { + + @Override + public PageResult pageRel(AppUserParam param) { + PageParam page = new PageParam<>(param); + page.setDefaultOrder("sort_number asc, create_time desc"); + List list = baseMapper.selectPageRel(page, param); + return new PageResult<>(list, page.getTotal()); + } + + @Override + public List listRel(AppUserParam param) { + List list = baseMapper.selectListRel(param); + // 排序 + PageParam page = new PageParam<>(); + page.setDefaultOrder("sort_number asc, create_time desc"); + return page.sortRecords(list); + } + + @Override + public AppUser getByIdRel(Integer id) { + AppUserParam param = new AppUserParam(); + param.setId(id); + return param.getOne(baseMapper.selectListRel(param)); + } + +} diff --git a/src/main/java/com/gxwebsoft/app/service/impl/AppVersionServiceImpl.java b/src/main/java/com/gxwebsoft/app/service/impl/AppVersionServiceImpl.java new file mode 100644 index 0000000..3a5e90b --- /dev/null +++ b/src/main/java/com/gxwebsoft/app/service/impl/AppVersionServiceImpl.java @@ -0,0 +1,47 @@ +package com.gxwebsoft.app.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.gxwebsoft.app.mapper.AppVersionMapper; +import com.gxwebsoft.app.service.AppVersionService; +import com.gxwebsoft.app.entity.AppVersion; +import com.gxwebsoft.app.param.AppVersionParam; +import com.gxwebsoft.common.core.web.PageParam; +import com.gxwebsoft.common.core.web.PageResult; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 应用版本发布记录Service实现 + * + * @author 科技小王子 + * @since 2026-03-28 21:29:44 + */ +@Service +public class AppVersionServiceImpl extends ServiceImpl implements AppVersionService { + + @Override + public PageResult pageRel(AppVersionParam param) { + PageParam page = new PageParam<>(param); + page.setDefaultOrder("sort_number asc, create_time desc"); + List list = baseMapper.selectPageRel(page, param); + return new PageResult<>(list, page.getTotal()); + } + + @Override + public List listRel(AppVersionParam param) { + List list = baseMapper.selectListRel(param); + // 排序 + PageParam page = new PageParam<>(); + page.setDefaultOrder("sort_number asc, create_time desc"); + return page.sortRecords(list); + } + + @Override + public AppVersion getByIdRel(Integer id) { + AppVersionParam param = new AppVersionParam(); + param.setId(id); + return param.getOne(baseMapper.selectListRel(param)); + } + +} diff --git a/src/test/java/com/gxwebsoft/generator/AppGenerator.java b/src/test/java/com/gxwebsoft/generator/AppGenerator.java new file mode 100644 index 0000000..5557843 --- /dev/null +++ b/src/test/java/com/gxwebsoft/generator/AppGenerator.java @@ -0,0 +1,384 @@ +package com.gxwebsoft.generator; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.generator.AutoGenerator; +import com.baomidou.mybatisplus.generator.InjectionConfig; +import com.baomidou.mybatisplus.generator.config.*; +import com.baomidou.mybatisplus.generator.config.po.TableInfo; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import com.gxwebsoft.generator.engine.BeetlTemplateEnginePlus; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * CMS模块-代码生成工具 + * + * @author WebSoft + * @since 2021-09-05 00:31:14 + */ +public class AppGenerator { + // 输出位置 + private static final String OUTPUT_LOCATION = System.getProperty("user.dir"); + //private static final String OUTPUT_LOCATION = "D:/codegen"; // 不想生成到项目中可以写磁盘路径 + // JAVA输出目录 + private static final String OUTPUT_DIR = "/src/main/java"; + // Vue文件输出位置 + private static final String OUTPUT_LOCATION_VUE = "/Users/gxwebsoft/VUE/mp-vue"; + // UniApp文件输出目录 + private static final String OUTPUT_LOCATION_UNIAPP = "/Users/gxwebsoft/VUE/template-5"; + // Vue文件输出目录 + private static final String OUTPUT_DIR_VUE = "/src"; + // 作者名称 + private static final String AUTHOR = "科技小王子"; + // 是否在xml中添加二级缓存配置 + private static final boolean ENABLE_CACHE = false; + // 数据库连接配置 + private static final String DB_URL = "jdbc:mysql://47.119.165.234:13308/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8"; + private static final String DB_DRIVER = "com.mysql.cj.jdbc.Driver"; + private static final String DB_USERNAME = "modules"; + private static final String DB_PASSWORD = "P7KsAyDXG8YdLnkA"; + // 包名 + private static final String PACKAGE_NAME = "com.gxwebsoft"; + // 模块名 + private static final String MODULE_NAME = "app"; + // 需要生成的表 + private static final String[] TABLE_NAMES = new String[]{ + "app_user", + "app_version", + "app_event", + "app_credential" + }; + // 需要去除的表前缀 + private static final String[] TABLE_PREFIX = new String[]{ + "tb_" + }; + // 不需要作为查询参数的字段 + private static final String[] PARAM_EXCLUDE_FIELDS = new String[]{ + "tenant_id", + "create_time", + "update_time" + }; + // 查询参数使用String的类型 + private static final String[] PARAM_TO_STRING_TYPE = new String[]{ + "Date", + "LocalDate", + "LocalTime", + "LocalDateTime" + }; + // 查询参数使用EQ的类型 + private static final String[] PARAM_EQ_TYPE = new String[]{ + "Integer", + "Boolean", + "BigDecimal" + }; + // 是否添加权限注解 + private static final boolean AUTH_ANNOTATION = true; + // 是否添加日志注解 + private static final boolean LOG_ANNOTATION = true; + // controller的mapping前缀 + private static final String CONTROLLER_MAPPING_PREFIX = "/api"; + // 模板所在位置 + private static final String TEMPLATES_DIR = "/src/test/java/com/gxwebsoft/generator/templates"; + + public static void main(String[] args) { + // 代码生成器 + AutoGenerator mpg = new AutoGenerator(); + + // 全局配置 + GlobalConfig gc = new GlobalConfig(); + gc.setOutputDir(OUTPUT_LOCATION + OUTPUT_DIR); + gc.setAuthor(AUTHOR); + gc.setOpen(false); + gc.setFileOverride(true); + gc.setEnableCache(ENABLE_CACHE); + gc.setSwagger2(true); + gc.setIdType(IdType.AUTO); + gc.setServiceName("%sService"); + mpg.setGlobalConfig(gc); + + // 数据源配置 + DataSourceConfig dsc = new DataSourceConfig(); + dsc.setUrl(DB_URL); + // dsc.setSchemaName("public"); + dsc.setDriverName(DB_DRIVER); + dsc.setUsername(DB_USERNAME); + dsc.setPassword(DB_PASSWORD); + mpg.setDataSource(dsc); + + // 包配置 + PackageConfig pc = new PackageConfig(); + pc.setModuleName(MODULE_NAME); + pc.setParent(PACKAGE_NAME); + mpg.setPackageInfo(pc); + + // 策略配置 + StrategyConfig strategy = new StrategyConfig(); + strategy.setNaming(NamingStrategy.underline_to_camel); + strategy.setColumnNaming(NamingStrategy.underline_to_camel); + strategy.setInclude(TABLE_NAMES); + strategy.setTablePrefix(TABLE_PREFIX); + strategy.setSuperControllerClass(PACKAGE_NAME + ".common.core.web.BaseController"); + strategy.setEntityLombokModel(true); + strategy.setRestControllerStyle(true); + strategy.setControllerMappingHyphenStyle(true); + strategy.setLogicDeleteFieldName("deleted"); + mpg.setStrategy(strategy); + + // 模板配置 + TemplateConfig templateConfig = new TemplateConfig(); + templateConfig.setController(TEMPLATES_DIR + "/controller.java"); + templateConfig.setEntity(TEMPLATES_DIR + "/entity.java"); + templateConfig.setMapper(TEMPLATES_DIR + "/mapper.java"); + templateConfig.setXml(TEMPLATES_DIR + "/mapper.xml"); + templateConfig.setService(TEMPLATES_DIR + "/service.java"); + templateConfig.setServiceImpl(TEMPLATES_DIR + "/serviceImpl.java"); + mpg.setTemplate(templateConfig); + mpg.setTemplateEngine(new BeetlTemplateEnginePlus()); + + // 自定义模板配置 + InjectionConfig cfg = new InjectionConfig() { + @Override + public void initMap() { + Map map = new HashMap<>(); + map.put("packageName", PACKAGE_NAME); + map.put("paramExcludeFields", PARAM_EXCLUDE_FIELDS); + map.put("paramToStringType", PARAM_TO_STRING_TYPE); + map.put("paramEqType", PARAM_EQ_TYPE); + map.put("authAnnotation", AUTH_ANNOTATION); + map.put("logAnnotation", LOG_ANNOTATION); + map.put("controllerMappingPrefix", CONTROLLER_MAPPING_PREFIX); + // 添加项目类型标识,用于模板中的条件判断 + map.put("isUniApp", false); // Vue 项目 + map.put("isVueAdmin", true); // 后台管理项目 + this.setMap(map); + } + }; + String templatePath = TEMPLATES_DIR + "/param.java.btl"; + List focList = new ArrayList<>(); + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION + OUTPUT_DIR + "/" + + PACKAGE_NAME.replace(".", "/") + + "/" + pc.getModuleName() + "/param/" + + tableInfo.getEntityName() + "Param" + StringPool.DOT_JAVA; + } + }); + /** + * 以下是生成VUE项目代码 + * 生成文件的路径 /api/shop/goods/index.ts + */ + templatePath = TEMPLATES_DIR + "/index.ts.btl"; + + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE + + "/api/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/" + "index.ts"; + } + }); + // UniApp 使用专门的模板 + String uniappTemplatePath = TEMPLATES_DIR + "/index.ts.uniapp.btl"; + focList.add(new FileOutConfig(uniappTemplatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE + + "/api/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/" + "index.ts"; + } + }); + // 生成TS文件 (/api/shop/goods/model/index.ts) + templatePath = TEMPLATES_DIR + "/model.ts.btl"; + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE + + "/api/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/model/" + "index.ts"; + } + }); + // UniApp 使用专门的 model 模板 + String uniappModelTemplatePath = TEMPLATES_DIR + "/model.ts.uniapp.btl"; + focList.add(new FileOutConfig(uniappModelTemplatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE + + "/api/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/model/" + "index.ts"; + } + }); + // 生成Vue文件(/views/shop/goods/index.vue) + templatePath = TEMPLATES_DIR + "/index.vue.btl"; + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE + + "/views/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/" + "index.vue"; + } + }); + + // 生成components文件(/views/shop/goods/components/edit.vue) + templatePath = TEMPLATES_DIR + "/components.edit.vue.btl"; + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE + + "/views/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/components/" + tableInfo.getEntityPath() + "Edit.vue"; + } + }); + + // 生成components文件(/views/shop/goods/components/search.vue) + templatePath = TEMPLATES_DIR + "/components.search.vue.btl"; + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE + + "/views/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/components/" + "search.vue"; + } + }); + + // ========== 移动端页面文件生成 ========== + // 生成移动端列表页面配置文件 (/src/shop/goods/index.config.ts) + templatePath = TEMPLATES_DIR + "/index.config.ts.btl"; + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE + + "/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/" + "index.config.ts"; + } + }); + + // 生成移动端列表页面组件文件 (/src/shop/goods/index.tsx) + templatePath = TEMPLATES_DIR + "/index.tsx.btl"; + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE + + "/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/" + "index.tsx"; + } + }); + + // 生成移动端新增/编辑页面配置文件 (/src/shop/goods/add.config.ts) + templatePath = TEMPLATES_DIR + "/add.config.ts.btl"; + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE + + "/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/" + "add.config.ts"; + } + }); + + // 生成移动端新增/编辑页面组件文件 (/src/shop/goods/add.tsx) + templatePath = TEMPLATES_DIR + "/add.tsx.btl"; + focList.add(new FileOutConfig(templatePath) { + @Override + public String outputFile(TableInfo tableInfo) { + return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE + + "/" + pc.getModuleName() + "/" + + tableInfo.getEntityPath() + "/" + "add.tsx"; + } + }); + + cfg.setFileOutConfigList(focList); + mpg.setCfg(cfg); + + mpg.execute(); + + // 自动更新 app.config.ts + updateAppConfig(TABLE_NAMES, MODULE_NAME); + } + + /** + * 自动更新 app.config.ts 文件,添加新生成的页面路径 + */ + private static void updateAppConfig(String[] tableNames, String moduleName) { + String appConfigPath = OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE + "/app.config.ts"; + + try { + // 读取原文件内容 + String content = new String(Files.readAllBytes(Paths.get(appConfigPath))); + + // 为每个表生成页面路径 + StringBuilder newPages = new StringBuilder(); + for (String tableName : tableNames) { + String entityPath = tableName.replaceAll("_", ""); + // 转换为驼峰命名 + String[] parts = tableName.split("_"); + StringBuilder camelCase = new StringBuilder(parts[0]); + for (int i = 1; i < parts.length; i++) { + camelCase.append(parts[i].substring(0, 1).toUpperCase()).append(parts[i].substring(1)); + } + entityPath = camelCase.toString(); + + newPages.append(" '").append(entityPath).append("/index',\n"); + newPages.append(" '").append(entityPath).append("/add',\n"); + } + + // 查找对应模块的子包配置 + String modulePattern = "\"root\":\\s*\"" + moduleName + "\",\\s*\"pages\":\\s*\\[([^\\]]*)]"; + Pattern pattern = Pattern.compile(modulePattern, Pattern.DOTALL); + Matcher matcher = pattern.matcher(content); + + if (matcher.find()) { + String existingPages = matcher.group(1); + + // 检查页面是否已存在,避免重复添加 + boolean needUpdate = false; + String[] newPageArray = newPages.toString().split("\n"); + for (String newPage : newPageArray) { + if (!newPage.trim().isEmpty() && !existingPages.contains(newPage.trim().replace(" ", "").replace(",", ""))) { + needUpdate = true; + break; + } + } + + if (needUpdate) { + // 备份原文件 + String backupPath = appConfigPath + ".backup." + System.currentTimeMillis(); + Files.copy(Paths.get(appConfigPath), Paths.get(backupPath)); + System.out.println("已备份原文件到: " + backupPath); + + // 在现有页面列表末尾添加新页面 + String updatedPages = existingPages.trim(); + if (!updatedPages.endsWith(",")) { + updatedPages += ","; + } + updatedPages += "\n" + newPages.toString().trim(); + + // 替换内容 + String updatedContent = content.replace(matcher.group(1), updatedPages); + + // 写入更新后的内容 + Files.write(Paths.get(appConfigPath), updatedContent.getBytes()); + + System.out.println("✅ 已自动更新 app.config.ts,添加了以下页面路径:"); + System.out.println(newPages.toString()); + } else { + System.out.println("ℹ️ app.config.ts 中已包含所有页面路径,无需更新"); + } + } else { + System.out.println("⚠️ 未找到 " + moduleName + " 模块的子包配置,请手动添加页面路径"); + } + + } catch (Exception e) { + System.err.println("❌ 更新 app.config.ts 失败: " + e.getMessage()); + e.printStackTrace(); + } + } + +}