iZaiZaiA 2 år sedan
förälder
incheckning
63ba1878f4

+ 36 - 0
src/api/modules/tasks/message.js

@@ -0,0 +1,36 @@
+import {httpApi} from "../../request/httpApi";
+
+export default {
+    //分页数据
+    async getPageData(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/messageWarning/list',
+            method: 'get',
+            params: form
+        }, msg)
+    },
+    //删除消息
+    async removeData(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/messageWarning/remove',
+            method: 'post',
+            params: form
+        }, msg)
+    },
+    //获取当前用户的消息数量
+    async queryCurrentUserMessageCount(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/messageWarning/queryCurrentUserMessageCount',
+            method: 'get',
+            params: form
+        }, msg)
+    },
+    //标记已读
+    async setMessageWarningRead(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/messageWarning/setMessageWarningRead',
+            method: 'post',
+            params: form
+        }, msg)
+    },
+}

+ 2 - 3
src/layout/modules/MenuItem.vue

@@ -3,9 +3,8 @@
         <el-sub-menu :index="item?.code" :popper-offset="0" :popper-class="'aside-menu-popper ' + curKey" v-if="item?.children && item?.children.length > 0">
             <template #title>
                 <div class="hc-aside-menu-item">
-                    <!-- v-if="item?.source"-->
                     <div class="menu---item">
-                        <HcIcon name="home-3" :fill="curKey === item?.code" class="hc-menu-icon"/>
+                        <HcIcon :name="item?.source" :fill="curKey === item?.code" class="hc-menu-icon" v-if="item?.source"/>
                         <div class="name truncate" v-if="isCollapse">{{ item?.name.substring(0,2) }}</div>
                         <div class="name truncate" v-else>{{ item?.name }}</div>
                         <el-badge :value="20" v-if="item?.code === 'tasks'"/>
@@ -18,7 +17,7 @@
         <el-menu-item :index="item?.code" v-else @click="MenuClick(item)">
             <div class="hc-aside-menu-item">
                 <div class="menu---item">
-                    <HcIcon name="home-3" :fill="curKey === item?.key" class="hc-menu-icon" v-if="item?.icon"/>
+                    <HcIcon :name="item?.source" :fill="curKey === item?.key" class="hc-menu-icon" v-if="item?.source"/>
                     <div class="name truncate" v-if="isCollapse">{{ item?.name.substring(0,2) }}</div>
                     <div class="name truncate" v-else>{{ item?.name }}</div>
                     <el-badge :value="12" v-if="item?.code === 'tasks-data' || item?.code === 'message-data'"/>

+ 2 - 2
src/views/ledger/write.vue

@@ -18,7 +18,7 @@
             <!--左右拖动-->
             <div class="horizontal-drag-line" @mousedown="onmousedown"/>
         </div>
-        <div class="hc-layout-content-box">
+        <div class="hc-layout-content-box ledger-write-box">
             <HcTabsSimple :datas="sbTableData" :cur="sbTableKey" @tabClick="sbTableClick">
                 <template #tab-internal>
                     <HcInternal v-if="sbTableKey === 'internal'" :projectId="projectId" :contractId="contractId" :treeData="nodeDataInfo"/>
@@ -126,7 +126,7 @@ const onmousedown = () => {
 </style>
 
 <style lang="scss">
-.hc-layout-box .hc-layout-content-box .hc-card-box.el-card {
+.hc-layout-box .hc-layout-content-box.ledger-write-box .hc-card-box.el-card {
     border-radius: 0 var(--el-card-border-radius) var(--el-card-border-radius) var(--el-card-border-radius);
     height: calc(100% - 44px);
 }

+ 202 - 20
src/views/tasks/message-data.vue

@@ -6,15 +6,15 @@
             </el-scrollbar>
         </div>
         <div class="hc-layout-content-box">
-            <HcCard :scrollbar="false" actionSize="lg">
+            <HcCard actionSize="lg">
                 <template #header>
                     <div class="w-32 ml-2">
-                        <el-select v-model="searchForm.smsType" placeholder="消息类型" clearable>
+                        <el-select v-model="searchForm.smsType" placeholder="消息类型" size="large" clearable>
                             <el-option v-for="item in smsTypeData" :label="item['label']" :value="item['value']"/>
                         </el-select>
                     </div>
                     <div class="w-64 ml-2">
-                        <HcDatePicker :dates="betweenTime" clearable @change="betweenTimeUpdate"/>
+                        <HcDatePicker :dates="betweenTime" size="large" clearable @change="betweenTimeUpdate"/>
                     </div>
                     <div class="ml-2">
                         <el-button type="primary" size="large" @click="searchClick">
@@ -23,35 +23,91 @@
                         </el-button>
                     </div>
                 </template>
-                <HcTable ref="tableListRef" :column="tableListColumn" :datas="tableListData" :loading="tableLoading" isCheck @selection-change="tableSelectionChange"/>
+                <template #extra>
+                    <el-button hc-btn :disabled="tableCheckedKeys.length <= 0" :loading="delLoading" @click="delClick">
+                        <HcIcon name="delete-bin-3"/>
+                        <span>删除消息</span>
+                    </el-button>
+                    <el-button hc-btn :disabled="tableCheckedKeys.length <= 0" :loading="markReadLoading" @click="markReadClick">
+                        <HcIcon name="bookmark"/>
+                        <span>标记已读</span>
+                    </el-button>
+                </template>
+                <HcTable ref="tableListRef" :column="tableListColumn" :datas="tableListData" :loading="tableLoading" isCheck @selection-change="tableSelectionChange">
+                    <template #content="{row}">
+                        <div class="text-link text-cut" @click="tableContent(row)">{{row.content}}</div>
+                    </template>
+                </HcTable>
                 <template #action>
                     <HcPages :pages="searchForm" @change="pageChange"/>
                 </template>
             </HcCard>
         </div>
+        <!--日志内容-->
+        <el-dialog v-model="operationContentModal" title="消息内容" width="38rem" class="hc-modal-border">
+            {{operationContent}}
+        </el-dialog>
     </div>
 </template>
 
 <script setup>
 import {ref,onMounted} from "vue";
 import {useAppStore} from "~src/store";
+import {useRouter, useRoute} from 'vue-router'
+import messageApi from '~api/tasks/message';
+import {getObjValue,getArrValue} from "vue-utils-plus"
 
 //变量
+const router = useRouter()
+const useRoutes = useRoute()
 const useAppState = useAppStore()
 const projectId = ref(useAppState.getProjectId);
 const contractId = ref(useAppState.getContractId);
 
+//路由参数数据
+const routerQuery = useRoutes?.query;
+let MenuType = routerQuery?.MenuType || '1'
+
+//渲染完成
+onMounted(()=> {
+    queryCurrentUserMessageCount()
+    searchForm.value.type = MenuType
+    searchForm.value.current = 1
+    searchClick()
+})
+
 //左侧菜单
-const menuKey = ref('basic')
+const menuKey = ref(MenuType)
 const menuOptions = ref([
-    {key: 'basic', label: '任务催办', icon: 'alarm-warning', badge: 10},
-    {key: 'password', label: '监测预警', icon: 'eye', badge: 10},
-    {key: 'project', label: '废除通知', icon: 'delete-bin-3', badge: 10},
-    {key: 'log', label: '工单反馈', icon: 'question-answer', badge: 10},
-    {key: 'recycle', label: '系统消息', icon: 'chat-settings', badge: 10},
+    {key: '1', label: '任务催办', icon: 'alarm-warning', badge: 0},
+    {key: '2', label: '监测预警', icon: 'eye', badge: 0},
+    {key: '3', label: '废除通知', icon: 'delete-bin-3', badge: 0},
+    {key: '4', label: '工单反馈', icon: 'question-answer', badge: 0},
+    {key: '5', label: '系统消息', icon: 'chat-settings', badge: 0},
 ]);
 const handleMenuValue = (item) => {
-    console.log(item)
+    searchForm.value.type = item.key
+    searchForm.value.current = 1
+    menuKey.value = item.key
+    searchClick()
+    router.push({
+        path: useRoutes.path,
+        query: {MenuType: item.key}
+    })
+}
+
+//获取消息数量
+const queryCurrentUserMessageCount = async () => {
+    const typeArr = ['typeOneNumber','typeTowNumber','typeThreeNumber','typeFourNumber','typeFiveNumber'];
+    const { data } = await messageApi.queryCurrentUserMessageCount({
+        projectId: projectId.value,
+        contractId: contractId.value,
+    })
+    //处理数据
+    let res = getObjValue(data)
+    for (let i = 0; i < typeArr.length; i++) {
+        menuOptions.value[i].badge = res[typeArr[i]] ?? 0
+    }
 }
 
 //消息类型
@@ -59,7 +115,7 @@ const smsTypeData = ref([{label: "已读消息", value: "1"}, {label: "未读消
 
 //搜索和分页数据
 const searchForm = ref({
-    smsType: '1', startTime: null, endTime: null,
+    isRead: null, startTime: null, endTime: null, type: 1,
     current: 1, size: 20, total: 0
 })
 
@@ -67,7 +123,13 @@ const searchForm = ref({
 const betweenTime = ref(null)
 const betweenTimeUpdate = ({val,arr}) => {
     betweenTime.value = arr
-    searchForm.value.betweenTime = `${val['start']}~${val['end']}`
+    if (val && val.length > 0) {
+        searchForm.value.startTime = val['start']
+        searchForm.value.endTime = val['end']
+    } else {
+        searchForm.value.startTime = null
+        searchForm.value.endTime = null
+    }
 }
 
 //搜索
@@ -83,27 +145,147 @@ const pageChange = ({current, size}) => {
     getTableData()
 }
 
-//获取数据
-const tableLoading = ref(false)
+//设置表头数据
+const tableListRef = ref(null)
 const tableListColumn = ref([
     {key:'typeValue', name: '类型', width: '120'},
-    {key:'startTime', name: '日期时间', width: '180'},
-    {key:'endTime', name: '内容'},
+    {key:'time', name: '日期时间', width: '180'},
+    {key:'content', name: '内容'},
 ])
-
 const tableListData = ref([])
-const getTableData = async () => {
 
+//获取数据
+const tableLoading = ref(false)
+const getTableData = async () => {
+    //处理初始数据
+    tableLoading.value = true
+    tableListData.value = []
+    tableListRef.value?.clearSelection()
+    tableCheckedKeys.value = []
+    //获取数据
+    const { error, code, data } = await messageApi.getPageData({
+        ...searchForm.value,
+        projectId: projectId.value,
+        contractId: contractId.value,
+    })
+    //处理返回数据
+    tableLoading.value = false
+    if (!error && code === 200) {
+        tableListData.value = getArrValue(data['records'])
+        searchForm.value.total = data['total'] ?? 0
+    } else {
+        tableListData.value = []
+        searchForm.value.total = 0
+    }
 }
 
 //多选
-const tableListRef = ref(null)
 const tableCheckedKeys = ref([]);
 const tableSelectionChange = (rows) => {
     tableCheckedKeys.value = rows.filter((item) => {
         return (item??'') !== '';
     })
 }
+
+//查看内容
+const operationContentModal = ref(false)
+const operationContent = ref('')
+const tableContent = (row) => {
+    operationContent.value = row['content'] ?? ''
+    operationContentModal.value = true
+    setMessageWarningReadApi(row['id'],false)
+}
+
+//删除消息
+const delClick = () => {
+    const rows = tableCheckedKeys.value;
+    if (rows.length > 0) {
+        window?.$messageBox?.alert('是否删除勾选的消息?', '确认操作', {
+            showCancelButton: true,
+            confirmButtonText: '确定删除',
+            cancelButtonText: '取消',
+            callback: (action) => {
+                if (action === 'confirm') {
+                    removeData(rows)
+                }
+            }
+        })
+    } else {
+        window.$message?.warning('请先勾选要删除的消息')
+    }
+}
+
+//确认删除消息
+const delLoading = ref(false)
+const removeData = async (rows) => {
+    delLoading.value = true
+    const ids = rowsToId(rows)
+    //请求数据
+    const { error, code } = await messageApi.removeData({
+        ids: ids
+    }, false)
+    //处理返回数据
+    delLoading.value = false
+    if (!error && code === 200) {
+        tableCheckedKeys.value = []
+        window.$message?.success('消息删除成功')
+        queryCurrentUserMessageCount()
+        searchClick()
+    } else {
+        window.$message?.error('消息删除失败')
+    }
+}
+
+//标记已读
+const markReadClick = () => {
+    const rows = tableCheckedKeys.value;
+    if (rows.length > 0) {
+        const ids = rowsToId(rows)
+        window?.$messageBox?.alert('勾选的消息是否标记为已读?', '确认操作', {
+            showCancelButton: true,
+            confirmButtonText: '确定标记',
+            cancelButtonText: '取消',
+            callback: (action) => {
+                if (action === 'confirm') {
+                    setMessageWarningReadApi(ids)
+                }
+            }
+        })
+    } else {
+        window.$message?.warning('请先勾选要标记的消息')
+    }
+}
+
+//确认标记
+const markReadLoading = ref(false)
+const setMessageWarningReadApi = async (ids, getTable = true) => {
+    markReadLoading.value = true
+    //请求数据
+    const { error, code } = await messageApi.setMessageWarningRead({
+        ids: ids
+    }, false)
+    //处理返回数据
+    markReadLoading.value = false
+    if (!error && code === 200) {
+        if (getTable) {
+            tableCheckedKeys.value = []
+            window.$message?.success('消息标记为已读成功')
+            queryCurrentUserMessageCount()
+            getTableData()
+        } else {
+            queryCurrentUserMessageCount()
+        }
+    } else {
+        window.$message?.error('消息标记为已读失败')
+    }
+}
+
+//拼接ID
+const rowsToId = (rows) => {
+    return rows.map((obj) => {
+        return obj.id;
+    }).join(",")
+}
 </script>
 
 <style lang="scss" scoped>