feat(cms): 新增客户案例模块及多模块统计接口

- 新增客户案例实体、参数、Mapper、Service及ServiceImpl实现
- 提供客户案例分页查询、列表查询、详情查询、添加、修改、删除及状态修改接口
- 各内容管理模块(文章、轮播图、留言、产品、用户)添加统计概览接口
- 统计接口支持按状态分类统计总数、发布、草稿等各类指标
- 统一返回统计数据方便前端展示管理后台数据概览
This commit is contained in:
2026-07-17 19:48:57 +08:00
parent 211cd2a7e8
commit 7ade096e81
11 changed files with 391 additions and 3 deletions

View File

@@ -390,4 +390,15 @@ public class CmsArticleController extends BaseController {
// 使用关联查询 // 使用关联查询
return success(cmsArticleService.list(new LambdaQueryWrapper<CmsArticle>().in(CmsArticle::getArticleId, param.getArticleIds()))); return success(cmsArticleService.list(new LambdaQueryWrapper<CmsArticle>().in(CmsArticle::getArticleId, param.getArticleIds())));
} }
@Operation(summary = "统计概览")
@GetMapping("/stats")
public ApiResult<Map<String, Object>> stats() {
Map<String, Object> map = new HashMap<>();
map.put("total", cmsArticleService.count());
map.put("published", cmsArticleService.count(new LambdaQueryWrapper<CmsArticle>().eq(CmsArticle::getStatus, 1)));
map.put("draft", cmsArticleService.count(new LambdaQueryWrapper<CmsArticle>().eq(CmsArticle::getStatus, 0)));
map.put("offline", cmsArticleService.count(new LambdaQueryWrapper<CmsArticle>().eq(CmsArticle::getStatus, 2)));
return success(map);
}
} }

View File

@@ -11,7 +11,8 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
/** /**
* 轮播图控制器 * 轮播图控制器
@@ -82,4 +83,14 @@ public class CmsBannerController extends BaseController {
} }
return fail("修改失败"); return fail("修改失败");
} }
@Operation(summary = "统计概览")
@GetMapping("/stats")
public ApiResult<Map<String, Object>> stats() {
Map<String, Object> map = new HashMap<>();
map.put("total", cmsBannerService.count());
map.put("enabled", cmsBannerService.count(new LambdaQueryWrapper<CmsBanner>().eq(CmsBanner::getStatus, 1)));
map.put("disabled", cmsBannerService.count(new LambdaQueryWrapper<CmsBanner>().eq(CmsBanner::getStatus, 0)));
return success(map);
}
} }

View File

@@ -0,0 +1,102 @@
package com.gxwebsoft.cms.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.cms.entity.CmsCase;
import com.gxwebsoft.cms.param.CmsCaseParam;
import com.gxwebsoft.cms.service.CmsCaseService;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.PageResult;
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.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
* 客户案例控制器
*
* @author WorkBuddy
* @since 2026-07-17
*/
@Tag(name = "客户案例管理")
@RestController
@RequestMapping("/api/cms/cms-case")
public class CmsCaseController extends BaseController {
@Resource
private CmsCaseService cmsCaseService;
@Operation(summary = "分页查询客户案例")
@GetMapping("/page")
public ApiResult<PageResult<CmsCase>> page(CmsCaseParam param) {
return success(cmsCaseService.pageRel(param));
}
@Operation(summary = "查询全部客户案例")
@GetMapping()
public ApiResult<java.util.List<CmsCase>> list(CmsCaseParam param) {
return success(cmsCaseService.listRel(param));
}
@Operation(summary = "根据id查询客户案例")
@GetMapping("/{id}")
public ApiResult<CmsCase> get(@PathVariable("id") Integer id) {
return success(cmsCaseService.getByIdRel(id));
}
@Operation(summary = "添加客户案例")
@PostMapping()
public ApiResult<?> save(@RequestBody CmsCase cmsCase) {
User loginUser = getLoginUser();
if (loginUser != null) {
cmsCase.setUserId(loginUser.getUserId());
}
if (cmsCaseService.save(cmsCase)) {
return success("添加成功");
}
return fail("添加失败");
}
@Operation(summary = "修改客户案例")
@PutMapping()
public ApiResult<?> update(@RequestBody CmsCase cmsCase) {
if (cmsCaseService.updateById(cmsCase)) {
return success("修改成功");
}
return fail("修改失败");
}
@Operation(summary = "删除客户案例")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (cmsCaseService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@Operation(summary = "修改案例状态(发布/下线)")
@PutMapping("/status")
public ApiResult<?> updateStatus(@RequestBody CmsCase cmsCase) {
CmsCase entity = new CmsCase();
entity.setCaseId(cmsCase.getCaseId());
entity.setStatus(cmsCase.getStatus());
if (cmsCaseService.updateById(entity)) {
return success("修改成功");
}
return fail("修改失败");
}
@Operation(summary = "统计概览")
@GetMapping("/stats")
public ApiResult<Map<String, Object>> stats() {
Map<String, Object> map = new HashMap<>();
map.put("total", cmsCaseService.count());
map.put("published", cmsCaseService.count(new LambdaQueryWrapper<CmsCase>().eq(CmsCase::getStatus, 1)));
map.put("offline", cmsCaseService.count(new LambdaQueryWrapper<CmsCase>().eq(CmsCase::getStatus, 0)));
return success(map);
}
}

View File

@@ -12,7 +12,8 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
/** /**
* 留言咨询控制器 * 留言咨询控制器
@@ -79,4 +80,15 @@ public class CmsMessageController extends BaseController {
} }
return fail("回复失败"); return fail("回复失败");
} }
@Operation(summary = "统计概览")
@GetMapping("/stats")
public ApiResult<Map<String, Object>> stats() {
Map<String, Object> map = new HashMap<>();
map.put("total", cmsMessageService.count());
map.put("pending", cmsMessageService.count(new LambdaQueryWrapper<CmsMessage>().eq(CmsMessage::getStatus, 0)));
map.put("replied", cmsMessageService.count(new LambdaQueryWrapper<CmsMessage>().eq(CmsMessage::getStatus, 1)));
map.put("done", cmsMessageService.count(new LambdaQueryWrapper<CmsMessage>().eq(CmsMessage::getStatus, 2)));
return success(map);
}
} }

View File

@@ -12,7 +12,8 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
/** /**
* 产品控制器 * 产品控制器
@@ -87,4 +88,14 @@ public class CmsProductController extends BaseController {
} }
return fail("修改失败"); return fail("修改失败");
} }
@Operation(summary = "统计概览")
@GetMapping("/stats")
public ApiResult<Map<String, Object>> stats() {
Map<String, Object> map = new HashMap<>();
map.put("total", cmsProductService.count());
map.put("onSale", cmsProductService.count(new LambdaQueryWrapper<CmsProduct>().eq(CmsProduct::getStatus, 1)));
map.put("offSale", cmsProductService.count(new LambdaQueryWrapper<CmsProduct>().eq(CmsProduct::getStatus, 0)));
return success(map);
}
} }

View File

@@ -0,0 +1,80 @@
package com.gxwebsoft.cms.entity;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 客户案例
*
* @author WorkBuddy
* @since 2026-07-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("cms_case")
@Schema(name = "CmsCase对象", description = "客户案例")
public class CmsCase implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "案例ID")
@TableId(value = "case_id", type = IdType.AUTO)
private Integer caseId;
@Schema(description = "案例名称")
private String caseName;
@Schema(description = "封面图")
private String cover;
@Schema(description = "简介")
private String summary;
@Schema(description = "案例详情")
private String content;
@Schema(description = "所属行业")
private String industry;
@Schema(description = "客户名称")
private String customer;
@Schema(description = "使用产品")
private String productUsed;
@Schema(description = "状态: 1已发布 0已下线")
private Integer status;
@Schema(description = "排序(数字越小越靠前)")
@JsonProperty("sortNum")
@JSONField(name = "sortNum")
private Integer sortNumber;
@Schema(description = "浏览量")
private Integer views;
@Schema(description = "是否删除: 0否 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,16 @@
package com.gxwebsoft.cms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gxwebsoft.cms.entity.CmsCase;
import org.apache.ibatis.annotations.Mapper;
/**
* 客户案例Mapper
*
* @author WorkBuddy
* @since 2026-07-17
*/
@Mapper
public interface CmsCaseMapper extends BaseMapper<CmsCase> {
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.cms.param;
import com.gxwebsoft.common.core.annotation.QueryField;
import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 客户案例查询参数
*
* @author WorkBuddy
* @since 2026-07-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CmsCaseParam对象", description = "客户案例查询参数")
public class CmsCaseParam extends BaseParam {
private static final long serialVersionUID = 1L;
@Schema(description = "案例ID")
@QueryField(type = QueryType.EQ)
private Integer caseId;
@Schema(description = "案例名称")
@QueryField(type = QueryType.LIKE)
private String caseName;
@Schema(description = "所属行业")
@QueryField(type = QueryType.EQ)
private String industry;
@Schema(description = "状态: 1已发布 0已下线")
@QueryField(type = QueryType.EQ)
private Integer status;
}

View File

@@ -0,0 +1,41 @@
package com.gxwebsoft.cms.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gxwebsoft.cms.entity.CmsCase;
import com.gxwebsoft.cms.param.CmsCaseParam;
import com.gxwebsoft.common.core.web.PageResult;
import java.util.List;
/**
* 客户案例Service接口
*
* @author WorkBuddy
* @since 2026-07-17
*/
public interface CmsCaseService extends IService<CmsCase> {
/**
* 分页查询
*
* @param param 查询参数
* @return 分页结果
*/
PageResult<CmsCase> pageRel(CmsCaseParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return 列表
*/
List<CmsCase> listRel(CmsCaseParam param);
/**
* 根据id查询
*
* @param caseId 案例ID
* @return 案例
*/
CmsCase getByIdRel(Integer caseId);
}

View File

@@ -0,0 +1,57 @@
package com.gxwebsoft.cms.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.cms.entity.CmsCase;
import com.gxwebsoft.cms.mapper.CmsCaseMapper;
import com.gxwebsoft.cms.param.CmsCaseParam;
import com.gxwebsoft.cms.service.CmsCaseService;
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 WorkBuddy
* @since 2026-07-17
*/
@Service
public class CmsCaseServiceImpl extends ServiceImpl<CmsCaseMapper, CmsCase> implements CmsCaseService {
@Override
public PageResult<CmsCase> pageRel(CmsCaseParam param) {
PageParam<CmsCase, CmsCaseParam> page = new PageParam<>(param);
page.setDefaultOrder("sort_number asc, create_time desc");
QueryWrapper<CmsCase> wrapper = page.getWrapper();
if (StrUtil.isNotBlank(param.getKeywords())) {
wrapper.and(w -> w.like("case_name", param.getKeywords())
.or().like("customer", param.getKeywords())
.or().like("industry", param.getKeywords()));
}
IPage<CmsCase> result = page(page, page.getOrderWrapper(wrapper));
return new PageResult<>(result.getRecords(), result.getTotal());
}
@Override
public List<CmsCase> listRel(CmsCaseParam param) {
PageParam<CmsCase, CmsCaseParam> page = new PageParam<>(param);
page.setDefaultOrder("sort_number asc, create_time desc");
QueryWrapper<CmsCase> wrapper = page.getWrapper();
if (StrUtil.isNotBlank(param.getKeywords())) {
wrapper.and(w -> w.like("case_name", param.getKeywords())
.or().like("customer", param.getKeywords())
.or().like("industry", param.getKeywords()));
}
return list(page.getOrderWrapper(wrapper));
}
@Override
public CmsCase getByIdRel(Integer caseId) {
return getById(caseId);
}
}

View File

@@ -398,4 +398,14 @@ public class UserController extends BaseController {
return success("统计成功",totalBalance); return success("统计成功",totalBalance);
} }
@Operation(summary = "用户统计概览")
@GetMapping("/stats")
public ApiResult<Map<String, Object>> stats() {
Map<String, Object> map = new HashMap<>();
map.put("total", userService.count());
map.put("enabled", userService.count(new LambdaQueryWrapper<User>().eq(User::getStatus, 1)));
map.put("disabled", userService.count(new LambdaQueryWrapper<User>().eq(User::getStatus, 0)));
return success(map);
}
} }