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 new file mode 100644 index 0000000..ebd3349 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/AppCommunityNoticeController.java @@ -0,0 +1,174 @@ +package com.fjrcloud.community.module.community.controller.app.notice; + +import cn.hutool.core.util.StrUtil; +import com.fjrcloud.community.framework.common.pojo.CommonResult; +import com.fjrcloud.community.framework.common.pojo.PageResult; +import com.fjrcloud.community.framework.common.util.json.JsonUtils; +import com.fjrcloud.community.framework.common.util.object.BeanUtils; +import com.fjrcloud.community.module.community.controller.admin.notice.vo.NoticePageReqVO; +import com.fjrcloud.community.module.community.controller.app.notice.vo.AppNoticeAttachmentVO; +import com.fjrcloud.community.module.community.controller.app.notice.vo.AppNoticePageReqVO; +import com.fjrcloud.community.module.community.controller.app.notice.vo.AppNoticeRespVO; +import com.fjrcloud.community.module.community.dal.dataobject.notice.CommunityNoticeDO; +import com.fjrcloud.community.module.community.dal.dataobject.notice.NoticeScopeDO; +import com.fjrcloud.community.module.community.dal.mysql.notice.NoticeScopeMapper; +import com.fjrcloud.community.module.community.service.notice.CommunityNoticeService; +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.net.URLDecoder; +import java.util.ArrayList; +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/notice") +@Validated +@Slf4j +public class AppCommunityNoticeController { + + @Resource + private CommunityNoticeService communityNoticeService; + + @Resource + private NoticeScopeMapper noticeScopeMapper; + + @GetMapping("/page") + @Operation(summary = "获取通知分页列表") + public CommonResult> getNoticePage(@Validated AppNoticePageReqVO pageReqVO) { + // 复用管理后台的 PageReqVO + NoticePageReqVO adminPageReqVO = new NoticePageReqVO(); + adminPageReqVO.setPageNo(pageReqVO.getPageNo()); + adminPageReqVO.setPageSize(pageReqVO.getPageSize()); + adminPageReqVO.setTitle(pageReqVO.getTitle()); + adminPageReqVO.setCommunityId(pageReqVO.getCommunityId()); + adminPageReqVO.setPublishTime(pageReqVO.getPublishTime()); + adminPageReqVO.setStatus(1); // 只查询已发布的通知 + + // 查询分页数据 + PageResult pageResult = communityNoticeService.getNoticePage(adminPageReqVO); + return success(buildAppNoticePageResult(pageResult)); + } + + @GetMapping("/get") + @Operation(summary = "获取通知详情") + public CommonResult getNotice(@RequestParam("id") Long id) { + // 增加浏览次数 + communityNoticeService.incrementViewCount(id); + + // 查询通知详情 + CommunityNoticeDO notice = communityNoticeService.getNotice(id); + return success(buildAppNoticeRespVO(notice)); + } + + /** + * 构建 App 端通知分页结果 + * + * @param pageResult 分页结果 + * @return App 端分页结果 + */ + private PageResult buildAppNoticePageResult(PageResult pageResult) { + PageResult respVOPageResult = BeanUtils.toBean(pageResult, AppNoticeRespVO.class); + + // 为每条通知填充附件、小区名称列表 + for (int i = 0; i < respVOPageResult.getList().size(); i++) { + AppNoticeRespVO respVO = respVOPageResult.getList().get(i); + CommunityNoticeDO notice = pageResult.getList().get(i); + fillAppNoticeRespVO(respVO, notice); + } + + return respVOPageResult; + } + + /** + * 构建 App 端通知响应对象 + * + * @param notice 通知 DO + * @return App 端响应 VO + */ + private AppNoticeRespVO buildAppNoticeRespVO(CommunityNoticeDO notice) { + AppNoticeRespVO respVO = BeanUtils.toBean(notice, AppNoticeRespVO.class); + fillAppNoticeRespVO(respVO, notice); + return respVO; + } + + /** + * 填充 App 端通知响应对象 + * + * @param respVO 响应 VO + * @param notice 通知 DO + */ + private void fillAppNoticeRespVO(AppNoticeRespVO respVO, CommunityNoticeDO notice) { + // 处理附件列表:提取文件名 + if (notice.getAttachments() != null) { + List attachmentUrls = JsonUtils.parseArray(notice.getAttachments(), String.class); + List attachments = new ArrayList<>(); + for (String url : attachmentUrls) { + if (StrUtil.isNotBlank(url)) { + AppNoticeAttachmentVO attachmentVO = new AppNoticeAttachmentVO(); + attachmentVO.setUrl(url); + // 从 URL 中提取文件名 + String fileName = extractFileNameFromUrl(url); + attachmentVO.setName(fileName); + attachments.add(attachmentVO); + } + } + respVO.setAttachments(attachments); + } else { + respVO.setAttachments(new ArrayList<>()); + } + + // 查询发布范围 + List scopeList = noticeScopeMapper.selectListByNoticeId(respVO.getId()); + if (scopeList != null && !scopeList.isEmpty()) { + List communityNames = scopeList.stream() + .map(NoticeScopeDO::getCommunityName) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + respVO.setCommunityNames(communityNames); + } + } + + /** + * 从 URL 中提取文件名 + * + * @param url 文件访问地址 + * @return 文件名 + */ + private String extractFileNameFromUrl(String url) { + if (StrUtil.isBlank(url)) { + return ""; + } + + try { + // 移除 URL 参数(? 后面的部分) + String path = url.split("\\?")[0]; + // 获取最后一个斜杠后的内容 + String fileName = path.substring(path.lastIndexOf('/') + 1); + // URL 解码,处理中文文件名 + fileName = URLDecoder.decode(fileName, "utf-8"); + return fileName; + } catch (Exception e) { + log.error("[extractFileNameFromUrl] 提取文件名失败, url: {}", url, e); + // 如果提取失败,返回原始 URL 的最后一部分 + return url.substring(url.lastIndexOf('/') + 1); + } + } + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticeAttachmentVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticeAttachmentVO.java new file mode 100644 index 0000000..fe702fd --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticeAttachmentVO.java @@ -0,0 +1,21 @@ +package com.fjrcloud.community.module.community.controller.app.notice.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 用户APP - 通知附件 VO + * + * @author fjrcloud + */ +@Schema(description = "用户APP - 通知附件 VO") +@Data +public class AppNoticeAttachmentVO { + + @Schema(description = "文件访问地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://xxx.com/notice/file1.pdf") + private String url; + + @Schema(description = "文件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "物业服务安排.pdf") + private String name; + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticePageReqVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticePageReqVO.java new file mode 100644 index 0000000..7cb5e7c --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticePageReqVO.java @@ -0,0 +1,31 @@ +package com.fjrcloud.community.module.community.controller.app.notice.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 AppNoticePageReqVO extends PageParam { + + @Schema(description = "公告标题", example = "春节通知") + private String title; + + @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/notice/vo/AppNoticeRespVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticeRespVO.java new file mode 100644 index 0000000..29f4a88 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/notice/vo/AppNoticeRespVO.java @@ -0,0 +1,42 @@ +package com.fjrcloud.community.module.community.controller.app.notice.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 AppNoticeRespVO { + + @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 publisher; + + @Schema(description = "附件列表", requiredMode = Schema.RequiredMode.REQUIRED) + private List attachments; + + @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/service/notice/CommunityNoticeService.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/notice/CommunityNoticeService.java index 82f8eb1..a881b52 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/notice/CommunityNoticeService.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/notice/CommunityNoticeService.java @@ -82,10 +82,17 @@ public interface CommunityNoticeService { int autoPublishNotices(); /** - * 自动过期到期的通知(定时任务调用) + * 自动过期通知 * * @return 过期数量 */ int autoExpireNotices(); + /** + * 增加通知浏览次数 + * + * @param id 通知ID + */ + void incrementViewCount(Long id); + } diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/notice/CommunityNoticeServiceImpl.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/notice/CommunityNoticeServiceImpl.java index 1ca2b08..3c92dca 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/notice/CommunityNoticeServiceImpl.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/notice/CommunityNoticeServiceImpl.java @@ -263,6 +263,17 @@ public class CommunityNoticeServiceImpl implements CommunityNoticeService { return count; } + @Override + @Transactional(rollbackFor = Exception.class) + public void incrementViewCount(Long id) { + CommunityNoticeDO notice = validateNoticeExists(id); + + CommunityNoticeDO updateObj = new CommunityNoticeDO(); + updateObj.setId(id); + updateObj.setViewCount(notice.getViewCount() + 1); + communityNoticeMapper.updateById(updateObj); + } + /** * 校验通知是否存在 *