From f1dde97538cd9ae6fbdc565774348e9262b3e1ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Wed, 1 Apr 2026 00:59:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(website):=20=E6=96=B0=E5=A2=9E=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=8F=91=E5=B8=83=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在CmsWebsite实体中添加发布状态、定价模式、应用描述等相关字段 - 实现应用上架审核流程:提交审核、撤回申请、下架、管理员审批等功能 - 添加审核列表分页查询接口,支持按发布状态筛选 - 更新路由配置,调整开发者资源路径 - 添加数据库表结构变更SQL脚本,增加发布管理相关字段 --- .../app/controller/AppResourceController.java | 2 +- .../cms/controller/CmsWebsiteController.java | 81 +++++++++++++ .../com/gxwebsoft/cms/entity/CmsWebsite.java | 44 +++++++ .../gxwebsoft/cms/param/CmsWebsiteParam.java | 3 + .../cms/service/CmsWebsiteService.java | 22 ++++ .../service/impl/CmsWebsiteServiceImpl.java | 110 +++++++++++++++++- .../gxwebsoft/cms/sql/cms_website_publish.sql | 17 +++ 7 files changed, 275 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/gxwebsoft/cms/sql/cms_website_publish.sql diff --git a/src/main/java/com/gxwebsoft/app/controller/AppResourceController.java b/src/main/java/com/gxwebsoft/app/controller/AppResourceController.java index 35a8273..28fa031 100644 --- a/src/main/java/com/gxwebsoft/app/controller/AppResourceController.java +++ b/src/main/java/com/gxwebsoft/app/controller/AppResourceController.java @@ -26,7 +26,7 @@ import java.util.Map; @Slf4j @Tag(name = "开发者资源管理") @RestController -@RequestMapping("/api/_modules/app/developer-resource") +@RequestMapping("/api/app/developer-resource") public class AppResourceController extends BaseController { @Resource diff --git a/src/main/java/com/gxwebsoft/cms/controller/CmsWebsiteController.java b/src/main/java/com/gxwebsoft/cms/controller/CmsWebsiteController.java index 0a1ade6..ddf42de 100644 --- a/src/main/java/com/gxwebsoft/cms/controller/CmsWebsiteController.java +++ b/src/main/java/com/gxwebsoft/cms/controller/CmsWebsiteController.java @@ -562,4 +562,85 @@ public class CmsWebsiteController extends BaseController { return success("清除成功"); } + // ─── 发布管理 ──────────────────────────────────────────────────────── + + @Operation(summary = "提交上架审核") + @PostMapping("/submitReview") + public ApiResult submitReview(@RequestBody Map body) { + Integer websiteId = body.get("websiteId") instanceof Number ? ((Number) body.get("websiteId")).intValue() : null; + if (websiteId == null) return fail("websiteId 不能为空"); + String priceType = (String) body.get("priceType"); + Integer price = body.get("price") instanceof Number ? ((Number) body.get("price")).intValue() : 0; + String subscriptionPeriod = (String) body.get("subscriptionPeriod"); + String appDescription = (String) body.get("appDescription"); + String detailDescription = (String) body.get("detailDescription"); + String screenshots = (String) body.get("screenshots"); + Integer userId = getLoginUserId(); + try { + cmsWebsiteService.submitReview(websiteId, priceType, price, subscriptionPeriod, + appDescription, detailDescription, screenshots, userId); + return success("上架申请提交成功,等待审核"); + } catch (Exception e) { + return fail(e.getMessage()); + } + } + + @Operation(summary = "撤回审核申请") + @PostMapping("/withdrawReview/{websiteId}") + public ApiResult withdrawReview(@PathVariable Integer websiteId) { + try { + cmsWebsiteService.withdrawReview(websiteId, getLoginUserId()); + return success("已撤回审核申请"); + } catch (Exception e) { + return fail(e.getMessage()); + } + } + + @Operation(summary = "下架应用") + @PostMapping("/unpublish/{websiteId}") + public ApiResult unpublish(@PathVariable Integer websiteId) { + try { + cmsWebsiteService.unpublish(websiteId, getLoginUserId()); + return success("已下架"); + } catch (Exception e) { + return fail(e.getMessage()); + } + } + + @PreAuthorize("hasAuthority('cms:website:update')") + @Operation(summary = "管理员审核通过") + @PostMapping("/approveReview/{websiteId}") + public ApiResult approveReview(@PathVariable Integer websiteId) { + try { + cmsWebsiteService.approveReview(websiteId, getLoginUserId()); + return success("审核通过,应用已上架"); + } catch (Exception e) { + return fail(e.getMessage()); + } + } + + @PreAuthorize("hasAuthority('cms:website:update')") + @Operation(summary = "管理员审核拒绝") + @PostMapping("/rejectReview") + public ApiResult rejectReview(@RequestBody Map body) { + Integer websiteId = body.get("websiteId") instanceof Number ? ((Number) body.get("websiteId")).intValue() : null; + String rejectReason = (String) body.get("rejectReason"); + if (websiteId == null) return fail("websiteId 不能为空"); + if (rejectReason == null || rejectReason.isBlank()) return fail("请填写拒绝原因"); + try { + cmsWebsiteService.rejectReview(websiteId, rejectReason, getLoginUserId()); + return success("已拒绝该应用上架申请"); + } catch (Exception e) { + return fail(e.getMessage()); + } + } + + @PreAuthorize("hasAuthority('cms:website:update')") + @Operation(summary = "获取审核列表(管理员)") + @GetMapping("/pageReviews") + public ApiResult> pageReviews(CmsWebsiteParam param) { + return success(cmsWebsiteService.pageReviews(param)); + } + } + diff --git a/src/main/java/com/gxwebsoft/cms/entity/CmsWebsite.java b/src/main/java/com/gxwebsoft/cms/entity/CmsWebsite.java index 31087c4..7f253b4 100644 --- a/src/main/java/com/gxwebsoft/cms/entity/CmsWebsite.java +++ b/src/main/java/com/gxwebsoft/cms/entity/CmsWebsite.java @@ -321,6 +321,50 @@ public class CmsWebsite implements Serializable { @TableField(exist = false) private CmsWebsiteSetting setting; + // ─── 发布管理字段 ────────────────────────────────────────────────── + + @Schema(description = "发布状态: developing开发中 pending_review待审核 published已上架 rejected审核未通过 deprecated已下架") + private String publishStatus; + + @Schema(description = "定价模式: free免费 one_time一次性 subscription订阅") + private String priceType; + + @Schema(description = "订阅周期: month按月 year按年") + private String subscriptionPeriod; + + @Schema(description = "应用简介(市场展示用)") + private String appDescription; + + @Schema(description = "详细说明(富文本)") + private String detailDescription; + + @Schema(description = "应用截图(JSON数组字符串)") + private String screenshots; + + @Schema(description = "安装/使用次数") + private Integer installCount; + + @Schema(description = "评分(1-5)") + private java.math.BigDecimal rating; + + @Schema(description = "审核拒绝原因") + private String rejectReason; + + @Schema(description = "提交审核时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date publishApplyTime; + + @Schema(description = "正式发布上架时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date publishTime; + + @Schema(description = "审核人用户ID") + private Integer reviewerId; + + @Schema(description = "审核操作时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date reviewTime; + public String getPhone(){ return DesensitizedUtil.mobilePhone(this.phone); } diff --git a/src/main/java/com/gxwebsoft/cms/param/CmsWebsiteParam.java b/src/main/java/com/gxwebsoft/cms/param/CmsWebsiteParam.java index 6236415..7c7be19 100644 --- a/src/main/java/com/gxwebsoft/cms/param/CmsWebsiteParam.java +++ b/src/main/java/com/gxwebsoft/cms/param/CmsWebsiteParam.java @@ -225,4 +225,7 @@ public class CmsWebsiteParam extends BaseParam { @QueryField(type = QueryType.EQ) private String adminPhone; + @Schema(description = "发布状态筛选: developing/pending_review/published/rejected/deprecated") + private String publishStatus; + } diff --git a/src/main/java/com/gxwebsoft/cms/service/CmsWebsiteService.java b/src/main/java/com/gxwebsoft/cms/service/CmsWebsiteService.java index a78dfa2..db72d5d 100644 --- a/src/main/java/com/gxwebsoft/cms/service/CmsWebsiteService.java +++ b/src/main/java/com/gxwebsoft/cms/service/CmsWebsiteService.java @@ -67,4 +67,26 @@ public interface CmsWebsiteService extends IService { * @param tenantId 租户ID */ void clearSiteInfoCache(Integer tenantId); + + // ─── 发布管理 ────────────────────────────────────────────────── + + /** 提交上架审核 */ + void submitReview(Integer websiteId, String priceType, Integer price, + String subscriptionPeriod, String appDescription, + String detailDescription, String screenshots, Integer userId); + + /** 撤回审核申请(回到开发中) */ + void withdrawReview(Integer websiteId, Integer userId); + + /** 下架应用 */ + void unpublish(Integer websiteId, Integer userId); + + /** 管理员审核通过 */ + void approveReview(Integer websiteId, Integer reviewerId); + + /** 管理员审核拒绝 */ + void rejectReview(Integer websiteId, String rejectReason, Integer reviewerId); + + /** 分页查询审核列表(管理员) */ + PageResult pageReviews(CmsWebsiteParam param); } diff --git a/src/main/java/com/gxwebsoft/cms/service/impl/CmsWebsiteServiceImpl.java b/src/main/java/com/gxwebsoft/cms/service/impl/CmsWebsiteServiceImpl.java index 8b74f83..c3a6868 100644 --- a/src/main/java/com/gxwebsoft/cms/service/impl/CmsWebsiteServiceImpl.java +++ b/src/main/java/com/gxwebsoft/cms/service/impl/CmsWebsiteServiceImpl.java @@ -417,9 +417,113 @@ public class CmsWebsiteServiceImpl extends ServiceImpl pageReviews(CmsWebsiteParam param) { + com.baomidou.mybatisplus.extension.plugins.pagination.Page page = + new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(param.getCurrent(), param.getSize() > 0 ? param.getSize() : 20); + com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper wrapper = + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(CmsWebsite::getDeleted, 0) + .isNotNull(CmsWebsite::getPublishStatus) + .ne(CmsWebsite::getPublishStatus, "developing") + .eq(cn.hutool.core.util.ObjectUtil.isNotEmpty(param.getPublishStatus()), + CmsWebsite::getPublishStatus, param.getPublishStatus()) + .and(cn.hutool.core.util.ObjectUtil.isNotEmpty(param.getKeywords()), q -> + q.like(CmsWebsite::getWebsiteName, param.getKeywords()) + .or().like(CmsWebsite::getWebsiteCode, param.getKeywords())) + .last("ORDER BY FIELD(publish_status,'pending_review','rejected','published','deprecated'), publish_apply_time DESC"); + baseMapper.selectPage(page, wrapper); + return new com.gxwebsoft.common.core.web.PageResult<>(page.getRecords(), page.getTotal()); + } + + private CmsWebsite getWebsiteFromDatabase(Integer tenantId) { return getByTenantId(tenantId); } diff --git a/src/main/java/com/gxwebsoft/cms/sql/cms_website_publish.sql b/src/main/java/com/gxwebsoft/cms/sql/cms_website_publish.sql new file mode 100644 index 0000000..a70f593 --- /dev/null +++ b/src/main/java/com/gxwebsoft/cms/sql/cms_website_publish.sql @@ -0,0 +1,17 @@ +-- 为 cms_website 表新增发布管理相关字段 +-- 执行前请确认已连接正确的数据库 + +ALTER TABLE `cms_website` + ADD COLUMN `publish_status` VARCHAR(20) NULL DEFAULT 'developing' COMMENT '发布状态: developing开发中 pending_review待审核 published已上架 rejected审核未通过 deprecated已下架' AFTER `market`, + ADD COLUMN `price_type` VARCHAR(20) NULL COMMENT '定价模式: free免费 one_time一次性 subscription订阅' AFTER `publish_status`, + ADD COLUMN `subscription_period` VARCHAR(10) NULL COMMENT '订阅周期: month按月 year按年' AFTER `price_type`, + ADD COLUMN `app_description` VARCHAR(500) NULL COMMENT '应用简介(市场展示用)' AFTER `subscription_period`, + ADD COLUMN `detail_description` TEXT NULL COMMENT '详细说明(富文本)' AFTER `app_description`, + ADD COLUMN `screenshots` TEXT NULL COMMENT '应用截图(JSON数组字符串)' AFTER `detail_description`, + ADD COLUMN `install_count` INT NULL DEFAULT 0 COMMENT '安装/使用次数' AFTER `screenshots`, + ADD COLUMN `rating` DECIMAL(3,1) NULL DEFAULT 0.0 COMMENT '评分(1-5)' AFTER `install_count`, + ADD COLUMN `reject_reason` VARCHAR(500) NULL COMMENT '审核拒绝原因' AFTER `rating`, + ADD COLUMN `publish_apply_time` DATETIME NULL COMMENT '提交审核时间' AFTER `reject_reason`, + ADD COLUMN `publish_time` DATETIME NULL COMMENT '正式发布上架时间' AFTER `publish_apply_time`, + ADD COLUMN `reviewer_id` INT NULL COMMENT '审核人用户ID' AFTER `publish_time`, + ADD COLUMN `review_time` DATETIME NULL COMMENT '审核操作时间' AFTER `reviewer_id`;