瀏覽代碼

通知公告新增阅读用户列表

RuoYi 2 月之前
父節點
當前提交
0728a04b1b

+ 13 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java

@@ -53,7 +53,6 @@ public class SysNoticeController extends BaseController
     /**
      * 根据通知公告编号获取详细信息
      */
-    @PreAuthorize("@ss.hasPermi('system:notice:query')")
     @GetMapping(value = "/{noticeId}")
     public AjaxResult getInfo(@PathVariable Long noticeId)
     {
@@ -125,6 +124,19 @@ public class SysNoticeController extends BaseController
     }
 
     /**
+     * 已读用户列表数据
+     */
+    @PreAuthorize("@ss.hasPermi('system:notice:list')")
+    @PostMapping("/readUsers/list")
+    @ResponseBody
+    public TableDataInfo readUsersList(Long noticeId, String searchValue)
+    {
+        startPage();
+        List<?> list = noticeReadService.selectReadUsersByNoticeId(noticeId, searchValue);
+        return getDataTable(list);
+    }
+
+    /**
      * 删除通知公告
      */
     @PreAuthorize("@ss.hasPermi('system:notice:remove')")

+ 11 - 1
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeReadMapper.java

@@ -1,9 +1,10 @@
 package com.ruoyi.system.mapper;
 
 import java.util.List;
+import java.util.Map;
 import org.apache.ibatis.annotations.Param;
-import com.ruoyi.system.domain.SysNoticeRead;
 import com.ruoyi.system.domain.SysNotice;
+import com.ruoyi.system.domain.SysNoticeRead;
 
 /**
  * 公告已读记录 数据层
@@ -56,6 +57,15 @@ public interface SysNoticeReadMapper
     public List<SysNotice> selectNoticeListWithReadStatus(@Param("userId") Long userId, @Param("limit") int limit);
 
     /**
+     * 查询已阅读某公告的用户列表
+     *
+     * @param noticeId 公告ID
+     * @param searchValue 搜索值
+     * @return 已读用户列表
+     */
+    public List<Map<String, Object>> selectReadUsersByNoticeId(@Param("noticeId") Long noticeId, @Param("searchValue") String searchValue);
+
+    /**
      * 公告删除时清理对应已读记录
      *
      * @param noticeIds 公告ID数组

+ 10 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeReadService.java

@@ -1,6 +1,7 @@
 package com.ruoyi.system.service;
 
 import java.util.List;
+import java.util.Map;
 import com.ruoyi.system.domain.SysNotice;
 
 /**
@@ -44,6 +45,15 @@ public interface ISysNoticeReadService
     public void markReadBatch(Long userId, Long[] noticeIds);
 
     /**
+     * 查询已阅读某公告的用户列表
+     *
+     * @param noticeId  公告ID
+     * @param searchValue 搜索值
+     * @return 已读用户列表
+     */
+    public List<Map<String, Object>> selectReadUsersByNoticeId(Long noticeId, String searchValue);
+
+    /**
      * 删除公告时清理对应已读记录
      *
      * @param noticeIds 公告ID数组

+ 1 - 1
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java

@@ -49,7 +49,7 @@ public interface ISysNoticeService
      * @return 结果
      */
     public int deleteNoticeById(Long noticeId);
-    
+
     /**
      * 批量删除公告信息
      * 

+ 11 - 1
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeReadServiceImpl.java

@@ -1,10 +1,11 @@
 package com.ruoyi.system.service.impl;
 
 import java.util.List;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import com.ruoyi.system.domain.SysNoticeRead;
 import com.ruoyi.system.domain.SysNotice;
+import com.ruoyi.system.domain.SysNoticeRead;
 import com.ruoyi.system.mapper.SysNoticeReadMapper;
 import com.ruoyi.system.service.ISysNoticeReadService;
 
@@ -63,6 +64,15 @@ public class SysNoticeReadServiceImpl implements ISysNoticeReadService
     }
 
     /**
+     * 查询已阅读某公告的用户列表
+     */
+    @Override
+    public List<Map<String, Object>> selectReadUsersByNoticeId(Long noticeId, String searchValue)
+    {
+        return noticeReadMapper.selectReadUsersByNoticeId(noticeId, searchValue);
+    }
+
+    /**
      * 删除公告时清理对应已读记录
      */
     @Override

+ 22 - 0
ruoyi-system/src/main/resources/mapper/system/SysNoticeReadMapper.xml

@@ -63,4 +63,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </foreach>
     </delete>
 
+    <!-- 查询已阅读某公告的用户列表,支持按登录名/用户名模糊筛选 -->
+    <select id="selectReadUsersByNoticeId" resultType="java.util.Map">
+        select
+            u.user_id      as userId,
+            u.user_name    as userName,
+            u.nick_name    as nickName,
+            d.dept_name    as deptName,
+            u.phonenumber  as phonenumber,
+            r.read_time    as readTime
+        from sys_notice_read r
+        inner join sys_user u on u.user_id = r.user_id and u.del_flag = '0'
+        left join sys_dept d on d.dept_id = u.dept_id
+        where r.notice_id = #{noticeId}
+        <if test="searchValue != null and searchValue != ''">
+            and (
+                u.user_name like concat('%', #{searchValue}, '%')
+                or u.nick_name like concat('%', #{searchValue}, '%')
+            )
+        </if>
+        order by r.read_time desc
+    </select>
+
 </mapper>

+ 9 - 0
ruoyi-ui/src/api/system/notice.js

@@ -68,3 +68,12 @@ export function markNoticeReadAll(ids) {
     params: { ids }
   })
 }
+
+// 查询公告已读用户列表
+export function listNoticeReadUsers(query) {
+  return request({
+    url: '/system/notice/readUsers/list',
+    method: 'post',
+    params: query
+  })
+}

+ 109 - 0
ruoyi-ui/src/views/system/notice/ReadUsers.vue

@@ -0,0 +1,109 @@
+<template>
+  <el-dialog :title="`「${noticeTitle}」已读用户`" :visible.sync="visible" width="760px" top="6vh" append-to-body @close="handleClose">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" style="margin-bottom: 4px;">
+      <el-form-item prop="searchValue">
+        <el-input
+          v-model="queryParams.searchValue"
+          placeholder="登录名称 / 用户名称"
+          clearable
+          prefix-icon="el-icon-search"
+          style="width: 220px;"
+          @keyup.enter.native="handleQuery"
+          @clear="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+      <el-form-item style="float: right; margin-right: 0;">
+        <span class="read-stat">
+          共 <strong>{{ total }}</strong> 人已读
+        </span>
+      </el-form-item>
+    </el-form>
+    <el-table v-loading="loading" :data="userList" size="small" stripe height="340px">
+      <el-table-column type="index" label="序号" width="55" align="center" />
+      <el-table-column label="登录名称" prop="userName" align="center" :show-overflow-tooltip="true" />
+      <el-table-column label="用户名称" prop="nickName" align="center" :show-overflow-tooltip="true" />
+      <el-table-column label="所属部门" prop="deptName" align="center" :show-overflow-tooltip="true" />
+      <el-table-column label="手机号码" prop="phonenumber" align="center" width="120" />
+      <el-table-column label="阅读时间" prop="readTime" align="center" width="160">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.readTime) }}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" style="padding: 6px 0px;"/>
+  </el-dialog>
+</template>
+
+<script>
+import { listNoticeReadUsers } from "@/api/system/notice"
+
+export default {
+  name: "ReadUsers",
+  data() {
+    return {
+      visible: false,
+      loading: false,
+      noticeId: undefined,
+      noticeTitle: "",
+      total: 0,
+      userList: [],
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        noticeId: undefined,
+        searchValue: undefined
+      }
+    }
+  },
+  methods: {
+    open(row) {
+      this.noticeId = row.noticeId
+      this.noticeTitle = row.noticeTitle
+      this.queryParams.noticeId = row.noticeId
+      this.queryParams.searchValue = undefined
+      this.queryParams.pageNum = 1
+      this.visible = true
+      this.getList()
+    },
+    getList() {
+      this.loading = true
+      listNoticeReadUsers(this.queryParams).then(res => {
+        this.userList = res.rows
+        this.total = res.total
+      }).finally(() => {
+        this.loading = false
+      })
+    },
+    handleQuery() {
+      this.queryParams.pageNum = 1
+      this.getList()
+    },
+    resetQuery() {
+      this.resetForm("queryForm")
+      this.handleQuery()
+    },
+    handleClose() {
+      this.userList = []
+      this.total = 0
+      this.queryParams.searchValue = undefined
+    }
+  }
+}
+</script>
+
+<style scoped>
+.read-stat {
+  font-size: 13px;
+  color: #606266;
+  line-height: 28px;
+}
+.read-stat strong {
+  color: #409eff;
+  font-size: 15px;
+  margin: 0 2px;
+}
+</style>

+ 14 - 1
ruoyi-ui/src/views/system/notice/index.vue

@@ -98,6 +98,13 @@
           <el-button
             size="mini"
             type="text"
+            icon="el-icon-user"
+            @click="handleReadUsers(scope.row)"
+            v-hasPermi="['system:notice:list']"
+          >阅读用户</el-button>
+          <el-button
+            size="mini"
+            type="text"
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
             v-hasPermi="['system:notice:edit']"
@@ -167,16 +174,18 @@
     </el-dialog>
 
     <notice-detail-view ref="noticeViewRef" />
+    <read-users-dialog ref="readUsersRef" />
   </div>
 </template>
 
 <script>
 import NoticeDetailView from "@/layout/components/HeaderNotice/DetailView"
+import ReadUsersDialog from "./ReadUsers"
 import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api/system/notice"
 
 export default {
   name: "Notice",
-  components: { NoticeDetailView },
+  components: { NoticeDetailView, ReadUsersDialog },
   dicts: ['sys_notice_status', 'sys_notice_type'],
   data() {
     return {
@@ -304,6 +313,10 @@ export default {
     handleViewData(row) {
       this.$refs.noticeViewRef.open(row)
     },
+    /** 查看已读用户 */
+    handleReadUsers(row) {
+      this.$refs.readUsersRef.open(row)
+    },
     /** 删除按钮操作 */
     handleDelete(row) {
       const noticeIds = row.noticeId || this.ids