From 7d7314c1c458e01331b2007d6b3b8f65c22a48aa Mon Sep 17 00:00:00 2001 From: zzy Date: Fri, 24 Apr 2026 16:05:55 +0800 Subject: [PATCH] =?UTF-8?q?=E9=99=84=E4=BB=B6=E5=AD=97=E6=AE=B5=E8=B7=B3?= =?UTF-8?q?=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/post/CommunityPostController.java | 170 +++++++++++ .../admin/post/vo/CommunityPostPageReqVO.java | 37 +++ .../admin/post/vo/CommunityPostRespVO.java | 76 +++++ .../admin/post/vo/CommunityPostSaveReqVO.java | 53 ++++ .../notice/AppCommunityNoticeController.java | 4 +- .../app/notice/vo/AppNoticeRespVO.java | 2 +- .../app/post/AppCommunityPostController.java | 125 ++++++++ .../post/vo/AppCommunityPostPageReqVO.java | 34 +++ .../app/post/vo/AppCommunityPostRespVO.java | 45 +++ .../dal/dataobject/post/CommunityPostDO.java | 77 +++++ .../dal/dataobject/post/PostScopeDO.java | 47 +++ .../dal/mysql/post/CommunityPostMapper.java | 36 +++ .../dal/mysql/post/PostScopeMapper.java | 70 +++++ .../community/enums/ErrorCodeConstants.java | 8 +- .../service/post/CommunityPostService.java | 98 ++++++ .../post/CommunityPostServiceImpl.java | 282 ++++++++++++++++++ 16 files changed, 1160 insertions(+), 4 deletions(-) create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/CommunityPostController.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostPageReqVO.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostRespVO.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostSaveReqVO.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/AppCommunityPostController.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/vo/AppCommunityPostPageReqVO.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/vo/AppCommunityPostRespVO.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/post/CommunityPostDO.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/post/PostScopeDO.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/post/CommunityPostMapper.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/post/PostScopeMapper.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/post/CommunityPostService.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/post/CommunityPostServiceImpl.java diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/CommunityPostController.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/CommunityPostController.java new file mode 100644 index 0000000..2a69df4 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/CommunityPostController.java @@ -0,0 +1,170 @@ +package com.fjrcloud.community.module.community.controller.admin.post; + +import com.fjrcloud.community.framework.apilog.core.annotation.ApiAccessLog; +import com.fjrcloud.community.framework.common.pojo.CommonResult; +import com.fjrcloud.community.framework.common.pojo.PageParam; +import com.fjrcloud.community.framework.common.pojo.PageResult; +import com.fjrcloud.community.framework.common.util.object.BeanUtils; +import com.fjrcloud.community.framework.excel.core.util.ExcelUtils; +import com.fjrcloud.community.module.community.controller.admin.post.vo.CommunityPostPageReqVO; +import com.fjrcloud.community.module.community.controller.admin.post.vo.CommunityPostRespVO; +import com.fjrcloud.community.module.community.controller.admin.post.vo.CommunityPostSaveReqVO; +import com.fjrcloud.community.module.community.dal.dataobject.post.CommunityPostDO; +import com.fjrcloud.community.module.community.dal.dataobject.post.PostScopeDO; +import com.fjrcloud.community.module.community.dal.mysql.post.PostScopeMapper; +import com.fjrcloud.community.module.community.service.post.CommunityPostService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.fjrcloud.community.framework.apilog.core.enums.OperateTypeEnum.EXPORT; +import static com.fjrcloud.community.framework.common.pojo.CommonResult.success; + +/** + * 管理后台 - 社区动态 + * + * @author fjrcloud + */ +@Tag(name = "管理后台 - 社区动态") +@RestController +@RequestMapping("/community/community-post") +@Validated +public class CommunityPostController { + + @Resource + private CommunityPostService communityPostService; + + @Resource + private PostScopeMapper postScopeMapper; + + @PostMapping("/create") + @Operation(summary = "创建社区动态") + @PreAuthorize("@ss.hasPermission('community:community-post:create')") + public CommonResult createCommunityPost(@Valid @RequestBody CommunityPostSaveReqVO createReqVO) { + return success(communityPostService.createCommunityPost(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新社区动态") + @PreAuthorize("@ss.hasPermission('community:community-post:update')") + public CommonResult updateCommunityPost(@Valid @RequestBody CommunityPostSaveReqVO updateReqVO) { + communityPostService.updateCommunityPost(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除社区动态") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('community:community-post:delete')") + public CommonResult deleteCommunityPost(@RequestParam("id") Long id) { + communityPostService.deleteCommunityPost(id); + return success(true); + } + + @DeleteMapping("/delete-list") + @Parameter(name = "ids", description = "编号", required = true) + @Operation(summary = "批量删除社区动态") + @PreAuthorize("@ss.hasPermission('community:community-post:delete')") + public CommonResult deleteCommunityPostList(@RequestParam("ids") List ids) { + communityPostService.deleteCommunityPostListByIds(ids); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得社区动态") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('community:community-post:query')") + public CommonResult getCommunityPost(@RequestParam("id") Long id) { + CommunityPostDO post = communityPostService.getCommunityPost(id); + CommunityPostRespVO respVO = BeanUtils.toBean(post, CommunityPostRespVO.class); + + // 查询发布范围 + List scopeList = postScopeMapper.selectListByPostId(id); + if (scopeList != null && !scopeList.isEmpty()) { + List communityIds = scopeList.stream() + .map(PostScopeDO::getCommunityId) + .collect(Collectors.toList()); + respVO.setCommunityIds(communityIds); + + List communityNames = scopeList.stream() + .map(PostScopeDO::getCommunityName) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + respVO.setCommunityNames(communityNames); + } + + return success(respVO); + } + + @GetMapping("/page") + @Operation(summary = "获得社区动态分页") + @PreAuthorize("@ss.hasPermission('community:community-post:query')") + public CommonResult> getCommunityPostPage(@Valid CommunityPostPageReqVO pageReqVO) { + PageResult pageResult = communityPostService.getCommunityPostPage(pageReqVO); + PageResult respVOPageResult = BeanUtils.toBean(pageResult, CommunityPostRespVO.class); + + // 为每条动态填充小区ID、名称列表 + for (int i = 0; i < respVOPageResult.getList().size(); i++) { + CommunityPostRespVO respVO = respVOPageResult.getList().get(i); + + List scopeList = postScopeMapper.selectListByPostId(respVO.getId()); + if (scopeList != null && !scopeList.isEmpty()) { + List communityIds = scopeList.stream() + .map(PostScopeDO::getCommunityId) + .collect(Collectors.toList()); + respVO.setCommunityIds(communityIds); + + List communityNames = scopeList.stream() + .map(PostScopeDO::getCommunityName) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + respVO.setCommunityNames(communityNames); + } + } + + return success(respVOPageResult); + } + + @PutMapping("/publish") + @Operation(summary = "发布动态") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('community:community-post:publish')") + public CommonResult publishCommunityPost(@RequestParam("id") Long id) { + communityPostService.publishCommunityPost(id); + return success(true); + } + + @PutMapping("/offline") + @Operation(summary = "下线动态") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('community:community-post:offline')") + public CommonResult offlineCommunityPost(@RequestParam("id") Long id) { + communityPostService.offlineCommunityPost(id); + return success(true); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出社区动态 Excel") + @PreAuthorize("@ss.hasPermission('community:community-post:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportCommunityPostExcel(@Valid CommunityPostPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = communityPostService.getCommunityPostPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "社区动态.xls", "数据", CommunityPostRespVO.class, + BeanUtils.toBean(list, CommunityPostRespVO.class)); + } + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostPageReqVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostPageReqVO.java new file mode 100644 index 0000000..18b34d9 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostPageReqVO.java @@ -0,0 +1,37 @@ +package com.fjrcloud.community.module.community.controller.admin.post.vo; + +import com.fjrcloud.community.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static com.fjrcloud.community.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * 管理后台 - 社区动态分页 Request VO + * + * @author fjrcloud + */ +@Schema(description = "管理后台 - 社区动态分页 Request VO") +@Data +public class CommunityPostPageReqVO extends PageParam { + + @Schema(description = "动态标题", example = "春节通知") + private String title; + + @Schema(description = "状态(0-草稿,1-已发布,2-已下线,3-已撤回)", example = "1") + private Integer status; + + @Schema(description = "动态类型(1-物业,2-业委会,3-社区)", example = "1") + private Integer postType; + + @Schema(description = "发布时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] publishTime; + + @Schema(description = "小区ID", example = "1") + private Long communityId; + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostRespVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostRespVO.java new file mode 100644 index 0000000..0ef90dd --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostRespVO.java @@ -0,0 +1,76 @@ +package com.fjrcloud.community.module.community.controller.admin.post.vo; + +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import com.fjrcloud.community.framework.excel.core.annotations.DictFormat; +import com.fjrcloud.community.framework.excel.core.convert.DictConvert; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 管理后台 - 社区动态 Response VO + * + * @author fjrcloud + */ +@Schema(description = "管理后台 - 社区动态 Response VO") +@Data +@ExcelIgnoreUnannotated +public class CommunityPostRespVO { + + @Schema(description = "动态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty("编号") + private Long id; + + @Schema(description = "动态标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "关于春节期间物业服务安排的通知") + @ExcelProperty("动态标题") + private String title; + + @Schema(description = "动态内容(富文本)", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("动态内容") + private String content; + + @Schema(description = "发布方", requiredMode = Schema.RequiredMode.REQUIRED, example = "物业管理处") + @ExcelProperty("发布方") + private String author; + + @Schema(description = "封面图片URL", example = "https://xxx.com/cover.jpg") + @ExcelProperty("封面图片") + private String coverImage; + + @Schema(description = "动态类型(1-物业,2-业委会,3-社区)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty(value = "动态类型", converter = DictConvert.class) + @DictFormat("comm_post_type") + private Integer postType; + + @Schema(description = "状态(0-草稿,1-已发布,2-已下线,3-已撤回)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty(value = "状态", converter = DictConvert.class) + @DictFormat("comm_post_status") + private Integer status; + + @Schema(description = "发布类型(1-立即发布,2-定时发布)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty(value = "发布类型", converter = DictConvert.class) + @DictFormat("comm_post_publish_type") + private Integer publishType; + + @Schema(description = "发布时间") + @ExcelProperty("发布时间") + private LocalDateTime publishTime; + + @Schema(description = "浏览次数", example = "100") + @ExcelProperty("浏览次数") + private Integer viewCount; + + @Schema(description = "小区ID列表", example = "[1, 2]") + private List communityIds; + + @Schema(description = "小区名称列表", example = "[\"阳光小区\", \"花园小区\"]") + private List communityNames; + + @Schema(description = "创建时间") + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostSaveReqVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostSaveReqVO.java new file mode 100644 index 0000000..a68f18d --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/post/vo/CommunityPostSaveReqVO.java @@ -0,0 +1,53 @@ +package com.fjrcloud.community.module.community.controller.admin.post.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 管理后台 - 社区动态新增/修改 Request VO + * + * @author fjrcloud + */ +@Schema(description = "管理后台 - 社区动态新增/修改 Request VO") +@Data +public class CommunityPostSaveReqVO { + + @Schema(description = "动态编号", example = "1") + private Long id; + + @Schema(description = "动态标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "关于春节期间物业服务安排的通知") + @NotEmpty(message = "动态标题不能为空") + private String title; + + @Schema(description = "动态内容(富文本)", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "动态内容不能为空") + private String content; + + @Schema(description = "发布方", requiredMode = Schema.RequiredMode.REQUIRED, example = "物业管理处") + @NotEmpty(message = "发布方不能为空") + private String author; + + @Schema(description = "封面图片URL", example = "https://xxx.com/cover.jpg") + private String coverImage; + + @Schema(description = "动态类型(1-物业,2-业委会,3-社区)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "动态类型不能为空") + private Integer postType; + + @Schema(description = "发布类型(1-立即发布,2-定时发布)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "发布类型不能为空") + private Integer publishType; + + @Schema(description = "定时发布时间", example = "2024-01-01 00:00:00") + private LocalDateTime publishTime; + + @Schema(description = "小区ID列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]") + @NotNull(message = "小区列表不能为空") + private List communityIds; + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/AppCommunityNoticeController.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/AppCommunityNoticeController.java index ebd3349..5686ab0 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/AppCommunityNoticeController.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/AppCommunityNoticeController.java @@ -129,9 +129,9 @@ public class AppCommunityNoticeController { attachments.add(attachmentVO); } } - respVO.setAttachments(attachments); + respVO.setAttachmentList(attachments); } else { - respVO.setAttachments(new ArrayList<>()); + respVO.setAttachmentList(new ArrayList<>()); } // 查询发布范围 diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticeRespVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticeRespVO.java index 29f4a88..a15d534 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticeRespVO.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticeRespVO.java @@ -28,7 +28,7 @@ public class AppNoticeRespVO { private String publisher; @Schema(description = "附件列表", requiredMode = Schema.RequiredMode.REQUIRED) - private List attachments; + private List attachmentList; @Schema(description = "浏览次数", example = "100") private Integer viewCount; diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/AppCommunityPostController.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/AppCommunityPostController.java new file mode 100644 index 0000000..f3c572e --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/AppCommunityPostController.java @@ -0,0 +1,125 @@ +package com.fjrcloud.community.module.community.controller.app.post; + +import com.fjrcloud.community.framework.common.pojo.CommonResult; +import com.fjrcloud.community.framework.common.pojo.PageResult; +import com.fjrcloud.community.framework.common.util.object.BeanUtils; +import com.fjrcloud.community.module.community.controller.admin.post.vo.CommunityPostPageReqVO; +import com.fjrcloud.community.module.community.controller.app.post.vo.AppCommunityPostPageReqVO; +import com.fjrcloud.community.module.community.controller.app.post.vo.AppCommunityPostRespVO; +import com.fjrcloud.community.module.community.dal.dataobject.post.CommunityPostDO; +import com.fjrcloud.community.module.community.dal.dataobject.post.PostScopeDO; +import com.fjrcloud.community.module.community.dal.mysql.post.PostScopeMapper; +import com.fjrcloud.community.module.community.service.post.CommunityPostService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import static com.fjrcloud.community.framework.common.pojo.CommonResult.success; + +/** + * 用户APP - 社区动态 + * + * @author fjrcloud + */ +@Tag(name = "用户APP - 社区动态") +@RestController +@RequestMapping("/community/community-post") +@Validated +@Slf4j +public class AppCommunityPostController { + + @Resource + private CommunityPostService communityPostService; + + @Resource + private PostScopeMapper postScopeMapper; + + @GetMapping("/page") + @Operation(summary = "获取社区动态分页列表") + public CommonResult> getCommunityPostPage(@Validated AppCommunityPostPageReqVO pageReqVO) { + // 复用管理后台的 PageReqVO + CommunityPostPageReqVO adminPageReqVO = new CommunityPostPageReqVO(); + adminPageReqVO.setPageNo(pageReqVO.getPageNo()); + adminPageReqVO.setPageSize(pageReqVO.getPageSize()); + adminPageReqVO.setTitle(pageReqVO.getTitle()); + adminPageReqVO.setPostType(pageReqVO.getPostType()); + adminPageReqVO.setCommunityId(pageReqVO.getCommunityId()); + adminPageReqVO.setPublishTime(pageReqVO.getPublishTime()); + adminPageReqVO.setStatus(1); // 只查询已发布的动态 + + // 查询分页数据 + PageResult pageResult = communityPostService.getCommunityPostPage(adminPageReqVO); + return success(buildAppCommunityPostPageResult(pageResult)); + } + + @GetMapping("/get") + @Operation(summary = "获取社区动态详情") + public CommonResult getCommunityPost(@RequestParam("id") Long id) { + // 增加浏览次数 + communityPostService.incrementViewCount(id); + + // 查询动态详情 + CommunityPostDO post = communityPostService.getCommunityPost(id); + return success(buildAppCommunityPostRespVO(post)); + } + + /** + * 构建 App 端社区动态分页结果 + * + * @param pageResult 分页结果 + * @return App 端分页结果 + */ + private PageResult buildAppCommunityPostPageResult(PageResult pageResult) { + PageResult respVOPageResult = BeanUtils.toBean(pageResult, AppCommunityPostRespVO.class); + + // 为每条动态填充小区名称列表 + for (int i = 0; i < respVOPageResult.getList().size(); i++) { + AppCommunityPostRespVO respVO = respVOPageResult.getList().get(i); + CommunityPostDO post = pageResult.getList().get(i); + fillAppCommunityPostRespVO(respVO, post); + } + + return respVOPageResult; + } + + /** + * 构建 App 端社区动态响应对象 + * + * @param post 动态 DO + * @return App 端响应 VO + */ + private AppCommunityPostRespVO buildAppCommunityPostRespVO(CommunityPostDO post) { + AppCommunityPostRespVO respVO = BeanUtils.toBean(post, AppCommunityPostRespVO.class); + fillAppCommunityPostRespVO(respVO, post); + return respVO; + } + + /** + * 填充 App 端社区动态响应对象 + * + * @param respVO 响应 VO + * @param post 动态 DO + */ + private void fillAppCommunityPostRespVO(AppCommunityPostRespVO respVO, CommunityPostDO post) { + // 查询发布范围 + List scopeList = postScopeMapper.selectListByPostId(respVO.getId()); + if (scopeList != null && !scopeList.isEmpty()) { + List communityNames = scopeList.stream() + .map(PostScopeDO::getCommunityName) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + respVO.setCommunityNames(communityNames); + } + } + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/vo/AppCommunityPostPageReqVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/vo/AppCommunityPostPageReqVO.java new file mode 100644 index 0000000..eda1b02 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/vo/AppCommunityPostPageReqVO.java @@ -0,0 +1,34 @@ +package com.fjrcloud.community.module.community.controller.app.post.vo; + +import com.fjrcloud.community.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static com.fjrcloud.community.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * 用户APP - 社区动态分页 Request VO + * + * @author fjrcloud + */ +@Schema(description = "用户APP - 社区动态分页 Request VO") +@Data +public class AppCommunityPostPageReqVO extends PageParam { + + @Schema(description = "动态标题", example = "春节通知") + private String title; + + @Schema(description = "动态类型(1-物业,2-业委会,3-社区)", example = "1") + private Integer postType; + + @Schema(description = "小区ID", example = "1") + private Long communityId; + + @Schema(description = "发布时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] publishTime; + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/vo/AppCommunityPostRespVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/vo/AppCommunityPostRespVO.java new file mode 100644 index 0000000..9582932 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/post/vo/AppCommunityPostRespVO.java @@ -0,0 +1,45 @@ +package com.fjrcloud.community.module.community.controller.app.post.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 用户APP - 社区动态 Response VO + * + * @author fjrcloud + */ +@Schema(description = "用户APP - 社区动态 Response VO") +@Data +public class AppCommunityPostRespVO { + + @Schema(description = "动态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "动态标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "关于春节期间物业服务安排的通知") + private String title; + + @Schema(description = "动态内容(富文本)", requiredMode = Schema.RequiredMode.REQUIRED) + private String content; + + @Schema(description = "发布方", requiredMode = Schema.RequiredMode.REQUIRED, example = "物业管理处") + private String author; + + @Schema(description = "封面图片URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://xxx.com/cover.jpg") + private String coverImage; + + @Schema(description = "动态类型(1-物业,2-业委会,3-社区)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer postType; + + @Schema(description = "浏览次数", example = "100") + private Integer viewCount; + + @Schema(description = "发布时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime publishTime; + + @Schema(description = "小区名称列表", example = "[\"阳光小区\", \"花园小区\"]") + private List communityNames; + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/post/CommunityPostDO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/post/CommunityPostDO.java new file mode 100644 index 0000000..a4a6a25 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/post/CommunityPostDO.java @@ -0,0 +1,77 @@ +package com.fjrcloud.community.module.community.dal.dataobject.post; + +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fjrcloud.community.framework.mybatis.core.dataobject.BaseDO; +import com.fjrcloud.community.framework.tenant.core.aop.TenantIgnore; +import lombok.*; + +/** + * 社区动态 DO + * + * @author fjrcloud + */ +@TableName("comm_post") +@KeySequence("comm_post_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TenantIgnore +public class CommunityPostDO extends BaseDO { + + /** + * 动态编号 + */ + @TableId + private Long id; + + /** + * 动态标题 + */ + private String title; + + /** + * 动态内容(富文本) + */ + private String content; + + /** + * 发布方 + */ + private String author; + + /** + * 封面图片URL + */ + private String coverImage; + + /** + * 动态类型(1-物业,2-业委会,3-社区) + */ + private Integer postType; + + /** + * 状态(0-草稿,1-已发布,2-已下线,3-已撤回) + */ + private Integer status; + + /** + * 发布类型(1-立即发布,2-定时发布) + */ + private Integer publishType; + + /** + * 发布时间 + */ + private java.time.LocalDateTime publishTime; + + /** + * 浏览次数 + */ + private Integer viewCount; + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/post/PostScopeDO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/post/PostScopeDO.java new file mode 100644 index 0000000..2f9978a --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/post/PostScopeDO.java @@ -0,0 +1,47 @@ +package com.fjrcloud.community.module.community.dal.dataobject.post; + +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fjrcloud.community.framework.mybatis.core.dataobject.BaseDO; +import com.fjrcloud.community.framework.tenant.core.aop.TenantIgnore; +import lombok.*; + +/** + * 社区动态小区关联 DO + * + * @author fjrcloud + */ +@TableName("comm_post_scope") +@KeySequence("comm_post_scope_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TenantIgnore +public class PostScopeDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + + /** + * 动态ID + */ + private Long postId; + + /** + * 小区ID + */ + private Long communityId; + + /** + * 小区名称 + */ + private String communityName; + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/post/CommunityPostMapper.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/post/CommunityPostMapper.java new file mode 100644 index 0000000..dfd1906 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/post/CommunityPostMapper.java @@ -0,0 +1,36 @@ +package com.fjrcloud.community.module.community.dal.mysql.post; + +import com.fjrcloud.community.framework.common.pojo.PageResult; +import com.fjrcloud.community.framework.mybatis.core.mapper.BaseMapperX; +import com.fjrcloud.community.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.fjrcloud.community.module.community.controller.admin.post.vo.CommunityPostPageReqVO; +import com.fjrcloud.community.module.community.dal.dataobject.post.CommunityPostDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 社区动态 Mapper + * + * @author fjrcloud + */ +@Mapper +public interface CommunityPostMapper extends BaseMapperX { + + /** + * 分页查询动态列表 + * + * @param reqVO 分页查询条件 + * @return 分页结果 + */ + default PageResult selectPage(CommunityPostPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(CommunityPostDO::getTitle, reqVO.getTitle()) + .eqIfPresent(CommunityPostDO::getStatus, reqVO.getStatus()) + .eqIfPresent(CommunityPostDO::getPostType, reqVO.getPostType()) + .betweenIfPresent(CommunityPostDO::getPublishTime, reqVO.getPublishTime()) + .apply(reqVO.getCommunityId() != null, + "EXISTS (SELECT 1 FROM comm_post_scope WHERE post_id = id AND community_id = {0})", + reqVO.getCommunityId()) + .orderByDesc(CommunityPostDO::getId)); + } + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/post/PostScopeMapper.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/post/PostScopeMapper.java new file mode 100644 index 0000000..ba05bd0 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/post/PostScopeMapper.java @@ -0,0 +1,70 @@ +package com.fjrcloud.community.module.community.dal.mysql.post; + +import com.fjrcloud.community.framework.mybatis.core.mapper.BaseMapperX; +import com.fjrcloud.community.module.community.dal.dataobject.post.PostScopeDO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 社区动态小区关联 Mapper + * + * @author fjrcloud + */ +@Mapper +public interface PostScopeMapper extends BaseMapperX { + + /** + * 根据动态ID查询小区关联列表 + * + * @param postId 动态ID + * @return 小区关联列表 + */ + default List selectListByPostId(Long postId) { + return selectList(PostScopeDO::getPostId, postId); + } + + /** + * 根据动态ID物理删除关联(真删除) + * + * @param postId 动态ID + * @return 删除数量 + */ + default int deleteByPostId(Long postId) { + List list = selectList(PostScopeDO::getPostId, postId); + if (list == null || list.isEmpty()) { + return 0; + } + + int count = 0; + for (PostScopeDO scope : list) { + count += deleteAbsoluteById(scope.getId()); + } + return count; + } + + /** + * 批量插入动态小区关联 + * + * @param postId 动态ID + * @param communityIds 小区ID列表 + * @param communityNames 小区名称列表 + */ + default void insertBatch(@Param("postId") Long postId, + @Param("communityIds") List communityIds, + @Param("communityNames") List communityNames) { + List list = new java.util.ArrayList<>(); + for (int i = 0; i < communityIds.size(); i++) { + PostScopeDO scopeDO = new PostScopeDO(); + scopeDO.setPostId(postId); + scopeDO.setCommunityId(communityIds.get(i)); + if (communityNames != null && i < communityNames.size()) { + scopeDO.setCommunityName(communityNames.get(i)); + } + list.add(scopeDO); + } + insertBatch(list); + } + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/enums/ErrorCodeConstants.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/enums/ErrorCodeConstants.java index facb31b..260e1c9 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/enums/ErrorCodeConstants.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/enums/ErrorCodeConstants.java @@ -29,7 +29,7 @@ public interface ErrorCodeConstants { ErrorCode MEMBER_HOUSE_REJECT_REASON_REQUIRED = new ErrorCode(2_002_001_006, "驳回时必须填写驳回原因"); - ErrorCode MEMBER_HOUSE_MOBILE_REQUIRED = new ErrorCode(2_002_001_007,"手机号不能为空"); + ErrorCode MEMBER_HOUSE_MOBILE_REQUIRED = new ErrorCode(2_002_001_007, "手机号不能为空"); ErrorCode BANNER_NOT_EXISTS = new ErrorCode(2_002_002_007, "banner不存在"); @@ -38,4 +38,10 @@ public interface ErrorCodeConstants { ErrorCode NOTICE_NOT_DRAFT = new ErrorCode(2_004_000_003, "只有草稿状态的通知才能修改"); ErrorCode MINI_APP_CONFIG_NOT_EXISTS = new ErrorCode(2_003_002_007, "小程序配置不存在"); + + // 社区动态 2_005_000_XXX + ErrorCode COMMUNITY_POST_NOT_EXISTS = new ErrorCode(2_005_000_000, "社区动态不存在"); + + ErrorCode COMMUNITY_POST_NOT_DRAFT = new ErrorCode(2_005_000_001, "只有草稿状态的动态才能修改"); + } diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/post/CommunityPostService.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/post/CommunityPostService.java new file mode 100644 index 0000000..d47cbe4 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/post/CommunityPostService.java @@ -0,0 +1,98 @@ +package com.fjrcloud.community.module.community.service.post; + +import com.fjrcloud.community.framework.common.pojo.PageResult; +import com.fjrcloud.community.module.community.controller.admin.post.vo.CommunityPostPageReqVO; +import com.fjrcloud.community.module.community.controller.admin.post.vo.CommunityPostSaveReqVO; +import com.fjrcloud.community.module.community.dal.dataobject.post.CommunityPostDO; + +import javax.validation.Valid; +import java.util.List; + +/** + * 社区动态 Service 接口 + * + * @author fjrcloud + */ +public interface CommunityPostService { + + /** + * 创建社区动态 + * + * @param createReqVO 创建信息 + * @return 动态ID + */ + Long createCommunityPost(@Valid CommunityPostSaveReqVO createReqVO); + + /** + * 更新社区动态 + * + * @param updateReqVO 更新信息 + */ + void updateCommunityPost(@Valid CommunityPostSaveReqVO updateReqVO); + + /** + * 删除社区动态 + * + * @param id 动态ID + */ + void deleteCommunityPost(Long id); + + /** + * 批量删除社区动态 + * + * @param ids 动态ID列表 + */ + void deleteCommunityPostListByIds(List ids); + + /** + * 获得社区动态 + * + * @param id 动态ID + * @return 社区动态 + */ + CommunityPostDO getCommunityPost(Long id); + + /** + * 获得社区动态分页 + * + * @param pageReqVO 分页查询 + * @return 分页结果 + */ + PageResult getCommunityPostPage(CommunityPostPageReqVO pageReqVO); + + /** + * 发布动态 + * + * @param id 动态ID + */ + void publishCommunityPost(Long id); + + /** + * 下线动态 + * + * @param id 动态ID + */ + void offlineCommunityPost(Long id); + + /** + * 自动发布动态 + * + * @return 发布数量 + */ + int autoPublishPosts(); + + /** + * 自动下线动态 + * + * @return 下线数量 + */ + int autoOfflinePosts(); + + /** + * 增加动态浏览次数 + * + * @param id 动态ID + */ + void incrementViewCount(Long id); + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/post/CommunityPostServiceImpl.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/post/CommunityPostServiceImpl.java new file mode 100644 index 0000000..3b3ed0c --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/post/CommunityPostServiceImpl.java @@ -0,0 +1,282 @@ +package com.fjrcloud.community.module.community.service.post; + +import cn.hutool.core.collection.CollUtil; +import com.fjrcloud.community.framework.common.pojo.PageResult; +import com.fjrcloud.community.framework.common.util.object.BeanUtils; +import com.fjrcloud.community.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.fjrcloud.community.framework.tenant.core.context.TenantContextHolder; +import com.fjrcloud.community.framework.tenant.core.util.TenantUtils; +import com.fjrcloud.community.module.community.controller.admin.post.vo.CommunityPostPageReqVO; +import com.fjrcloud.community.module.community.controller.admin.post.vo.CommunityPostSaveReqVO; +import com.fjrcloud.community.module.community.dal.dataobject.community.CommunityDO; +import com.fjrcloud.community.module.community.dal.dataobject.post.CommunityPostDO; +import com.fjrcloud.community.module.community.dal.mysql.community.CommunityMapper; +import com.fjrcloud.community.module.community.dal.mysql.post.CommunityPostMapper; +import com.fjrcloud.community.module.community.dal.mysql.post.PostScopeMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static com.fjrcloud.community.framework.common.exception.util.ServiceExceptionUtil.exception; +import static com.fjrcloud.community.module.community.enums.ErrorCodeConstants.COMMUNITY_POST_NOT_DRAFT; +import static com.fjrcloud.community.module.community.enums.ErrorCodeConstants.COMMUNITY_POST_NOT_EXISTS; + +/** + * 社区动态 Service 实现类 + * + * @author fjrcloud + */ +@Service +@Validated +@Slf4j +public class CommunityPostServiceImpl implements CommunityPostService { + + /** + * 超级管理员租户ID + */ + private static final Long SYSTEM_TENANT_ID = 1L; + + @Resource + private CommunityPostMapper communityPostMapper; + + @Resource + private PostScopeMapper postScopeMapper; + + @Resource + private CommunityMapper communityMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createCommunityPost(CommunityPostSaveReqVO createReqVO) { + // 插入动态 + CommunityPostDO post = BeanUtils.toBean(createReqVO, CommunityPostDO.class); + + // 根据发布类型设置状态:1-立即发布直接设为已发布,2-定时发布设为草稿 + if (createReqVO.getPublishType() == 1) { + post.setStatus(1); // 已发布 + post.setPublishTime(LocalDateTime.now()); + } else { + post.setStatus(0); // 草稿 + } + post.setViewCount(0); + communityPostMapper.insert(post); + + // 插入动态小区关联 + if (createReqVO.getCommunityIds() != null && !createReqVO.getCommunityIds().isEmpty()) { + List communityNames = getCommunityNamesByIds(createReqVO.getCommunityIds()); + postScopeMapper.insertBatch(post.getId(), createReqVO.getCommunityIds(), communityNames); + } + + return post.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateCommunityPost(CommunityPostSaveReqVO updateReqVO) { + // 校验存在 + CommunityPostDO oldPost = validatePostExists(updateReqVO.getId()); + + // 如果原状态是已发布、已下线或已撤回,不允许修改 + if (oldPost.getStatus() != 0) { + throw exception(COMMUNITY_POST_NOT_DRAFT); + } + + // 更新动态 + CommunityPostDO updateObj = BeanUtils.toBean(updateReqVO, CommunityPostDO.class); + + // 根据发布类型设置状态:1-立即发布直接设为已发布,2-定时发布设为草稿 + if (updateReqVO.getPublishType() == 1) { + updateObj.setStatus(1); // 已发布 + updateObj.setPublishTime(LocalDateTime.now()); + } else { + updateObj.setStatus(0); // 草稿 + } + + communityPostMapper.updateById(updateObj); + + // 更新动态小区关联:先删除旧的,再插入新的 + postScopeMapper.deleteByPostId(updateReqVO.getId()); + if (updateReqVO.getCommunityIds() != null && !updateReqVO.getCommunityIds().isEmpty()) { + List communityNames = getCommunityNamesByIds(updateReqVO.getCommunityIds()); + postScopeMapper.insertBatch(updateReqVO.getId(), updateReqVO.getCommunityIds(), communityNames); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteCommunityPost(Long id) { + // 校验存在 + validatePostExists(id); + // 删除动态 + communityPostMapper.deleteById(id); + // 删除动态小区关联 + postScopeMapper.deleteByPostId(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteCommunityPostListByIds(List ids) { + // 删除动态 + communityPostMapper.deleteByIds(ids); + // 删除动态小区关联 + for (Long id : ids) { + postScopeMapper.deleteByPostId(id); + } + } + + @Override + public CommunityPostDO getCommunityPost(Long id) { + return communityPostMapper.selectById(id); + } + + @Override + public PageResult getCommunityPostPage(CommunityPostPageReqVO pageReqVO) { + // 获取当前租户ID + Long tenantId = TenantContextHolder.getTenantId(); + + // 如果没有指定小区ID,则根据租户类型确定 + if (pageReqVO.getCommunityId() == null) { + // 超级管理员租户查询所有动态,忽略租户隔离 + if (SYSTEM_TENANT_ID.equals(tenantId)) { + return TenantUtils.executeIgnore(() -> communityPostMapper.selectPage(pageReqVO)); + } + // 普通租户:租户ID即小区ID + pageReqVO.setCommunityId(tenantId); + } + + // 使用 EXISTS 子查询 + return communityPostMapper.selectPage(pageReqVO); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void publishCommunityPost(Long id) { + // 校验存在 + CommunityPostDO post = validatePostExists(id); + + // 校验状态 + if (post.getStatus() != 0) { + throw exception(new com.fjrcloud.community.framework.common.exception.ErrorCode(2_005_000_001, "只有草稿状态的动态才能发布")); + } + + // 更新状态为已发布 + CommunityPostDO updateObj = new CommunityPostDO(); + updateObj.setId(id); + updateObj.setStatus(1); + updateObj.setPublishTime(LocalDateTime.now()); + communityPostMapper.updateById(updateObj); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void offlineCommunityPost(Long id) { + // 校验存在 + CommunityPostDO post = validatePostExists(id); + + // 校验状态 + if (post.getStatus() != 1) { + throw exception(new com.fjrcloud.community.framework.common.exception.ErrorCode(2_005_000_002, "只有已发布状态的动态才能下线")); + } + + // 更新状态为已下线 + CommunityPostDO updateObj = new CommunityPostDO(); + updateObj.setId(id); + updateObj.setStatus(2); + communityPostMapper.updateById(updateObj); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int autoPublishPosts() { + // 查询需要发布的动态:草稿状态 + 发布时间已到 + LocalDateTime now = LocalDateTime.now(); + List posts = communityPostMapper.selectList(new LambdaQueryWrapperX() + .eq(CommunityPostDO::getStatus, 0) // 草稿状态 + .eq(CommunityPostDO::getPublishType, 2) // 定时发布 + .le(CommunityPostDO::getPublishTime, now) // 发布时间已到 + ); + + if (CollUtil.isEmpty(posts)) { + return 0; + } + + // 批量更新状态为已发布 + int count = 0; + for (CommunityPostDO post : posts) { + CommunityPostDO updateObj = new CommunityPostDO(); + updateObj.setId(post.getId()); + updateObj.setStatus(1); // 已发布 + communityPostMapper.updateById(updateObj); + count++; + } + + return count; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int autoOfflinePosts() { + // 查询需要下线的动态:已发布状态 + 结束类型是定时结束 + 结束时间已到 + // 注:当前版本暂不支持定时下线,后续可扩展 + return 0; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void incrementViewCount(Long id) { + CommunityPostDO post = validatePostExists(id); + + CommunityPostDO updateObj = new CommunityPostDO(); + updateObj.setId(id); + updateObj.setViewCount(post.getViewCount() + 1); + communityPostMapper.updateById(updateObj); + } + + /** + * 校验动态是否存在 + * + * @param id 动态ID + * @return 动态对象 + */ + private CommunityPostDO validatePostExists(Long id) { + CommunityPostDO post = communityPostMapper.selectById(id); + if (post == null) { + throw exception(COMMUNITY_POST_NOT_EXISTS); + } + return post; + } + + /** + * 根据小区ID列表批量查询小区名称 + * + * @param communityIds 小区ID列表 + * @return 小区名称列表(与输入顺序一致,不存在的小区返回null) + */ + private List getCommunityNamesByIds(List communityIds) { + if (CollUtil.isEmpty(communityIds)) { + return Collections.emptyList(); + } + + // 批量查询小区信息 + List communities = communityMapper.selectBatchIds(communityIds); + + // 构建ID到名称的映射 + Map communityNameMap = communities.stream() + .filter(community -> community.getCommunityName() != null) + .collect(Collectors.toMap(CommunityDO::getId, CommunityDO::getCommunityName)); + + // 按照原始ID顺序返回名称列表,不存在的小区返回null + return communityIds.stream() + .map(communityNameMap::get) + .collect(Collectors.toList()); + } + +}