Pārlūkot izejas kodu

消息通知, 历史消息页面

lxf 1 gadu atpakaļ
vecāks
revīzija
a439d1d53e

+ 1 - 1
.env.development

@@ -7,6 +7,6 @@ VITE_APP_ENV = 'development'
 # 若依管理系统/开发环境
 VITE_APP_BASE_API = '/dev-api'
 
-VITE_APP_WS_API = '/test-api'
+VITE_APP_WS_API = ':10000/test-api'
 
 VITE_APP_IP = '121.37.194.75'

+ 1 - 1
.env.staging

@@ -7,7 +7,7 @@ VITE_APP_ENV = 'staging'
 # 若依管理系统/生产环境
 VITE_APP_BASE_API = '/test-api'
 
-VITE_APP_WS_API = '/test-api'
+VITE_APP_WS_API = ':10000/test-api'
 
 # 是否在打包时开启压缩,支持 gzip 和 brotli
 VITE_BUILD_COMPRESS = gzip

+ 184 - 27
src/components/notice/index.vue

@@ -3,61 +3,160 @@
     <el-dialog title="系统公告" v-model="value" width="460px" :align-center="true" :before-close="handleClose">
       <div class="title"></div>
       <div class="text-content" v-if="data.length > 0" style="margin-top: 10px">
-        {{ data[index].content }}
+        <h3>{{ data[index].title }}</h3>
+        {{ data[index].businessData }}
       </div>
       <template #footer>
-        <span class="dialog-footer"> </span>
+        <span class="dialog-footer">
+          <el-button size="small" @click="index--" :disabled="data.length < 2 || index == 0">上一条</el-button>
+          <el-button size="small" @click="index++" :disabled="data.length == index + 1">下一条</el-button>
+          <el-button type="primary" size="small" :disabled="data.length == 0 || data[index].isRead" @click="confirm">确认已读</el-button>
+        </span>
       </template>
     </el-dialog>
     <div class="notice-table-warp" :class="modelValue ? 'notice-table-warp-open' : ''" @click.stop="closeNoticeTableModal">
-      <div class="notice-table" @click.stop>
+      <div class="notice-table" @click.stop v-loading="loading">
         <div class="tabs">
           <ul>
-            <li style="padding-left: 0; border: none" @click="tableTagType = 1" :class="tableTagType == 1 ? 'active' : ''">全部(0)</li>
-            <li @click="tableTagType = 2" :class="tableTagType == 2 ? 'active' : ''">待办(0)</li>
-            <li @click="tableTagType = 3" :class="tableTagType == 3 ? 'active' : ''">通知(0)</li>
+            <li
+              style="padding-left: 0; border: none"
+              @click="
+                pushInfoReq.whetherFlow = '';
+                getPushInfoInit();
+              "
+              :class="pushInfoReq.whetherFlow === '' ? 'active' : ''">
+              全部<span v-if="pushInfoReq.whetherFlow === ''">({{ pushInfoReq.total }})</span>
+            </li>
+            <li
+              @click="
+                pushInfoReq.whetherFlow = 1;
+                getPushInfoInit();
+              "
+              :class="pushInfoReq.whetherFlow === 1 ? 'active' : ''">
+              流程<span v-if="pushInfoReq.whetherFlow === 1">({{ pushInfoReq.total }})</span>
+            </li>
+            <li
+              @click="
+                pushInfoReq.whetherFlow = 0;
+                getPushInfoInit();
+              "
+              :class="pushInfoReq.whetherFlow === 0 ? 'active' : ''">
+              业务<span v-if="pushInfoReq.whetherFlow === 0">({{ pushInfoReq.total }})</span>
+            </li>
           </ul>
-          <div class="more">查看更多&gt;</div>
+          <div class="more" @click="toDealWith({ businessType: 'hisMsg' })">查看更多&gt;</div>
         </div>
-        <el-table :data="noticeData" style="width: 100%">
-          <el-table-column prop="date" label="标题内容" width="250"> </el-table-column>
-          <el-table-column prop="name" label="类型" width="120"> </el-table-column>
+        <el-table :data="noticeData" style="width: 100%" @row-click="rowClick">
+          <el-table-column prop="title" label="标题内容" width="250">
+            <template #default="scope">
+              <el-tooltip class="box-item" effect="dark" :content="scope.row.title" placement="top">
+                <div class="noticeData-title">{{ scope.row.title }}</div>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+          <el-table-column prop="businessType" label="类型" width="120">
+            <template #default="scope">
+              <span>{{ scope.row.businessType === 0 ? "流程" : "业务" }}</span>
+            </template>
+          </el-table-column>
           <el-table-column prop="address" label="操作">
             <template #default="scope">
-              <span style="cursor: pointer">未读</span>
+              <span style="cursor: pointer; color: #0084ff" @click.stop="readFn(scope)">已读</span>
             </template>
           </el-table-column>
         </el-table>
-        <div class="notice-btn-box" style="margin-top: 20px">
-          <el-button plain disabled>点击清空</el-button>
-          <el-button type="primary" disabled>全部已读</el-button>
+        <div v-if="noticeData && noticeData.length > 0">
+          <el-pagination
+            style="text-align: center"
+            :page-size="5"
+            layout="prev, pager, next"
+            :current-page="pushInfoReq.pageNum"
+            :total="pushInfoReq.total"
+            @current-change="handlePageChange" />
+        </div>
+        <div class="notice-btn-box" style="margin-top: 20px" v-if="noticeData && noticeData.length > 0">
+          <el-button type="primary" @click="allReadFn" v-if="noticeData.length != 0">全部已读</el-button>
         </div>
       </div>
     </div>
   </div>
 </template>
 <script setup>
+import { ElMessageBox, ElNotification, ElMessage } from "element-plus";
 import { getToken } from "@/utils/auth";
+
+const { proxy } = getCurrentInstance();
 defineProps({
   modelValue: {
     type: Object,
     default: false,
   },
 });
-const emit = defineEmits(["update:modelValue"]);
+const emit = defineEmits(["update:modelValue"], "changeNum");
 const closeNoticeTableModal = () => {
   emit("update:modelValue", false);
 };
-const tableTagType = ref(1);
 let noticeData = ref([]);
 let index = ref(0);
 let data = ref([]);
 let value = ref(false);
+const rowClick = (row) => {
+  commonRead([row.id]);
+  toDealWith(row);
+};
+const toDealWith = (item) => {
+  let urlConfig = {
+    0: "DealWith",
+    5: "Claim",
+    6: "Abnormal",
+    hisMsg: "hisMsg",
+  };
+  proxy.$router.push({
+    name: urlConfig[item.businessType],
+  });
+};
+const allReadFn = () => {
+  ElMessageBox.confirm("此操作将会把所有未读消息标记为已读,是否继续?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(() => {
+      let arr = [];
+      noticeData.value.filter((item) => {
+        arr.push(item.id);
+      });
+      commonRead(arr);
+    })
+    .catch(() => {
+      ElMessage({
+        type: "info",
+        message: "已取消操作",
+      });
+    });
+};
+const readFn = (item) => {
+  commonRead([item.row.id]);
+};
+const commonRead = (ids, type) => {
+  proxy.post("/pushInfo/read", { idList: ids }).then(() => {
+    ElMessage({
+      message: "已读成功",
+      type: "success",
+    });
+    if (type == "confirm") {
+      data.value[index].isRead = true;
+    } else {
+      getPushInfo();
+    }
+  });
+};
+const confirm = () => {
+  value.value = false;
+  commonRead([data.value[index.value].id], "confirm");
+};
 const socketInit = () => {
-  window.ws = new WebSocket(
-    "ws://" + import.meta.env.VITE_APP_IP + ":20001" + import.meta.env.VITE_APP_WS_API + "/webStock/" + getToken()
-    // 'ws://192.168.1.97:8300/webStock/' + window.localStorage.getItem('token')
-  );
+  window.ws = new WebSocket("ws://" + import.meta.env.VITE_APP_IP + import.meta.env.VITE_APP_WS_API + "/webStock/" + getToken());
   //申请一个WebSocket对象,参数是服务端地址,同http协议使用http://开头一样,WebSocket协议的url使用ws://开头,另外安全的WebSocket协议使用wss://开头
   window.ws.onopen = function () {
     //当WebSocket创建成功时,触发onopen事件
@@ -66,20 +165,72 @@ const socketInit = () => {
   window.ws.onmessage = function (e) {
     //当客户端收到服务端发来的消息时,触发onmessage事件,参数e.data包含server传递过来的数据
     //在data.value前面插入
-    console.log(JSON.parse(e.data).data);
-    data.value.unshift({ title: "最新公告", content: JSON.parse(e.data).data });
-    index.value = 0;
-    value.value = true;
+    const res = JSON.parse(e.data);
+    if (res.type == 1) {
+      index.value = 0;
+      data.value = res.list;
+      if (res.list.length > 0) value.value = true;
+    }
+    if (res.type == 2) {
+      emit("changeNum", res.count * 1);
+      getPushInfo();
+    }
+    if (res.type == 3) {
+      ElNotification({
+        title: "提示",
+        message: res.title,
+        position: "bottom-right",
+        duration: 0,
+      });
+    }
   };
   window.ws.onclose = function (e) {
     //当客户端收到服务端发送的关闭连接请求时,触发onclose事件
-    console.log("close");
+    console.log(e, "close");
   };
   window.ws.onerror = function (e) {
     //如果出现连接、处理、接收、发送数据失败的时候触发onerror事件
-    console.log(error);
+    console.log(e, "error");
   };
 };
+let pushInfoReq = ref({
+  pageNum: 1,
+  pageSize: 5,
+  pushRead: 0,
+  type: "",
+  total: 0,
+  whetherFlow: "",
+});
+const handlePageChange = (val) => {
+  pushInfoReq.value.pageNum = val;
+  getPushInfo();
+};
+const loading = ref(false);
+const getPushInfoInit = () => {
+  pushInfoReq.value.pageNum = 1;
+  getPushInfo();
+};
+const getPushInfo = () => {
+  loading.value = true;
+  proxy.post("/pushInfo/page", pushInfoReq.value).then((res) => {
+    noticeData.value = res.rows;
+    pushInfoReq.value.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+      proxy
+        .post("/pushInfo/page", {
+          pageNum: 1,
+          pageSize: 5,
+          pushRead: 0,
+          type: "",
+          whetherFlow: "",
+        })
+        .then((res) => {
+          emit("changeNum", res.total * 1);
+        });
+    }, 500);
+  });
+};
 socketInit();
 const handleClose = () => {
   value.value = false;
@@ -98,7 +249,6 @@ const handleClose = () => {
   opacity: 0;
   display: none;
 }
-
 .notice-table-warp-open {
   opacity: 1;
   display: block;
@@ -146,6 +296,13 @@ const handleClose = () => {
 }
 </style>
 <style>
+.noticeData-title {
+  width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  cursor: pointer;
+}
 .commons-notice .el-table__row {
   height: 50px;
 }

+ 0 - 18
src/layout/components/Navbar.vue

@@ -59,11 +59,9 @@ import useSettingsStore from "@/store/modules/settings";
 const appStore = useAppStore();
 const userStore = useUserStore();
 const settingsStore = useSettingsStore();
-
 function toggleSideBar() {
   appStore.toggleSideBar();
 }
-
 function handleCommand(command) {
   switch (command) {
     case "setLayout":
@@ -76,7 +74,6 @@ function handleCommand(command) {
       break;
   }
 }
-
 function logout() {
   ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
     confirmButtonText: "确定",
@@ -90,7 +87,6 @@ function logout() {
     })
     .catch(() => {});
 }
-
 const emits = defineEmits(["setLayout"]);
 function setLayout() {
   emits("setLayout");
@@ -104,7 +100,6 @@ function setLayout() {
   position: relative;
   background: #fff;
   box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
-
   .hamburger-container {
     line-height: 46px;
     height: 100%;
@@ -112,36 +107,29 @@ function setLayout() {
     cursor: pointer;
     transition: background 0.3s;
     -webkit-tap-highlight-color: transparent;
-
     &:hover {
       background: rgba(0, 0, 0, 0.025);
     }
   }
-
   .breadcrumb-container {
     float: left;
   }
-
   .topmenu-container {
     position: absolute;
     left: 50px;
   }
-
   .errLog-container {
     display: inline-block;
     vertical-align: top;
   }
-
   .right-menu {
     float: right;
     height: 100%;
     line-height: 50px;
     display: flex;
-
     &:focus {
       outline: none;
     }
-
     .right-menu-item {
       display: inline-block;
       padding: 0 8px;
@@ -149,31 +137,25 @@ function setLayout() {
       font-size: 18px;
       color: #5a5e66;
       vertical-align: text-bottom;
-
       &.hover-effect {
         cursor: pointer;
         transition: background 0.3s;
-
         &:hover {
           background: rgba(0, 0, 0, 0.025);
         }
       }
     }
-
     .avatar-container {
       margin-right: 40px;
-
       .avatar-wrapper {
         margin-top: 5px;
         position: relative;
-
         .user-avatar {
           cursor: pointer;
           width: 40px;
           height: 40px;
           border-radius: 10px;
         }
-
         i {
           cursor: pointer;
           position: absolute;

+ 14 - 0
src/router/index.js

@@ -91,6 +91,20 @@ export const constantRoutes = [
     ],
   },
   {
+    path: "/hisMsg",
+    component: Layout,
+    redirect: "/hisMsg",
+    children: [
+      {
+        path: "/hisMsg",
+        name: "hisMsg",
+        component: () => import(/* webpackChunkName: "page" */ "@/views/system/msg/hisMsg.vue"),
+        props: true,
+        meta: { title: "历史消息" },
+      },
+    ],
+  },
+  {
     path: "/addOrder",
     component: Layout,
     redirect: "/addOrder",

+ 0 - 1
src/views/group/finance/check-bill/index.vue

@@ -96,7 +96,6 @@
 import byTable from "@/components/byTable/index";
 import byForm from "@/components/byForm/index";
 import { ElMessage, ElMessageBox } from "element-plus";
-import { ref } from "vue";
 
 const { proxy } = getCurrentInstance();
 const departmentList = ref([{ dictKey: "0", dictValue: "胜德体育" }]);

+ 87 - 0
src/views/system/msg/hisMsg.vue

@@ -0,0 +1,87 @@
+<template>
+  <el-card class="box-card">
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        :searchConfig="searchConfig"
+        highlight-current-row
+        @get-list="getList">
+      </byTable>
+    </div>
+  </el-card>
+</template>
+
+<script setup>
+import byTable from "@/components/byTable/index";
+import { computed, ref } from "vue";
+
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    corporationId: "",
+    keyword: "",
+  },
+});
+const searchConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "keyword",
+      label: "关键词",
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "消息类型",
+        prop: "type",
+        width: "200",
+      },
+      render() {
+        return "消息提醒";
+      },
+    },
+    {
+      attrs: {
+        label: "消息内容",
+        prop: "title",
+      },
+    },
+    {
+      attrs: {
+        label: "发送时间",
+        prop: "createTime",
+        width: "200",
+      },
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy.post("/pushInfo/page", sourceList.value.pagination).then((res) => {
+    sourceList.value.data = res.rows;
+    sourceList.value.pagination.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+getList();
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+</style>