附件字段跳转

master
zzy 2026-04-24 16:05:55 +08:00
parent f44f44e960
commit 7d7314c1c4
16 changed files with 1160 additions and 4 deletions

View File

@ -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<Long> createCommunityPost(@Valid @RequestBody CommunityPostSaveReqVO createReqVO) {
return success(communityPostService.createCommunityPost(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新社区动态")
@PreAuthorize("@ss.hasPermission('community:community-post:update')")
public CommonResult<Boolean> 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<Boolean> 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<Boolean> deleteCommunityPostList(@RequestParam("ids") List<Long> 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<CommunityPostRespVO> getCommunityPost(@RequestParam("id") Long id) {
CommunityPostDO post = communityPostService.getCommunityPost(id);
CommunityPostRespVO respVO = BeanUtils.toBean(post, CommunityPostRespVO.class);
// 查询发布范围
List<PostScopeDO> scopeList = postScopeMapper.selectListByPostId(id);
if (scopeList != null && !scopeList.isEmpty()) {
List<Long> communityIds = scopeList.stream()
.map(PostScopeDO::getCommunityId)
.collect(Collectors.toList());
respVO.setCommunityIds(communityIds);
List<String> 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<PageResult<CommunityPostRespVO>> getCommunityPostPage(@Valid CommunityPostPageReqVO pageReqVO) {
PageResult<CommunityPostDO> pageResult = communityPostService.getCommunityPostPage(pageReqVO);
PageResult<CommunityPostRespVO> respVOPageResult = BeanUtils.toBean(pageResult, CommunityPostRespVO.class);
// 为每条动态填充小区ID、名称列表
for (int i = 0; i < respVOPageResult.getList().size(); i++) {
CommunityPostRespVO respVO = respVOPageResult.getList().get(i);
List<PostScopeDO> scopeList = postScopeMapper.selectListByPostId(respVO.getId());
if (scopeList != null && !scopeList.isEmpty()) {
List<Long> communityIds = scopeList.stream()
.map(PostScopeDO::getCommunityId)
.collect(Collectors.toList());
respVO.setCommunityIds(communityIds);
List<String> 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<Boolean> 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<Boolean> 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<CommunityPostDO> list = communityPostService.getCommunityPostPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "社区动态.xls", "数据", CommunityPostRespVO.class,
BeanUtils.toBean(list, CommunityPostRespVO.class));
}
}

View File

@ -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;
}

View File

@ -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<Long> communityIds;
@Schema(description = "小区名称列表", example = "[\"阳光小区\", \"花园小区\"]")
private List<String> communityNames;
@Schema(description = "创建时间")
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -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<Long> communityIds;
}

View File

@ -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<>());
}
// 查询发布范围

View File

@ -28,7 +28,7 @@ public class AppNoticeRespVO {
private String publisher;
@Schema(description = "附件列表", requiredMode = Schema.RequiredMode.REQUIRED)
private List<AppNoticeAttachmentVO> attachments;
private List<AppNoticeAttachmentVO> attachmentList;
@Schema(description = "浏览次数", example = "100")
private Integer viewCount;

View File

@ -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<PageResult<AppCommunityPostRespVO>> 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<CommunityPostDO> pageResult = communityPostService.getCommunityPostPage(adminPageReqVO);
return success(buildAppCommunityPostPageResult(pageResult));
}
@GetMapping("/get")
@Operation(summary = "获取社区动态详情")
public CommonResult<AppCommunityPostRespVO> getCommunityPost(@RequestParam("id") Long id) {
// 增加浏览次数
communityPostService.incrementViewCount(id);
// 查询动态详情
CommunityPostDO post = communityPostService.getCommunityPost(id);
return success(buildAppCommunityPostRespVO(post));
}
/**
* App
*
* @param pageResult
* @return App
*/
private PageResult<AppCommunityPostRespVO> buildAppCommunityPostPageResult(PageResult<CommunityPostDO> pageResult) {
PageResult<AppCommunityPostRespVO> 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<PostScopeDO> scopeList = postScopeMapper.selectListByPostId(respVO.getId());
if (scopeList != null && !scopeList.isEmpty()) {
List<String> communityNames = scopeList.stream()
.map(PostScopeDO::getCommunityName)
.filter(Objects::nonNull)
.collect(Collectors.toList());
respVO.setCommunityNames(communityNames);
}
}
}

View File

@ -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;
}

View File

@ -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<String> communityNames;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<CommunityPostDO> {
/**
*
*
* @param reqVO
* @return
*/
default PageResult<CommunityPostDO> selectPage(CommunityPostPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<CommunityPostDO>()
.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));
}
}

View File

@ -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<PostScopeDO> {
/**
* ID
*
* @param postId ID
* @return
*/
default List<PostScopeDO> selectListByPostId(Long postId) {
return selectList(PostScopeDO::getPostId, postId);
}
/**
* ID
*
* @param postId ID
* @return
*/
default int deleteByPostId(Long postId) {
List<PostScopeDO> 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<Long> communityIds,
@Param("communityNames") List<String> communityNames) {
List<PostScopeDO> 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);
}
}

View File

@ -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, "只有草稿状态的动态才能修改");
}

View File

@ -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<Long> ids);
/**
*
*
* @param id ID
* @return
*/
CommunityPostDO getCommunityPost(Long id);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<CommunityPostDO> 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);
}

View File

@ -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<String> 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<String> 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<Long> ids) {
// 删除动态
communityPostMapper.deleteByIds(ids);
// 删除动态小区关联
for (Long id : ids) {
postScopeMapper.deleteByPostId(id);
}
}
@Override
public CommunityPostDO getCommunityPost(Long id) {
return communityPostMapper.selectById(id);
}
@Override
public PageResult<CommunityPostDO> 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<CommunityPostDO> posts = communityPostMapper.selectList(new LambdaQueryWrapperX<CommunityPostDO>()
.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<String> getCommunityNamesByIds(List<Long> communityIds) {
if (CollUtil.isEmpty(communityIds)) {
return Collections.emptyList();
}
// 批量查询小区信息
List<CommunityDO> communities = communityMapper.selectBatchIds(communityIds);
// 构建ID到名称的映射
Map<Long, String> 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());
}
}