Преглед на файлове

feat(message): 添加消息管理功能并移除测评权限检查

- 添加了消息管理相关实体类MainMessage
- 创建了消息管理业务接口IMainMessageService及实现
- 实现了消息的增删改查、标记已读等功能
- 在小程序端添加了消息管理控制器MainMessageController
- 集成了公司名称查询功能
- 移除了测评评价相关的权限注解检查
- 为测评评价VO类添加了翻译注解支持职位类型显示
西格玛许 преди 1 седмица
родител
ревизия
154f20b162

+ 17 - 17
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/controller/MainExamEvaluationController.java

@@ -42,32 +42,32 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 查询测评列表
      */
-    @SaCheckPermission("main:examEvaluation:list")
+//    @SaCheckPermission("main:examEvaluation:list")
     @GetMapping("/list")
     public TableDataInfo<MainExamEvaluationVo> list(MainExamEvaluationBo bo, PageQuery pageQuery) {
         return examEvaluationService.queryPageList(bo, pageQuery);
     }
 
-    @SaCheckPermission("main:examEvaluation:list")
+//    @SaCheckPermission("main:examEvaluation:list")
     @GetMapping("/stats/participant")
     public R<Map<Long, Map<String, Long>>> participantStats(@RequestParam("ids") Collection<Long> ids) {
         return R.ok(examEvaluationService.getParticipantStats(ids));
     }
 
-    @SaCheckPermission("main:examEvaluation:list")
+//    @SaCheckPermission("main:examEvaluation:list")
     @GetMapping("/sync/employeeOptions")
     public R<List<MainExamSyncEmployeeOptionVo>> syncEmployeeOptions() {
         return R.ok(examEvaluationService.getSyncEmployeeOptions());
     }
 
-    @SaCheckPermission("main:examEvaluation:sync")
+//    @SaCheckPermission("main:examEvaluation:sync")
     @Log(title = "同步至员工", businessType = BusinessType.UPDATE)
     @PostMapping("/sync/employees")
     public R<Void> syncToEmployees(@Validated @RequestBody MainExamEvaluationSyncBo bo) {
         return toAjax(examEvaluationService.syncToEmployees(bo));
     }
 
-    @SaCheckPermission("main:examEvaluation:list")
+//    @SaCheckPermission("main:examEvaluation:list")
     @GetMapping("/applyList")
     public TableDataInfo<MainExamApplyListVo> applyList(@RequestParam("evaluationId") Long evaluationId,
                                                         @RequestParam(value = "keyword", required = false) String keyword,
@@ -75,7 +75,7 @@ public class MainExamEvaluationController extends BaseController {
         return examEvaluationService.getApplyList(evaluationId, keyword, pageQuery);
     }
 
-    @SaCheckPermission("main:examEvaluation:edit")
+//    @SaCheckPermission("main:examEvaluation:edit")
     @Log(title = "移除测评报名", businessType = BusinessType.DELETE)
     @DeleteMapping("/apply/{applyId}")
     public R<Void> removeApply(@PathVariable("applyId") Long applyId) {
@@ -85,7 +85,7 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 获取测评详细信息
      */
-    @SaCheckPermission("main:examEvaluation:query")
+//    @SaCheckPermission("main:examEvaluation:query")
     @GetMapping("/{id}")
     public R<MainExamEvaluationVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
         return R.ok(examEvaluationService.queryById(id));
@@ -94,7 +94,7 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 新增测评
      */
-    @SaCheckPermission("main:examEvaluation:add")
+//    @SaCheckPermission("main:examEvaluation:add")
     @Log(title = "测评管理", businessType = BusinessType.INSERT)
     @PostMapping()
     public R<Void> add(@Validated(AddGroup.class) @RequestBody MainExamEvaluationBo bo) {
@@ -104,7 +104,7 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 修改测评
      */
-    @SaCheckPermission("main:examEvaluation:edit")
+//    @SaCheckPermission("main:examEvaluation:edit")
     @Log(title = "测评管理", businessType = BusinessType.UPDATE)
     @PutMapping()
     public R<Void> edit(@Validated(EditGroup.class) @RequestBody MainExamEvaluationBo bo) {
@@ -114,7 +114,7 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 删除测评
      */
-    @SaCheckPermission("main:examEvaluation:remove")
+//    @SaCheckPermission("main:examEvaluation:remove")
     @Log(title = "测评管理", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ids}")
     public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
@@ -124,7 +124,7 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 批量更新状态
      */
-    @SaCheckPermission("main:examEvaluation:edit")
+//    @SaCheckPermission("main:examEvaluation:edit")
     @Log(title = "测评管理", businessType = BusinessType.UPDATE)
     @PutMapping("/updateStatus")
     public R<Void> updateStatus(@RequestBody List<Long> ids, @RequestParam String status) {
@@ -134,7 +134,7 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 单个更新状态
      */
-    @SaCheckPermission("main:examEvaluation:edit")
+//    @SaCheckPermission("main:examEvaluation:edit")
     @Log(title = "测评管理", businessType = BusinessType.UPDATE)
     @PutMapping("/status/{id}/{status}")
     public R<Void> updateSingleStatus(@NotNull(message = "主键不能为空") @PathVariable Long id,
@@ -145,7 +145,7 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 同步第三方数据
      */
-    @SaCheckPermission("main:examEvaluation:sync")
+//    @SaCheckPermission("main:examEvaluation:sync")
     @Log(title = "测评管理", businessType = BusinessType.OTHER)
     @PostMapping("/sync")
     public R<Void> syncThirdPartyData() {
@@ -154,7 +154,7 @@ public class MainExamEvaluationController extends BaseController {
 
 
 
-    @SaCheckPermission("main:evaluation:list")
+//    @SaCheckPermission("main:evaluation:list")
     @ResponseBody
     @PostMapping("/exam-list")
     @Log(title = "获取第三方考试列表", businessType = BusinessType.OTHER)
@@ -191,7 +191,7 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 获取试卷试题列表 (603)
      */
-    @SaCheckPermission("main:evaluation:list")
+//    @SaCheckPermission("main:evaluation:list")
     @PostMapping("/paper-questions")
     public R<String> getPaperQuestions(@RequestBody Map<String, Object> params) {
         KaoshixingRequest request = new KaoshixingRequest();
@@ -202,7 +202,7 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 获取考生答案列表 (604)
      */
-    @SaCheckPermission("main:evaluation:list")
+//    @SaCheckPermission("main:evaluation:list")
     @PostMapping("/answer-list")
     public R<String> getAnswerList(@RequestBody Map<String, Object> params) {
         KaoshixingAnswerListRequest request = new KaoshixingAnswerListRequest();
@@ -213,7 +213,7 @@ public class MainExamEvaluationController extends BaseController {
     /**
      * 获取在线学习内容列表 (605)
      */
-    @SaCheckPermission("main:evaluation:list")
+//    @SaCheckPermission("main:evaluation:list")
     @PostMapping("/learning-contents")
     public R<String> getLearningContents(@RequestBody Map<String, Object> params) {
         KaoshixingExamListRequest request = new KaoshixingExamListRequest();

+ 78 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/controller/miniapp/MainMessageController.java

@@ -0,0 +1,78 @@
+package org.dromara.main.controller.miniapp;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.main.domain.bo.MainMessageBo;
+import org.dromara.main.domain.vo.MainMessageVo;
+import org.dromara.main.service.IMainMessageService;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author chenYing
+ * @date 2026-04-03 14:19:19
+ **/
+
+@RestController
+@RequestMapping("/miniapp/message")
+@RequiredArgsConstructor
+public class MainMessageController extends BaseController {
+    private final IMainMessageService service;
+
+    @GetMapping("/list")
+    public R<List<MainMessageVo>> list(MainMessageBo bo){
+        return R.ok(service.queryList(bo));
+    }
+
+    @GetMapping("/{id}")
+    public R<MainMessageVo> getInfo(@PathVariable Long id){
+        return R.ok(service.queryById(id));
+    }
+
+    @PostMapping("/add")
+    public R<Boolean> add(MainMessageBo bo){
+        return R.ok(service.insertByBo(bo));
+    }
+
+    @PutMapping("/edit")
+    public R<Boolean> edit(MainMessageBo bo){
+        return R.ok(service.updateByBo(bo));
+    }
+
+    @DeleteMapping("/{ids}")
+    public R<Boolean> remove(@PathVariable Long[] ids){
+        return R.ok(service.deleteWithValidByIds(List.of(ids), true));
+    }
+
+
+    // 1. 获取未读消息数量
+    @GetMapping("/unread-count")
+    public R<Long> getUnreadCount() {
+        MainMessageBo bo = new MainMessageBo();
+        bo.setStudentId(LoginHelper.getUserId()); // 【修复】设置当前用户ID
+        bo.setIsRead(0);
+        return R.ok(service.selectCount(bo));
+    }
+    @PostMapping("/read-all")
+    public R<Boolean> readAll() {
+        // 【修复】使用 LoginHelper.getUserId()
+        return R.ok(service.markAllAsRead(LoginHelper.getUserId()));
+    }
+
+
+    @PutMapping("/read/{id}")
+    public R<Boolean> read(@PathVariable Long id) {
+        return R.ok(service.markRead(id));
+    }
+
+
+}

+ 34 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/domain/MainMessage.java

@@ -0,0 +1,34 @@
+package org.dromara.main.domain;
+
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+/**
+ * @author chenYing
+ * @date 2026-04-03 13:57:26
+ **/
+
+
+@Data
+@TableName("main_message")
+public class MainMessage extends BaseEntity {
+    private Long id;
+
+    private Long studentId;
+
+    private String title;
+
+    private String content;
+
+    private String positionId;
+
+    private Integer isRead;
+
+
+    @TableLogic
+    private String delFlag;
+
+
+}

+ 23 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/domain/bo/MainMessageBo.java

@@ -0,0 +1,23 @@
+package org.dromara.main.domain.bo;
+
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.main.domain.MainMessage;
+
+/**
+ * @author chenYing
+ * @date 2026-04-03 14:03:21
+ **/
+@Data
+@AutoMapper(target = MainMessage.class)
+public class MainMessageBo {
+    private Long id;
+    private Long studentId;
+    private String content;
+    private String title;
+
+    private Long positionId;
+
+    private Integer isRead;
+
+}

+ 7 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/domain/vo/MainExamEvaluationVo.java

@@ -8,6 +8,8 @@ import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 import org.dromara.common.excel.annotation.ExcelDictFormat;
 import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
 import org.dromara.main.domain.MainAbilityConfig;
 import org.dromara.main.domain.MainExamEvaluation;
 
@@ -89,6 +91,11 @@ public class MainExamEvaluationVo implements Serializable {
     @TableLogic
     private String delFlag;
 
+    @Translation(type= TransConstant.DICT_TYPE_TO_LABEL,mapper="positionType",other="main_position_type")
+    private String positionTypeLabel;
+
+    @Translation(type= TransConstant.DICT_TYPE_TO_LABEL,mapper="grade",other="main_position_level")
+    private String gradeLabel;
     /**
      * 能力配置列表
      */

+ 27 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/domain/vo/MainMessageVo.java

@@ -0,0 +1,27 @@
+package org.dromara.main.domain.vo;
+
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.main.domain.MainMessage;
+
+/**
+ * @author chenYing
+ * @date 2026-04-03 14:01:35
+ **/
+
+@Data
+@AutoMapper(target = MainMessage.class)
+public class MainMessageVo {
+    private Long id;
+    private Long studentId;
+    private String content;
+    private String title;
+
+    private Long positionId;
+
+    private Integer isRead;
+
+    private String positionName;
+    private String companyName;
+
+}

+ 13 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/mapper/MainMessageMapper.java

@@ -0,0 +1,13 @@
+package org.dromara.main.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.main.domain.MainMessage;
+import org.dromara.main.domain.vo.MainMessageVo;
+
+/**
+ * @author chenYing
+ * @date 2026-04-03 14:03:46
+ **/
+public interface MainMessageMapper extends BaseMapperPlus<MainMessage, MainMessageVo> {
+
+}

+ 37 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/service/IMainMessageService.java

@@ -0,0 +1,37 @@
+package org.dromara.main.service;
+
+import com.sun.tools.javac.Main;
+import org.dromara.main.domain.MainMessage;
+import org.dromara.main.domain.bo.MainMessageBo;
+import org.dromara.main.domain.vo.MainMessageVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author chenYing
+ * @date 2026-04-03 14:04:42
+ **/
+public interface IMainMessageService {
+    List<MainMessageVo> queryList(MainMessageBo bo);
+
+    MainMessageVo queryById(Long id);
+
+    Boolean updateByBo(MainMessageBo bo);
+
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    Boolean insertByBo(MainMessageBo bo);
+
+    // 获取满足条件的记录数(用于未读数统计)
+    Long selectCount(MainMessageBo bo);
+
+    // 将该学生的所有消息标为已读
+    Boolean markAllAsRead(Long studentId);
+
+    Boolean markRead(Long id);
+
+
+
+
+}

+ 121 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/service/impl/MainMessageServiceImpl.java

@@ -0,0 +1,121 @@
+package org.dromara.main.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.main.domain.MainMessage;
+import org.dromara.main.domain.MainPosition;
+import org.dromara.main.domain.bo.MainMessageBo;
+import org.dromara.main.domain.vo.MainMessageVo;
+import org.dromara.main.domain.vo.MainPositionVo;
+import org.dromara.main.mapper.MainMessageMapper;
+import org.dromara.main.mapper.MainPositionMapper;
+import org.dromara.main.service.IMainMessageService;
+import org.dromara.system.domain.SysTenant;
+import org.dromara.system.domain.vo.SysTenantVo;
+import org.dromara.system.mapper.SysTenantMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+
+import static io.smallrye.common.function.FunctionsLogging.log;
+
+/**
+ * @author chenYing
+ * @date 2026-04-03 14:07:16
+ **/
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+
+public class MainMessageServiceImpl implements IMainMessageService {
+
+    private final MainMessageMapper baseMapper;
+    private final MainPositionMapper positionMapper;
+    private final SysTenantMapper tenantMapper;
+
+    @Override
+    public List<MainMessageVo> queryList(MainMessageBo bo) {
+        LambdaQueryWrapper<MainMessage> lqw = new LambdaQueryWrapper<>();
+        // 基础过滤:学生ID
+        lqw.eq(bo.getStudentId() != null, MainMessage::getStudentId, bo.getStudentId());
+        // 【修复】增加对已读/未读状态的过滤支持
+        lqw.eq(bo.getIsRead() != null, MainMessage::getIsRead, bo.getIsRead());
+        // 按时间倒序
+        lqw.orderByDesc(MainMessage::getCreateTime);
+        List<MainMessageVo> message=baseMapper.selectVoList(lqw);
+
+        for (MainMessageVo mainMessageVo : message) {
+            if (mainMessageVo.getPositionId() != null) {
+                MainPositionVo position = positionMapper.selectVoById(mainMessageVo.getPositionId());
+                if (position != null && position.getTenantId() != null) {
+                    SysTenant tenant = tenantMapper.selectOne(new LambdaQueryWrapper<SysTenant>()
+                            .eq(SysTenant::getTenantId, position.getTenantId()));
+                    if (tenant != null) {
+                        mainMessageVo.setCompanyName(tenant.getCompanyName());
+                    }
+                }
+            }
+        }
+        return message;
+    }
+
+
+    @Override
+    public MainMessageVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    @Override
+    public Boolean updateByBo(MainMessageBo bo) {
+        MainMessage message=BeanUtil.toBean(bo,MainMessage.class);
+        return baseMapper.updateById(message)>0;
+    }
+
+    @Override
+    public Boolean insertByBo(MainMessageBo bo){
+        MainMessage message=BeanUtil.toBean(bo,MainMessage.class);
+        return baseMapper.insert(message)>0;
+    }
+
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        return baseMapper.deleteBatchIds(ids)>0;
+    }
+
+    @Override
+    public Long selectCount(MainMessageBo bo) {
+        LambdaQueryWrapper<MainMessage> lqw = new LambdaQueryWrapper<>();
+        lqw.eq(bo.getStudentId() != null, MainMessage::getStudentId, bo.getStudentId());
+        lqw.eq(bo.getIsRead() != null, MainMessage::getIsRead, bo.getIsRead());
+        return baseMapper.selectCount(lqw);
+    }
+    @Override
+    public Boolean markAllAsRead(Long studentId) {
+        // 将该学生所有 isRead=0 的记录改为 1
+        return baseMapper.update(null,
+            new LambdaUpdateWrapper<MainMessage>()
+                .eq(MainMessage::getStudentId, studentId)
+                .eq(MainMessage::getIsRead, 0)
+                .set(MainMessage::getIsRead, 1)
+        ) > 0;
+    }
+
+    @Override
+    public Boolean markRead(Long id) {
+        return baseMapper.update(null,
+            new LambdaUpdateWrapper<MainMessage>()
+                .eq(MainMessage::getId, id)
+                .set(MainMessage::getIsRead, 1)
+        ) > 0;
+    }
+
+
+}