From 620bb4712a31791231c4381581f0f60088f079fe Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 27 五月 2026 14:03:45 +0800
Subject: [PATCH] Merge branch 'refs/heads/dev_New_pro' into dev_宁夏_英泽防锈
---
src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java | 409 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 409 insertions(+), 0 deletions(-)
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java
new file mode 100644
index 0000000..4a4d9c1
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java
@@ -0,0 +1,409 @@
+package com.ruoyi.collaborativeApproval.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.approve.mapper.ApprovalInstanceMapper;
+import com.ruoyi.approve.mapper.ApprovalTemplateMapper;
+import com.ruoyi.approve.pojo.ApprovalInstance;
+import com.ruoyi.approve.pojo.ApprovalTask;
+import com.ruoyi.approve.pojo.ApprovalTemplate;
+import com.ruoyi.approve.service.ApprovalInstanceService;
+import com.ruoyi.approve.utils.ApproveProcessConfigNodeUtils;
+import com.ruoyi.basic.enums.ApplicationTypeEnum;
+import com.ruoyi.basic.enums.RecordTypeEnum;
+import com.ruoyi.basic.utils.FileUtil;
+import com.ruoyi.collaborativeApproval.dto.EnterpriseNewsDto;
+import com.ruoyi.collaborativeApproval.mapper.EnterpriseNewsMapper;
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNews;
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeDept;
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeUser;
+import com.ruoyi.collaborativeApproval.service.EnterpriseNewsScopeDeptService;
+import com.ruoyi.collaborativeApproval.service.EnterpriseNewsScopeUserService;
+import com.ruoyi.collaborativeApproval.service.EnterpriseNewsService;
+import com.ruoyi.collaborativeApproval.vo.EnterpriseNewsVo;
+import com.ruoyi.common.enums.TypeEnums;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.OrderUtils;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.project.system.domain.SysDept;
+import com.ruoyi.project.system.domain.SysUser;
+import com.ruoyi.project.system.mapper.SysDeptMapper;
+import com.ruoyi.project.system.mapper.SysUserDeptMapper;
+import com.ruoyi.project.system.mapper.SysUserMapper;
+import com.ruoyi.project.system.service.ISysNoticeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 浼佷笟鏂伴椈琛ㄦ湇鍔″疄鐜扮被
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:50:59
+ */
+@Service
+@RequiredArgsConstructor
+public class EnterpriseNewsServiceImpl extends ServiceImpl<EnterpriseNewsMapper, EnterpriseNews> implements EnterpriseNewsService {
+
+ private static final String READ_SCOPE_ALL = "all";
+ private static final String READ_SCOPE_DEPT = "dept";
+ private static final String READ_SCOPE_CUSTOM = "custom";
+
+ private static final String STATUS_DRAFT = "DRAFT";
+ private static final String STATUS_PENDING = "PENDING";
+ private static final String STATUS_PUBLISHED = "PUBLISHED";
+ private static final String STATUS_REJECTED = "REJECTED";
+ private static final String STATUS_OFFLINE = "OFFLINE";
+
+ private final EnterpriseNewsMapper enterpriseNewsMapper;
+ private final EnterpriseNewsScopeDeptService enterpriseNewsScopeDeptService;
+ private final EnterpriseNewsScopeUserService enterpriseNewsScopeUserService;
+ private final SysUserMapper sysUserMapper;
+ private final SysDeptMapper sysDeptMapper;
+ private final SysUserDeptMapper sysUserDeptMapper;
+ private final ApprovalInstanceMapper approvalInstanceMapper;
+ private final ApprovalInstanceService approvalInstanceService;
+ private final ApprovalTemplateMapper approvalTemplateMapper;
+ private final ApproveProcessConfigNodeUtils approveProcessConfigNodeUtils;
+ private final ISysNoticeService sysNoticeService;
+ private final FileUtil fileUtil;
+
+ @Override
+ public IPage<EnterpriseNewsVo> listPage(Page<EnterpriseNewsVo> page, EnterpriseNewsDto enterpriseNewsDto) {
+ IPage<EnterpriseNewsVo> enterpriseNewsVoIPage = enterpriseNewsMapper.listPage(page, enterpriseNewsDto);
+ enterpriseNewsVoIPage.getRecords().forEach(enterpriseNewsVo -> {
+ enterpriseNewsVo.setStorageBlobDTOs(fileUtil.getStorageBlobVOsByRecordTypeAndRecordId(RecordTypeEnum.ENTERPRISE_NEWS, enterpriseNewsVo.getId()));
+ });
+ return enterpriseNewsVoIPage;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Boolean add(EnterpriseNewsDto enterpriseNewsDto) {
+ validateForSave(enterpriseNewsDto);
+ String readScope = normalizeReadScope(enterpriseNewsDto.getReadScope());
+ List<Long> deptIds = distinctIds(enterpriseNewsDto.getDeptIds());
+ List<Long> userIds = distinctIds(enterpriseNewsDto.getUserIds());
+
+ EnterpriseNews enterpriseNews = new EnterpriseNews();
+ BeanUtils.copyProperties(enterpriseNewsDto, enterpriseNews);
+ enterpriseNews.setReadScope(readScope);
+ enterpriseNews.setIsRequired(enterpriseNewsDto.getIsRequired() == null ? (byte) 0 : enterpriseNewsDto.getIsRequired());
+ enterpriseNews.setStatus(normalizeStatus(enterpriseNewsDto.getStatus(), STATUS_DRAFT));
+ enterpriseNews.setReadCount(0);
+ enterpriseNews.setRequiredReadCount(calculateRequiredReadCount(readScope, deptIds, userIds));
+
+ Long[] loginDeptIds = SecurityUtils.getDeptId();
+ if (StringUtils.isNotEmpty(loginDeptIds)) {
+ enterpriseNews.setDeptId(loginDeptIds[0]);
+ }
+
+ if (!save(enterpriseNews) || enterpriseNews.getId() == null) {
+ throw new ServiceException("鏂板浼佷笟鏂伴椈澶辫触");
+ }
+
+ saveReadScopeRelations(enterpriseNews.getId(), readScope, deptIds, userIds);
+ if (STATUS_PENDING.equals(enterpriseNews.getStatus())) {
+ startEnterpriseNewsApproval(enterpriseNews, enterpriseNewsDto);
+ }
+ //娣诲姞闄勪欢
+ fileUtil.saveStorageAttachment(ApplicationTypeEnum.FILE, RecordTypeEnum.ENTERPRISE_NEWS, enterpriseNews.getId(), enterpriseNewsDto.getStorageBlobDTOs());
+ return true;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Boolean updateEnterpriseNewsDto(EnterpriseNewsDto enterpriseNewsDto) {
+ if (enterpriseNewsDto == null || enterpriseNewsDto.getId() == null) {
+ throw new ServiceException("浼佷笟鏂伴椈ID涓嶈兘涓虹┖");
+ }
+
+ EnterpriseNews oldEnterpriseNews = getById(enterpriseNewsDto.getId());
+ if (oldEnterpriseNews == null) {
+ throw new ServiceException("浼佷笟鏂伴椈涓嶅瓨鍦�");
+ }
+ if (!STATUS_DRAFT.equals(oldEnterpriseNews.getStatus())
+ && !STATUS_REJECTED.equals(oldEnterpriseNews.getStatus())) {
+ throw new ServiceException("寰呭鎵规垨宸插彂甯冪殑浼佷笟鏂伴椈涓嶅厑璁镐慨鏀�");
+ }
+
+ validateForSave(enterpriseNewsDto);
+ String readScope = normalizeReadScope(enterpriseNewsDto.getReadScope());
+ List<Long> deptIds = distinctIds(enterpriseNewsDto.getDeptIds());
+ List<Long> userIds = distinctIds(enterpriseNewsDto.getUserIds());
+
+ EnterpriseNews enterpriseNews = new EnterpriseNews();
+ BeanUtils.copyProperties(enterpriseNewsDto, enterpriseNews);
+ enterpriseNews.setReadScope(readScope);
+ enterpriseNews.setIsRequired(enterpriseNewsDto.getIsRequired() == null ? oldEnterpriseNews.getIsRequired() : enterpriseNewsDto.getIsRequired());
+ enterpriseNews.setStatus(normalizeStatus(enterpriseNewsDto.getStatus(), oldEnterpriseNews.getStatus()));
+ enterpriseNews.setReadCount(oldEnterpriseNews.getReadCount());
+ enterpriseNews.setRequiredReadCount(calculateRequiredReadCount(readScope, deptIds, userIds));
+ enterpriseNews.setCreateUser(oldEnterpriseNews.getCreateUser());
+ enterpriseNews.setCreateTime(oldEnterpriseNews.getCreateTime());
+ enterpriseNews.setDeptId(oldEnterpriseNews.getDeptId());
+
+ if (!updateById(enterpriseNews)) {
+ throw new ServiceException("淇敼浼佷笟鏂伴椈澶辫触");
+ }
+
+ clearReadScopeRelations(enterpriseNews.getId());
+ saveReadScopeRelations(enterpriseNews.getId(), readScope, deptIds, userIds);
+ fileUtil.saveStorageAttachment(ApplicationTypeEnum.FILE, RecordTypeEnum.ENTERPRISE_NEWS, enterpriseNews.getId(), enterpriseNewsDto.getStorageBlobDTOs());
+ if (STATUS_PENDING.equals(enterpriseNews.getStatus())) {
+ resetEnterpriseNewsApprovalFlow(oldEnterpriseNews);
+ startEnterpriseNewsApproval(enterpriseNews, enterpriseNewsDto);
+ }
+ return true;
+ }
+
+ @Override
+ public Boolean delete(List<Long> ids) {
+ if (ids == null || ids.isEmpty()) {
+ return false;
+ }
+ if (!removeByIds(ids)) {
+ throw new ServiceException("鍒犻櫎浼佷笟鏂伴椈澶辫触");
+ }
+ ids.forEach(this::clearReadScopeRelations);
+ return true;
+ }
+
+ private void validateForSave(EnterpriseNewsDto enterpriseNewsDto) {
+ if (enterpriseNewsDto == null) {
+ throw new ServiceException("浼佷笟鏂伴椈鏁版嵁涓嶈兘涓虹┖");
+ }
+ if (StringUtils.isEmpty(enterpriseNewsDto.getTitle())) {
+ throw new ServiceException("鏍囬涓嶈兘涓虹┖");
+ }
+ if (StringUtils.isEmpty(enterpriseNewsDto.getContent())) {
+ throw new ServiceException("姝f枃涓嶈兘涓虹┖");
+ }
+
+ normalizeStatus(enterpriseNewsDto.getStatus(), STATUS_DRAFT);
+ String readScope = normalizeReadScope(enterpriseNewsDto.getReadScope());
+ List<Long> deptIds = distinctIds(enterpriseNewsDto.getDeptIds());
+ List<Long> userIds = distinctIds(enterpriseNewsDto.getUserIds());
+
+ if (READ_SCOPE_DEPT.equals(readScope) && StringUtils.isEmpty(deptIds)) {
+ throw new ServiceException("璇烽�夋嫨闃呰鑼冨洿閮ㄩ棬");
+ }
+ if (READ_SCOPE_CUSTOM.equals(readScope) && StringUtils.isEmpty(userIds)) {
+ throw new ServiceException("璇烽�夋嫨鑷畾涔夐槄璇讳汉鍛�");
+ }
+
+ validateDeptIds(deptIds);
+ validateUserIds(userIds);
+ }
+
+ private String normalizeReadScope(String readScope) {
+ String normalized = StringUtils.isEmpty(readScope) ? READ_SCOPE_ALL : readScope.trim();
+ if (!READ_SCOPE_ALL.equals(normalized)
+ && !READ_SCOPE_DEPT.equals(normalized)
+ && !READ_SCOPE_CUSTOM.equals(normalized)) {
+ throw new ServiceException("闃呰鑼冨洿涓嶅悎娉�");
+ }
+ return normalized;
+ }
+
+ private String normalizeStatus(String status, String defaultStatus) {
+ String normalized = StringUtils.isEmpty(status) ? defaultStatus : status.trim().toUpperCase();
+ if (!STATUS_DRAFT.equals(normalized)
+ && !STATUS_PENDING.equals(normalized)
+ && !STATUS_PUBLISHED.equals(normalized)
+ && !STATUS_REJECTED.equals(normalized)
+ && !STATUS_OFFLINE.equals(normalized)) {
+ throw new ServiceException("浼佷笟鏂伴椈鐘舵�佷笉鍚堟硶");
+ }
+ return normalized;
+ }
+
+ private void validateDeptIds(List<Long> deptIds) {
+ if (StringUtils.isEmpty(deptIds)) {
+ return;
+ }
+ for (Long deptId : deptIds) {
+ SysDept sysDept = sysDeptMapper.selectDeptById(deptId);
+ if (deptId == null || sysDept == null) {
+ throw new ServiceException("闃呰鑼冨洿閮ㄩ棬涓嶅瓨鍦�");
+ }
+ }
+ }
+
+ private void validateUserIds(List<Long> userIds) {
+ if (StringUtils.isEmpty(userIds)) {
+ return;
+ }
+ List<SysUser> users = sysUserMapper.selectUsersByIds(userIds);
+ if (users.size() != userIds.size()) {
+ throw new ServiceException("鑷畾涔夐槄璇讳汉鍛樺寘鍚棤鏁堢敤鎴�");
+ }
+ }
+
+ private Integer calculateRequiredReadCount(String readScope, List<Long> deptIds, List<Long> userIds) {
+ if (READ_SCOPE_ALL.equals(readScope)) {
+ Long count = sysUserMapper.selectCount(new LambdaQueryWrapper<SysUser>()
+ .eq(SysUser::getDelFlag, "0"));
+ return count == null ? 0 : count.intValue();
+ }
+ if (READ_SCOPE_DEPT.equals(readScope)) {
+ List<Long> allDeptIds = collectDeptIdsWithChildren(deptIds);
+ if (StringUtils.isEmpty(allDeptIds)) {
+ return 0;
+ }
+ Long count = sysUserDeptMapper.countDistinctUserIdsByDeptIds(allDeptIds);
+ return count == null ? 0 : count.intValue();
+ }
+ return userIds.size();
+ }
+
+ private List<Long> collectDeptIdsWithChildren(List<Long> deptIds) {
+ Set<Long> allDeptIds = new LinkedHashSet<>();
+ for (Long deptId : deptIds) {
+ if (deptId == null) {
+ continue;
+ }
+ allDeptIds.add(deptId);
+ List<SysDept> children = sysDeptMapper.selectChildrenDeptById(deptId);
+ if (StringUtils.isNotEmpty(children)) {
+ for (SysDept child : children) {
+ allDeptIds.add(child.getDeptId());
+ }
+ }
+ }
+ return new ArrayList<>(allDeptIds);
+ }
+
+ private void saveReadScopeRelations(Long newsId, String readScope, List<Long> deptIds, List<Long> userIds) {
+ if (READ_SCOPE_DEPT.equals(readScope)) {
+ List<EnterpriseNewsScopeDept> scopeDeptList = new ArrayList<>();
+ for (Long deptId : deptIds) {
+ EnterpriseNewsScopeDept scopeDept = new EnterpriseNewsScopeDept();
+ scopeDept.setNewsId(newsId);
+ scopeDept.setDeptId(deptId);
+ scopeDeptList.add(scopeDept);
+ }
+ if (StringUtils.isNotEmpty(scopeDeptList)) {
+ enterpriseNewsScopeDeptService.saveBatch(scopeDeptList);
+ }
+ return;
+ }
+
+ if (READ_SCOPE_CUSTOM.equals(readScope)) {
+ List<EnterpriseNewsScopeUser> scopeUserList = new ArrayList<>();
+ for (Long userId : userIds) {
+ EnterpriseNewsScopeUser scopeUser = new EnterpriseNewsScopeUser();
+ scopeUser.setNewsId(newsId);
+ scopeUser.setUserId(userId);
+ scopeUserList.add(scopeUser);
+ }
+ if (StringUtils.isNotEmpty(scopeUserList)) {
+ enterpriseNewsScopeUserService.saveBatch(scopeUserList);
+ }
+ }
+ }
+
+ private void clearReadScopeRelations(Long newsId) {
+ enterpriseNewsScopeDeptService.remove(new LambdaQueryWrapper<EnterpriseNewsScopeDept>()
+ .eq(EnterpriseNewsScopeDept::getNewsId, newsId));
+ enterpriseNewsScopeUserService.remove(new LambdaQueryWrapper<EnterpriseNewsScopeUser>()
+ .eq(EnterpriseNewsScopeUser::getNewsId, newsId));
+ }
+
+ private void resetEnterpriseNewsApprovalFlow(EnterpriseNews oldEnterpriseNews) {
+ if (oldEnterpriseNews == null || !STATUS_DRAFT.equals(oldEnterpriseNews.getStatus())) {
+ return;
+ }
+ List<Long> approvalInstanceIds = approvalInstanceMapper.selectList(new LambdaQueryWrapper<ApprovalInstance>()
+ .eq(ApprovalInstance::getBusinessId, oldEnterpriseNews.getId())
+ .eq(ApprovalInstance::getBusinessType, TypeEnums.ENTERPRISE_NEWS_APPROVAL.getCode())
+ .eq(ApprovalInstance::getDeleted, (byte) 0))
+ .stream()
+ .map(ApprovalInstance::getId)
+ .filter(id -> id != null && id > 0)
+ .collect(Collectors.toList());
+ if (StringUtils.isEmpty(approvalInstanceIds)) {
+ return;
+ }
+ approvalInstanceService.delete(approvalInstanceIds);
+ }
+
+ private List<Long> distinctIds(List<Long> ids) {
+ if (StringUtils.isEmpty(ids)) {
+ return new ArrayList<>();
+ }
+ Set<Long> distinctSet = new LinkedHashSet<>();
+ for (Long id : ids) {
+ if (id != null) {
+ distinctSet.add(id);
+ }
+ }
+ return new ArrayList<>(distinctSet);
+ }
+
+ private void startEnterpriseNewsApproval(EnterpriseNews enterpriseNews, EnterpriseNewsDto enterpriseNewsDto) {
+ if (enterpriseNewsDto.getTemplateId() == null) {
+ throw new ServiceException("瀹℃壒妯℃澘涓嶈兘涓虹┖");
+ }
+
+ String templateName = enterpriseNewsDto.getTemplateName();
+ if (StringUtils.isEmpty(templateName)) {
+ ApprovalTemplate approvalTemplate = approvalTemplateMapper.selectById(enterpriseNewsDto.getTemplateId());
+ if (approvalTemplate == null) {
+ throw new ServiceException("瀹℃壒妯℃澘涓嶅瓨鍦�");
+ }
+ templateName = approvalTemplate.getTemplateName();
+ }
+
+ ApprovalInstance approvalInstance = new ApprovalInstance();
+ approvalInstance.setInstanceNo(OrderUtils.countTodayByCreateTime(approvalInstanceMapper, "SP", "instance_no", enterpriseNews.getCreateTime() != null ? enterpriseNews.getCreateTime() : LocalDateTime.now()));
+ approvalInstance.setTemplateId(enterpriseNewsDto.getTemplateId());
+ approvalInstance.setTemplateName(templateName);
+ approvalInstance.setBusinessId(enterpriseNews.getId());
+ approvalInstance.setBusinessType(TypeEnums.ENTERPRISE_NEWS_APPROVAL.getCode());
+ approvalInstance.setTitle(enterpriseNews.getTitle());
+ approvalInstance.setStatus("PENDING");
+ approvalInstance.setCurrentLevel(1);
+ approvalInstance.setApplicantId(SecurityUtils.getUserId());
+ approvalInstance.setApplicantName(SecurityUtils.getLoginUser().getNickName());
+ approvalInstance.setApplyTime(LocalDateTime.now());
+ approvalInstance.setDeleted((byte) 0);
+ approvalInstance.setCreateUser(SecurityUtils.getUserId());
+ approvalInstance.setUpdateUser(SecurityUtils.getUserId());
+ approvalInstance.setDeptId(enterpriseNews.getDeptId());
+ approvalInstanceMapper.insert(approvalInstance);
+
+ approveProcessConfigNodeUtils.createCurrentNodeAndTasks(approvalInstance);
+ sendApproveNotice(approvalInstance, approveProcessConfigNodeUtils.getCurrentPendingTasks(approvalInstance.getId()));
+ }
+
+ private void sendApproveNotice(ApprovalInstance instance, List<ApprovalTask> tasks) {
+ if (instance == null || tasks == null || tasks.isEmpty()) {
+ return;
+ }
+ List<Long> approverIds = tasks.stream()
+ .map(ApprovalTask::getApproverId)
+ .filter(id -> id != null && id > 0)
+ .distinct()
+ .collect(Collectors.toList());
+ if (approverIds.isEmpty()) {
+ return;
+ }
+
+ String title = StringUtils.isNotEmpty(instance.getTemplateName()) ? instance.getTemplateName() : "瀹℃壒鎻愰啋";
+ String message = "瀹℃壒鍗曞彿 " + instance.getInstanceNo() + " 闇�瑕佹偍瀹℃壒";
+ String jumpPath = "/officeProcessAutomation/ApproveManage/approve-list/?id=" + instance.getId();
+ sysNoticeService.simpleNoticeByUser(title, message, approverIds, jumpPath);
+ }
+}
--
Gitblit v1.9.3