Ver Fonte

消息模块。

lighter há 3 anos atrás
pai
commit
15e8d24cd6

+ 11 - 4
src/api/messages/index.js

@@ -1,10 +1,17 @@
 import request from '../../utils/request'
 
-export function onPageRefresh(data) {
+export function selectSystemMessages(date) {
   return request({
-    url: '/socketMessage/onPageRefresh',
-    method: 'post',
-    data,
+    url: '/socketMessage/selectSystemMessages',
+    method: 'get',
+    params: { date },
+  })
+}
+
+export function fetchUnreadCount() {
+  return request({
+    url: '/socketMessage/fetchUnreadCount',
+    method: 'get',
   })
 }
 

+ 19 - 10
src/components/MyClock.vue

@@ -1,6 +1,6 @@
 <template>
   <div style="display: flex" :style="boxSize">
-    <div>
+    <div v-if="showLogo">
       <img src="../assets/thyylogo.png" alt="" :style="boxSize" />
     </div>
     <div style="width: 30px"></div>
@@ -10,6 +10,7 @@
 
 <script>
 import { ref } from '@vue/reactivity'
+import { getServerDateApi } from '@/api/public-api'
 import { onMounted, onUnmounted } from 'vue'
 export default {
   props: {
@@ -17,6 +18,10 @@ export default {
       type: String,
       default: 'large',
     },
+    showLogo: {
+      type: Boolean,
+      defaut: true,
+    },
   },
   setup(props) {
     const mInterval = ref(null)
@@ -24,11 +29,12 @@ export default {
     const time = ref('')
     const week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
 
+    let nowtime = ''
     const updateTime = () => {
-      let cd = new Date()
+      nowtime += 1000
+      let cd = new Date(nowtime)
       time.value = zeroPadding(cd.getHours(), 2) + ':' + zeroPadding(cd.getMinutes(), 2) + ':' + zeroPadding(cd.getSeconds(), 2)
-      date.value =
-        zeroPadding(cd.getFullYear(), 4) + '-' + zeroPadding(cd.getMonth() + 1, 2) + '-' + zeroPadding(cd.getDate(), 2) + ' ' + week[cd.getDay()]
+      date.value = zeroPadding(cd.getFullYear(), 4) + '-' + zeroPadding(cd.getMonth() + 1, 2) + '-' + zeroPadding(cd.getDate(), 2) + ' ' + week[cd.getDay()]
     }
     const zeroPadding = (num, digit) => {
       let zero = ''
@@ -39,18 +45,21 @@ export default {
     }
 
     const boxSize = {
-      height: props.size === 'large' ? '60px' : '45px',
-      lineHeight: props.size === 'large' ? '60px' : '45px',
+      height: props.size === 'large' ? '60px' : '',
+      lineHeight: props.size === 'large' ? '60px' : '',
     }
 
     const fontSize = {
-      fontSize: props.size === 'large' ? '26px' : '16px',
+      fontSize: props.size === 'large' ? '26px' : '20px',
     }
 
     onMounted(() => {
-      mInterval.value = setInterval(() => {
-        updateTime()
-      }, 1000)
+      getServerDateApi().then((res) => {
+        nowtime = new Date(res).getTime()
+        mInterval.value = setInterval(() => {
+          updateTime()
+        }, 1000)
+      })
     })
 
     onUnmounted(() => {

+ 27 - 55
src/layout/Header/functionList/message.vue

@@ -15,57 +15,32 @@
     </div>
     <div class="content">
       <p v-show="currentSender.senderName">{{ currentSender.senderName }}</p>
-      <div v-for="(itm, index) in allMessages" :key="index">
-        <div class="content-title-box">
-          <div class="content-title">{{ itm.title }}</div>
-          <div class="content-time">{{ itm.sendDatetime }}</div>
+      <div style="height: 400px; overflow-y: auto">
+        <div v-for="(itm, index) in allMessages" :key="index">
+          <div class="content-title-box" :style="readStatus(itm.status)">
+            <div class="content-title">
+              {{ itm.title }}
+            </div>
+            <div class="content-time">{{ itm.sendDatetime }}</div>
+          </div>
+          <div class="content-box" v-html="itm.content"></div>
         </div>
-        <div class="content-box">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ itm.content }}</div>
       </div>
     </div>
   </div>
-  <el-dialog title="重要系统通知" v-model="systemMessages.show" :append-to-body="true" :destroy-on-close="true" center>
-    <div class="system-message-time">{{ systemMessages.list[systemMessages.current].sendDatetime }}</div>
-    <div class="system-message-content">{{ systemMessages.list[systemMessages.current].content }}</div>
-    <div class="system-message-footer">
-      <el-button type="primary" icon="el-icon-arrow-left" :disabled="systemMessages.current === 0" circle title="上一条" @click="messageIndexIncrease(-1)"></el-button>
-      <span class="system-message-count">{{ systemMessages.current + 1 }} / {{ systemMessages.list.length }}</span>
-      <el-button
-        type="primary"
-        icon="el-icon-arrow-right"
-        :disabled="systemMessages.current === systemMessages.list.length - 1"
-        circle
-        title="下一条"
-        @click="messageIndexIncrease(1)"
-      ></el-button>
-    </div>
-  </el-dialog>
 </template>
 
 <script>
-import { defineComponent, onMounted, reactive, ref } from 'vue'
-import { onPageRefresh, fetchAllSenders, fetchAllMessages } from '../../../api/messages/index'
-import store from '@/store'
-import { clone } from '../../../utils/clone'
+import { computed, defineComponent, onMounted, ref } from 'vue'
+import { fetchUnreadCount, fetchAllSenders, fetchAllMessages } from '../../../api/messages/index'
+import store from '../../../store'
 
 export default defineComponent({
   name: 'message',
   setup() {
-    const unreadCount = ref(0)
-    const systemMessages = reactive({
-      show: false,
-      list: [],
-      current: 0,
+    const unreadCount = computed(() => {
+      return store.state.app.unreadMessageCount
     })
-    const messageIndexIncrease = (val) => {
-      systemMessages.current += val
-      if (val === 1) {
-        if (pushedMessageIds.value.indexOf(systemMessages.list[systemMessages.current].id) === -1) {
-          store.commit('app/setSystemMessages', systemMessages.list[systemMessages.current].id)
-        }
-      }
-    }
-    const pushedMessageIds = ref([])
 
     const currentSender = ref({})
     const activated = (sender) => {
@@ -75,6 +50,11 @@ export default defineComponent({
         fontWeight: currentSender.value.sender === sender ? 'bold' : '',
       }
     }
+    const readStatus = (status) => {
+      return {
+        background: status === 0 ? 'rgba(233, 158, 158, 0.548)' : 'rgba(198, 231, 148, 0.452)',
+      }
+    }
     const allSenders = ref([])
     const allMessages = ref([])
     const messageLayerVisible = ref(false)
@@ -94,23 +74,15 @@ export default defineComponent({
       currentSender.value = messageIndex
       fetchAllMessages(messageIndex.sender).then((res) => {
         allMessages.value = res
+        let newCount = store.state.app.unreadMessageCount - messageIndex.unreadCount
+        store.commit('app/setUnreadMessageCount', newCount)
         messageIndex.unreadCount = 0
       })
     }
 
     onMounted(() => {
-      pushedMessageIds.value = clone(store.state.app.systemMessages)
-      onPageRefresh(pushedMessageIds.value).then((res) => {
-        unreadCount.value = res.unreadCount
-        if (res.systemMessage.length > 0) {
-          systemMessages.list = res.systemMessage
-          systemMessages.current = 0
-          systemMessages.show = true
-          if (pushedMessageIds.value.indexOf(systemMessages.list[0].id) === -1) {
-            pushedMessageIds.value.push(systemMessages.list[0].id)
-            store.commit('app/setSystemMessages', systemMessages.list[0].id)
-          }
-        }
+      fetchUnreadCount().then((res) => {
+        store.commit('app/setUnreadMessageCount', res)
       })
     })
 
@@ -120,11 +92,10 @@ export default defineComponent({
       unreadCount,
       currentSender,
       messageLayerVisible,
-      systemMessages,
       activated,
+      readStatus,
       showMessageLayer,
       handleClickSender,
-      messageIndexIncrease,
     }
   },
 })
@@ -195,7 +166,6 @@ i {
   display: flex;
   height: 26px;
   line-height: 26px;
-  background: rgba(198, 231, 148, 0.452);
   padding: 0 4px;
   font-weight: bold;
   border-bottom: 1px dashed lightgray;
@@ -208,11 +178,13 @@ i {
   overflow: hidden;
 }
 .content-time {
+  font-size: 12px;
   width: 130px;
 }
 .content-box {
-  background: rgba(198, 231, 148, 0.452);
   padding: 4px;
+  margin-bottom: 12px;
+  background: rgb(248, 247, 247);
 }
 .system-message-time {
   font-size: 13px;

+ 3 - 1
src/layout/Header/index.vue

@@ -64,7 +64,9 @@ export default defineComponent({
   },
   setup() {
     const store = useStore()
-    const username = store.getters['user/info'].name
+    const username = computed(() => {
+      return store.getters['user/info'].name
+    })
     const layer = reactive({
       show: false,
       showButton: true,

+ 10 - 1
src/layout/Menu/MenuItem.vue

@@ -8,7 +8,7 @@
       <menu-item v-for="(item, key) in menu.children" :key="key" :menu="item" :basePath="pathResolve" />
     </el-submenu>
     <app-link v-else-if="showMenuType === 1" :to="pathResolve">
-      <el-menu-item :index="pathResolve" v-if="!menu.children[0].children || menu.children[0].children.length === 0">
+      <el-menu-item :index="pathResolve" v-if="noGrandChildren">
         <i :class="menu.children[0].meta.icon || menu.meta.icon" v-if="menu.children[0].meta.icon || menu.meta.icon"></i>
         <template #title>{{ menu.children[0].meta.title }}</template>
       </el-menu-item>
@@ -84,10 +84,19 @@ export default defineComponent({
       path = props.basePath ? props.basePath + '/' + path : path
       return path
     })
+
+    const noGrandChildren = () => {
+      if (menu.children && menu.children.length > 0) {
+        return !menu.children[0].children || menu.children[0].children.length === 0
+      }
+      return false
+    }
+
     return {
       showMenuType,
       pathResolve,
       isCollapse,
+      noGrandChildren,
     }
   },
 })

+ 3 - 3
src/layout/Tabs/tabsHook.js

@@ -1,9 +1,9 @@
 const tabsHook = {
-  setItem: function(arr) {
+  setItem: function (arr) {
     localStorage.setItem('tabs', JSON.stringify(arr))
   },
-  getItem: function() {
+  getItem: function () {
     return JSON.parse(localStorage.getItem('tabs') || '[]')
-  }
+  },
 }
 export default tabsHook

+ 3 - 7
src/store/modules/app.js

@@ -27,7 +27,7 @@ const state = () => ({
     jianRongMoShi: true,
     elTabgName: '',
   },
-  systemMessages: [], // 已经看过的系统通知id
+  unreadMessageCount: 0, // 未查看的消息数量
 })
 
 // mutations
@@ -69,12 +69,8 @@ const mutations = {
   setJianRongMuShi(state, val) {
     state.yiZhuLuRu.jianRongMoShi = val
   },
-  setSystemMessages(state, val) {
-    if (val === null) {
-      state.systemMessages = []
-    } else {
-      state.systemMessages.push(val)
-    }
+  setUnreadMessageCount(state, val) {
+    state.unreadMessageCount = val
   },
 }
 

+ 102 - 103
src/store/modules/user.js

@@ -1,126 +1,125 @@
-import {fetchMenusApi, getWardsApi, loginApi} from '@/api/login'
+import { fetchMenusApi, getWardsApi, loginApi } from '@/api/login'
 import router from '@/router'
 
 const state = () => ({
-    token: '', // 登录token
-    sid: '', // 用户websocket id
-    info: {}, // 用户信息
-    wards: {}, // 病房列表
-    menus: [], // 用户菜单
-    routes: [], // 用户所以可访问路由
-    ward: '', // 用户当前选择的病房
-    paths: [], // 装载path的string数组
+  token: '', // 登录token
+  sid: '', // 用户websocket id
+  info: {}, // 用户信息
+  wards: {}, // 病房列表
+  menus: [], // 用户菜单
+  routes: [], // 用户所以可访问路由
+  ward: '', // 用户当前选择的病房
+  paths: [], // 装载path的string数组
 })
 
 // getters
 const getters = {
-    token(state) {
-        return state.token
-    },
-    sid(state) {
-        return state.sid
-    },
-    info(state) {
-        return state.info
-    },
-    wards(state) {
-        return state.wards
-    },
-    menus(state) {
-        return state.menus
-    },
-    routes(state) {
-        return state.routes
-    },
-    ward(state) {
-        return state.ward
-    },
-    pahts(state) {
-        return state.paths
-    },
+  token(state) {
+    return state.token
+  },
+  sid(state) {
+    return state.sid
+  },
+  info(state) {
+    return state.info
+  },
+  wards(state) {
+    return state.wards
+  },
+  menus(state) {
+    return state.menus
+  },
+  routes(state) {
+    return state.routes
+  },
+  ward(state) {
+    return state.ward
+  },
+  pahts(state) {
+    return state.paths
+  },
 }
 
 // mutations
 const mutations = {
-    tokenChange(state, token) {
-        state.token = token
-    },
-    closeSid(state, sid) {
-        state.sid = ''
-    },
-    sidChange(state, sid) {
-        state.sid = sid
-    },
-    infoChange(state, info) {
-        state.info = info
-    },
-    wardsChange(state, wards) {
-        state.wards = wards
-    },
-    menusChange(state, menus) {
-        state.menus = menus
-    },
-    routesChange(state, routes) {
-        state.routes = routes
-    },
-    wardChange(state, ward) {
-        state.ward = ward
-    },
-    pathsChange(state, paths) {
-        state.paths = paths
-    },
+  tokenChange(state, token) {
+    state.token = token
+  },
+  closeSid(state, sid) {
+    state.sid = ''
+  },
+  sidChange(state, sid) {
+    state.sid = sid
+  },
+  infoChange(state, info) {
+    state.info = info
+  },
+  wardsChange(state, wards) {
+    state.wards = wards
+  },
+  menusChange(state, menus) {
+    state.menus = menus
+  },
+  routesChange(state, routes) {
+    state.routes = routes
+  },
+  wardChange(state, ward) {
+    state.ward = ward
+  },
+  pathsChange(state, paths) {
+    state.paths = paths
+  },
 }
 
 // actions
 const actions = {
-    // login by login.vue
-    login({commit, dispatch}, params) {
-        return new Promise((resolve, reject) => {
-            loginApi(params).then((res) => {
-                commit('tokenChange', res.token)
-                commit('sidChange', res.sid)
-                commit('infoChange', res)
-                dispatch('getWards').then((infoRes) => {
-                    resolve(res)
-                })
-            })
+  // login by login.vue
+  login({ commit, dispatch }, params) {
+    return new Promise((resolve, reject) => {
+      loginApi(params).then((res) => {
+        commit('tokenChange', res.token)
+        commit('sidChange', res.sid)
+        commit('infoChange', res)
+        dispatch('getWards').then((infoRes) => {
+          resolve(res)
         })
-    },
-    // get user info after user logined
-    getWards({commit, dispatch}) {
-        return new Promise((resolve, reject) => {
-            getWardsApi().then((res) => {
-                commit('wardsChange', res)
-                dispatch('getMenus').then((menusRes) => {
-                    resolve(res)
-                })
-            })
+      })
+    })
+  },
+  // get user info after user logined
+  getWards({ commit, dispatch }) {
+    return new Promise((resolve, reject) => {
+      getWardsApi().then((res) => {
+        commit('wardsChange', res)
+        dispatch('getMenus').then((menusRes) => {
+          resolve(res)
         })
-    },
+      })
+    })
+  },
 
-    getMenus({commit}) {
-        return new Promise((resolve, reject) => {
-            fetchMenusApi().then((res) => {
-                commit('menusChange', res.routes)
-                commit('routesChange', res.routes)
-                commit('pathsChange', res.paths)
-                resolve(res)
-            })
-        })
-    },
+  getMenus({ commit }) {
+    return new Promise((resolve, reject) => {
+      fetchMenusApi().then((res) => {
+        commit('menusChange', res.routes)
+        commit('routesChange', res.routes)
+        commit('pathsChange', res.paths)
+        resolve(res)
+      })
+    })
+  },
 
-    // login out the system after user click the loginOut button
-    loginOut({commit}) {
-        localStorage.removeItem('tabs')
-        localStorage.removeItem('vuex')
-        router.push('/login')
-    },
+  // login out the system after user click the loginOut button
+  loginOut({ commit }) {
+    localStorage.clear()
+    router.push('/login')
+  },
 }
 
 export default {
-    namespaced: true,
-    state,
-    actions,
-    getters,
-    mutations,
+  namespaced: true,
+  state,
+  actions,
+  getters,
+  mutations,
 }

+ 99 - 94
src/utils/websocket.js

@@ -1,8 +1,8 @@
-import {ElMessageBox, ElNotification} from 'element-plus'
+import { ElMessageBox, ElNotification } from 'element-plus'
 import Cookies from 'js-cookie'
 import router from '@/router'
 import store from '@/store'
-import {endLoading} from "./loading";
+import { endLoading } from './loading'
 
 const socketUrl = import.meta.env.VITE_SOCKET_URL
 
@@ -10,110 +10,115 @@ let webSocket = null
 let globalCallback = null
 
 export function closeWebSocket() {
-    store.commit("user/closeSid")
-    if (webSocket !== null) {
-        webSocket.close()
-        webSocket = null
-    }
+  store.commit('user/closeSid')
+  if (webSocket !== null) {
+    webSocket.close()
+    webSocket = null
+  }
 }
 
 export function setCallback(callback) {
-    if (callback !== null) {
-        globalCallback = callback
-        console.log('global callback settled.')
-    }
+  if (callback !== null) {
+    globalCallback = callback
+    console.log('global callback settled.')
+  }
 }
 
 export function initWebSocket(sid) {
-    if ('WebSocket' in window) {
-        if (webSocket === null) {
-            const url = socketUrl + sid
-            webSocket = new WebSocket(url)
-        }
-    } else {
-        alert('该浏览器不支持websocket!')
-        webSocket = 'unsupport'
+  if ('WebSocket' in window) {
+    if (webSocket === null) {
+      const url = socketUrl + sid
+      webSocket = new WebSocket(url)
     }
+  } else {
+    alert('该浏览器不支持websocket!')
+    webSocket = 'unsupport'
+  }
 
-    webSocket.onopen = function () {
-        console.log('WebSocket连接成功')
-    }
+  webSocket.onopen = function () {
+    console.log('WebSocket连接成功')
+  }
 
-    webSocket.onmessage = function (e) {
-        let data = JSON.parse(e.data)
-        if (data.name === 'refreshToken') {
-            store.commit('user/tokenChange', data.token)
-        } else if (data.name === 'systemNotification') {
-            ElNotification({
-                title: typeof data.title === 'undefined' ? '新消息' : data.title,
-                message: data.message,
-                dangerouslyUseHTMLString: true,
-                type: typeof data.type === 'undefined' ? 'warning' : data.type,
-                duration: 0,
-            })
-            if (data.refreshDelay) {
-                setTimeout(() => {
-                    location.reload()
-                }, data.refreshDelay)
-            }
-            if (null !== globalCallback) {
-                globalCallback(data)
-            }
-        } else if (data.name === 'jdtMessage') {
-            if (null != globalCallback) {
-                if (!store.state.app.jdt.isOpen) {
-                    store.commit('app/setJdt', {
-                        title: Cookies.get('jdtTitle'),
-                        isOpen: true,
-                        closeButton: false,
-                    })
-                }
-                endLoading()
-                globalCallback(data)
-            }
-        } else if (data.name === 'sidSingle') {
-            store.dispatch('user/loginOut')
-            ElMessageBox.alert('您的账号已在其他地方登陆,如需修改密码请在个人中心中修改。', '提示', {
-                type: 'warning'
-            }).then(() => {
-            }).catch(() => {
-            })
-        } else {
-            if (null !== globalCallback) {
-                globalCallback(data)
-            }
-        }
-    }
+  webSocket.onmessage = function (e) {
+    let data = JSON.parse(e.data)
+    if (data.name === 'refreshToken') {
+      store.commit('user/tokenChange', data.token)
+    } else if (data.name === 'systemNotification') {
+      if (data.count) {
+        let newCount = store.state.app.unreadMessageCount + data.count
+        store.commit('app/setUnreadMessageCount', newCount)
+      }
 
-    webSocket.onclose = function () {
-        webSocket = null
-        let sid
-        if (router.currentRoute.value.path === '/triageRoomScreen') {
-            sid = Cookies.get('room-screen-sid')
-        } else {
-            sid = store.getters['user/sid']
-        }
-        if (!sid) {
-            if (router.currentRoute.value.path === '/login') {
-                return
-            }
-            ElMessageBox.confirm('未检测到WebSocket连接的sid,请重新登录。', '提示', {
-                showCancelButton: false,
-                type: 'warning',
-            }).then(() => {
-                router.push('/login')
-            })
-        } else {
-            if (router.currentRoute.value.path === '/triageFloorScreen') {
-                sid += '-triageFloorScreen'
-            }
-            setTimeout(() => {
-                initWebSocket(sid)
-            }, 3000)
+      ElNotification({
+        title: typeof data.title === 'undefined' ? '新消息' : data.title,
+        message: data.message,
+        dangerouslyUseHTMLString: true,
+        type: typeof data.type === 'undefined' ? 'warning' : data.type,
+        duration: 0,
+      })
+      if (data.refreshDelay) {
+        setTimeout(() => {
+          location.reload()
+        }, data.refreshDelay)
+      }
+      if (null !== globalCallback) {
+        globalCallback(data)
+      }
+    } else if (data.name === 'jdtMessage') {
+      if (null != globalCallback) {
+        if (!store.state.app.jdt.isOpen) {
+          store.commit('app/setJdt', {
+            title: Cookies.get('jdtTitle'),
+            isOpen: true,
+            closeButton: false,
+          })
         }
+        endLoading()
+        globalCallback(data)
+      }
+    } else if (data.name === 'sidSingle') {
+      store.dispatch('user/loginOut')
+      ElMessageBox.alert('您的账号已在其他地方登陆,如需修改密码请在个人中心中修改。', '提示', {
+        type: 'warning',
+      })
+        .then(() => {})
+        .catch(() => {})
+    } else {
+      if (null !== globalCallback) {
+        globalCallback(data)
+      }
     }
+  }
 
-    webSocket.onerror = function () {
-        console.error('WebSocket连接发生错误')
+  webSocket.onclose = function () {
+    webSocket = null
+    let sid
+    if (router.currentRoute.value.path === '/triageRoomScreen') {
+      sid = Cookies.get('room-screen-sid')
+    } else {
+      sid = store.getters['user/sid']
     }
+    if (!sid) {
+      if (router.currentRoute.value.path === '/login') {
+        return
+      }
+      ElMessageBox.confirm('未检测到WebSocket连接的sid,请重新登录。', '提示', {
+        showCancelButton: false,
+        type: 'warning',
+      }).then(() => {
+        router.push('/login')
+      })
+    } else {
+      if (router.currentRoute.value.path === '/triageFloorScreen') {
+        sid += '-triageFloorScreen'
+      }
+      setTimeout(() => {
+        initWebSocket(sid)
+      }, 3000)
+    }
+  }
+
+  webSocket.onerror = function () {
+    console.error('WebSocket连接发生错误')
+  }
 }

+ 155 - 11
src/views/dashboard/index.vue

@@ -1,31 +1,175 @@
 <template>
-  <div class="box">我是首页</div>
+  <el-container>
+    <el-main>
+      <div style="display: flex">
+        <!-- 左边部分 -->
+        <div class="left-pane">
+          <div class="divider-line">
+            <div class="divider-text">
+              <div class="avatar-box__inner">
+                <el-avatar :size="80" :src="userInfo.avatar" @error="errorHandler">
+                  <img :src="makeTextPortrait()" />
+                </el-avatar>
+              </div>
+            </div>
+            <div class="psninfo-box">
+              {{ userInfo.name }}
+              &nbsp;
+              {{ userInfo.deptName }}
+              &nbsp;
+              <MyClock :show-logo="false" size="small" />
+            </div>
+          </div>
+        </div>
+        <!-- 右边部分 -->
+        <div class="right-pane">
+          <div class="check-more" @click="fetchMoreMessages">查看更多</div>
+          <el-timeline v-for="item in messages" :key="item.id">
+            <el-timeline-item :timestamp="item.simpledate" placement="top" icon="el-icon-warning" color="orange">
+              <el-card>
+                <div style="margin-bottom: 12px; font-size: 16px; font-weight: bold">{{ item.title }}</div>
+                <div v-html="item.content"></div>
+              </el-card>
+            </el-timeline-item>
+          </el-timeline>
+        </div>
+      </div>
+    </el-main>
+  </el-container>
 </template>
 
 <script>
-import {defineComponent, onMounted} from 'vue'
-import {useStore} from 'vuex'
-import {ElMessage} from "element-plus";
+import { computed, defineComponent, onActivated, onMounted, ref, watch } from 'vue'
+import { useStore } from 'vuex'
+import { selectSystemMessages } from '../../api/messages/index'
+import { formatDate } from '../../utils/date'
+import { getUserInfo } from '@/api/settings/user-settings'
+import { genTextPortrait } from '@/utils/portrait'
+import MyClock from '@/components/MyClock.vue'
 
 export default defineComponent({
+  components: {
+    MyClock,
+  },
   setup() {
     const store = useStore()
+    const token = computed(() => {
+      return store.state.user.token
+    })
+    watch(
+      () => token.value,
+      () => {
+        setTimeout(() => {
+          location.reload()
+        }, 100)
+      }
+    )
+
+    const messages = ref([])
+    const fetchMoreMessages = () => {
+      let lastdate = 'latest'
+      if (messages.value.length > 0) {
+        lastdate = formatDate(messages.value[0].simpledate)
+      }
+      selectSystemMessages(lastdate).then((res) => {
+        res.forEach((item) => {
+          messages.value.unshift(item)
+        })
+      })
+    }
+
+    const userInfo = ref({})
+    const errorHandler = () => {
+      return true
+    }
+    const makeTextPortrait = () => {
+      return genTextPortrait(userInfo.value.name)
+    }
+
+    onActivated(() => {
+      selectSystemMessages('latest').then((res) => {
+        messages.value = res
+      })
+    })
 
     onMounted(() => {
-      ElMessage.success({
-        message: '登录成功',
-        type: 'success',
-        showClose: true,
-        duration: 1000,
+      getUserInfo().then((res) => {
+        userInfo.value = res
       })
     })
 
+    return {
+      messages,
+      userInfo,
+      errorHandler,
+      fetchMoreMessages,
+      makeTextPortrait,
+    }
   },
 })
 </script>
 
 <style lang="scss" scoped>
-.box {
-  padding: 15px;
+.left-pane {
+  margin-top: 20px;
+  width: 68%;
+  background-image: linear-gradient(#d0ddee, #64b6e6);
+  height: 120px;
+  border-radius: 6px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
+}
+.right-pane {
+  margin-top: 20px;
+  width: 30%;
+  padding-right: 20px;
+  height: 80vh;
+  overflow-y: scroll;
+}
+.avatar-box__inner {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 86px;
+  height: 86px;
+  border-radius: 43px;
+  border-bottom: 3px solid #1080f0;
+  z-index: 600;
+}
+.check-more {
+  width: 60%;
+  text-align: right;
+  color: #409eff;
+  &:hover {
+    cursor: pointer;
+  }
+}
+
+.divider-line {
+  display: block;
+  height: 1px;
+  width: 100%;
+  margin: 70px 0 50px 0;
+  background-color: #4297ec88;
+  position: relative;
+}
+.divider-text {
+  left: 12px;
+  -webkit-transform: translateY(-55%);
+  transform: translateY(-55%);
+  position: absolute;
+  font-weight: 500;
+  color: black;
+  font-size: 14px;
+}
+.psninfo-box {
+  display: flex;
+  left: 108px;
+  -webkit-transform: translateY(-120%);
+  transform: translateY(-120%);
+  position: absolute;
+  font-weight: 500;
+  color: rgb(3, 72, 94);
+  font-size: 20px;
+  font-weight: bold;
 }
 </style>

+ 16 - 25
src/views/system/login.vue

@@ -9,21 +9,20 @@
           </template>
         </el-input>
         <el-input
-            ref="password"
-            v-model="form.password"
-            :type="passwordType"
-            codeRs="password"
-            maxlength="50"
-            placeholder="密码(默认密码为:123456)"
-            size="large"
-            @keyup.enter="submit"
+          ref="password"
+          v-model="form.password"
+          :type="passwordType"
+          codeRs="password"
+          maxlength="50"
+          placeholder="密码(默认密码为:123456)"
+          size="large"
+          @keyup.enter="submit"
         >
           <template #prepend>
             <i class="sfont system-mima"></i>
           </template>
           <template #append>
-            <i :class="passwordType ? 'system-yanjing-guan' : 'system-yanjing'" class="sfont password-icon"
-               @click="passwordTypeChange"></i>
+            <i :class="passwordType ? 'system-yanjing-guan' : 'system-yanjing'" class="sfont password-icon" @click="passwordTypeChange"></i>
           </template>
         </el-input>
         <el-button size="medium" style="width: 100%" type="primary" @click="submit">登录</el-button>
@@ -33,13 +32,13 @@
 </template>
 
 <script>
-import {systemTitle} from '@/config'
-import {defineComponent, onActivated, onMounted, reactive, ref} from 'vue'
-import {useStore} from 'vuex'
-import {useRoute, useRouter} from 'vue-router'
-import {addRoutes} from '@/router'
-import {ElMessage} from 'element-plus'
-import {closeWebSocket} from '@/utils/websocket'
+import { systemTitle } from '@/config'
+import { defineComponent, onActivated, onMounted, reactive, ref } from 'vue'
+import { useStore } from 'vuex'
+import { useRoute, useRouter } from 'vue-router'
+import { addRoutes } from '@/router'
+import { ElMessage } from 'element-plus'
+import { closeWebSocket } from '@/utils/websocket'
 
 export default defineComponent({
   setup() {
@@ -82,18 +81,10 @@ export default defineComponent({
         store.dispatch('user/login', params).then(() => {
           addRoutes()
           router.push(route.query.redirect || '/')
-          setTimeout(() => {
-            location.reload();
-          }, 200)
         })
       })
     }
 
-    onMounted(() => {
-      closeWebSocket()
-      localStorage.clear()
-    })
-
     onActivated(() => {
       closeWebSocket()
       localStorage.clear()