feat: 新增后台管理业务模块heritage-admin
- 新增用户管理:用户列表、详情、禁用启用等功能 - 新增新闻管理:新闻的增删改查、发布撤回等功能 - 新增活动管理:活动的增删改查、发布管理、报名管理等功能 - 新增非遗项目管理:项目的增删改查、审核上架等功能 - 新增传承人管理:传承人的增删改查、认证管理等功能 - 新增评论管理:评论审核、删除等功能 - 新增数据统计:平台数据统计、排行榜、趋势分析等功能 - 所有接口均配置Sa-Token权限验证和Swagger接口文档
This commit is contained in:
parent
9a9a279a39
commit
0f9a58b085
56
heritage-modules/heritage-admin/pom.xml
Normal file
56
heritage-modules/heritage-admin/pom.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.leocoder.heritage</groupId>
|
||||
<artifactId>heritage-backend</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
<name>heritage-admin</name>
|
||||
<artifactId>heritage-admin</artifactId>
|
||||
<description>后台管理模块</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- 公共模块 -->
|
||||
<dependency>
|
||||
<groupId>org.leocoder.heritage</groupId>
|
||||
<artifactId>heritage-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<!-- 数据统一返回、全局异常以及限流、数据脱敏、重复提交等插件 -->
|
||||
<dependency>
|
||||
<groupId>org.leocoder.heritage</groupId>
|
||||
<artifactId>heritage-resultex</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<!-- Sa-Token组件 -->
|
||||
<dependency>
|
||||
<groupId>org.leocoder.heritage</groupId>
|
||||
<artifactId>heritage-sa-token</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<!-- 操作日志组件 -->
|
||||
<dependency>
|
||||
<groupId>org.leocoder.heritage</groupId>
|
||||
<artifactId>heritage-oper-logs</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<!-- OSS存储组件 -->
|
||||
<dependency>
|
||||
<groupId>org.leocoder.heritage</groupId>
|
||||
<artifactId>heritage-oss</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<!-- SpringDoc OpenAPI 3.0 -->
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,111 @@
|
||||
package org.leocoder.heritage.admin.controller.comment;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.admin.service.comment.HrtCommentAdminService;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtCommentAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtCommentAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtCommentAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtCommentAdminVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [后台评论管理控制器]
|
||||
*/
|
||||
@Tag(name = "后台评论管理", description = "评论审核、删除、查询等管理功能")
|
||||
@Validated
|
||||
@RequestMapping("/coder/admin/comment")
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class HrtCommentAdminController {
|
||||
|
||||
private final HrtCommentAdminService commentAdminService;
|
||||
|
||||
/**
|
||||
* @description [分页查询评论列表]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "分页查询评论列表", description = "根据查询条件分页获取评论列表,支持多条件筛选")
|
||||
@SaCheckPermission("heritage:comment:list")
|
||||
@GetMapping("/listPage")
|
||||
public IPage<HrtCommentAdminVo> listPage(@Validated HrtCommentAdminQueryBo bo) {
|
||||
return commentAdminService.listPage(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看评论详情]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "查看评论详情", description = "根据评论ID获取评论的完整详细信息")
|
||||
@SaCheckPermission("heritage:comment:detail")
|
||||
@GetMapping("/detail/{id}")
|
||||
public HrtCommentAdminDetailVo detail(@Parameter(description = "评论ID") @PathVariable Long id) {
|
||||
return commentAdminService.getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [审核评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "审核评论", description = "审核评论(批准或拒绝)")
|
||||
@SaCheckPermission("heritage:comment:audit")
|
||||
@PutMapping("/audit")
|
||||
public Boolean audit(@Validated @RequestBody HrtCommentAdminBo bo) {
|
||||
return commentAdminService.auditComment(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量审核评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "批量审核评论", description = "批量审核多个评论")
|
||||
@SaCheckPermission("heritage:comment:audit")
|
||||
@PutMapping("/batchAudit")
|
||||
public Boolean batchAudit(
|
||||
@Parameter(description = "评论ID列表") @RequestBody List<Long> ids,
|
||||
@Parameter(description = "审核状态:0-待审核,1-已通过,2-已拒绝") @RequestParam Integer status) {
|
||||
return commentAdminService.batchAudit(ids, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "删除评论", description = "删除指定评论,同时会删除该评论下的所有回复")
|
||||
@SaCheckPermission("heritage:comment:delete")
|
||||
@DeleteMapping("/delete/{id}")
|
||||
public Boolean delete(@Parameter(description = "评论ID") @PathVariable Long id) {
|
||||
return commentAdminService.deleteComment(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "批量删除评论", description = "批量删除多个评论")
|
||||
@SaCheckPermission("heritage:comment:delete")
|
||||
@DeleteMapping("/batchDelete")
|
||||
public Boolean batchDelete(@Parameter(description = "评论ID列表") @RequestBody List<Long> ids) {
|
||||
return commentAdminService.batchDelete(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [获取待审核评论数量]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "获取待审核评论数量", description = "获取待审核评论的数量")
|
||||
@SaCheckPermission("heritage:comment:list")
|
||||
@GetMapping("/pendingCount")
|
||||
public Long getPendingCount() {
|
||||
return commentAdminService.getPendingCount();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
package org.leocoder.heritage.admin.controller.event;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.admin.service.event.HrtEventAdminService;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtEventAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtEventAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtEventAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtEventAdminVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [活动管理控制器]
|
||||
*/
|
||||
@Tag(name = "活动管理", description = "非遗活动的增删改查、状态管理和发布控制")
|
||||
@Validated
|
||||
@RequestMapping("/coder/admin/event")
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class HrtEventAdminController {
|
||||
|
||||
private final HrtEventAdminService eventAdminService;
|
||||
|
||||
/**
|
||||
* @description [分页查询活动列表]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "分页查询活动列表", description = "根据查询条件分页获取活动列表,支持标题、地点、状态等多条件筛选")
|
||||
@SaCheckPermission("heritage:event:list")
|
||||
@GetMapping("/listPage")
|
||||
public IPage<HrtEventAdminVo> listPage(@Validated HrtEventAdminQueryBo bo) {
|
||||
return eventAdminService.listPage(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看活动详情]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "查看活动详情", description = "根据活动ID获取活动的完整详细信息")
|
||||
@SaCheckPermission("heritage:event:detail")
|
||||
@GetMapping("/detail/{id}")
|
||||
public HrtEventAdminDetailVo detail(@Parameter(description = "活动ID") @PathVariable Long id) {
|
||||
return eventAdminService.getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [新增活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "新增活动", description = "创建新的非遗活动,包括活动信息、时间安排和报名设置")
|
||||
@SaCheckPermission("heritage:event:add")
|
||||
@PostMapping("/add")
|
||||
public Long add(@Validated @RequestBody HrtEventAdminBo bo) {
|
||||
return eventAdminService.addEvent(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [编辑活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "编辑活动", description = "修改已存在活动的信息")
|
||||
@SaCheckPermission("heritage:event:edit")
|
||||
@PutMapping("/edit")
|
||||
public Boolean edit(@Validated @RequestBody HrtEventAdminBo bo) {
|
||||
return eventAdminService.editEvent(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "删除活动", description = "根据ID删除指定活动(已有报名的活动不可删除)")
|
||||
@SaCheckPermission("heritage:event:delete")
|
||||
@DeleteMapping("/delete/{id}")
|
||||
public Boolean delete(@Parameter(description = "活动ID") @PathVariable Long id) {
|
||||
return eventAdminService.deleteEvent(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "批量删除活动", description = "批量删除多个活动(已有报名的活动不可删除)")
|
||||
@SaCheckPermission("heritage:event:delete")
|
||||
@DeleteMapping("/batchDelete")
|
||||
public Boolean batchDelete(@Parameter(description = "活动ID列表") @RequestBody List<Long> ids) {
|
||||
return eventAdminService.batchDelete(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "修改发布状态", description = "修改活动的发布状态(0-草稿,1-已发布)")
|
||||
@SaCheckPermission("heritage:event:status")
|
||||
@PutMapping("/changePublishStatus")
|
||||
public Boolean changePublishStatus(
|
||||
@Parameter(description = "活动ID") @RequestParam Long id,
|
||||
@Parameter(description = "发布状态:0-草稿,1-已发布") @RequestParam Integer publishStatus) {
|
||||
return eventAdminService.changePublishStatus(id, publishStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改活动状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "修改活动状态", description = "修改活动的状态(upcoming-即将开始、ongoing-进行中、finished-已结束、cancelled-已取消)")
|
||||
@SaCheckPermission("heritage:event:status")
|
||||
@PutMapping("/changeEventStatus")
|
||||
public Boolean changeEventStatus(
|
||||
@Parameter(description = "活动ID") @RequestParam Long id,
|
||||
@Parameter(description = "活动状态:upcoming、ongoing、finished、cancelled") @RequestParam String status) {
|
||||
return eventAdminService.changeEventStatus(id, status);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
package org.leocoder.heritage.admin.controller.heritage;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.admin.service.heritage.HrtHeritageAdminService;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtHeritageAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtHeritageAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtHeritageAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtHeritageAdminVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [非遗项目管理控制器]
|
||||
*/
|
||||
@Tag(name = "非遗项目管理", description = "后台管理非遗项目的增删改查、审核、发布等功能")
|
||||
@Validated
|
||||
@RequestMapping("/coder/admin/heritage")
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class HrtHeritageAdminController {
|
||||
|
||||
private final HrtHeritageAdminService hrtHeritageAdminService;
|
||||
|
||||
/**
|
||||
* @description [分页查询非遗项目列表]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "分页查询非遗项目列表", description = "支持多条件筛选和关键词搜索,包含草稿和已发布的项目")
|
||||
@SaCheckPermission("heritage:items:list")
|
||||
@GetMapping("/listPage")
|
||||
public IPage<HrtHeritageAdminVo> listPage(@Validated HrtHeritageAdminQueryBo bo) {
|
||||
return hrtHeritageAdminService.listPage(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看非遗项目详情]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "查看非遗项目详情", description = "根据ID查看非遗项目的完整详细信息")
|
||||
@SaCheckPermission("heritage:items:detail")
|
||||
@GetMapping("/detail/{id}")
|
||||
public HrtHeritageAdminDetailVo detail(@Parameter(description = "非遗项目ID") @PathVariable Long id) {
|
||||
return hrtHeritageAdminService.getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [新增非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "新增非遗项目", description = "新增一个非遗项目,返回新增项目的ID")
|
||||
@SaCheckPermission("heritage:items:add")
|
||||
@PostMapping("/add")
|
||||
public Long add(@Validated @RequestBody HrtHeritageAdminBo bo) {
|
||||
return hrtHeritageAdminService.addHeritage(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [编辑非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "编辑非遗项目", description = "根据ID编辑非遗项目信息")
|
||||
@SaCheckPermission("heritage:items:edit")
|
||||
@PutMapping("/edit")
|
||||
public Boolean edit(@Validated @RequestBody HrtHeritageAdminBo bo) {
|
||||
return hrtHeritageAdminService.editHeritage(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "删除非遗项目", description = "根据ID逻辑删除非遗项目")
|
||||
@SaCheckPermission("heritage:items:delete")
|
||||
@DeleteMapping("/delete/{id}")
|
||||
public Boolean delete(@Parameter(description = "非遗项目ID") @PathVariable Long id) {
|
||||
return hrtHeritageAdminService.deleteHeritage(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "批量删除非遗项目", description = "根据ID列表批量逻辑删除非遗项目")
|
||||
@SaCheckPermission("heritage:items:delete")
|
||||
@DeleteMapping("/batchDelete")
|
||||
public Boolean batchDelete(@Parameter(description = "非遗项目ID列表") @RequestBody List<Long> ids) {
|
||||
return hrtHeritageAdminService.batchDelete(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "修改发布状态", description = "修改非遗项目的发布状态(0-草稿,1-已发布)")
|
||||
@SaCheckPermission("heritage:items:status")
|
||||
@PutMapping("/changePublishStatus")
|
||||
public Boolean changePublishStatus(
|
||||
@Parameter(description = "非遗项目ID") @RequestParam Long id,
|
||||
@Parameter(description = "发布状态:0-草稿,1-已发布") @RequestParam Integer publishStatus) {
|
||||
return hrtHeritageAdminService.changePublishStatus(id, publishStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [设置精选状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "设置精选状态", description = "设置非遗项目是否为精选项目(0-否,1-是)")
|
||||
@SaCheckPermission("heritage:items:status")
|
||||
@PutMapping("/setFeatured")
|
||||
public Boolean setFeatured(
|
||||
@Parameter(description = "非遗项目ID") @RequestParam Long id,
|
||||
@Parameter(description = "精选状态:0-否,1-是") @RequestParam Integer isFeatured) {
|
||||
return hrtHeritageAdminService.setFeatured(id, isFeatured);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
package org.leocoder.heritage.admin.controller.inheritor;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.admin.service.inheritor.HrtInheritorAdminService;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtInheritorAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtInheritorAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtInheritorAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtInheritorAdminVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [传承人管理控制器]
|
||||
*/
|
||||
@Tag(name = "传承人管理", description = "后台管理传承人的增删改查、审核、发布等功能")
|
||||
@Validated
|
||||
@RequestMapping("/coder/admin/inheritor")
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class HrtInheritorAdminController {
|
||||
|
||||
private final HrtInheritorAdminService hrtInheritorAdminService;
|
||||
|
||||
/**
|
||||
* @description [分页查询传承人列表]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "分页查询传承人列表", description = "支持多条件筛选和关键词搜索,包含草稿和已发布的传承人")
|
||||
@SaCheckPermission("heritage:inheritors:list")
|
||||
@GetMapping("/listPage")
|
||||
public IPage<HrtInheritorAdminVo> listPage(@Validated HrtInheritorAdminQueryBo bo) {
|
||||
return hrtInheritorAdminService.listPage(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看传承人详情]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "查看传承人详情", description = "根据ID查看传承人的完整详细信息")
|
||||
@SaCheckPermission("heritage:inheritors:detail")
|
||||
@GetMapping("/detail/{id}")
|
||||
public HrtInheritorAdminDetailVo detail(@Parameter(description = "传承人ID") @PathVariable Long id) {
|
||||
return hrtInheritorAdminService.getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [新增传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "新增传承人", description = "新增一个传承人,返回新增传承人的ID")
|
||||
@SaCheckPermission("heritage:inheritors:add")
|
||||
@PostMapping("/add")
|
||||
public Long add(@Validated @RequestBody HrtInheritorAdminBo bo) {
|
||||
return hrtInheritorAdminService.addInheritor(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [编辑传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "编辑传承人", description = "根据ID编辑传承人信息")
|
||||
@SaCheckPermission("heritage:inheritors:edit")
|
||||
@PutMapping("/edit")
|
||||
public Boolean edit(@Validated @RequestBody HrtInheritorAdminBo bo) {
|
||||
return hrtInheritorAdminService.editInheritor(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "删除传承人", description = "根据ID逻辑删除传承人")
|
||||
@SaCheckPermission("heritage:inheritors:delete")
|
||||
@DeleteMapping("/delete/{id}")
|
||||
public Boolean delete(@Parameter(description = "传承人ID") @PathVariable Long id) {
|
||||
return hrtInheritorAdminService.deleteInheritor(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "批量删除传承人", description = "根据ID列表批量逻辑删除传承人")
|
||||
@SaCheckPermission("heritage:inheritors:delete")
|
||||
@DeleteMapping("/batchDelete")
|
||||
public Boolean batchDelete(@Parameter(description = "传承人ID列表") @RequestBody List<Long> ids) {
|
||||
return hrtInheritorAdminService.batchDelete(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "修改发布状态", description = "修改传承人的发布状态(0-草稿,1-已发布)")
|
||||
@SaCheckPermission("heritage:inheritors:status")
|
||||
@PutMapping("/changePublishStatus")
|
||||
public Boolean changePublishStatus(
|
||||
@Parameter(description = "传承人ID") @RequestParam Long id,
|
||||
@Parameter(description = "发布状态:0-草稿,1-已发布") @RequestParam Integer publishStatus) {
|
||||
return hrtInheritorAdminService.changePublishStatus(id, publishStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [设置精选状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "设置精选状态", description = "设置传承人是否为精选传承人(0-否,1-是)")
|
||||
@SaCheckPermission("heritage:inheritors:status")
|
||||
@PutMapping("/setFeatured")
|
||||
public Boolean setFeatured(
|
||||
@Parameter(description = "传承人ID") @RequestParam Long id,
|
||||
@Parameter(description = "精选状态:0-否,1-是") @RequestParam Integer isFeatured) {
|
||||
return hrtInheritorAdminService.setFeatured(id, isFeatured);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
package org.leocoder.heritage.admin.controller.news;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.admin.service.news.HrtNewsAdminService;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtNewsAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtNewsAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtNewsAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtNewsAdminVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [新闻资讯管理控制器]
|
||||
*/
|
||||
@Tag(name = "新闻资讯管理", description = "后台管理新闻资讯的增删改查、审核、发布等功能")
|
||||
@Validated
|
||||
@RequestMapping("/coder/admin/news")
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class HrtNewsAdminController {
|
||||
|
||||
private final HrtNewsAdminService hrtNewsAdminService;
|
||||
|
||||
/**
|
||||
* @description [分页查询新闻资讯列表]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "分页查询新闻资讯列表", description = "支持多条件筛选和关键词搜索,包含草稿和已发布的新闻")
|
||||
@SaCheckPermission("heritage:news:list")
|
||||
@GetMapping("/listPage")
|
||||
public IPage<HrtNewsAdminVo> listPage(@Validated HrtNewsAdminQueryBo bo) {
|
||||
return hrtNewsAdminService.listPage(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看新闻资讯详情]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "查看新闻资讯详情", description = "根据ID查看新闻资讯的完整详细信息")
|
||||
@SaCheckPermission("heritage:news:detail")
|
||||
@GetMapping("/detail/{id}")
|
||||
public HrtNewsAdminDetailVo detail(@Parameter(description = "新闻资讯ID") @PathVariable Long id) {
|
||||
return hrtNewsAdminService.getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [新增新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "新增新闻资讯", description = "新增一条新闻资讯,返回新增新闻的ID")
|
||||
@SaCheckPermission("heritage:news:add")
|
||||
@PostMapping("/add")
|
||||
public Long add(@Validated @RequestBody HrtNewsAdminBo bo) {
|
||||
return hrtNewsAdminService.addNews(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [编辑新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "编辑新闻资讯", description = "根据ID编辑新闻资讯信息")
|
||||
@SaCheckPermission("heritage:news:edit")
|
||||
@PutMapping("/edit")
|
||||
public Boolean edit(@Validated @RequestBody HrtNewsAdminBo bo) {
|
||||
return hrtNewsAdminService.editNews(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "删除新闻资讯", description = "根据ID逻辑删除新闻资讯")
|
||||
@SaCheckPermission("heritage:news:delete")
|
||||
@DeleteMapping("/delete/{id}")
|
||||
public Boolean delete(@Parameter(description = "新闻资讯ID") @PathVariable Long id) {
|
||||
return hrtNewsAdminService.deleteNews(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "批量删除新闻资讯", description = "根据ID列表批量逻辑删除新闻资讯")
|
||||
@SaCheckPermission("heritage:news:delete")
|
||||
@DeleteMapping("/batchDelete")
|
||||
public Boolean batchDelete(@Parameter(description = "新闻资讯ID列表") @RequestBody List<Long> ids) {
|
||||
return hrtNewsAdminService.batchDelete(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "修改发布状态", description = "修改新闻资讯的发布状态(0-草稿,1-已发布)")
|
||||
@SaCheckPermission("heritage:news:status")
|
||||
@PutMapping("/changePublishStatus")
|
||||
public Boolean changePublishStatus(
|
||||
@Parameter(description = "新闻资讯ID") @RequestParam Long id,
|
||||
@Parameter(description = "发布状态:0-草稿,1-已发布") @RequestParam Integer publishStatus) {
|
||||
return hrtNewsAdminService.changePublishStatus(id, publishStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [设置置顶状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "设置置顶状态", description = "设置新闻资讯是否置顶显示(0-否,1-是)")
|
||||
@SaCheckPermission("heritage:news:status")
|
||||
@PutMapping("/setTop")
|
||||
public Boolean setTop(
|
||||
@Parameter(description = "新闻资讯ID") @RequestParam Long id,
|
||||
@Parameter(description = "置顶状态:0-否,1-是") @RequestParam Integer isTop) {
|
||||
return hrtNewsAdminService.setTop(id, isTop);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package org.leocoder.heritage.admin.controller.statistics;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.admin.service.statistics.HrtStatisticsService;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtRankingVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtStatisticsVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtTrendVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [统计分析控制器]
|
||||
*/
|
||||
@Tag(name = "统计分析管理", description = "平台数据统计、趋势分析和排行榜功能")
|
||||
@Validated
|
||||
@RequestMapping("/coder/admin/statistics")
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class HrtStatisticsController {
|
||||
|
||||
private final HrtStatisticsService statisticsService;
|
||||
|
||||
/**
|
||||
* @description [获取核心统计数据]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "获取核心统计数据", description = "获取平台核心数据统计,包括非遗项目、用户、评论、点赞、收藏等数据")
|
||||
@SaCheckPermission("heritage:statistics:view")
|
||||
@GetMapping("/core")
|
||||
public HrtStatisticsVo getStatistics() {
|
||||
return statisticsService.getStatistics();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [获取用户增长趋势]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "获取用户增长趋势", description = "获取最近7天或30天的用户注册增长趋势数据")
|
||||
@SaCheckPermission("heritage:statistics:view")
|
||||
@GetMapping("/userTrend")
|
||||
public List<HrtTrendVo> getUserTrend(
|
||||
@Parameter(description = "天数:7或30") @RequestParam(defaultValue = "7") Integer days) {
|
||||
return statisticsService.getUserTrend(days);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [获取内容发布趋势]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "获取内容发布趋势", description = "获取最近7天或30天的内容发布趋势数据(非遗项目+新闻+活动)")
|
||||
@SaCheckPermission("heritage:statistics:view")
|
||||
@GetMapping("/contentTrend")
|
||||
public List<HrtTrendVo> getContentTrend(
|
||||
@Parameter(description = "天数:7或30") @RequestParam(defaultValue = "7") Integer days) {
|
||||
return statisticsService.getContentTrend(days);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [获取热门非遗项目排行榜]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "获取热门非遗项目排行榜", description = "获取热门非遗项目TOP榜单,支持按浏览量或收藏数排序")
|
||||
@SaCheckPermission("heritage:statistics:view")
|
||||
@GetMapping("/heritageRanking")
|
||||
public List<HrtRankingVo> getHeritageRanking(
|
||||
@Parameter(description = "排序类型:view-浏览量,favorite-收藏数") @RequestParam(defaultValue = "view") String type,
|
||||
@Parameter(description = "返回数量") @RequestParam(defaultValue = "10") Integer limit) {
|
||||
return statisticsService.getHeritageRanking(type, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [获取活跃用户排行榜]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "获取活跃用户排行榜", description = "获取活跃用户TOP榜单,根据评论、点赞、收藏等行为综合计算")
|
||||
@SaCheckPermission("heritage:statistics:view")
|
||||
@GetMapping("/activeUserRanking")
|
||||
public List<HrtRankingVo> getActiveUserRanking(
|
||||
@Parameter(description = "返回数量") @RequestParam(defaultValue = "10") Integer limit) {
|
||||
return statisticsService.getActiveUserRanking(limit);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
package org.leocoder.heritage.admin.controller.user;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.admin.service.user.HrtUserAdminService;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtUserAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtUserAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtUserAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtUserAdminVo;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [前台用户管理控制器]
|
||||
*/
|
||||
@Tag(name = "前台用户管理", description = "前台用户的增删改查、状态管理和密码重置")
|
||||
@Validated
|
||||
@RequestMapping("/coder/admin/user")
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class HrtUserAdminController {
|
||||
|
||||
private final HrtUserAdminService userAdminService;
|
||||
|
||||
/**
|
||||
* @description [分页查询用户列表]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "分页查询用户列表", description = "根据查询条件分页获取前台用户列表,支持用户名、昵称、手机号等多条件筛选")
|
||||
@SaCheckPermission("heritage:user:list")
|
||||
@GetMapping("/listPage")
|
||||
public IPage<HrtUserAdminVo> listPage(@Validated HrtUserAdminQueryBo bo) {
|
||||
return userAdminService.listPage(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看用户详情]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "查看用户详情", description = "根据用户ID获取用户的完整详细信息")
|
||||
@SaCheckPermission("heritage:user:detail")
|
||||
@GetMapping("/detail/{id}")
|
||||
public HrtUserAdminDetailVo detail(@Parameter(description = "用户ID") @PathVariable Long id) {
|
||||
return userAdminService.getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [新增用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "新增用户", description = "创建新的前台用户,包括用户基本信息和初始密码设置")
|
||||
@SaCheckPermission("heritage:user:add")
|
||||
@PostMapping("/add")
|
||||
public Long add(@Validated @RequestBody HrtUserAdminBo bo) {
|
||||
return userAdminService.addUser(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [编辑用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "编辑用户", description = "修改已存在用户的信息,可选择性更新密码")
|
||||
@SaCheckPermission("heritage:user:edit")
|
||||
@PutMapping("/edit")
|
||||
public Boolean edit(@Validated @RequestBody HrtUserAdminBo bo) {
|
||||
return userAdminService.editUser(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "删除用户", description = "根据ID删除指定用户")
|
||||
@SaCheckPermission("heritage:user:delete")
|
||||
@DeleteMapping("/delete/{id}")
|
||||
public Boolean delete(@Parameter(description = "用户ID") @PathVariable Long id) {
|
||||
return userAdminService.deleteUser(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "批量删除用户", description = "批量删除多个用户")
|
||||
@SaCheckPermission("heritage:user:delete")
|
||||
@DeleteMapping("/batchDelete")
|
||||
public Boolean batchDelete(@Parameter(description = "用户ID列表") @RequestBody List<Long> ids) {
|
||||
return userAdminService.batchDelete(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改用户状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "修改用户状态", description = "修改用户的启用/禁用状态(0-禁用,1-正常)")
|
||||
@SaCheckPermission("heritage:user:status")
|
||||
@PutMapping("/changeStatus")
|
||||
public Boolean changeStatus(
|
||||
@Parameter(description = "用户ID") @RequestParam Long id,
|
||||
@Parameter(description = "用户状态:0-禁用,1-正常") @RequestParam Integer status) {
|
||||
return userAdminService.changeStatus(id, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [重置用户密码]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Operation(summary = "重置用户密码", description = "管理员重置指定用户的登录密码")
|
||||
@SaCheckPermission("heritage:user:edit")
|
||||
@PutMapping("/resetPassword")
|
||||
public Boolean resetPassword(
|
||||
@Parameter(description = "用户ID") @RequestParam Long id,
|
||||
@Parameter(description = "新密码") @RequestParam String newPassword) {
|
||||
return userAdminService.resetPassword(id, newPassword);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package org.leocoder.heritage.admin.service.comment;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtCommentAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtCommentAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtCommentAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtCommentAdminVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [后台评论管理服务接口]
|
||||
*/
|
||||
public interface HrtCommentAdminService {
|
||||
|
||||
/**
|
||||
* @description [分页查询评论列表]
|
||||
* @author Leocoder
|
||||
*/
|
||||
IPage<HrtCommentAdminVo> listPage(HrtCommentAdminQueryBo bo);
|
||||
|
||||
/**
|
||||
* @description [查看评论详情]
|
||||
* @author Leocoder
|
||||
*/
|
||||
HrtCommentAdminDetailVo getDetail(Long id);
|
||||
|
||||
/**
|
||||
* @description [审核评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean auditComment(HrtCommentAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [批量审核评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean batchAudit(List<Long> ids, Integer status);
|
||||
|
||||
/**
|
||||
* @description [删除评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean deleteComment(Long id);
|
||||
|
||||
/**
|
||||
* @description [批量删除评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean batchDelete(List<Long> ids);
|
||||
|
||||
/**
|
||||
* @description [获取待审核评论数量]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Long getPendingCount();
|
||||
|
||||
}
|
||||
@ -0,0 +1,293 @@
|
||||
package org.leocoder.heritage.admin.service.comment;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.common.exception.BusinessException;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtCommentAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtCommentAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtCommentAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtCommentAdminVo;
|
||||
import org.leocoder.heritage.domain.pojo.portal.*;
|
||||
import org.leocoder.heritage.mybatisplus.mapper.portal.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [后台评论管理服务实现类]
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class HrtCommentAdminServiceImpl implements HrtCommentAdminService {
|
||||
|
||||
private final HrtCommentMapper commentMapper;
|
||||
private final HrtUserMapper userMapper;
|
||||
private final HrtHeritageMapper heritageMapper;
|
||||
private final HrtInheritorMapper inheritorMapper;
|
||||
private final HrtNewsMapper newsMapper;
|
||||
private final HrtEventMapper eventMapper;
|
||||
|
||||
/**
|
||||
* @description [分页查询评论列表]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public IPage<HrtCommentAdminVo> listPage(HrtCommentAdminQueryBo bo) {
|
||||
Page<HrtComment> page = new Page<>(bo.getPageNum(), bo.getPageSize());
|
||||
|
||||
LambdaQueryWrapper<HrtComment> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 用户ID查询
|
||||
wrapper.eq(Objects.nonNull(bo.getUserId()), HrtComment::getUserId, bo.getUserId());
|
||||
|
||||
// 目标类型查询
|
||||
wrapper.eq(StrUtil.isNotEmpty(bo.getTargetType()), HrtComment::getTargetType, bo.getTargetType());
|
||||
|
||||
// 目标ID查询
|
||||
wrapper.eq(Objects.nonNull(bo.getTargetId()), HrtComment::getTargetId, bo.getTargetId());
|
||||
|
||||
// 评论内容模糊查询
|
||||
wrapper.like(StrUtil.isNotEmpty(bo.getContent()), HrtComment::getContent, bo.getContent());
|
||||
|
||||
// 状态查询
|
||||
wrapper.eq(Objects.nonNull(bo.getStatus()), HrtComment::getStatus, bo.getStatus());
|
||||
|
||||
// 时间范围查询
|
||||
if (StrUtil.isNotEmpty(bo.getStartTime())) {
|
||||
LocalDateTime startDateTime = LocalDate.parse(bo.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"))
|
||||
.atStartOfDay();
|
||||
wrapper.ge(HrtComment::getCreateTime, startDateTime);
|
||||
}
|
||||
if (StrUtil.isNotEmpty(bo.getEndTime())) {
|
||||
LocalDateTime endDateTime = LocalDate.parse(bo.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"))
|
||||
.atTime(LocalTime.MAX);
|
||||
wrapper.le(HrtComment::getCreateTime, endDateTime);
|
||||
}
|
||||
|
||||
// 按创建时间倒序排序
|
||||
wrapper.orderByDesc(HrtComment::getCreateTime);
|
||||
|
||||
IPage<HrtComment> commentPage = commentMapper.selectPage(page, wrapper);
|
||||
|
||||
// 转换为VO并补充用户信息和目标信息
|
||||
return commentPage.convert(comment -> {
|
||||
HrtCommentAdminVo vo = BeanUtil.copyProperties(comment, HrtCommentAdminVo.class);
|
||||
|
||||
// 补充用户信息
|
||||
HrtUser user = userMapper.selectById(comment.getUserId());
|
||||
if (user != null) {
|
||||
vo.setUsername(user.getUsername());
|
||||
vo.setNickname(user.getNickname());
|
||||
vo.setAvatar(user.getAvatar());
|
||||
}
|
||||
|
||||
// 补充目标信息
|
||||
fillTargetInfo(vo, comment.getTargetType(), comment.getTargetId());
|
||||
|
||||
return vo;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看评论详情]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public HrtCommentAdminDetailVo getDetail(Long id) {
|
||||
HrtComment comment = commentMapper.selectById(id);
|
||||
if (comment == null) {
|
||||
throw new BusinessException(404, "评论不存在");
|
||||
}
|
||||
|
||||
HrtCommentAdminDetailVo vo = BeanUtil.copyProperties(comment, HrtCommentAdminDetailVo.class);
|
||||
|
||||
// 补充用户详细信息
|
||||
HrtUser user = userMapper.selectById(comment.getUserId());
|
||||
if (user != null) {
|
||||
vo.setUsername(user.getUsername());
|
||||
vo.setNickname(user.getNickname());
|
||||
vo.setAvatar(user.getAvatar());
|
||||
vo.setPhone(user.getPhone());
|
||||
vo.setEmail(user.getEmail());
|
||||
}
|
||||
|
||||
// 补充目标信息
|
||||
fillTargetInfo(vo, comment.getTargetType(), comment.getTargetId());
|
||||
|
||||
// 补充父评论信息
|
||||
if (comment.getParentId() != null && comment.getParentId() > 0) {
|
||||
HrtComment parentComment = commentMapper.selectById(comment.getParentId());
|
||||
if (parentComment != null) {
|
||||
vo.setParentContent(parentComment.getContent());
|
||||
|
||||
// 获取父评论用户昵称
|
||||
HrtUser parentUser = userMapper.selectById(parentComment.getUserId());
|
||||
if (parentUser != null) {
|
||||
vo.setParentUserNickname(parentUser.getNickname());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 查询回复数量
|
||||
LambdaQueryWrapper<HrtComment> replyWrapper = new LambdaQueryWrapper<>();
|
||||
replyWrapper.eq(HrtComment::getParentId, id);
|
||||
Long replyCount = commentMapper.selectCount(replyWrapper);
|
||||
vo.setReplyCount(replyCount.intValue());
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [审核评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean auditComment(HrtCommentAdminBo bo) {
|
||||
HrtComment comment = commentMapper.selectById(bo.getId());
|
||||
if (comment == null) {
|
||||
throw new BusinessException(404, "评论不存在");
|
||||
}
|
||||
|
||||
if (bo.getStatus() == null || (bo.getStatus() != 0 && bo.getStatus() != 1 && bo.getStatus() != 2)) {
|
||||
throw new BusinessException(400, "审核状态参数错误");
|
||||
}
|
||||
|
||||
HrtComment updateComment = new HrtComment();
|
||||
updateComment.setId(bo.getId());
|
||||
updateComment.setStatus(bo.getStatus());
|
||||
|
||||
int result = commentMapper.updateById(updateComment);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量审核评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean batchAudit(List<Long> ids, Integer status) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new BusinessException(400, "请选择要审核的评论");
|
||||
}
|
||||
|
||||
if (status == null || (status != 0 && status != 1 && status != 2)) {
|
||||
throw new BusinessException(400, "审核状态参数错误");
|
||||
}
|
||||
|
||||
for (Long id : ids) {
|
||||
HrtComment updateComment = new HrtComment();
|
||||
updateComment.setId(id);
|
||||
updateComment.setStatus(status);
|
||||
commentMapper.updateById(updateComment);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteComment(Long id) {
|
||||
HrtComment comment = commentMapper.selectById(id);
|
||||
if (comment == null) {
|
||||
throw new BusinessException(404, "评论不存在");
|
||||
}
|
||||
|
||||
// 删除该评论的所有回复
|
||||
LambdaQueryWrapper<HrtComment> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(HrtComment::getParentId, id);
|
||||
commentMapper.delete(wrapper);
|
||||
|
||||
// 删除评论本身
|
||||
int result = commentMapper.deleteById(id);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean batchDelete(List<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new BusinessException(400, "请选择要删除的评论");
|
||||
}
|
||||
|
||||
for (Long id : ids) {
|
||||
deleteComment(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [获取待审核评论数量]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public Long getPendingCount() {
|
||||
LambdaQueryWrapper<HrtComment> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(HrtComment::getStatus, 0);
|
||||
return commentMapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [补充目标信息]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private void fillTargetInfo(Object vo, String targetType, Long targetId) {
|
||||
String targetTitle = null;
|
||||
|
||||
switch (targetType) {
|
||||
case "heritage":
|
||||
HrtHeritage heritage = heritageMapper.selectById(targetId);
|
||||
if (heritage != null) {
|
||||
targetTitle = heritage.getName();
|
||||
}
|
||||
break;
|
||||
case "inheritor":
|
||||
HrtInheritor inheritor = inheritorMapper.selectById(targetId);
|
||||
if (inheritor != null) {
|
||||
targetTitle = inheritor.getName();
|
||||
}
|
||||
break;
|
||||
case "news":
|
||||
HrtNews news = newsMapper.selectById(targetId);
|
||||
if (news != null) {
|
||||
targetTitle = news.getTitle();
|
||||
}
|
||||
break;
|
||||
case "event":
|
||||
HrtEvent event = eventMapper.selectById(targetId);
|
||||
if (event != null) {
|
||||
targetTitle = event.getTitle();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 使用反射设置targetTitle
|
||||
if (vo instanceof HrtCommentAdminVo) {
|
||||
((HrtCommentAdminVo) vo).setTargetTitle(targetTitle);
|
||||
} else if (vo instanceof HrtCommentAdminDetailVo) {
|
||||
((HrtCommentAdminDetailVo) vo).setTargetTitle(targetTitle);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package org.leocoder.heritage.admin.service.event;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtEventAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtEventAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtEventAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtEventAdminVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [活动管理服务接口]
|
||||
*/
|
||||
public interface HrtEventAdminService {
|
||||
|
||||
/**
|
||||
* @description [分页查询活动列表(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
IPage<HrtEventAdminVo> listPage(HrtEventAdminQueryBo bo);
|
||||
|
||||
/**
|
||||
* @description [查看活动详情(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
HrtEventAdminDetailVo getDetail(Long id);
|
||||
|
||||
/**
|
||||
* @description [新增活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Long addEvent(HrtEventAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [编辑活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean editEvent(HrtEventAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [删除活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean deleteEvent(Long id);
|
||||
|
||||
/**
|
||||
* @description [批量删除活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean batchDelete(List<Long> ids);
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean changePublishStatus(Long id, Integer publishStatus);
|
||||
|
||||
/**
|
||||
* @description [修改活动状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean changeEventStatus(Long id, String status);
|
||||
|
||||
}
|
||||
@ -0,0 +1,307 @@
|
||||
package org.leocoder.heritage.admin.service.event;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.common.exception.BusinessException;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtEventAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtEventAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.pojo.portal.HrtEvent;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtEventAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtEventAdminVo;
|
||||
import org.leocoder.heritage.mybatisplus.mapper.portal.HrtEventMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [活动管理服务实现类]
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class HrtEventAdminServiceImpl implements HrtEventAdminService {
|
||||
|
||||
private final HrtEventMapper eventMapper;
|
||||
|
||||
/**
|
||||
* @description [分页查询活动列表(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public IPage<HrtEventAdminVo> listPage(HrtEventAdminQueryBo bo) {
|
||||
Page<HrtEvent> page = new Page<>(bo.getPageNum(), bo.getPageSize());
|
||||
|
||||
LambdaQueryWrapper<HrtEvent> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 标题模糊查询
|
||||
wrapper.like(StrUtil.isNotEmpty(bo.getTitle()), HrtEvent::getTitle, bo.getTitle());
|
||||
|
||||
// 地点模糊查询
|
||||
wrapper.like(StrUtil.isNotEmpty(bo.getLocation()), HrtEvent::getLocation, bo.getLocation());
|
||||
|
||||
// 状态精确查询
|
||||
wrapper.eq(StrUtil.isNotEmpty(bo.getStatus()), HrtEvent::getStatus, bo.getStatus());
|
||||
|
||||
// 发布状态查询
|
||||
wrapper.eq(Objects.nonNull(bo.getPublishStatus()), HrtEvent::getPublishStatus, bo.getPublishStatus());
|
||||
|
||||
// 关键词搜索(标题、摘要、内容)
|
||||
if (StrUtil.isNotEmpty(bo.getKeyword())) {
|
||||
wrapper.and(w -> w
|
||||
.like(HrtEvent::getTitle, bo.getKeyword())
|
||||
.or()
|
||||
.like(HrtEvent::getSummary, bo.getKeyword())
|
||||
.or()
|
||||
.like(HrtEvent::getContent, bo.getKeyword())
|
||||
);
|
||||
}
|
||||
|
||||
// 活动开始时间范围查询
|
||||
wrapper.ge(Objects.nonNull(bo.getStartTimeBegin()), HrtEvent::getStartTime, bo.getStartTimeBegin());
|
||||
wrapper.le(Objects.nonNull(bo.getStartTimeEnd()), HrtEvent::getStartTime, bo.getStartTimeEnd());
|
||||
|
||||
// 排序处理
|
||||
if ("asc".equalsIgnoreCase(bo.getSortOrder())) {
|
||||
switch (bo.getSortField()) {
|
||||
case "view_count" -> wrapper.orderByAsc(HrtEvent::getViewCount);
|
||||
case "start_time" -> wrapper.orderByAsc(HrtEvent::getStartTime);
|
||||
case "current_participants" -> wrapper.orderByAsc(HrtEvent::getCurrentParticipants);
|
||||
default -> wrapper.orderByAsc(HrtEvent::getCreateTime);
|
||||
}
|
||||
} else {
|
||||
switch (bo.getSortField()) {
|
||||
case "view_count" -> wrapper.orderByDesc(HrtEvent::getViewCount);
|
||||
case "start_time" -> wrapper.orderByDesc(HrtEvent::getStartTime);
|
||||
case "current_participants" -> wrapper.orderByDesc(HrtEvent::getCurrentParticipants);
|
||||
default -> wrapper.orderByDesc(HrtEvent::getCreateTime);
|
||||
}
|
||||
}
|
||||
|
||||
IPage<HrtEvent> eventPage = eventMapper.selectPage(page, wrapper);
|
||||
return eventPage.convert(event -> BeanUtil.copyProperties(event, HrtEventAdminVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看活动详情(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public HrtEventAdminDetailVo getDetail(Long id) {
|
||||
HrtEvent event = eventMapper.selectById(id);
|
||||
if (event == null) {
|
||||
throw new BusinessException(404, "活动不存在");
|
||||
}
|
||||
return BeanUtil.copyProperties(event, HrtEventAdminDetailVo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [新增活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long addEvent(HrtEventAdminBo bo) {
|
||||
// 验证时间合理性
|
||||
validateEventTimes(bo);
|
||||
|
||||
HrtEvent event = BeanUtil.copyProperties(bo, HrtEvent.class);
|
||||
|
||||
// 初始化当前参与人数为0
|
||||
event.setCurrentParticipants(0);
|
||||
|
||||
// 初始化浏览量为0
|
||||
event.setViewCount(0);
|
||||
|
||||
// 设置创建人
|
||||
event.setCreateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
int result = eventMapper.insert(event);
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "新增活动失败");
|
||||
}
|
||||
|
||||
return event.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [编辑活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean editEvent(HrtEventAdminBo bo) {
|
||||
if (bo.getId() == null) {
|
||||
throw new BusinessException(400, "活动ID不能为空");
|
||||
}
|
||||
|
||||
// 检查活动是否存在
|
||||
HrtEvent existEvent = eventMapper.selectById(bo.getId());
|
||||
if (existEvent == null) {
|
||||
throw new BusinessException(404, "活动不存在");
|
||||
}
|
||||
|
||||
// 验证时间合理性
|
||||
validateEventTimes(bo);
|
||||
|
||||
HrtEvent event = BeanUtil.copyProperties(bo, HrtEvent.class);
|
||||
|
||||
// 设置更新人
|
||||
event.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
int result = eventMapper.updateById(event);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteEvent(Long id) {
|
||||
// 检查活动是否存在
|
||||
HrtEvent event = eventMapper.selectById(id);
|
||||
if (event == null) {
|
||||
throw new BusinessException(404, "活动不存在");
|
||||
}
|
||||
|
||||
// 检查是否有用户报名(如果已有报名,不允许删除)
|
||||
if (event.getCurrentParticipants() != null && event.getCurrentParticipants() > 0) {
|
||||
throw new BusinessException(400, "该活动已有用户报名,无法删除");
|
||||
}
|
||||
|
||||
int result = eventMapper.deleteById(id);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean batchDelete(List<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new BusinessException(400, "请选择要删除的活动");
|
||||
}
|
||||
|
||||
// 检查是否有活动已有报名
|
||||
LambdaQueryWrapper<HrtEvent> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.in(HrtEvent::getId, ids);
|
||||
wrapper.gt(HrtEvent::getCurrentParticipants, 0);
|
||||
|
||||
Long count = eventMapper.selectCount(wrapper);
|
||||
if (count > 0) {
|
||||
throw new BusinessException(400, "选中的活动中有已报名的活动,无法删除");
|
||||
}
|
||||
|
||||
int result = eventMapper.deleteBatchIds(ids);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean changePublishStatus(Long id, Integer publishStatus) {
|
||||
// 检查活动是否存在
|
||||
HrtEvent event = eventMapper.selectById(id);
|
||||
if (event == null) {
|
||||
throw new BusinessException(404, "活动不存在");
|
||||
}
|
||||
|
||||
if (publishStatus == null || (publishStatus != 0 && publishStatus != 1)) {
|
||||
throw new BusinessException(400, "发布状态参数错误");
|
||||
}
|
||||
|
||||
HrtEvent updateEvent = new HrtEvent();
|
||||
updateEvent.setId(id);
|
||||
updateEvent.setPublishStatus(publishStatus);
|
||||
updateEvent.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
int result = eventMapper.updateById(updateEvent);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改活动状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean changeEventStatus(Long id, String status) {
|
||||
// 检查活动是否存在
|
||||
HrtEvent event = eventMapper.selectById(id);
|
||||
if (event == null) {
|
||||
throw new BusinessException(404, "活动不存在");
|
||||
}
|
||||
|
||||
// 验证状态值
|
||||
if (StrUtil.isEmpty(status)) {
|
||||
throw new BusinessException(400, "活动状态不能为空");
|
||||
}
|
||||
|
||||
if (!isValidEventStatus(status)) {
|
||||
throw new BusinessException(400, "活动状态参数错误,只能是:upcoming、ongoing、finished、cancelled");
|
||||
}
|
||||
|
||||
HrtEvent updateEvent = new HrtEvent();
|
||||
updateEvent.setId(id);
|
||||
updateEvent.setStatus(status);
|
||||
updateEvent.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
int result = eventMapper.updateById(updateEvent);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [验证活动时间的合理性]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private void validateEventTimes(HrtEventAdminBo bo) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 验证活动时间
|
||||
if (bo.getStartTime() != null && bo.getEndTime() != null) {
|
||||
if (bo.getEndTime().isBefore(bo.getStartTime())) {
|
||||
throw new BusinessException(400, "活动结束时间不能早于开始时间");
|
||||
}
|
||||
}
|
||||
|
||||
// 验证报名时间
|
||||
if (bo.getRegistrationStart() != null && bo.getRegistrationEnd() != null) {
|
||||
if (bo.getRegistrationEnd().isBefore(bo.getRegistrationStart())) {
|
||||
throw new BusinessException(400, "报名结束时间不能早于报名开始时间");
|
||||
}
|
||||
}
|
||||
|
||||
// 验证报名时间与活动时间的关系
|
||||
if (bo.getRegistrationEnd() != null && bo.getStartTime() != null) {
|
||||
if (bo.getRegistrationEnd().isAfter(bo.getStartTime())) {
|
||||
throw new BusinessException(400, "报名结束时间不能晚于活动开始时间");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [验证活动状态是否合法]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private boolean isValidEventStatus(String status) {
|
||||
return "upcoming".equals(status)
|
||||
|| "ongoing".equals(status)
|
||||
|| "finished".equals(status)
|
||||
|| "cancelled".equals(status);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package org.leocoder.heritage.admin.service.heritage;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtHeritageAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtHeritageAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtHeritageAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtHeritageAdminVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [非遗项目管理服务接口]
|
||||
*/
|
||||
public interface HrtHeritageAdminService {
|
||||
|
||||
/**
|
||||
* @description [分页查询非遗项目列表(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
IPage<HrtHeritageAdminVo> listPage(HrtHeritageAdminQueryBo bo);
|
||||
|
||||
/**
|
||||
* @description [查看非遗项目详情(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
HrtHeritageAdminDetailVo getDetail(Long id);
|
||||
|
||||
/**
|
||||
* @description [新增非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Long addHeritage(HrtHeritageAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [编辑非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean editHeritage(HrtHeritageAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [删除非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean deleteHeritage(Long id);
|
||||
|
||||
/**
|
||||
* @description [批量删除非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean batchDelete(List<Long> ids);
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean changePublishStatus(Long id, Integer publishStatus);
|
||||
|
||||
/**
|
||||
* @description [设置精选状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean setFeatured(Long id, Integer isFeatured);
|
||||
|
||||
}
|
||||
@ -0,0 +1,327 @@
|
||||
package org.leocoder.heritage.admin.service.heritage;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.common.exception.BusinessException;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtHeritageAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtHeritageAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtHeritageAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtHeritageAdminVo;
|
||||
import org.leocoder.heritage.domain.pojo.portal.HrtHeritage;
|
||||
import org.leocoder.heritage.mybatisplus.mapper.portal.HrtHeritageMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [非遗项目管理服务实现类]
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class HrtHeritageAdminServiceImpl implements HrtHeritageAdminService {
|
||||
|
||||
private final HrtHeritageMapper hrtHeritageMapper;
|
||||
|
||||
/**
|
||||
* @description [分页查询非遗项目列表(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public IPage<HrtHeritageAdminVo> listPage(HrtHeritageAdminQueryBo bo) {
|
||||
Page<HrtHeritage> page = new Page<>(bo.getPageNum(), bo.getPageSize());
|
||||
|
||||
LambdaQueryWrapper<HrtHeritage> wrapper = buildQueryWrapper(bo);
|
||||
|
||||
// 排序
|
||||
applySorting(wrapper, bo.getSortField(), bo.getSortOrder());
|
||||
|
||||
IPage<HrtHeritage> heritagePageResult = hrtHeritageMapper.selectPage(page, wrapper);
|
||||
|
||||
// 转换为VO
|
||||
return heritagePageResult.convert(heritage -> BeanUtil.copyProperties(heritage, HrtHeritageAdminVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看非遗项目详情(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public HrtHeritageAdminDetailVo getDetail(Long id) {
|
||||
HrtHeritage heritage = hrtHeritageMapper.selectById(id);
|
||||
|
||||
if (heritage == null) {
|
||||
throw new BusinessException(404, "非遗项目不存在");
|
||||
}
|
||||
|
||||
// 转换为详情VO
|
||||
return BeanUtil.copyProperties(heritage, HrtHeritageAdminDetailVo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [新增非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long addHeritage(HrtHeritageAdminBo bo) {
|
||||
// 转换为实体
|
||||
HrtHeritage heritage = BeanUtil.copyProperties(bo, HrtHeritage.class);
|
||||
|
||||
// 设置创建人
|
||||
heritage.setCreateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
// 初始化统计数据
|
||||
heritage.setViewCount(0);
|
||||
heritage.setLikeCount(0);
|
||||
heritage.setFavoriteCount(0);
|
||||
heritage.setCommentCount(0);
|
||||
|
||||
// 设置默认值
|
||||
if (heritage.getIsFeatured() == null) {
|
||||
heritage.setIsFeatured(0);
|
||||
}
|
||||
if (heritage.getPublishStatus() == null) {
|
||||
heritage.setPublishStatus(0);
|
||||
}
|
||||
if (heritage.getSortOrder() == null) {
|
||||
heritage.setSortOrder(0);
|
||||
}
|
||||
|
||||
// 插入数据库
|
||||
int result = hrtHeritageMapper.insert(heritage);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "新增非遗项目失败");
|
||||
}
|
||||
|
||||
return heritage.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [编辑非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean editHeritage(HrtHeritageAdminBo bo) {
|
||||
// 验证ID
|
||||
if (bo.getId() == null) {
|
||||
throw new BusinessException(400, "非遗项目ID不能为空");
|
||||
}
|
||||
|
||||
// 验证是否存在
|
||||
HrtHeritage existHeritage = hrtHeritageMapper.selectById(bo.getId());
|
||||
if (existHeritage == null) {
|
||||
throw new BusinessException(404, "非遗项目不存在");
|
||||
}
|
||||
|
||||
// 转换为实体
|
||||
HrtHeritage heritage = BeanUtil.copyProperties(bo, HrtHeritage.class);
|
||||
|
||||
// 设置更新人
|
||||
heritage.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
// 更新数据库
|
||||
int result = hrtHeritageMapper.updateById(heritage);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "编辑非遗项目失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteHeritage(Long id) {
|
||||
// 验证是否存在
|
||||
HrtHeritage heritage = hrtHeritageMapper.selectById(id);
|
||||
if (heritage == null) {
|
||||
throw new BusinessException(404, "非遗项目不存在");
|
||||
}
|
||||
|
||||
// 逻辑删除
|
||||
int result = hrtHeritageMapper.deleteById(id);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "删除非遗项目失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean batchDelete(List<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new BusinessException(400, "删除的ID列表不能为空");
|
||||
}
|
||||
|
||||
// 批量逻辑删除
|
||||
int result = hrtHeritageMapper.deleteBatchIds(ids);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "批量删除非遗项目失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean changePublishStatus(Long id, Integer publishStatus) {
|
||||
// 验证参数
|
||||
if (publishStatus == null || (publishStatus != 0 && publishStatus != 1)) {
|
||||
throw new BusinessException(400, "发布状态参数错误,必须为0或1");
|
||||
}
|
||||
|
||||
// 验证是否存在
|
||||
HrtHeritage heritage = hrtHeritageMapper.selectById(id);
|
||||
if (heritage == null) {
|
||||
throw new BusinessException(404, "非遗项目不存在");
|
||||
}
|
||||
|
||||
// 更新发布状态
|
||||
HrtHeritage updateHeritage = new HrtHeritage();
|
||||
updateHeritage.setId(id);
|
||||
updateHeritage.setPublishStatus(publishStatus);
|
||||
updateHeritage.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
int result = hrtHeritageMapper.updateById(updateHeritage);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "修改发布状态失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [设置精选状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean setFeatured(Long id, Integer isFeatured) {
|
||||
// 验证参数
|
||||
if (isFeatured == null || (isFeatured != 0 && isFeatured != 1)) {
|
||||
throw new BusinessException(400, "精选状态参数错误,必须为0或1");
|
||||
}
|
||||
|
||||
// 验证是否存在
|
||||
HrtHeritage heritage = hrtHeritageMapper.selectById(id);
|
||||
if (heritage == null) {
|
||||
throw new BusinessException(404, "非遗项目不存在");
|
||||
}
|
||||
|
||||
// 更新精选状态
|
||||
HrtHeritage updateHeritage = new HrtHeritage();
|
||||
updateHeritage.setId(id);
|
||||
updateHeritage.setIsFeatured(isFeatured);
|
||||
updateHeritage.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
int result = hrtHeritageMapper.updateById(updateHeritage);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "设置精选状态失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [构建查询条件]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private LambdaQueryWrapper<HrtHeritage> buildQueryWrapper(HrtHeritageAdminQueryBo bo) {
|
||||
LambdaQueryWrapper<HrtHeritage> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 关键词搜索(搜索名称、英文名称、描述)
|
||||
if (StrUtil.isNotBlank(bo.getKeyword())) {
|
||||
wrapper.and(w -> w
|
||||
.like(HrtHeritage::getName, bo.getKeyword())
|
||||
.or().like(HrtHeritage::getNameEn, bo.getKeyword())
|
||||
.or().like(HrtHeritage::getDescription, bo.getKeyword())
|
||||
);
|
||||
}
|
||||
|
||||
// 名称模糊查询
|
||||
wrapper.like(StrUtil.isNotBlank(bo.getName()), HrtHeritage::getName, bo.getName());
|
||||
|
||||
// 英文名称模糊查询
|
||||
wrapper.like(StrUtil.isNotBlank(bo.getNameEn()), HrtHeritage::getNameEn, bo.getNameEn());
|
||||
|
||||
// 分类
|
||||
wrapper.eq(StrUtil.isNotBlank(bo.getCategory()), HrtHeritage::getCategory, bo.getCategory());
|
||||
|
||||
// 级别
|
||||
wrapper.eq(StrUtil.isNotBlank(bo.getLevel()), HrtHeritage::getLevel, bo.getLevel());
|
||||
|
||||
// 省份
|
||||
wrapper.eq(StrUtil.isNotBlank(bo.getProvince()), HrtHeritage::getProvince, bo.getProvince());
|
||||
|
||||
// 城市
|
||||
wrapper.eq(StrUtil.isNotBlank(bo.getCity()), HrtHeritage::getCity, bo.getCity());
|
||||
|
||||
// 状态
|
||||
wrapper.eq(StrUtil.isNotBlank(bo.getStatus()), HrtHeritage::getStatus, bo.getStatus());
|
||||
|
||||
// 标签模糊匹配
|
||||
wrapper.like(StrUtil.isNotBlank(bo.getTag()), HrtHeritage::getTags, bo.getTag());
|
||||
|
||||
// 发布状态
|
||||
wrapper.eq(bo.getPublishStatus() != null, HrtHeritage::getPublishStatus, bo.getPublishStatus());
|
||||
|
||||
// 是否精选
|
||||
wrapper.eq(bo.getIsFeatured() != null, HrtHeritage::getIsFeatured, bo.getIsFeatured());
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [应用排序规则]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private void applySorting(LambdaQueryWrapper<HrtHeritage> wrapper, String sortField, String sortOrder) {
|
||||
boolean isAsc = "asc".equalsIgnoreCase(sortOrder);
|
||||
|
||||
switch (sortField) {
|
||||
case "view_count":
|
||||
wrapper.orderBy(true, isAsc, HrtHeritage::getViewCount);
|
||||
break;
|
||||
case "like_count":
|
||||
wrapper.orderBy(true, isAsc, HrtHeritage::getLikeCount);
|
||||
break;
|
||||
case "favorite_count":
|
||||
wrapper.orderBy(true, isAsc, HrtHeritage::getFavoriteCount);
|
||||
break;
|
||||
case "sort_order":
|
||||
wrapper.orderBy(true, isAsc, HrtHeritage::getSortOrder);
|
||||
break;
|
||||
case "create_time":
|
||||
default:
|
||||
wrapper.orderBy(true, isAsc, HrtHeritage::getCreateTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package org.leocoder.heritage.admin.service.inheritor;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtInheritorAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtInheritorAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtInheritorAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtInheritorAdminVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [传承人管理服务接口]
|
||||
*/
|
||||
public interface HrtInheritorAdminService {
|
||||
|
||||
/**
|
||||
* @description [分页查询传承人列表(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
IPage<HrtInheritorAdminVo> listPage(HrtInheritorAdminQueryBo bo);
|
||||
|
||||
/**
|
||||
* @description [查看传承人详情(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
HrtInheritorAdminDetailVo getDetail(Long id);
|
||||
|
||||
/**
|
||||
* @description [新增传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Long addInheritor(HrtInheritorAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [编辑传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean editInheritor(HrtInheritorAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [删除传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean deleteInheritor(Long id);
|
||||
|
||||
/**
|
||||
* @description [批量删除传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean batchDelete(List<Long> ids);
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean changePublishStatus(Long id, Integer publishStatus);
|
||||
|
||||
/**
|
||||
* @description [设置精选状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean setFeatured(Long id, Integer isFeatured);
|
||||
|
||||
}
|
||||
@ -0,0 +1,323 @@
|
||||
package org.leocoder.heritage.admin.service.inheritor;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.common.exception.BusinessException;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtInheritorAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtInheritorAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtInheritorAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtInheritorAdminVo;
|
||||
import org.leocoder.heritage.domain.pojo.portal.HrtInheritor;
|
||||
import org.leocoder.heritage.mybatisplus.mapper.portal.HrtInheritorMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [传承人管理服务实现类]
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class HrtInheritorAdminServiceImpl implements HrtInheritorAdminService {
|
||||
|
||||
private final HrtInheritorMapper hrtInheritorMapper;
|
||||
|
||||
/**
|
||||
* @description [分页查询传承人列表(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public IPage<HrtInheritorAdminVo> listPage(HrtInheritorAdminQueryBo bo) {
|
||||
Page<HrtInheritor> page = new Page<>(bo.getPageNum(), bo.getPageSize());
|
||||
|
||||
LambdaQueryWrapper<HrtInheritor> wrapper = buildQueryWrapper(bo);
|
||||
|
||||
// 排序
|
||||
applySorting(wrapper, bo.getSortField(), bo.getSortOrder());
|
||||
|
||||
IPage<HrtInheritor> inheritorPageResult = hrtInheritorMapper.selectPage(page, wrapper);
|
||||
|
||||
// 转换为VO
|
||||
return inheritorPageResult.convert(inheritor -> BeanUtil.copyProperties(inheritor, HrtInheritorAdminVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看传承人详情(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public HrtInheritorAdminDetailVo getDetail(Long id) {
|
||||
HrtInheritor inheritor = hrtInheritorMapper.selectById(id);
|
||||
|
||||
if (inheritor == null) {
|
||||
throw new BusinessException(404, "传承人不存在");
|
||||
}
|
||||
|
||||
// 转换为详情VO
|
||||
return BeanUtil.copyProperties(inheritor, HrtInheritorAdminDetailVo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [新增传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long addInheritor(HrtInheritorAdminBo bo) {
|
||||
// 转换为实体
|
||||
HrtInheritor inheritor = BeanUtil.copyProperties(bo, HrtInheritor.class);
|
||||
|
||||
// 设置创建人
|
||||
inheritor.setCreateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
// 初始化统计数据
|
||||
inheritor.setViewCount(0);
|
||||
inheritor.setLikeCount(0);
|
||||
|
||||
// 设置默认值
|
||||
if (inheritor.getIsFeatured() == null) {
|
||||
inheritor.setIsFeatured(0);
|
||||
}
|
||||
if (inheritor.getPublishStatus() == null) {
|
||||
inheritor.setPublishStatus(0);
|
||||
}
|
||||
if (inheritor.getSortOrder() == null) {
|
||||
inheritor.setSortOrder(0);
|
||||
}
|
||||
|
||||
// 插入数据库
|
||||
int result = hrtInheritorMapper.insert(inheritor);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "新增传承人失败");
|
||||
}
|
||||
|
||||
return inheritor.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [编辑传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean editInheritor(HrtInheritorAdminBo bo) {
|
||||
// 验证ID
|
||||
if (bo.getId() == null) {
|
||||
throw new BusinessException(400, "传承人ID不能为空");
|
||||
}
|
||||
|
||||
// 验证是否存在
|
||||
HrtInheritor existInheritor = hrtInheritorMapper.selectById(bo.getId());
|
||||
if (existInheritor == null) {
|
||||
throw new BusinessException(404, "传承人不存在");
|
||||
}
|
||||
|
||||
// 转换为实体
|
||||
HrtInheritor inheritor = BeanUtil.copyProperties(bo, HrtInheritor.class);
|
||||
|
||||
// 设置更新人
|
||||
inheritor.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
// 更新数据库
|
||||
int result = hrtInheritorMapper.updateById(inheritor);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "编辑传承人失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteInheritor(Long id) {
|
||||
// 验证是否存在
|
||||
HrtInheritor inheritor = hrtInheritorMapper.selectById(id);
|
||||
if (inheritor == null) {
|
||||
throw new BusinessException(404, "传承人不存在");
|
||||
}
|
||||
|
||||
// 逻辑删除
|
||||
int result = hrtInheritorMapper.deleteById(id);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "删除传承人失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean batchDelete(List<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new BusinessException(400, "删除的ID列表不能为空");
|
||||
}
|
||||
|
||||
// 批量逻辑删除
|
||||
int result = hrtInheritorMapper.deleteBatchIds(ids);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "批量删除传承人失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean changePublishStatus(Long id, Integer publishStatus) {
|
||||
// 验证参数
|
||||
if (publishStatus == null || (publishStatus != 0 && publishStatus != 1)) {
|
||||
throw new BusinessException(400, "发布状态参数错误,必须为0或1");
|
||||
}
|
||||
|
||||
// 验证是否存在
|
||||
HrtInheritor inheritor = hrtInheritorMapper.selectById(id);
|
||||
if (inheritor == null) {
|
||||
throw new BusinessException(404, "传承人不存在");
|
||||
}
|
||||
|
||||
// 更新发布状态
|
||||
HrtInheritor updateInheritor = new HrtInheritor();
|
||||
updateInheritor.setId(id);
|
||||
updateInheritor.setPublishStatus(publishStatus);
|
||||
updateInheritor.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
int result = hrtInheritorMapper.updateById(updateInheritor);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "修改发布状态失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [设置精选状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean setFeatured(Long id, Integer isFeatured) {
|
||||
// 验证参数
|
||||
if (isFeatured == null || (isFeatured != 0 && isFeatured != 1)) {
|
||||
throw new BusinessException(400, "精选状态参数错误,必须为0或1");
|
||||
}
|
||||
|
||||
// 验证是否存在
|
||||
HrtInheritor inheritor = hrtInheritorMapper.selectById(id);
|
||||
if (inheritor == null) {
|
||||
throw new BusinessException(404, "传承人不存在");
|
||||
}
|
||||
|
||||
// 更新精选状态
|
||||
HrtInheritor updateInheritor = new HrtInheritor();
|
||||
updateInheritor.setId(id);
|
||||
updateInheritor.setIsFeatured(isFeatured);
|
||||
updateInheritor.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
int result = hrtInheritorMapper.updateById(updateInheritor);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "设置精选状态失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [构建查询条件]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private LambdaQueryWrapper<HrtInheritor> buildQueryWrapper(HrtInheritorAdminQueryBo bo) {
|
||||
LambdaQueryWrapper<HrtInheritor> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 关键词搜索(搜索姓名、简介、故事等字段)
|
||||
if (StrUtil.isNotBlank(bo.getKeyword())) {
|
||||
wrapper.and(w -> w
|
||||
.like(HrtInheritor::getName, bo.getKeyword())
|
||||
.or().like(HrtInheritor::getNameEn, bo.getKeyword())
|
||||
.or().like(HrtInheritor::getIntroduction, bo.getKeyword())
|
||||
.or().like(HrtInheritor::getStory, bo.getKeyword())
|
||||
);
|
||||
}
|
||||
|
||||
// 姓名模糊查询
|
||||
wrapper.like(StrUtil.isNotBlank(bo.getName()), HrtInheritor::getName, bo.getName());
|
||||
|
||||
// 英文名模糊查询
|
||||
wrapper.like(StrUtil.isNotBlank(bo.getNameEn()), HrtInheritor::getNameEn, bo.getNameEn());
|
||||
|
||||
// 性别
|
||||
wrapper.eq(bo.getGender() != null, HrtInheritor::getGender, bo.getGender());
|
||||
|
||||
// 关联非遗项目ID
|
||||
wrapper.eq(bo.getHeritageId() != null, HrtInheritor::getHeritageId, bo.getHeritageId());
|
||||
|
||||
// 传承项目名称模糊查询
|
||||
wrapper.like(StrUtil.isNotBlank(bo.getHeritageName()), HrtInheritor::getHeritageName, bo.getHeritageName());
|
||||
|
||||
// 传承人级别
|
||||
wrapper.eq(StrUtil.isNotBlank(bo.getLevel()), HrtInheritor::getLevel, bo.getLevel());
|
||||
|
||||
// 省份
|
||||
wrapper.eq(StrUtil.isNotBlank(bo.getProvince()), HrtInheritor::getProvince, bo.getProvince());
|
||||
|
||||
// 城市
|
||||
wrapper.eq(StrUtil.isNotBlank(bo.getCity()), HrtInheritor::getCity, bo.getCity());
|
||||
|
||||
// 发布状态
|
||||
wrapper.eq(bo.getPublishStatus() != null, HrtInheritor::getPublishStatus, bo.getPublishStatus());
|
||||
|
||||
// 是否精选
|
||||
wrapper.eq(bo.getIsFeatured() != null, HrtInheritor::getIsFeatured, bo.getIsFeatured());
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [应用排序规则]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private void applySorting(LambdaQueryWrapper<HrtInheritor> wrapper, String sortField, String sortOrder) {
|
||||
boolean isAsc = "asc".equalsIgnoreCase(sortOrder);
|
||||
|
||||
switch (sortField) {
|
||||
case "view_count":
|
||||
wrapper.orderBy(true, isAsc, HrtInheritor::getViewCount);
|
||||
break;
|
||||
case "like_count":
|
||||
wrapper.orderBy(true, isAsc, HrtInheritor::getLikeCount);
|
||||
break;
|
||||
case "sort_order":
|
||||
wrapper.orderBy(true, isAsc, HrtInheritor::getSortOrder);
|
||||
break;
|
||||
case "create_time":
|
||||
default:
|
||||
wrapper.orderBy(true, isAsc, HrtInheritor::getCreateTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package org.leocoder.heritage.admin.service.news;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtNewsAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtNewsAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtNewsAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtNewsAdminVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [新闻资讯管理服务接口]
|
||||
*/
|
||||
public interface HrtNewsAdminService {
|
||||
|
||||
/**
|
||||
* @description [分页查询新闻资讯列表(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
IPage<HrtNewsAdminVo> listPage(HrtNewsAdminQueryBo bo);
|
||||
|
||||
/**
|
||||
* @description [查看新闻资讯详情(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
HrtNewsAdminDetailVo getDetail(Long id);
|
||||
|
||||
/**
|
||||
* @description [新增新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Long addNews(HrtNewsAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [编辑新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean editNews(HrtNewsAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [删除新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean deleteNews(Long id);
|
||||
|
||||
/**
|
||||
* @description [批量删除新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean batchDelete(List<Long> ids);
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean changePublishStatus(Long id, Integer publishStatus);
|
||||
|
||||
/**
|
||||
* @description [设置置顶状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean setTop(Long id, Integer isTop);
|
||||
|
||||
}
|
||||
@ -0,0 +1,334 @@
|
||||
package org.leocoder.heritage.admin.service.news;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.common.exception.BusinessException;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtNewsAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtNewsAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtNewsAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtNewsAdminVo;
|
||||
import org.leocoder.heritage.domain.pojo.portal.HrtNews;
|
||||
import org.leocoder.heritage.mybatisplus.mapper.portal.HrtNewsMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [新闻资讯管理服务实现类]
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class HrtNewsAdminServiceImpl implements HrtNewsAdminService {
|
||||
|
||||
private final HrtNewsMapper hrtNewsMapper;
|
||||
|
||||
/**
|
||||
* @description [分页查询新闻资讯列表(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public IPage<HrtNewsAdminVo> listPage(HrtNewsAdminQueryBo bo) {
|
||||
Page<HrtNews> page = new Page<>(bo.getPageNum(), bo.getPageSize());
|
||||
|
||||
LambdaQueryWrapper<HrtNews> wrapper = buildQueryWrapper(bo);
|
||||
|
||||
// 排序
|
||||
applySorting(wrapper, bo.getSortField(), bo.getSortOrder());
|
||||
|
||||
IPage<HrtNews> newsPageResult = hrtNewsMapper.selectPage(page, wrapper);
|
||||
|
||||
// 转换为VO
|
||||
return newsPageResult.convert(news -> BeanUtil.copyProperties(news, HrtNewsAdminVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看新闻资讯详情(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public HrtNewsAdminDetailVo getDetail(Long id) {
|
||||
HrtNews news = hrtNewsMapper.selectById(id);
|
||||
|
||||
if (news == null) {
|
||||
throw new BusinessException(404, "新闻资讯不存在");
|
||||
}
|
||||
|
||||
// 转换为详情VO
|
||||
return BeanUtil.copyProperties(news, HrtNewsAdminDetailVo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [新增新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long addNews(HrtNewsAdminBo bo) {
|
||||
// 转换为实体
|
||||
HrtNews news = BeanUtil.copyProperties(bo, HrtNews.class);
|
||||
|
||||
// 设置创建人
|
||||
news.setCreateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
// 初始化统计数据
|
||||
news.setViewCount(0);
|
||||
news.setLikeCount(0);
|
||||
|
||||
// 设置默认值
|
||||
if (news.getIsTop() == null) {
|
||||
news.setIsTop(0);
|
||||
}
|
||||
if (news.getPublishStatus() == null) {
|
||||
news.setPublishStatus(0);
|
||||
}
|
||||
|
||||
// 如果发布状态为1且未设置发布时间,则设置为当前时间
|
||||
if (news.getPublishStatus() == 1 && news.getPublishTime() == null) {
|
||||
news.setPublishTime(LocalDateTime.now());
|
||||
}
|
||||
|
||||
// 插入数据库
|
||||
int result = hrtNewsMapper.insert(news);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "新增新闻资讯失败");
|
||||
}
|
||||
|
||||
return news.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [编辑新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean editNews(HrtNewsAdminBo bo) {
|
||||
// 验证ID
|
||||
if (bo.getId() == null) {
|
||||
throw new BusinessException(400, "新闻资讯ID不能为空");
|
||||
}
|
||||
|
||||
// 验证是否存在
|
||||
HrtNews existNews = hrtNewsMapper.selectById(bo.getId());
|
||||
if (existNews == null) {
|
||||
throw new BusinessException(404, "新闻资讯不存在");
|
||||
}
|
||||
|
||||
// 转换为实体
|
||||
HrtNews news = BeanUtil.copyProperties(bo, HrtNews.class);
|
||||
|
||||
// 设置更新人
|
||||
news.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
// 如果发布状态从草稿变为已发布,且未设置发布时间,则设置为当前时间
|
||||
if (news.getPublishStatus() != null && news.getPublishStatus() == 1
|
||||
&& existNews.getPublishStatus() == 0 && news.getPublishTime() == null) {
|
||||
news.setPublishTime(LocalDateTime.now());
|
||||
}
|
||||
|
||||
// 更新数据库
|
||||
int result = hrtNewsMapper.updateById(news);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "编辑新闻资讯失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteNews(Long id) {
|
||||
// 验证是否存在
|
||||
HrtNews news = hrtNewsMapper.selectById(id);
|
||||
if (news == null) {
|
||||
throw new BusinessException(404, "新闻资讯不存在");
|
||||
}
|
||||
|
||||
// 逻辑删除
|
||||
int result = hrtNewsMapper.deleteById(id);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "删除新闻资讯失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除新闻资讯]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean batchDelete(List<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new BusinessException(400, "删除的ID列表不能为空");
|
||||
}
|
||||
|
||||
// 批量逻辑删除
|
||||
int result = hrtNewsMapper.deleteBatchIds(ids);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "批量删除新闻资讯失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改发布状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean changePublishStatus(Long id, Integer publishStatus) {
|
||||
// 验证参数
|
||||
if (publishStatus == null || (publishStatus != 0 && publishStatus != 1)) {
|
||||
throw new BusinessException(400, "发布状态参数错误,必须为0或1");
|
||||
}
|
||||
|
||||
// 验证是否存在
|
||||
HrtNews news = hrtNewsMapper.selectById(id);
|
||||
if (news == null) {
|
||||
throw new BusinessException(404, "新闻资讯不存在");
|
||||
}
|
||||
|
||||
// 更新发布状态
|
||||
HrtNews updateNews = new HrtNews();
|
||||
updateNews.setId(id);
|
||||
updateNews.setPublishStatus(publishStatus);
|
||||
updateNews.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
// 如果从草稿变为已发布,且未设置发布时间,则设置为当前时间
|
||||
if (publishStatus == 1 && news.getPublishStatus() == 0 && news.getPublishTime() == null) {
|
||||
updateNews.setPublishTime(LocalDateTime.now());
|
||||
}
|
||||
|
||||
int result = hrtNewsMapper.updateById(updateNews);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "修改发布状态失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [设置置顶状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean setTop(Long id, Integer isTop) {
|
||||
// 验证参数
|
||||
if (isTop == null || (isTop != 0 && isTop != 1)) {
|
||||
throw new BusinessException(400, "置顶状态参数错误,必须为0或1");
|
||||
}
|
||||
|
||||
// 验证是否存在
|
||||
HrtNews news = hrtNewsMapper.selectById(id);
|
||||
if (news == null) {
|
||||
throw new BusinessException(404, "新闻资讯不存在");
|
||||
}
|
||||
|
||||
// 更新置顶状态
|
||||
HrtNews updateNews = new HrtNews();
|
||||
updateNews.setId(id);
|
||||
updateNews.setIsTop(isTop);
|
||||
updateNews.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||
|
||||
int result = hrtNewsMapper.updateById(updateNews);
|
||||
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "设置置顶状态失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [构建查询条件]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private LambdaQueryWrapper<HrtNews> buildQueryWrapper(HrtNewsAdminQueryBo bo) {
|
||||
LambdaQueryWrapper<HrtNews> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 关键词搜索(搜索标题、摘要、内容等字段)
|
||||
if (StrUtil.isNotBlank(bo.getKeyword())) {
|
||||
wrapper.and(w -> w
|
||||
.like(HrtNews::getTitle, bo.getKeyword())
|
||||
.or().like(HrtNews::getSummary, bo.getKeyword())
|
||||
.or().like(HrtNews::getContent, bo.getKeyword())
|
||||
);
|
||||
}
|
||||
|
||||
// 标题模糊查询
|
||||
wrapper.like(StrUtil.isNotBlank(bo.getTitle()), HrtNews::getTitle, bo.getTitle());
|
||||
|
||||
// 作者模糊查询
|
||||
wrapper.like(StrUtil.isNotBlank(bo.getAuthor()), HrtNews::getAuthor, bo.getAuthor());
|
||||
|
||||
// 来源模糊查询
|
||||
wrapper.like(StrUtil.isNotBlank(bo.getSource()), HrtNews::getSource, bo.getSource());
|
||||
|
||||
// 分类
|
||||
wrapper.eq(StrUtil.isNotBlank(bo.getCategory()), HrtNews::getCategory, bo.getCategory());
|
||||
|
||||
// 标签模糊匹配
|
||||
wrapper.like(StrUtil.isNotBlank(bo.getTag()), HrtNews::getTags, bo.getTag());
|
||||
|
||||
// 是否置顶
|
||||
wrapper.eq(bo.getIsTop() != null, HrtNews::getIsTop, bo.getIsTop());
|
||||
|
||||
// 发布状态
|
||||
wrapper.eq(bo.getPublishStatus() != null, HrtNews::getPublishStatus, bo.getPublishStatus());
|
||||
|
||||
// 发布时间范围查询
|
||||
wrapper.ge(bo.getPublishTimeStart() != null, HrtNews::getPublishTime, bo.getPublishTimeStart());
|
||||
wrapper.le(bo.getPublishTimeEnd() != null, HrtNews::getPublishTime, bo.getPublishTimeEnd());
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [应用排序规则]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private void applySorting(LambdaQueryWrapper<HrtNews> wrapper, String sortField, String sortOrder) {
|
||||
boolean isAsc = "asc".equalsIgnoreCase(sortOrder);
|
||||
|
||||
switch (sortField) {
|
||||
case "view_count":
|
||||
wrapper.orderBy(true, isAsc, HrtNews::getViewCount);
|
||||
break;
|
||||
case "like_count":
|
||||
wrapper.orderBy(true, isAsc, HrtNews::getLikeCount);
|
||||
break;
|
||||
case "publish_time":
|
||||
wrapper.orderBy(true, isAsc, HrtNews::getPublishTime);
|
||||
break;
|
||||
case "create_time":
|
||||
default:
|
||||
wrapper.orderBy(true, isAsc, HrtNews::getCreateTime);
|
||||
break;
|
||||
}
|
||||
|
||||
// 置顶的新闻始终排在前面
|
||||
wrapper.orderByDesc(HrtNews::getIsTop);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package org.leocoder.heritage.admin.service.statistics;
|
||||
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtRankingVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtStatisticsVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtTrendVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [统计分析服务接口]
|
||||
*/
|
||||
public interface HrtStatisticsService {
|
||||
|
||||
/**
|
||||
* @description [获取核心统计数据]
|
||||
* @author Leocoder
|
||||
*/
|
||||
HrtStatisticsVo getStatistics();
|
||||
|
||||
/**
|
||||
* @description [获取用户增长趋势]
|
||||
* @author Leocoder
|
||||
* @param days 天数(7或30)
|
||||
*/
|
||||
List<HrtTrendVo> getUserTrend(Integer days);
|
||||
|
||||
/**
|
||||
* @description [获取内容发布趋势]
|
||||
* @author Leocoder
|
||||
* @param days 天数(7或30)
|
||||
*/
|
||||
List<HrtTrendVo> getContentTrend(Integer days);
|
||||
|
||||
/**
|
||||
* @description [获取热门非遗项目排行榜]
|
||||
* @author Leocoder
|
||||
* @param type 排序类型:view-浏览量,favorite-收藏数
|
||||
* @param limit 返回数量,默认10
|
||||
*/
|
||||
List<HrtRankingVo> getHeritageRanking(String type, Integer limit);
|
||||
|
||||
/**
|
||||
* @description [获取活跃用户排行榜]
|
||||
* @author Leocoder
|
||||
* @param limit 返回数量,默认10
|
||||
*/
|
||||
List<HrtRankingVo> getActiveUserRanking(Integer limit);
|
||||
|
||||
}
|
||||
@ -0,0 +1,393 @@
|
||||
package org.leocoder.heritage.admin.service.statistics;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtRankingVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtStatisticsVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtTrendVo;
|
||||
import org.leocoder.heritage.domain.pojo.portal.*;
|
||||
import org.leocoder.heritage.mybatisplus.mapper.portal.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [统计分析服务实现类]
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class HrtStatisticsServiceImpl implements HrtStatisticsService {
|
||||
|
||||
private final HrtHeritageMapper heritageMapper;
|
||||
private final HrtInheritorMapper inheritorMapper;
|
||||
private final HrtUserMapper userMapper;
|
||||
private final HrtEventMapper eventMapper;
|
||||
private final HrtNewsMapper newsMapper;
|
||||
private final HrtCommentMapper commentMapper;
|
||||
private final HrtLikeMapper likeMapper;
|
||||
private final HrtFavoriteMapper favoriteMapper;
|
||||
private final HrtViewHistoryMapper viewHistoryMapper;
|
||||
private final HrtEventRegistrationMapper registrationMapper;
|
||||
|
||||
/**
|
||||
* @description [获取核心统计数据]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public HrtStatisticsVo getStatistics() {
|
||||
HrtStatisticsVo vo = new HrtStatisticsVo();
|
||||
|
||||
// 获取今日开始时间
|
||||
LocalDateTime todayStart = LocalDate.now().atStartOfDay();
|
||||
|
||||
// ===== 核心数据统计 =====
|
||||
|
||||
// 非遗项目统计
|
||||
vo.setHeritageTotal(heritageMapper.selectCount(null));
|
||||
vo.setHeritageTodayCount(countTodayRecords(heritageMapper, todayStart));
|
||||
|
||||
// 传承人统计
|
||||
vo.setInheritorTotal(inheritorMapper.selectCount(null));
|
||||
vo.setInheritorTodayCount(countTodayRecords(inheritorMapper, todayStart));
|
||||
|
||||
// 用户统计
|
||||
vo.setUserTotal(userMapper.selectCount(null));
|
||||
vo.setUserTodayCount(countTodayRecords(userMapper, todayStart));
|
||||
|
||||
// 活动统计
|
||||
vo.setEventTotal(eventMapper.selectCount(null));
|
||||
vo.setEventTodayCount(countTodayRecords(eventMapper, todayStart));
|
||||
|
||||
// 新闻统计
|
||||
vo.setNewsTotal(newsMapper.selectCount(null));
|
||||
vo.setNewsTodayCount(countTodayRecords(newsMapper, todayStart));
|
||||
|
||||
// ===== 用户行为统计 =====
|
||||
|
||||
// 评论统计
|
||||
vo.setCommentTotal(commentMapper.selectCount(null));
|
||||
vo.setCommentTodayCount(countTodayRecords(commentMapper, todayStart));
|
||||
|
||||
// 待审核评论数
|
||||
LambdaQueryWrapper<HrtComment> pendingWrapper = new LambdaQueryWrapper<>();
|
||||
pendingWrapper.eq(HrtComment::getStatus, 0);
|
||||
vo.setCommentPendingCount(commentMapper.selectCount(pendingWrapper));
|
||||
|
||||
// 点赞统计
|
||||
vo.setLikeTotal(likeMapper.selectCount(null));
|
||||
vo.setLikeTodayCount(countTodayRecords(likeMapper, todayStart));
|
||||
|
||||
// 收藏统计
|
||||
vo.setFavoriteTotal(favoriteMapper.selectCount(null));
|
||||
vo.setFavoriteTodayCount(countTodayRecords(favoriteMapper, todayStart));
|
||||
|
||||
// 浏览统计
|
||||
vo.setViewTotal(viewHistoryMapper.selectCount(null));
|
||||
vo.setViewTodayCount(countTodayRecords(viewHistoryMapper, todayStart));
|
||||
|
||||
// 活动报名统计
|
||||
vo.setRegistrationTotal(registrationMapper.selectCount(null));
|
||||
vo.setRegistrationTodayCount(countTodayRecords(registrationMapper, todayStart));
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [获取用户增长趋势]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public List<HrtTrendVo> getUserTrend(Integer days) {
|
||||
if (days == null || (days != 7 && days != 30)) {
|
||||
days = 7;
|
||||
}
|
||||
|
||||
List<HrtTrendVo> trendList = new ArrayList<>();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
|
||||
for (int i = days - 1; i >= 0; i--) {
|
||||
LocalDate date = LocalDate.now().minusDays(i);
|
||||
LocalDateTime startTime = date.atStartOfDay();
|
||||
LocalDateTime endTime = date.atTime(LocalTime.MAX);
|
||||
|
||||
LambdaQueryWrapper<HrtUser> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtUser::getCreateTime, startTime);
|
||||
wrapper.le(HrtUser::getCreateTime, endTime);
|
||||
|
||||
Long count = userMapper.selectCount(wrapper);
|
||||
|
||||
HrtTrendVo trendVo = new HrtTrendVo();
|
||||
trendVo.setDate(date.format(formatter));
|
||||
trendVo.setValue(count);
|
||||
trendList.add(trendVo);
|
||||
}
|
||||
|
||||
return trendList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [获取内容发布趋势]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public List<HrtTrendVo> getContentTrend(Integer days) {
|
||||
if (days == null || (days != 7 && days != 30)) {
|
||||
days = 7;
|
||||
}
|
||||
|
||||
List<HrtTrendVo> trendList = new ArrayList<>();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
|
||||
for (int i = days - 1; i >= 0; i--) {
|
||||
LocalDate date = LocalDate.now().minusDays(i);
|
||||
LocalDateTime startTime = date.atStartOfDay();
|
||||
LocalDateTime endTime = date.atTime(LocalTime.MAX);
|
||||
|
||||
// 统计当天发布的内容总数(非遗项目+新闻+活动)
|
||||
Long heritageCount = countByDateRange(heritageMapper, startTime, endTime);
|
||||
Long newsCount = countByDateRange(newsMapper, startTime, endTime);
|
||||
Long eventCount = countByDateRange(eventMapper, startTime, endTime);
|
||||
|
||||
Long totalCount = heritageCount + newsCount + eventCount;
|
||||
|
||||
HrtTrendVo trendVo = new HrtTrendVo();
|
||||
trendVo.setDate(date.format(formatter));
|
||||
trendVo.setValue(totalCount);
|
||||
trendList.add(trendVo);
|
||||
}
|
||||
|
||||
return trendList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [获取热门非遗项目排行榜]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public List<HrtRankingVo> getHeritageRanking(String type, Integer limit) {
|
||||
if (limit == null || limit <= 0) {
|
||||
limit = 10;
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<HrtHeritage> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(HrtHeritage::getPublishStatus, 1);
|
||||
|
||||
// 根据类型排序
|
||||
if ("favorite".equals(type)) {
|
||||
wrapper.orderByDesc(HrtHeritage::getFavoriteCount);
|
||||
} else {
|
||||
// 默认按浏览量排序
|
||||
wrapper.orderByDesc(HrtHeritage::getViewCount);
|
||||
}
|
||||
|
||||
wrapper.last("LIMIT " + limit);
|
||||
|
||||
List<HrtHeritage> heritageList = heritageMapper.selectList(wrapper);
|
||||
|
||||
return heritageList.stream().map(heritage -> {
|
||||
HrtRankingVo vo = new HrtRankingVo();
|
||||
vo.setId(heritage.getId());
|
||||
vo.setTitle(heritage.getName());
|
||||
vo.setType("heritage");
|
||||
vo.setCoverImage(heritage.getCoverImage());
|
||||
vo.setValue("favorite".equals(type) ? heritage.getFavoriteCount().longValue() : heritage.getViewCount().longValue());
|
||||
vo.setValueType("favorite".equals(type) ? "收藏数" : "浏览量");
|
||||
return vo;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [获取活跃用户排行榜]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public List<HrtRankingVo> getActiveUserRanking(Integer limit) {
|
||||
if (limit == null || limit <= 0) {
|
||||
limit = 10;
|
||||
}
|
||||
|
||||
// 根据用户的评论数、点赞数、收藏数综合计算活跃度
|
||||
List<HrtUser> allUsers = userMapper.selectList(null);
|
||||
|
||||
List<HrtRankingVo> rankingList = allUsers.stream().map(user -> {
|
||||
// 统计用户的评论数
|
||||
LambdaQueryWrapper<HrtComment> commentWrapper = new LambdaQueryWrapper<>();
|
||||
commentWrapper.eq(HrtComment::getUserId, user.getId());
|
||||
Long commentCount = commentMapper.selectCount(commentWrapper);
|
||||
|
||||
// 统计用户的点赞数
|
||||
LambdaQueryWrapper<HrtLike> likeWrapper = new LambdaQueryWrapper<>();
|
||||
likeWrapper.eq(HrtLike::getUserId, user.getId());
|
||||
Long likeCount = likeMapper.selectCount(likeWrapper);
|
||||
|
||||
// 统计用户的收藏数
|
||||
LambdaQueryWrapper<HrtFavorite> favoriteWrapper = new LambdaQueryWrapper<>();
|
||||
favoriteWrapper.eq(HrtFavorite::getUserId, user.getId());
|
||||
Long favoriteCount = favoriteMapper.selectCount(favoriteWrapper);
|
||||
|
||||
// 计算活跃度分数(评论权重3,点赞权重1,收藏权重2)
|
||||
Long activityScore = commentCount * 3 + likeCount + favoriteCount * 2;
|
||||
|
||||
HrtRankingVo vo = new HrtRankingVo();
|
||||
vo.setId(user.getId());
|
||||
vo.setTitle(user.getNickname() != null ? user.getNickname() : user.getUsername());
|
||||
vo.setType("user");
|
||||
vo.setCoverImage(user.getAvatar());
|
||||
vo.setValue(activityScore);
|
||||
vo.setValueType("活跃度");
|
||||
return vo;
|
||||
})
|
||||
.sorted(Comparator.comparing(HrtRankingVo::getValue).reversed())
|
||||
.limit(limit)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 设置排名
|
||||
for (int i = 0; i < rankingList.size(); i++) {
|
||||
rankingList.get(i).setRank(i + 1);
|
||||
}
|
||||
|
||||
return rankingList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [统计今日新增非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countTodayRecords(HrtHeritageMapper mapper, LocalDateTime todayStart) {
|
||||
LambdaQueryWrapper<HrtHeritage> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtHeritage::getCreateTime, todayStart);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [统计今日新增传承人]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countTodayRecords(HrtInheritorMapper mapper, LocalDateTime todayStart) {
|
||||
LambdaQueryWrapper<HrtInheritor> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtInheritor::getCreateTime, todayStart);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [统计今日新增用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countTodayRecords(HrtUserMapper mapper, LocalDateTime todayStart) {
|
||||
LambdaQueryWrapper<HrtUser> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtUser::getCreateTime, todayStart);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [统计今日新增活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countTodayRecords(HrtEventMapper mapper, LocalDateTime todayStart) {
|
||||
LambdaQueryWrapper<HrtEvent> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtEvent::getCreateTime, todayStart);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [统计今日新增新闻]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countTodayRecords(HrtNewsMapper mapper, LocalDateTime todayStart) {
|
||||
LambdaQueryWrapper<HrtNews> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtNews::getCreateTime, todayStart);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [统计今日新增评论]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countTodayRecords(HrtCommentMapper mapper, LocalDateTime todayStart) {
|
||||
LambdaQueryWrapper<HrtComment> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtComment::getCreateTime, todayStart);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [统计今日新增点赞]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countTodayRecords(HrtLikeMapper mapper, LocalDateTime todayStart) {
|
||||
LambdaQueryWrapper<HrtLike> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtLike::getCreateTime, todayStart);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [统计今日新增收藏]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countTodayRecords(HrtFavoriteMapper mapper, LocalDateTime todayStart) {
|
||||
LambdaQueryWrapper<HrtFavorite> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtFavorite::getCreateTime, todayStart);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [统计今日新增浏览]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countTodayRecords(HrtViewHistoryMapper mapper, LocalDateTime todayStart) {
|
||||
LambdaQueryWrapper<HrtViewHistory> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtViewHistory::getCreateTime, todayStart);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [统计今日新增报名]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countTodayRecords(HrtEventRegistrationMapper mapper, LocalDateTime todayStart) {
|
||||
LambdaQueryWrapper<HrtEventRegistration> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtEventRegistration::getCreateTime, todayStart);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [按日期范围统计非遗项目]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countByDateRange(HrtHeritageMapper mapper, LocalDateTime startTime, LocalDateTime endTime) {
|
||||
LambdaQueryWrapper<HrtHeritage> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtHeritage::getCreateTime, startTime);
|
||||
wrapper.le(HrtHeritage::getCreateTime, endTime);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [按日期范围统计新闻]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countByDateRange(HrtNewsMapper mapper, LocalDateTime startTime, LocalDateTime endTime) {
|
||||
LambdaQueryWrapper<HrtNews> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtNews::getCreateTime, startTime);
|
||||
wrapper.le(HrtNews::getCreateTime, endTime);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [按日期范围统计活动]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private Long countByDateRange(HrtEventMapper mapper, LocalDateTime startTime, LocalDateTime endTime) {
|
||||
LambdaQueryWrapper<HrtEvent> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ge(HrtEvent::getCreateTime, startTime);
|
||||
wrapper.le(HrtEvent::getCreateTime, endTime);
|
||||
return mapper.selectCount(wrapper);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package org.leocoder.heritage.admin.service.user;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtUserAdminBo;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtUserAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtUserAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtUserAdminVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [前台用户管理服务接口]
|
||||
*/
|
||||
public interface HrtUserAdminService {
|
||||
|
||||
/**
|
||||
* @description [分页查询用户列表(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
IPage<HrtUserAdminVo> listPage(HrtUserAdminQueryBo bo);
|
||||
|
||||
/**
|
||||
* @description [查看用户详情(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
HrtUserAdminDetailVo getDetail(Long id);
|
||||
|
||||
/**
|
||||
* @description [新增用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Long addUser(HrtUserAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [编辑用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean editUser(HrtUserAdminBo bo);
|
||||
|
||||
/**
|
||||
* @description [删除用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean deleteUser(Long id);
|
||||
|
||||
/**
|
||||
* @description [批量删除用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean batchDelete(List<Long> ids);
|
||||
|
||||
/**
|
||||
* @description [修改用户状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean changeStatus(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* @description [重置用户密码]
|
||||
* @author Leocoder
|
||||
*/
|
||||
Boolean resetPassword(Long id, String newPassword);
|
||||
|
||||
}
|
||||
@ -0,0 +1,351 @@
|
||||
package org.leocoder.heritage.admin.service.user;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.leocoder.heritage.common.exception.BusinessException;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtUserAdminBo;
|
||||
import org.leocoder.heritage.satoken.config.CoderSaTokenPasswordUtil;
|
||||
import org.leocoder.heritage.domain.model.bo.admin.HrtUserAdminQueryBo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtUserAdminDetailVo;
|
||||
import org.leocoder.heritage.domain.model.vo.admin.HrtUserAdminVo;
|
||||
import org.leocoder.heritage.domain.pojo.portal.HrtUser;
|
||||
import org.leocoder.heritage.mybatisplus.mapper.portal.HrtUserMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Leocoder
|
||||
* @description [前台用户管理服务实现类]
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class HrtUserAdminServiceImpl implements HrtUserAdminService {
|
||||
|
||||
private final HrtUserMapper userMapper;
|
||||
|
||||
/**
|
||||
* @description [分页查询用户列表(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public IPage<HrtUserAdminVo> listPage(HrtUserAdminQueryBo bo) {
|
||||
Page<HrtUser> page = new Page<>(bo.getPageNum(), bo.getPageSize());
|
||||
|
||||
LambdaQueryWrapper<HrtUser> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 用户名模糊查询
|
||||
wrapper.like(StrUtil.isNotEmpty(bo.getUsername()), HrtUser::getUsername, bo.getUsername());
|
||||
|
||||
// 昵称模糊查询
|
||||
wrapper.like(StrUtil.isNotEmpty(bo.getNickname()), HrtUser::getNickname, bo.getNickname());
|
||||
|
||||
// 手机号精确查询
|
||||
wrapper.eq(StrUtil.isNotEmpty(bo.getPhone()), HrtUser::getPhone, bo.getPhone());
|
||||
|
||||
// 邮箱精确查询
|
||||
wrapper.eq(StrUtil.isNotEmpty(bo.getEmail()), HrtUser::getEmail, bo.getEmail());
|
||||
|
||||
// 状态查询
|
||||
wrapper.eq(Objects.nonNull(bo.getStatus()), HrtUser::getStatus, bo.getStatus());
|
||||
|
||||
// 性别查询
|
||||
wrapper.eq(Objects.nonNull(bo.getGender()), HrtUser::getGender, bo.getGender());
|
||||
|
||||
// 省份查询
|
||||
wrapper.eq(StrUtil.isNotEmpty(bo.getProvince()), HrtUser::getProvince, bo.getProvince());
|
||||
|
||||
// 城市查询
|
||||
wrapper.eq(StrUtil.isNotEmpty(bo.getCity()), HrtUser::getCity, bo.getCity());
|
||||
|
||||
// 关键词搜索(用户名、昵称、手机号、邮箱)
|
||||
if (StrUtil.isNotEmpty(bo.getKeyword())) {
|
||||
wrapper.and(w -> w
|
||||
.like(HrtUser::getUsername, bo.getKeyword())
|
||||
.or()
|
||||
.like(HrtUser::getNickname, bo.getKeyword())
|
||||
.or()
|
||||
.like(HrtUser::getPhone, bo.getKeyword())
|
||||
.or()
|
||||
.like(HrtUser::getEmail, bo.getKeyword())
|
||||
);
|
||||
}
|
||||
|
||||
// 注册时间范围查询
|
||||
wrapper.ge(Objects.nonNull(bo.getCreateTimeBegin()), HrtUser::getCreateTime, bo.getCreateTimeBegin());
|
||||
wrapper.le(Objects.nonNull(bo.getCreateTimeEnd()), HrtUser::getCreateTime, bo.getCreateTimeEnd());
|
||||
|
||||
// 排序处理
|
||||
if ("asc".equalsIgnoreCase(bo.getSortOrder())) {
|
||||
if ("login_time".equals(bo.getSortField())) {
|
||||
wrapper.orderByAsc(HrtUser::getLoginTime);
|
||||
} else {
|
||||
wrapper.orderByAsc(HrtUser::getCreateTime);
|
||||
}
|
||||
} else {
|
||||
if ("login_time".equals(bo.getSortField())) {
|
||||
wrapper.orderByDesc(HrtUser::getLoginTime);
|
||||
} else {
|
||||
wrapper.orderByDesc(HrtUser::getCreateTime);
|
||||
}
|
||||
}
|
||||
|
||||
IPage<HrtUser> userPage = userMapper.selectPage(page, wrapper);
|
||||
return userPage.convert(user -> BeanUtil.copyProperties(user, HrtUserAdminVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [查看用户详情(后台管理)]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
public HrtUserAdminDetailVo getDetail(Long id) {
|
||||
HrtUser user = userMapper.selectById(id);
|
||||
if (user == null) {
|
||||
throw new BusinessException(404, "用户不存在");
|
||||
}
|
||||
return BeanUtil.copyProperties(user, HrtUserAdminDetailVo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [新增用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long addUser(HrtUserAdminBo bo) {
|
||||
// 验证用户名是否已存在
|
||||
checkUsernameExists(bo.getUsername(), null);
|
||||
|
||||
// 验证手机号是否已存在
|
||||
if (StrUtil.isNotEmpty(bo.getPhone())) {
|
||||
checkPhoneExists(bo.getPhone(), null);
|
||||
}
|
||||
|
||||
// 验证邮箱是否已存在
|
||||
if (StrUtil.isNotEmpty(bo.getEmail())) {
|
||||
checkEmailExists(bo.getEmail(), null);
|
||||
}
|
||||
|
||||
// 密码必填校验
|
||||
if (StrUtil.isEmpty(bo.getPassword())) {
|
||||
throw new BusinessException(400, "密码不能为空");
|
||||
}
|
||||
|
||||
HrtUser user = BeanUtil.copyProperties(bo, HrtUser.class);
|
||||
|
||||
// 处理空字符串转null,避免唯一索引冲突
|
||||
if (StrUtil.isEmpty(bo.getEmail())) {
|
||||
user.setEmail(null);
|
||||
}
|
||||
if (StrUtil.isEmpty(bo.getPhone())) {
|
||||
user.setPhone(null);
|
||||
}
|
||||
|
||||
// 加密密码 - 使用统一的密码加密工具
|
||||
String encryptedPassword = CoderSaTokenPasswordUtil.encryptPassword(bo.getPassword());
|
||||
user.setPassword(encryptedPassword);
|
||||
|
||||
// 初始化状态为正常
|
||||
if (user.getStatus() == null) {
|
||||
user.setStatus(1);
|
||||
}
|
||||
|
||||
int result = userMapper.insert(user);
|
||||
if (result <= 0) {
|
||||
throw new BusinessException(500, "新增用户失败");
|
||||
}
|
||||
|
||||
return user.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [编辑用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean editUser(HrtUserAdminBo bo) {
|
||||
if (bo.getId() == null) {
|
||||
throw new BusinessException(400, "用户ID不能为空");
|
||||
}
|
||||
|
||||
// 检查用户是否存在
|
||||
HrtUser existUser = userMapper.selectById(bo.getId());
|
||||
if (existUser == null) {
|
||||
throw new BusinessException(404, "用户不存在");
|
||||
}
|
||||
|
||||
// 验证用户名是否已被其他用户使用
|
||||
checkUsernameExists(bo.getUsername(), bo.getId());
|
||||
|
||||
// 验证手机号是否已被其他用户使用
|
||||
if (StrUtil.isNotEmpty(bo.getPhone())) {
|
||||
checkPhoneExists(bo.getPhone(), bo.getId());
|
||||
}
|
||||
|
||||
// 验证邮箱是否已被其他用户使用
|
||||
if (StrUtil.isNotEmpty(bo.getEmail())) {
|
||||
checkEmailExists(bo.getEmail(), bo.getId());
|
||||
}
|
||||
|
||||
HrtUser user = BeanUtil.copyProperties(bo, HrtUser.class);
|
||||
|
||||
// 处理空字符串转null,避免唯一索引冲突
|
||||
if (StrUtil.isEmpty(bo.getEmail())) {
|
||||
user.setEmail(null);
|
||||
}
|
||||
if (StrUtil.isEmpty(bo.getPhone())) {
|
||||
user.setPhone(null);
|
||||
}
|
||||
|
||||
// 编辑用户时不修改密码,密码修改请使用专门的重置密码接口
|
||||
user.setPassword(null);
|
||||
|
||||
int result = userMapper.updateById(user);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [删除用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean deleteUser(Long id) {
|
||||
// 检查用户是否存在
|
||||
HrtUser user = userMapper.selectById(id);
|
||||
if (user == null) {
|
||||
throw new BusinessException(404, "用户不存在");
|
||||
}
|
||||
|
||||
int result = userMapper.deleteById(id);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [批量删除用户]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean batchDelete(List<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new BusinessException(400, "请选择要删除的用户");
|
||||
}
|
||||
|
||||
int result = userMapper.deleteBatchIds(ids);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [修改用户状态]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean changeStatus(Long id, Integer status) {
|
||||
// 检查用户是否存在
|
||||
HrtUser user = userMapper.selectById(id);
|
||||
if (user == null) {
|
||||
throw new BusinessException(404, "用户不存在");
|
||||
}
|
||||
|
||||
if (status == null || (status != 0 && status != 1)) {
|
||||
throw new BusinessException(400, "用户状态参数错误");
|
||||
}
|
||||
|
||||
HrtUser updateUser = new HrtUser();
|
||||
updateUser.setId(id);
|
||||
updateUser.setStatus(status);
|
||||
|
||||
int result = userMapper.updateById(updateUser);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [重置用户密码]
|
||||
* @author Leocoder
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean resetPassword(Long id, String newPassword) {
|
||||
// 检查用户是否存在
|
||||
HrtUser user = userMapper.selectById(id);
|
||||
if (user == null) {
|
||||
throw new BusinessException(404, "用户不存在");
|
||||
}
|
||||
|
||||
if (StrUtil.isEmpty(newPassword)) {
|
||||
throw new BusinessException(400, "新密码不能为空");
|
||||
}
|
||||
|
||||
// 加密密码 - 使用统一的密码加密工具
|
||||
String encryptedPassword = CoderSaTokenPasswordUtil.encryptPassword(newPassword);
|
||||
|
||||
HrtUser updateUser = new HrtUser();
|
||||
updateUser.setId(id);
|
||||
updateUser.setPassword(encryptedPassword);
|
||||
|
||||
int result = userMapper.updateById(updateUser);
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [检查用户名是否已存在]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private void checkUsernameExists(String username, Long excludeId) {
|
||||
LambdaQueryWrapper<HrtUser> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(HrtUser::getUsername, username);
|
||||
if (excludeId != null) {
|
||||
wrapper.ne(HrtUser::getId, excludeId);
|
||||
}
|
||||
|
||||
Long count = userMapper.selectCount(wrapper);
|
||||
if (count > 0) {
|
||||
throw new BusinessException(400, "用户名已存在");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [检查手机号是否已存在]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private void checkPhoneExists(String phone, Long excludeId) {
|
||||
LambdaQueryWrapper<HrtUser> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(HrtUser::getPhone, phone);
|
||||
if (excludeId != null) {
|
||||
wrapper.ne(HrtUser::getId, excludeId);
|
||||
}
|
||||
|
||||
Long count = userMapper.selectCount(wrapper);
|
||||
if (count > 0) {
|
||||
throw new BusinessException(400, "手机号已存在");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description [检查邮箱是否已存在]
|
||||
* @author Leocoder
|
||||
*/
|
||||
private void checkEmailExists(String email, Long excludeId) {
|
||||
LambdaQueryWrapper<HrtUser> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(HrtUser::getEmail, email);
|
||||
if (excludeId != null) {
|
||||
wrapper.ne(HrtUser::getId, excludeId);
|
||||
}
|
||||
|
||||
Long count = userMapper.selectCount(wrapper);
|
||||
if (count > 0) {
|
||||
throw new BusinessException(400, "邮箱已存在");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user