From ed0d872dddf37672ceb9bc499099f65d63ed1ce3 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期四, 21 五月 2026 09:28:36 +0800
Subject: [PATCH] feat(approve): 添加企业新闻审批功能并完善审批实例管理
---
src/main/java/com/ruoyi/project/system/mapper/SysUserDeptMapper.java | 25 +
src/main/java/com/ruoyi/approve/controller/ApprovalInstanceController.java | 3
src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsScopeDeptController.java | 18
src/main/java/com/ruoyi/collaborativeApproval/dto/EnterpriseNewsDto.java | 22
src/main/resources/mapper/system/SysNoticeMapper.xml | 5
src/main/resources/mapper/approve/ApprovalInstanceMapper.xml | 18
src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsScopeDeptMapper.java | 18
src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java | 128 ++++
src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsMapper.java | 24
src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsService.java | 29 +
src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java | 1
src/main/java/com/ruoyi/approve/controller/ApprovalInstanceNodeController.java | 3
src/main/java/com/ruoyi/collaborativeApproval/vo/EnterpriseNewsVo.java | 10
src/main/resources/mapper/collaborativeApproval/EnterpriseNewsScopeUserMapper.xml | 13
src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java | 378 +++++++++++++++
src/main/java/com/ruoyi/approve/bean/dto/ApprovalInstanceDto.java | 4
src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsScopeUserService.java | 16
src/main/resources/mapper/collaborativeApproval/EnterpriseNewsScopeDeptMapper.xml | 13
src/main/resources/mapper/staff/StaffLeaveMapper.xml | 21
src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsScopeUserMapper.java | 18
src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNewsScopeUser.java | 59 ++
src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNewsScopeDept.java | 59 ++
src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsScopeDeptService.java | 16
src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsScopeUserServiceImpl.java | 20
src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsScopeUserController.java | 18
src/main/resources/mapper/collaborativeApproval/EnterpriseNewsMapper.xml | 46 +
src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java | 169 +++++-
src/main/java/com/ruoyi/common/enums/ApprovalStatusEnum.java | 1
src/main/java/com/ruoyi/common/enums/EnterpriseNewsStatusEnum.java | 143 +++++
src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsScopeDeptServiceImpl.java | 20
src/main/java/com/ruoyi/approve/pojo/ApprovalInstance.java | 4
src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNews.java | 88 +++
src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsController.java | 55 ++
33 files changed, 1,400 insertions(+), 65 deletions(-)
diff --git a/src/main/java/com/ruoyi/approve/bean/dto/ApprovalInstanceDto.java b/src/main/java/com/ruoyi/approve/bean/dto/ApprovalInstanceDto.java
index ab4dced..17e4921 100644
--- a/src/main/java/com/ruoyi/approve/bean/dto/ApprovalInstanceDto.java
+++ b/src/main/java/com/ruoyi/approve/bean/dto/ApprovalInstanceDto.java
@@ -9,4 +9,8 @@
private String approveAction;
private String approveComment;
+
+ private String createTimeEnd;
+
+ private String createTimeStart;
}
diff --git a/src/main/java/com/ruoyi/approve/controller/ApprovalInstanceController.java b/src/main/java/com/ruoyi/approve/controller/ApprovalInstanceController.java
index c7225c2..f13e1b3 100644
--- a/src/main/java/com/ruoyi/approve/controller/ApprovalInstanceController.java
+++ b/src/main/java/com/ruoyi/approve/controller/ApprovalInstanceController.java
@@ -4,6 +4,7 @@
import com.ruoyi.approve.bean.dto.ApprovalInstanceDto;
import com.ruoyi.approve.bean.vo.ApprovalInstanceVo;
import com.ruoyi.approve.service.ApprovalInstanceService;
+import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -24,7 +25,7 @@
@RequestMapping("/approvalInstance")
@Tag(name = "瀹℃壒瀹炰緥琛�")
@AllArgsConstructor
-public class ApprovalInstanceController {
+public class ApprovalInstanceController extends BaseController {
private final ApprovalInstanceService approvalInstanceService;
@GetMapping("/listPage")
diff --git a/src/main/java/com/ruoyi/approve/controller/ApprovalInstanceNodeController.java b/src/main/java/com/ruoyi/approve/controller/ApprovalInstanceNodeController.java
index 186b2fd..e42af42 100644
--- a/src/main/java/com/ruoyi/approve/controller/ApprovalInstanceNodeController.java
+++ b/src/main/java/com/ruoyi/approve/controller/ApprovalInstanceNodeController.java
@@ -1,5 +1,6 @@
package com.ruoyi.approve.controller;
+import com.ruoyi.framework.web.controller.BaseController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -13,6 +14,6 @@
*/
@RestController
@RequestMapping("/approvalInstanceNode")
-public class ApprovalInstanceNodeController {
+public class ApprovalInstanceNodeController extends BaseController {
}
diff --git a/src/main/java/com/ruoyi/approve/pojo/ApprovalInstance.java b/src/main/java/com/ruoyi/approve/pojo/ApprovalInstance.java
index b58a836..77d8d58 100644
--- a/src/main/java/com/ruoyi/approve/pojo/ApprovalInstance.java
+++ b/src/main/java/com/ruoyi/approve/pojo/ApprovalInstance.java
@@ -1,11 +1,13 @@
package com.ruoyi.approve.pojo;
import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
@@ -118,6 +120,8 @@
*/
@Schema(description ="鍒涘缓鏃堕棿")
@TableField(fill = FieldFill.INSERT)
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/**
diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
index 1d7f217..c15ccb7 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApprovalInstanceServiceImpl.java
@@ -10,23 +10,29 @@
import com.ruoyi.approve.bean.dto.ApprovalInstanceDto;
import com.ruoyi.approve.bean.vo.ApprovalInstanceVo;
import com.ruoyi.approve.mapper.ApprovalInstanceMapper;
-import com.ruoyi.approve.mapper.ApprovalTemplateMapper;
import com.ruoyi.approve.pojo.*;
import com.ruoyi.approve.service.*;
import com.ruoyi.approve.utils.ApproveProcessConfigNodeUtils;
+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.common.enums.*;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.procurementrecord.utils.StockUtils;
+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 com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
-import com.ruoyi.quality.mapper.QualityInspectMapper;
-import com.ruoyi.quality.mapper.QualityInspectParamMapper;
-import com.ruoyi.quality.mapper.QualityTestStandardMapper;
-import com.ruoyi.quality.mapper.QualityTestStandardParamMapper;
import com.ruoyi.quality.utils.QualityInspectHelper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.mapper.SalesQuotationMapper;
@@ -54,6 +60,9 @@
@RequiredArgsConstructor
public class ApprovalInstanceServiceImpl extends ServiceImpl<ApprovalInstanceMapper, ApprovalInstance> implements ApprovalInstanceService {
+ private static final String ENTERPRISE_NEWS_STATUS_PUBLISHED = "PUBLISHED";
+ private static final String ENTERPRISE_NEWS_STATUS_REJECTED = "REJECTED";
+
private final ApprovalInstanceMapper approvalInstanceMapper;
private final ApproveProcessConfigNodeUtils approveProcessConfigNodeUtils;
private final ApprovalInstanceNodeService approvalInstanceNodeService;
@@ -65,14 +74,15 @@
private final PurchaseLedgerMapper purchaseLedgerMapper;
private final SalesLedgerProductMapper salesLedgerProductMapper;
private final StockUtils stockUtils;
- private final QualityInspectMapper qualityInspectMapper;
- private final QualityTestStandardMapper qualityTestStandardMapper;
- private final QualityTestStandardParamMapper qualityTestStandardParamMapper;
- private final QualityInspectParamMapper qualityInspectParamMapper;
private final SalesQuotationMapper salesQuotationMapper;
private final ShippingInfoMapper shippingInfoMapper;
- private final ApprovalTemplateMapper approvalTemplateMapper;
private final QualityInspectHelper qualityInspectHelper;
+ private final EnterpriseNewsService enterpriseNewsService;
+ private final EnterpriseNewsScopeDeptService enterpriseNewsScopeDeptService;
+ private final EnterpriseNewsScopeUserService enterpriseNewsScopeUserService;
+ private final SysUserMapper sysUserMapper;
+ private final SysUserDeptMapper sysUserDeptMapper;
+ private final SysDeptMapper sysDeptMapper;
@Override
public R listPage(Page<ApprovalInstanceVo> page, ApprovalInstanceDto approvalInstanceDto) {
@@ -331,6 +341,28 @@
}
if (TypeEnums.SHIPPING_APPROVAL.getCode().equals(businessType)) {
handleShippingApprovalFinished(instance, status);
+ return;
+ }
+ if (TypeEnums.ENTERPRISE_NEWS_APPROVAL.getCode().equals(businessType)) {
+ handleNewsApprovalFinished(instance, status);
+ }
+ }
+
+ private void handleNewsApprovalFinished(ApprovalInstance instance, String status) {
+ if (instance == null || instance.getBusinessId() == null) {
+ return;
+ }
+ EnterpriseNews enterpriseNews = new EnterpriseNews();
+ enterpriseNews.setId(instance.getBusinessId());
+ if ("APPROVED".equals(status)) {
+ enterpriseNews.setStatus(ENTERPRISE_NEWS_STATUS_PUBLISHED);
+ enterpriseNewsService.updateById(enterpriseNews);
+ sendEnterpriseNewsNotice(instance.getBusinessId());
+ return;
+ }
+ if ("REJECTED".equals(status)) {
+ enterpriseNews.setStatus(ENTERPRISE_NEWS_STATUS_REJECTED);
+ enterpriseNewsService.updateById(enterpriseNews);
}
}
@@ -474,6 +506,82 @@
sysNoticeService.simpleNoticeByUser(title, message, approverIds, jumpPath);
}
+ private void sendEnterpriseNewsNotice(Long newsId) {
+ EnterpriseNews enterpriseNews = enterpriseNewsService.getById(newsId);
+ if (enterpriseNews == null) {
+ return;
+ }
+ List<Long> userIds = getEnterpriseNewsNoticeUserIds(enterpriseNews);
+ if (userIds == null || userIds.isEmpty()) {
+ return;
+ }
+ String title = "浼佷笟鏂伴椈";
+ String message = "鎮ㄦ湁鏂扮殑浼佷笟鏂伴椈銆�" + enterpriseNews.getTitle() + "銆嬭鍙婃椂鏌ラ槄";
+ String jumpPath = "/enterpriseNews?id=" + newsId;
+ sysNoticeService.simpleNoticeByUser(title, message, userIds, jumpPath);
+ }
+
+ private List<Long> getEnterpriseNewsNoticeUserIds(EnterpriseNews enterpriseNews) {
+ if (enterpriseNews == null || !org.springframework.util.StringUtils.hasText(enterpriseNews.getReadScope())) {
+ return Collections.emptyList();
+ }
+ String readScope = enterpriseNews.getReadScope().trim();
+ if ("all".equals(readScope)) {
+ return sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
+ .select(SysUser::getUserId)
+ .eq(SysUser::getDelFlag, "0"))
+ .stream()
+ .map(SysUser::getUserId)
+ .filter(id -> id != null && id > 0)
+ .distinct()
+ .collect(Collectors.toList());
+ }
+ if ("dept".equals(readScope)) {
+ List<Long> deptIds = enterpriseNewsScopeDeptService.list(
+ new LambdaQueryWrapper<EnterpriseNewsScopeDept>()
+ .eq(EnterpriseNewsScopeDept::getNewsId, enterpriseNews.getId()))
+ .stream()
+ .map(EnterpriseNewsScopeDept::getDeptId)
+ .filter(id -> id != null && id > 0)
+ .distinct()
+ .collect(Collectors.toList());
+ if (deptIds.isEmpty()) {
+ return Collections.emptyList();
+ }
+ return sysUserDeptMapper.selectDistinctUserIdsByDeptIds(collectDeptIdsWithChildren(deptIds));
+ }
+ if ("custom".equals(readScope)) {
+ return enterpriseNewsScopeUserService.list(
+ new LambdaQueryWrapper<EnterpriseNewsScopeUser>()
+ .eq(EnterpriseNewsScopeUser::getNewsId, enterpriseNews.getId()))
+ .stream()
+ .map(EnterpriseNewsScopeUser::getUserId)
+ .filter(id -> id != null && id > 0)
+ .distinct()
+ .collect(Collectors.toList());
+ }
+ return Collections.emptyList();
+ }
+
+ 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 (children != null && !children.isEmpty()) {
+ for (SysDept child : children) {
+ if (child != null && child.getDeptId() != null) {
+ allDeptIds.add(child.getDeptId());
+ }
+ }
+ }
+ }
+ return new ArrayList<>(allDeptIds);
+ }
+
private void closePendingTasks(Long instanceId, Long nodeId) {
LambdaUpdateWrapper<ApprovalTask> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(ApprovalTask::getInstanceId, instanceId)
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsController.java b/src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsController.java
new file mode 100644
index 0000000..88445fa
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsController.java
@@ -0,0 +1,55 @@
+package com.ruoyi.collaborativeApproval.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.collaborativeApproval.dto.EnterpriseNewsDto;
+import com.ruoyi.collaborativeApproval.service.EnterpriseNewsService;
+import com.ruoyi.collaborativeApproval.vo.EnterpriseNewsVo;
+import com.ruoyi.framework.web.domain.R;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈琛� 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:50:59
+ */
+@RestController
+@RequestMapping("/enterpriseNews")
+@Tag(name = "浼佷笟鏂伴椈琛�")
+@AllArgsConstructor
+public class EnterpriseNewsController {
+
+ private final EnterpriseNewsService enterpriseNewsService;
+
+ @Operation(summary = "鍒嗛〉鏌ヨ")
+ @GetMapping("/listPage")
+ public R listPage(Page<EnterpriseNewsVo> page , EnterpriseNewsDto enterpriseNewsDto) {
+ return R.ok(enterpriseNewsService.listPage(page, enterpriseNewsDto));
+ }
+
+ @PostMapping("/save")
+ @Operation(summary = "淇濆瓨")
+ public R save(@RequestBody EnterpriseNewsDto enterpriseNewsDto) {
+ return R.ok(enterpriseNewsService.add(enterpriseNewsDto));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "鏇存柊")
+ public R update(@RequestBody EnterpriseNewsDto enterpriseNewsDto) {
+ return R.ok(enterpriseNewsService.updateEnterpriseNewsDto(enterpriseNewsDto));
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "鍒犻櫎")
+ public R delete(@RequestBody List<Long> ids) {
+ return R.ok(enterpriseNewsService.delete(ids));
+ }
+
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsScopeDeptController.java b/src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsScopeDeptController.java
new file mode 100644
index 0000000..8c68d1a
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsScopeDeptController.java
@@ -0,0 +1,18 @@
+package com.ruoyi.collaborativeApproval.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈闃呰鑼冨洿閮ㄩ棬琛� 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:51:12
+ */
+@RestController
+@RequestMapping("/enterpriseNewsScopeDept")
+public class EnterpriseNewsScopeDeptController {
+
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsScopeUserController.java b/src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsScopeUserController.java
new file mode 100644
index 0000000..7ceba13
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/controller/EnterpriseNewsScopeUserController.java
@@ -0,0 +1,18 @@
+package com.ruoyi.collaborativeApproval.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈闃呰鑼冨洿鐢ㄦ埛琛� 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:51:23
+ */
+@RestController
+@RequestMapping("/enterpriseNewsScopeUser")
+public class EnterpriseNewsScopeUserController {
+
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/dto/EnterpriseNewsDto.java b/src/main/java/com/ruoyi/collaborativeApproval/dto/EnterpriseNewsDto.java
new file mode 100644
index 0000000..3cde773
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/dto/EnterpriseNewsDto.java
@@ -0,0 +1,22 @@
+package com.ruoyi.collaborativeApproval.dto;
+
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNews;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class EnterpriseNewsDto extends EnterpriseNews {
+
+ private String createUserName;
+
+ private List<Long> deptIds;
+
+ private List<Long> userIds;
+
+ private Long templateId;
+ private String templateName;
+
+ private String createTimeStart;
+ private String createTimeEnd;
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsMapper.java b/src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsMapper.java
new file mode 100644
index 0000000..799ae82
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsMapper.java
@@ -0,0 +1,24 @@
+package com.ruoyi.collaborativeApproval.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.collaborativeApproval.dto.EnterpriseNewsDto;
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNews;
+import com.ruoyi.collaborativeApproval.vo.EnterpriseNewsVo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈琛� Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:50:59
+ */
+@Mapper
+public interface EnterpriseNewsMapper extends BaseMapper<EnterpriseNews> {
+
+ IPage<EnterpriseNewsVo> listPage(Page<EnterpriseNewsVo> page,@Param("enterpriseNewsDto") EnterpriseNewsDto enterpriseNewsDto);
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsScopeDeptMapper.java b/src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsScopeDeptMapper.java
new file mode 100644
index 0000000..5b4639f
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsScopeDeptMapper.java
@@ -0,0 +1,18 @@
+package com.ruoyi.collaborativeApproval.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeDept;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈闃呰鑼冨洿閮ㄩ棬琛� Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:51:12
+ */
+@Mapper
+public interface EnterpriseNewsScopeDeptMapper extends BaseMapper<EnterpriseNewsScopeDept> {
+
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsScopeUserMapper.java b/src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsScopeUserMapper.java
new file mode 100644
index 0000000..ab9a64f
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/mapper/EnterpriseNewsScopeUserMapper.java
@@ -0,0 +1,18 @@
+package com.ruoyi.collaborativeApproval.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeUser;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈闃呰鑼冨洿鐢ㄦ埛琛� Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:51:23
+ */
+@Mapper
+public interface EnterpriseNewsScopeUserMapper extends BaseMapper<EnterpriseNewsScopeUser> {
+
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNews.java b/src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNews.java
new file mode 100644
index 0000000..f5e001b
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNews.java
@@ -0,0 +1,88 @@
+package com.ruoyi.collaborativeApproval.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 浼佷笟鏂伴椈琛�
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:50:59
+ */
+@Getter
+@Setter
+@ToString
+@TableName("enterprise_news")
+@ApiModel(value = "EnterpriseNews瀵硅薄", description = "浼佷笟鏂伴椈琛�")
+public class EnterpriseNews implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Schema(description = "缂栧彿 ID")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ @Schema(description = "鏍囬 Title")
+ private String title;
+
+ @Schema(description = "鎽樿 Summary")
+ private String summary;
+
+ @Schema(description = "姝f枃 Content")
+ private String content;
+
+ @Schema(description = "鍒嗙被 Category")
+ private String category;
+
+ @Schema(description = "闃呰鑼冨洿 Read scope: all 鍏ㄥ憳, dept 閮ㄩ棬, custom 鑷畾涔�")
+ private String readScope;
+
+ @Schema(description = "鏄惁蹇呰 Required flag: 0 鍚�, 1 鏄�")
+ private Byte isRequired;
+
+ @Schema(description = "鐘舵�� Status: DRAFT 鑽夌, PENDING 寰呭鎵�, PUBLISHED 宸插彂甯�, REJECTED 椹冲洖, OFFLINE 宸蹭笅绾�")
+ private String status;
+
+ @Schema(description = "搴旇浜烘暟 Required read count")
+ private Integer requiredReadCount;
+
+ @Schema(description = "宸茶浜烘暟 Read count")
+ private Integer readCount;
+
+ @Schema(description = "鍒涘缓浜� Create user")
+ @TableField(fill = FieldFill.INSERT)
+ private Long createUser;
+
+ @Schema(description = "鍒涘缓鏃堕棿 Create time")
+ @TableField(fill = FieldFill.INSERT)
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss", iso = DateTimeFormat.ISO.DATE_TIME)
+ private LocalDateTime createTime;
+
+ @Schema(description = "鏇存柊浜� Update user")
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long updateUser;
+
+ @Schema(description = "鏇存柊鏃堕棿 Update time")
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss", iso = DateTimeFormat.ISO.DATE_TIME)
+ private LocalDateTime updateTime;
+
+ @Schema(description = "閮ㄩ棬ID Dept ID")
+ @TableField(fill = FieldFill.INSERT)
+ private Long deptId;
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNewsScopeDept.java b/src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNewsScopeDept.java
new file mode 100644
index 0000000..97ff9de
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNewsScopeDept.java
@@ -0,0 +1,59 @@
+package com.ruoyi.collaborativeApproval.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈闃呰鑼冨洿閮ㄩ棬琛�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:51:12
+ */
+@Getter
+@Setter
+@ToString
+@TableName("enterprise_news_scope_dept")
+@ApiModel(value = "EnterpriseNewsScopeDept瀵硅薄", description = "浼佷笟鏂伴椈闃呰鑼冨洿閮ㄩ棬琛�")
+public class EnterpriseNewsScopeDept implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 缂栧彿
+ */
+ @ApiModelProperty("缂栧彿")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 浼佷笟鏂伴椈ID
+ */
+ @ApiModelProperty("浼佷笟鏂伴椈ID")
+ private Long newsId;
+
+ /**
+ * 閮ㄩ棬ID
+ */
+ @ApiModelProperty("閮ㄩ棬ID")
+ private Long deptId;
+
+ /**
+ * 鍒涘缓鏃堕棿
+ */
+ @ApiModelProperty("鍒涘缓鏃堕棿")
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNewsScopeUser.java b/src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNewsScopeUser.java
new file mode 100644
index 0000000..9d43df2
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/pojo/EnterpriseNewsScopeUser.java
@@ -0,0 +1,59 @@
+package com.ruoyi.collaborativeApproval.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈闃呰鑼冨洿鐢ㄦ埛琛�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:51:23
+ */
+@Getter
+@Setter
+@ToString
+@TableName("enterprise_news_scope_user")
+@ApiModel(value = "EnterpriseNewsScopeUser瀵硅薄", description = "浼佷笟鏂伴椈闃呰鑼冨洿鐢ㄦ埛琛�")
+public class EnterpriseNewsScopeUser implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 缂栧彿
+ */
+ @ApiModelProperty("缂栧彿")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 浼佷笟鏂伴椈ID
+ */
+ @ApiModelProperty("浼佷笟鏂伴椈ID")
+ private Long newsId;
+
+ /**
+ * 鐢ㄦ埛ID
+ */
+ @ApiModelProperty("鐢ㄦ埛ID")
+ private Long userId;
+
+ /**
+ * 鍒涘缓鏃堕棿
+ */
+ @ApiModelProperty("鍒涘缓鏃堕棿")
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsScopeDeptService.java b/src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsScopeDeptService.java
new file mode 100644
index 0000000..b41a7d8
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsScopeDeptService.java
@@ -0,0 +1,16 @@
+package com.ruoyi.collaborativeApproval.service;
+
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeDept;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈闃呰鑼冨洿閮ㄩ棬琛� 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:51:12
+ */
+public interface EnterpriseNewsScopeDeptService extends IService<EnterpriseNewsScopeDept> {
+
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsScopeUserService.java b/src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsScopeUserService.java
new file mode 100644
index 0000000..28ac6c7
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsScopeUserService.java
@@ -0,0 +1,16 @@
+package com.ruoyi.collaborativeApproval.service;
+
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeUser;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈闃呰鑼冨洿鐢ㄦ埛琛� 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:51:23
+ */
+public interface EnterpriseNewsScopeUserService extends IService<EnterpriseNewsScopeUser> {
+
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsService.java b/src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsService.java
new file mode 100644
index 0000000..21e7e6c
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/service/EnterpriseNewsService.java
@@ -0,0 +1,29 @@
+package com.ruoyi.collaborativeApproval.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.collaborativeApproval.dto.EnterpriseNewsDto;
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNews;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.collaborativeApproval.vo.EnterpriseNewsVo;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈琛� 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:50:59
+ */
+public interface EnterpriseNewsService extends IService<EnterpriseNews> {
+
+ IPage<EnterpriseNewsVo> listPage(Page<EnterpriseNewsVo> page, EnterpriseNewsDto enterpriseNewsDto);
+
+ Boolean add(EnterpriseNewsDto enterpriseNewsDto);
+
+ Boolean updateEnterpriseNewsDto(EnterpriseNewsDto enterpriseNewsDto);
+
+ Boolean delete(List<Long> ids);
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsScopeDeptServiceImpl.java b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsScopeDeptServiceImpl.java
new file mode 100644
index 0000000..22283c7
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsScopeDeptServiceImpl.java
@@ -0,0 +1,20 @@
+package com.ruoyi.collaborativeApproval.service.impl;
+
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeDept;
+import com.ruoyi.collaborativeApproval.mapper.EnterpriseNewsScopeDeptMapper;
+import com.ruoyi.collaborativeApproval.service.EnterpriseNewsScopeDeptService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈闃呰鑼冨洿閮ㄩ棬琛� 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:51:12
+ */
+@Service
+public class EnterpriseNewsScopeDeptServiceImpl extends ServiceImpl<EnterpriseNewsScopeDeptMapper, EnterpriseNewsScopeDept> implements EnterpriseNewsScopeDeptService {
+
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsScopeUserServiceImpl.java b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsScopeUserServiceImpl.java
new file mode 100644
index 0000000..db1521e
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsScopeUserServiceImpl.java
@@ -0,0 +1,20 @@
+package com.ruoyi.collaborativeApproval.service.impl;
+
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeUser;
+import com.ruoyi.collaborativeApproval.mapper.EnterpriseNewsScopeUserMapper;
+import com.ruoyi.collaborativeApproval.service.EnterpriseNewsScopeUserService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 浼佷笟鏂伴椈闃呰鑼冨洿鐢ㄦ埛琛� 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-05-20 11:51:23
+ */
+@Service
+public class EnterpriseNewsScopeUserServiceImpl extends ServiceImpl<EnterpriseNewsScopeUserMapper, EnterpriseNewsScopeUser> implements EnterpriseNewsScopeUserService {
+
+}
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..2cf7fae
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/service/impl/EnterpriseNewsServiceImpl.java
@@ -0,0 +1,378 @@
+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.utils.ApproveProcessConfigNodeUtils;
+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 ApprovalTemplateMapper approvalTemplateMapper;
+ private final ApproveProcessConfigNodeUtils approveProcessConfigNodeUtils;
+ private final ISysNoticeService sysNoticeService;
+
+ @Override
+ public IPage<EnterpriseNewsVo> listPage(Page<EnterpriseNewsVo> page, EnterpriseNewsDto enterpriseNewsDto) {
+ return enterpriseNewsMapper.listPage(page, enterpriseNewsDto);
+ }
+
+ @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);
+ }
+ 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);
+
+ if (STATUS_PENDING.equals(enterpriseNews.getStatus())) {
+ 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 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"));
+ 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 = "/approvalInstance?id=" + instance.getId();
+ sysNoticeService.simpleNoticeByUser(title, message, approverIds, jumpPath);
+ }
+}
diff --git a/src/main/java/com/ruoyi/collaborativeApproval/vo/EnterpriseNewsVo.java b/src/main/java/com/ruoyi/collaborativeApproval/vo/EnterpriseNewsVo.java
new file mode 100644
index 0000000..ef40e65
--- /dev/null
+++ b/src/main/java/com/ruoyi/collaborativeApproval/vo/EnterpriseNewsVo.java
@@ -0,0 +1,10 @@
+package com.ruoyi.collaborativeApproval.vo;
+
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNews;
+import lombok.Data;
+
+@Data
+public class EnterpriseNewsVo extends EnterpriseNews {
+
+ private String createUserName;
+}
diff --git a/src/main/java/com/ruoyi/common/enums/ApprovalStatusEnum.java b/src/main/java/com/ruoyi/common/enums/ApprovalStatusEnum.java
index bece915..8913ebd 100644
--- a/src/main/java/com/ruoyi/common/enums/ApprovalStatusEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/ApprovalStatusEnum.java
@@ -16,6 +16,7 @@
APPROVED(3, "宸查�氳繃"),
REJECTED(4, "宸查┏鍥�");
+
private final Integer value;
private final String label;
diff --git a/src/main/java/com/ruoyi/common/enums/EnterpriseNewsStatusEnum.java b/src/main/java/com/ruoyi/common/enums/EnterpriseNewsStatusEnum.java
new file mode 100644
index 0000000..8e6e480
--- /dev/null
+++ b/src/main/java/com/ruoyi/common/enums/EnterpriseNewsStatusEnum.java
@@ -0,0 +1,143 @@
+package com.ruoyi.common.enums;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+
+/**
+ * 浼佷笟鏂伴椈鐘舵�佹灇涓剧被
+ *
+ * @author ruoyi
+ * @date 2026-05-20
+ */
+@Schema(description = "浼佷笟鏂伴椈鐘舵�佹灇涓�")
+public enum EnterpriseNewsStatusEnum implements BaseEnum<String> {
+
+ /**
+ * 鑽夌
+ */
+ @Schema(description = "鑽夌")
+ DRAFT("DRAFT", "鑽夌"),
+
+ /**
+ * 寰呭鎵�
+ */
+ @Schema(description = "寰呭鎵�")
+ PENDING("PENDING", "寰呭鎵�"),
+
+ /**
+ * 宸插彂甯�
+ */
+ @Schema(description = "宸插彂甯�")
+ PUBLISHED("PUBLISHED", "宸插彂甯�"),
+
+ /**
+ * 椹冲洖
+ */
+ @Schema(description = "椹冲洖")
+ REJECTED("REJECTED", "椹冲洖"),
+
+ /**
+ * 宸蹭笅绾�
+ */
+ @Schema(description = "宸蹭笅绾�")
+ OFFLINE("OFFLINE", "宸蹭笅绾�");
+
+ /**
+ * 鐘舵�佺爜
+ */
+ private final String code;
+
+ /**
+ * 鐘舵�佹弿杩�
+ * -- GETTER --
+ * 鑾峰彇鐘舵�佹弿杩�
+ *
+ * @return 鐘舵�佹弿杩�
+
+ */
+ @Getter
+ private final String description;
+
+ EnterpriseNewsStatusEnum(String code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ /**
+ * 鑾峰彇鐘舵�佺爜
+ *
+ * @return 鐘舵�佺爜
+ */
+ @JsonValue
+ public String getCode() {
+ return code;
+ }
+
+ @Override
+ public String getValue() {
+ return "";
+ }
+
+ /**
+ * 鏍规嵁鐘舵�佺爜鑾峰彇鏋氫妇
+ *
+ * @param code 鐘舵�佺爜
+ * @return 鏋氫妇鍊�
+ */
+ @JsonCreator
+ public static EnterpriseNewsStatusEnum getByCode(String code) {
+ for (EnterpriseNewsStatusEnum status : values()) {
+ if (status.code.equals(code)) {
+ return status;
+ }
+ }
+ throw new IllegalArgumentException("Invalid enterprise news status code: " + code);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓鸿崏绋跨姸鎬�
+ *
+ * @return 鏄惁涓鸿崏绋跨姸鎬�
+ */
+ public boolean isDraft() {
+ return DRAFT.equals(this);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓哄緟瀹℃壒鐘舵��
+ *
+ * @return 鏄惁涓哄緟瀹℃壒鐘舵��
+ */
+ public boolean isPending() {
+ return PENDING.equals(this);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓哄凡鍙戝竷鐘舵��
+ *
+ * @return 鏄惁涓哄凡鍙戝竷鐘舵��
+ */
+ public boolean isPublished() {
+ return PUBLISHED.equals(this);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓洪┏鍥炵姸鎬�
+ *
+ * @return 鏄惁涓洪┏鍥炵姸鎬�
+ */
+ public boolean isRejected() {
+ return REJECTED.equals(this);
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓哄凡涓嬬嚎鐘舵��
+ *
+ * @return 鏄惁涓哄凡涓嬬嚎鐘舵��
+ */
+ public boolean isOffline() {
+ return OFFLINE.equals(this);
+ }
+}
diff --git a/src/main/java/com/ruoyi/project/system/mapper/SysUserDeptMapper.java b/src/main/java/com/ruoyi/project/system/mapper/SysUserDeptMapper.java
index 8c0ca53..f5baaec 100644
--- a/src/main/java/com/ruoyi/project/system/mapper/SysUserDeptMapper.java
+++ b/src/main/java/com/ruoyi/project/system/mapper/SysUserDeptMapper.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.project.system.domain.SysUserDept;
import com.ruoyi.project.system.domain.vo.SysUserDeptVo;
+import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -15,4 +16,28 @@
List<SysUserDeptVo> userLoginFacotryList(@Param("userDeptVo") SysUserDeptVo userDeptVo);
List<Map<String, Object>> setSchemeApplicableStaffUserInfo(@Param("ids") List<Long> ids);
+
+ @Select("<script>" +
+ "select count(distinct sud.user_id) " +
+ "from sys_user_dept sud " +
+ "inner join sys_user su on su.user_id = sud.user_id " +
+ "where su.del_flag = '0' " +
+ "and sud.dept_id in " +
+ "<foreach collection='deptIds' item='deptId' open='(' separator=',' close=')'>" +
+ "#{deptId}" +
+ "</foreach>" +
+ "</script>")
+ Long countDistinctUserIdsByDeptIds(@Param("deptIds") List<Long> deptIds);
+
+ @Select("<script>" +
+ "select distinct sud.user_id " +
+ "from sys_user_dept sud " +
+ "inner join sys_user su on su.user_id = sud.user_id " +
+ "where su.del_flag = '0' " +
+ "and sud.dept_id in " +
+ "<foreach collection='deptIds' item='deptId' open='(' separator=',' close=')'>" +
+ "#{deptId}" +
+ "</foreach>" +
+ "</script>")
+ List<Long> selectDistinctUserIdsByDeptIds(@Param("deptIds") List<Long> deptIds);
}
diff --git a/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java b/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
index dcbcded..fdb610b 100644
--- a/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
+++ b/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
@@ -1,12 +1,14 @@
package com.ruoyi.project.system.service.impl;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.common.utils.SecurityUtils;
-import com.ruoyi.project.system.domain.SysDept;
-import com.ruoyi.project.system.domain.SysNotice;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.collaborativeApproval.mapper.EnterpriseNewsMapper;
+import com.ruoyi.collaborativeApproval.pojo.EnterpriseNews;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.project.system.domain.SysDept;
+import com.ruoyi.project.system.domain.SysNotice;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.domain.SysUserDept;
import com.ruoyi.project.system.mapper.SysDeptMapper;
@@ -15,11 +17,15 @@
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.ISysNoticeService;
import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-import java.util.stream.Collectors;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* 鍏憡 鏈嶅姟灞傚疄鐜�
@@ -28,13 +34,16 @@
*/
@Service
@RequiredArgsConstructor
-public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice> implements ISysNoticeService {
-
- private final SysNoticeMapper noticeMapper;
- private final SysUserMapper userMapper;
- private final SysDeptMapper deptMapper;
- private final SysUserDeptMapper userDeptMapper;
- private final UnipushService unipushService;
+public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice> implements ISysNoticeService {
+
+ private static final Pattern ENTERPRISE_NEWS_ID_PATTERN = Pattern.compile("[?&]id=(\\d+)");
+
+ private final SysNoticeMapper noticeMapper;
+ private final SysUserMapper userMapper;
+ private final SysDeptMapper deptMapper;
+ private final SysUserDeptMapper userDeptMapper;
+ private final UnipushService unipushService;
+ private final EnterpriseNewsMapper enterpriseNewsMapper;
/**
* 鏌ヨ鍏憡淇℃伅
@@ -77,11 +86,26 @@
* @param notice 鍏憡淇℃伅
* @return 缁撴灉
*/
- @Override
- public int updateNotice(SysNotice notice)
- {
- return noticeMapper.updateNotice(notice);
- }
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public int updateNotice(SysNotice notice)
+ {
+ if (notice == null || notice.getNoticeId() == null) {
+ return 0;
+ }
+ SysNotice dbNotice = noticeMapper.selectNoticeById(notice.getNoticeId());
+ if (dbNotice == null) {
+ return 0;
+ }
+ boolean needSyncNewsReadCount = isEnterpriseNewsNotice(dbNotice)
+ && notice.getStatus() != null
+ && !notice.getStatus().equals(dbNotice.getStatus());
+ int rows = noticeMapper.updateNotice(notice);
+ if (rows > 0 && needSyncNewsReadCount) {
+ syncEnterpriseNewsReadCount(dbNotice.getJumpPath());
+ }
+ return rows;
+ }
/**
* 鍒犻櫎鍏憡瀵硅薄
@@ -115,13 +139,20 @@
}
@Override
- public int readAll() {
- Long userId = SecurityUtils.getUserId();
- return noticeMapper.update(null, Wrappers.<SysNotice>lambdaUpdate()
- .eq(SysNotice::getConsigneeId, userId)
- .eq(SysNotice::getStatus, "0")
- .set(SysNotice::getStatus, "1"));
- }
+ public int readAll() {
+ Long userId = SecurityUtils.getUserId();
+ List<SysNotice> unreadNotices = noticeMapper.selectList(Wrappers.<SysNotice>lambdaQuery()
+ .eq(SysNotice::getConsigneeId, userId)
+ .eq(SysNotice::getStatus, "0"));
+ int rows = noticeMapper.update(null, Wrappers.<SysNotice>lambdaUpdate()
+ .eq(SysNotice::getConsigneeId, userId)
+ .eq(SysNotice::getStatus, "0")
+ .set(SysNotice::getStatus, "1"));
+ if (rows > 0) {
+ syncEnterpriseNewsReadCount(unreadNotices);
+ }
+ return rows;
+ }
@Override
public void simpleNoticeByUser(String title, String message, List<Long> consigneeId, String jumpPath) {
@@ -211,18 +242,72 @@
@Override
@Transactional(rollbackFor = Exception.class)
- public boolean appReadNotice(Long noticeId) {
- if (noticeId == null) {
- return false;
+ public boolean appReadNotice(Long noticeId) {
+ if (noticeId == null) {
+ return false;
}
SysNotice sysNotice = noticeMapper.selectNoticeById(noticeId);
if (sysNotice == null) {
return false;
- }
- sysNotice.setStatus("1");
- return noticeMapper.update(null, Wrappers.<SysNotice>lambdaUpdate()
- .eq(SysNotice::getNoticeId, noticeId)
- .eq(SysNotice::getStatus, "0")
- .set(SysNotice::getStatus, "1")) > 0;
- }
-}
+ }
+ sysNotice.setStatus("1");
+ boolean updated = noticeMapper.update(null, Wrappers.<SysNotice>lambdaUpdate()
+ .eq(SysNotice::getNoticeId, noticeId)
+ .eq(SysNotice::getStatus, "0")
+ .set(SysNotice::getStatus, "1")) > 0;
+ if (updated) {
+ syncEnterpriseNewsReadCount(sysNotice.getJumpPath());
+ }
+ return updated;
+ }
+
+ private boolean isEnterpriseNewsNotice(SysNotice sysNotice) {
+ return sysNotice != null
+ && sysNotice.getJumpPath() != null
+ && sysNotice.getJumpPath().startsWith("/enterpriseNews?id=");
+ }
+
+ private void syncEnterpriseNewsReadCount(List<SysNotice> notices) {
+ if (notices == null || notices.isEmpty()) {
+ return;
+ }
+ Set<String> jumpPaths = new HashSet<>();
+ for (SysNotice notice : notices) {
+ if (isEnterpriseNewsNotice(notice)) {
+ jumpPaths.add(notice.getJumpPath());
+ }
+ }
+ for (String jumpPath : jumpPaths) {
+ syncEnterpriseNewsReadCount(jumpPath);
+ }
+ }
+
+ private void syncEnterpriseNewsReadCount(String jumpPath) {
+ Long newsId = parseEnterpriseNewsId(jumpPath);
+ if (newsId == null) {
+ return;
+ }
+ long readCount = noticeMapper.selectCount(Wrappers.<SysNotice>lambdaQuery()
+ .eq(SysNotice::getStatus, "1")
+ .eq(SysNotice::getJumpPath, jumpPath));
+ EnterpriseNews enterpriseNews = new EnterpriseNews();
+ enterpriseNews.setId(newsId);
+ enterpriseNews.setReadCount((int) readCount);
+ enterpriseNewsMapper.updateById(enterpriseNews);
+ }
+
+ private Long parseEnterpriseNewsId(String jumpPath) {
+ if (jumpPath == null || !jumpPath.startsWith("/enterpriseNews")) {
+ return null;
+ }
+ Matcher matcher = ENTERPRISE_NEWS_ID_PATTERN.matcher(jumpPath);
+ if (!matcher.find()) {
+ return null;
+ }
+ try {
+ return Long.parseLong(matcher.group(1));
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
index 548323d..4978d0f 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
@@ -59,6 +59,7 @@
StaffLeave staffLeave = new StaffLeave();
staffLeave.setStaffOnJobId(staffLeaveDto.getStaffOnJobId());
staffLeave.setReason(staffLeaveDto.getReason());
+ staffLeave.setLeaveDate(staffLeaveDto.getLeaveDate());
String reason = staffLeaveDto.getReason();
if (StaffLeaveReasonOther.getCode().equals(reason)){
staffLeave.setRemark(staffLeaveDto.getRemark());
diff --git a/src/main/resources/mapper/approve/ApprovalInstanceMapper.xml b/src/main/resources/mapper/approve/ApprovalInstanceMapper.xml
index 8f45b99..6b47daa 100644
--- a/src/main/resources/mapper/approve/ApprovalInstanceMapper.xml
+++ b/src/main/resources/mapper/approve/ApprovalInstanceMapper.xml
@@ -24,16 +24,28 @@
<result column="deleted" property="deleted" />
</resultMap>
<select id="listPage" resultType="com.ruoyi.approve.bean.vo.ApprovalInstanceVo">
- select ai.*,su.nick_name as create_user_name from
+ select ai.*,su.nick_name as create_user_name from
approval_instance ai
left join sys_user su on ai.create_user = su.user_id
<where>
deleted = 0
<if test="ew.instanceNo != null">
- and instance_no like concat('%',#{ew.instanceNo},'%')
+ and ai.instance_no like concat('%',#{ew.instanceNo},'%')
</if>
<if test="ew.templateName != null">
- and template_name like concat('%',#{ew.templateName},'%')
+ and ai.template_name like concat('%',#{ew.templateName},'%')
+ </if>
+ <if test="ew.templateId != null ">
+ and ai. template_id = #{ew.templateId}
+ </if>
+ <if test="ew.businessType != null ">
+ and ai. business_type = #{ew.businessType}
+ </if>
+ <if test="ew.createTime != null">
+ and ai.create_time between to_date(#{ew.createTimeStart}) and to_date(#{ew.createTimeEnd})
+ </if>
+ <if test="ew.status != null">
+ and ai.status = #{ew.status}
</if>
</where>
order by ai.id desc
diff --git a/src/main/resources/mapper/collaborativeApproval/EnterpriseNewsMapper.xml b/src/main/resources/mapper/collaborativeApproval/EnterpriseNewsMapper.xml
new file mode 100644
index 0000000..fa45ea6
--- /dev/null
+++ b/src/main/resources/mapper/collaborativeApproval/EnterpriseNewsMapper.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.collaborativeApproval.mapper.EnterpriseNewsMapper">
+
+ <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+ <resultMap id="BaseResultMap" type="com.ruoyi.collaborativeApproval.pojo.EnterpriseNews">
+ <id column="id" property="id" />
+ <result column="title" property="title" />
+ <result column="summary" property="summary" />
+ <result column="content" property="content" />
+ <result column="category" property="category" />
+ <result column="read_scope" property="readScope" />
+ <result column="is_required" property="isRequired" />
+ <result column="status" property="status" />
+ <result column="required_read_count" property="requiredReadCount" />
+ <result column="read_count" property="readCount" />
+ <result column="create_user" property="createUser" />
+ <result column="create_time" property="createTime" />
+ <result column="update_user" property="updateUser" />
+ <result column="update_time" property="updateTime" />
+ <result column="dept_id" property="deptId" />
+ </resultMap>
+ <select id="listPage" resultType="com.ruoyi.collaborativeApproval.vo.EnterpriseNewsVo">
+ select en.*, u.nick_name as create_user_name from
+ enterprise_news en
+ left join sys_user u on en.create_user = u.user_id
+ <where>
+ <if test="enterpriseNewsDto.title != null and enterpriseNewsDto.title != ''">
+ and en.title like concat('%',#{enterpriseNewsDto.title},'%')
+ </if>
+ <if test="enterpriseNewsDto.category != null and enterpriseNewsDto.category != ''">
+ and en.category = #{enterpriseNewsDto.category}
+ </if>
+ <if test="enterpriseNewsDto.status != null ">
+ and en.status = #{enterpriseNewsDto.status}
+ </if>
+ <if test="enterpriseNewsDto.createUser != null and enterpriseNewsDto.createUser != ''">
+ and en.create_user = #{enterpriseNewsDto.createUser}
+ </if>
+ <if test="enterpriseNewsDto.createTimeStart != null and enterpriseNewsDto.createTimeEnd != null">
+ and en.create_time between #{enterpriseNewsDto.createTimeStart} and #{enterpriseNewsDto.createTimeEnd}
+ </if>
+ </where>
+ </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/collaborativeApproval/EnterpriseNewsScopeDeptMapper.xml b/src/main/resources/mapper/collaborativeApproval/EnterpriseNewsScopeDeptMapper.xml
new file mode 100644
index 0000000..0b13f67
--- /dev/null
+++ b/src/main/resources/mapper/collaborativeApproval/EnterpriseNewsScopeDeptMapper.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.collaborativeApproval.mapper.EnterpriseNewsScopeDeptMapper">
+
+ <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+ <resultMap id="BaseResultMap" type="com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeDept">
+ <id column="id" property="id" />
+ <result column="news_id" property="newsId" />
+ <result column="dept_id" property="deptId" />
+ <result column="create_time" property="createTime" />
+ </resultMap>
+
+</mapper>
diff --git a/src/main/resources/mapper/collaborativeApproval/EnterpriseNewsScopeUserMapper.xml b/src/main/resources/mapper/collaborativeApproval/EnterpriseNewsScopeUserMapper.xml
new file mode 100644
index 0000000..7f4ac4b
--- /dev/null
+++ b/src/main/resources/mapper/collaborativeApproval/EnterpriseNewsScopeUserMapper.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.collaborativeApproval.mapper.EnterpriseNewsScopeUserMapper">
+
+ <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+ <resultMap id="BaseResultMap" type="com.ruoyi.collaborativeApproval.pojo.EnterpriseNewsScopeUser">
+ <id column="id" property="id" />
+ <result column="news_id" property="newsId" />
+ <result column="user_id" property="userId" />
+ <result column="create_time" property="createTime" />
+ </resultMap>
+
+</mapper>
diff --git a/src/main/resources/mapper/staff/StaffLeaveMapper.xml b/src/main/resources/mapper/staff/StaffLeaveMapper.xml
index 4637ff0..8bc9607 100644
--- a/src/main/resources/mapper/staff/StaffLeaveMapper.xml
+++ b/src/main/resources/mapper/staff/StaffLeaveMapper.xml
@@ -18,15 +18,20 @@
soj.emergency_contact as emergencyContact,
soj.emergency_contact_phone as emergencyContactPhone,
sp.post_name as postName,
- sd.dept_name as deptName
+ sd.dept_name as deptName,
+ se.education as first_study,
+ se.major as profession
FROM staff_leave
- LEFT JOIN
- staff_on_job soj ON soj.id = staff_leave.staff_on_job_id
- LEFT JOIN
- sys_post sp ON sp.post_id = soj.sys_post_id
- LEFT JOIN
- sys_dept sd ON sd.dept_id = soj.sys_dept_id
- where 1=1
+ LEFT JOIN staff_on_job soj ON soj.id = staff_leave.staff_on_job_id
+ LEFT JOIN sys_post sp ON sp.post_id = soj.sys_post_id
+ LEFT JOIN sys_dept sd ON sd.dept_id = soj.sys_dept_id
+ LEFT JOIN staff_education se ON se.staff_on_job_id = staff_leave.staff_on_job_id
+ AND se.id = (
+ SELECT MAX(se2.id)
+ FROM staff_education se2
+ WHERE se2.staff_on_job_id = staff_leave.staff_on_job_id
+ )
+ WHERE 1=1
<if test="c.staffName != null and c.staffName != '' ">
AND soj.staff_name LIKE CONCAT('%',#{c.staffName},'%')
</if>
diff --git a/src/main/resources/mapper/system/SysNoticeMapper.xml b/src/main/resources/mapper/system/SysNoticeMapper.xml
index 3dd5735..14372d8 100644
--- a/src/main/resources/mapper/system/SysNoticeMapper.xml
+++ b/src/main/resources/mapper/system/SysNoticeMapper.xml
@@ -10,11 +10,16 @@
<result property="noticeType" column="notice_type" />
<result property="noticeContent" column="notice_content" />
<result property="status" column="status" />
+ <result property="senderId" column="sender_id" />
+ <result property="consigneeId" column="consignee_id" />
+ <result property="jumpPath" column="jump_path" />
+ <result property="appJumpPath" column="app_jump_path" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
+ <result property="tenantId" column="tenant_id" />
</resultMap>
<sql id="selectNoticeVo">
--
Gitblit v1.9.3