瀏覽代碼

基本框架

CzRger 1 年之前
父節點
當前提交
ad6bfe9e74

+ 5 - 0
src/api/modules/ztpt.ts

@@ -21,6 +21,11 @@ export const getUserInfo = () => handle({
   method: 'get',
 })
 
+export const getUserRoleList = () => handle({
+  url: `/${suffix}/api-idaas/idaas/ps/user/roleList`,
+  method: 'get',
+})
+
 export const logout = () => handle({
   url: `/${suffix}/api-idaas/mq/user/logout`,
   method: 'get',

二進制
src/assets/images/layout/head_bg.png


二進制
src/assets/images/layout/head_exit.png


二進制
src/assets/images/layout/head_icon-1.png


二進制
src/assets/images/layout/head_icon-2.png


二進制
src/assets/images/layout/layout_bg.png


二進制
src/assets/images/layout/sub-menu_bg.png


二進制
src/assets/images/layout/sub-menu_icon-active.png


二進制
src/assets/images/layout/sub-menu_icon.png


+ 93 - 6
src/layout/header/head-com.vue

@@ -3,7 +3,14 @@
     <div class="head-com-left">
       <CusEllipsis :value="dutyPeopleCpt"/>
     </div>
-    <div class="head-com-right"></div>
+    <div class="head-com-right">
+      <img class="icon-date" src="@/assets/images/layout/head_icon-1.png">
+      <div class="date">{{currentDateCpt}}</div>
+      <img class="icon-user" src="@/assets/images/layout/head_icon-2.png">
+      <div class="name">{{$store.state.app.userInfo?.displayName}}</div>
+      <div class="dept">{{$store.state.app.userInfo?.organizations[0].organizationName}}</div>
+      <div class="button __hover" @click="onLogout">退出</div>
+    </div>
   </div>
 </template>
 
@@ -22,6 +29,8 @@ import {
 } from 'vue'
 import {useStore} from 'vuex'
 import {useRouter, useRoute} from 'vue-router'
+import {toLogin} from '@/router/index'
+import {ElMessageBox} from "element-plus";
 
 export default defineComponent({
   name: '',
@@ -35,12 +44,45 @@ export default defineComponent({
     })
     const dutyPeopleCpt = computed(() => {
       let str = ''
-      str += '值班厅领导:XXX     总值班:XXX    带班领导:XXX    值班员:XXX、XXX、XXX'
+      str += '值班厅领导:XXX     总值班:XXX    带班领导:XXX    值班员:XXX、XXX、XXX少时诵诗书所所所所所所所所所所所所所所所所所所所所所所所所'
       return str
     })
+    const currentDateCpt = computed(() => {
+      let d = ''
+      console.log(new Date(store.state.app.timestamp).getDay())
+      switch (new Date(store.state.app.timestamp).getDay()) {
+        case 0: d = '星期日'
+          break
+        case 1: d = '星期一'
+          break
+        case 2: d = '星期二'
+          break
+        case 3: d = '星期三'
+          break
+        case 4: d = '星期四'
+          break
+        case 5: d = '星期五'
+          break
+        case 6: d = '星期六'
+          break
+      }
+      return that.$util.YMDHms(store.state.app.timestamp) + ' ' + d
+    })
+    const onLogout = () => {
+      ElMessageBox.confirm('请确认是否退出登录!', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: "warning",
+      }).then(() => {
+        that.$api.logout()
+        toLogin()
+      }).catch(() => {})
+    }
     return {
       ...toRefs(state),
-      dutyPeopleCpt
+      dutyPeopleCpt,
+      currentDateCpt,
+      onLogout
     }
   },
 })
@@ -48,8 +90,53 @@ export default defineComponent({
 
 <style scoped lang="scss">
   .head-com {
-    position: absolute;
-    top: 0;
-    right: 0;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: space-between;
+    padding-top: 42px;
+    box-sizing: border-box;
+    background-image: url("@/assets/images/layout/head_bg.png");
+    background-size: 100% 100%;
+    font-size: 14px;
+    font-family: PingFang SC-Regular, PingFang SC;
+    font-weight: 400;
+    color: #2EB8FF;
+    line-height: 20px;
+    .head-com-left {
+      width: 30%;
+      margin-left: 30px;
+      height: fit-content;
+    }
+    .head-com-right {
+      margin-right: 30px;
+      height: fit-content;
+      display: flex;
+      .icon-date, .icon-user {
+        width: 16px;
+        height: 16px;
+        margin-right: 8px;
+        margin-top: 1px;
+      }
+      .date {
+        margin-right: 16px;
+      }
+      .name {
+        margin-right: 4px;
+      }
+      .dept {
+        margin-right: 16px;
+      }
+      .button {
+        background-image: url("@/assets/images/layout/head_exit.png");
+        background-repeat: no-repeat;
+        background-size: 100% 100%;
+        width: 54px;
+        height: 26px;
+        color: #FFFFFF;
+        display: flex;
+        justify-content: center;
+      }
+    }
   }
 </style>

+ 22 - 46
src/layout/index.vue

@@ -3,58 +3,19 @@
     <div class="layout-head">
       <HeadCom/>
     </div>
-    <div class="layout-content">
-      <div class="layout-sub-menu" v-if="hasSubMenu">
+    <div class="layout-main">
+      <div class="layout-main-sub-menu" v-if="hasSubMenu">
         <SubMenuCom/>
       </div>
-      <div class="layout-content">
+      <div class="layout-main-content">
 <!--        <NavigationCom v-if="hasSubMenu"/>-->
-<!--        <RouterViewCom class="content"/>-->
+        <RouterViewCom/>
       </div>
     </div>
     <div class="layout-foot">
       <MenuCom/>
     </div>
   </div>
-<!--  <template v-if="isSpecial">-->
-<!--    <div class="layout-special">-->
-<!--      <div class="layout-head-title">-->
-<!--        <div class="lh-logo __hover" @click="goIndexPage">-->
-<!--          <img class="lh-logo-icon" src="@/assets/images/layout/logo_icon.png"/>-->
-<!--          <div class="lh-logo-title">综合态势防控平台</div>-->
-<!--        </div>-->
-<!--        <SvgIcon name="arrow_1" color="#ffffff" size="20" class="lh-expend __hover" :class="{not: !$store.state.menu.menuExpend}" @click="$store.dispatch('menu/LOAD_SWITCH_MENU_EXPEND')"/>-->
-<!--      </div>-->
-<!--      <MenuCom class="menu" :isSpecial="isSpecial" v-if="$store.state.menu.menuExpend"/>-->
-<!--      <HeadCom class="head"/>-->
-<!--      <RouterViewCom class="content"/>-->
-<!--    </div>-->
-<!--  </template>-->
-<!--  <template v-else>-->
-<!--    <div class="layout">-->
-<!--      <div class="layout-head">-->
-<!--        <div class="bg"/>-->
-<!--        <div class="layout-head-title">-->
-<!--          <div class="lh-logo __hover" @click="goIndexPage">-->
-<!--            <img class="lh-logo-icon" src="@/assets/images/layout/logo_icon.png"/>-->
-<!--            <div class="lh-logo-title">综合态势防控平台</div>-->
-<!--          </div>-->
-<!--          <SvgIcon name="arrow_1" color="#ffffff" size="20" class="lh-expend __hover" :class="{not: !$store.state.menu.menuExpend}" @click="$store.dispatch('menu/LOAD_SWITCH_MENU_EXPEND')"/>-->
-<!--        </div>-->
-<!--        <MenuCom class="menu" :isSpecial="isSpecial"/>-->
-<!--        <HeadCom class="head"/>-->
-<!--      </div>-->
-<!--      <div class="layout-bottom">-->
-<!--        <div class="layout-sub-menu" :class="{expend: $store.state.menu.menuExpend}" v-if="hasSubMenu">-->
-<!--          <SubMenuCom :isExpend="$store.state.menu.menuExpend"/>-->
-<!--        </div>-->
-<!--        <div class="layout-content">-->
-<!--          <NavigationCom v-if="hasSubMenu"/>-->
-<!--          <RouterViewCom class="content"/>-->
-<!--        </div>-->
-<!--      </div>-->
-<!--    </div>-->
-<!--  </template>-->
 </template>
 
 <script lang="ts">
@@ -112,13 +73,28 @@ export default defineComponent({
   align-items: center;
   position: relative;
   .layout-head {
+    position: absolute;
     width: 100%;
-    height: 70px;
+    height: 135px;
+    top: 0;
+    left: 0;
+    z-index: 1;
   }
-  .layout-content {
-    flex: 1;
+  .layout-main {
+    z-index: 2;
+    margin-top: 91px;
+    width: 100%;
+    height: calc(100% - 70px);
+    display: flex;
+    .layout-main-sub-menu {
+
+    }
+    .layout-main-content {
+      flex: 1;
+    }
   }
   .layout-foot {
+    z-index: 3;
     position: absolute;
     bottom: 0;
   }

+ 61 - 108
src/layout/menu/sub-menu.vue

@@ -1,49 +1,16 @@
 <!--左侧二级菜单树-->
 <template>
   <div class="sub-menu-main">
-    <template v-for="(item, index) in $store.state.menu.subMenuRouter">
-      <template v-if="isExpend">
-        <div class="smm-parent">
-          <div class="p-item __hover" :class="{current: item.name === $route.name}" @click="item.children?.length > 0 ? item.expend = !item.expend : toSubMenu(item)">
-            <SvgIcon class="menu-logo" name="menu-mock" size="18" color="#ffffff" rotate="90"/>
+    <div class="sub-menu-main-content">
+      <template v-for="(item, index) in $store.state.menu.subMenuRouter">
+        <div class="sub-menu-item __hover" :class="{active: item.name === $route.name}" @click="toSubMenu(item)">
+          <div class="sub-menu-item-content">
+            <div class="icon"/>
             {{item.meta.title}}
-            <SvgIcon class="menu-expend" name="arrow_2" size="12" color="#ffffff" :class="{active: item.expend}" v-if="item.children?.length > 0"/>
-          </div>
-          <div class="smm-son" v-if="item.children?.length > 0 && item.expend">
-            <template v-for="(subItem, subIndex) in item.children">
-              <div class="s-item __hover" :class="{current: subItem.name === $route.name}" @click="toSubMenu(subItem)">
-                {{subItem.meta.title}}
-              </div>
-            </template>
           </div>
         </div>
       </template>
-      <template v-else>
-        <template v-if="item.children?.length > 0">
-          <el-popover placement="right" :teleported="false" popper-class="smm-parent-son">
-            <template #reference>
-              <div class="smm-parent-not-expend __hover"  :class="{current: item.name === $route.name || item.children?.some(v => v.name === $route.name)}"  @click="toSubMenu(item)">
-                <SvgIcon class="menu-logo" name="menu-mock" size="18" color="#ffffff"/>
-<!--                <SvgIcon class="menu-expend" name="arrow_2" size="12" color="#ffffff" :class="{active: item.expend}" v-if="item.children?.length > 0"/>-->
-              </div>
-            </template>
-            <div class="smm-son">
-              <template v-for="(subItem, subIndex) in item.children">
-                <div class="s-item __hover" :class="{current: subItem.name === $route.name}" @click="toSubMenu(subItem)">
-                  {{subItem.meta.title}}
-                </div>
-              </template>
-            </div>
-          </el-popover>
-        </template>
-        <template v-else>
-          <div class="smm-parent-not-expend __hover"  :class="{current: item.name === $route.name || item.children?.some(v => v.name === $route.name)}"  @click="toSubMenu(item)">
-            <SvgIcon class="menu-logo" name="menu-mock" size="18" color="#ffffff"/>
-<!--            <SvgIcon class="menu-expend" name="arrow_2" size="12" color="#ffffff" :class="{active: item.expend}" v-if="item.children?.length > 0"/>-->
-          </div>
-        </template>
-      </template>
-    </template>
+    </div>
   </div>
 </template>
 
@@ -68,7 +35,6 @@ export default defineComponent({
   name: '',
   components: {},
   props: {
-    isExpend: {}
   },
   setup() {
     const store = useStore();
@@ -101,82 +67,69 @@ export default defineComponent({
 </script>
 
 <style scoped lang="scss">
-  .current {
-    background-color: #0062E9;
-  }
   .sub-menu-main {
-    width: 100%;
-    height: 100%;
-    overflow-y: auto;
-    background: linear-gradient(0deg, #021D78 0%, #0F44B6 100%);
-    padding-top: 13px;
-    .smm-parent {
-      .p-item {
+    width: 290px;
+    height: 918px;
+    background-image: url("@/assets/images/layout/sub-menu_bg.png");
+    background-repeat: no-repeat;
+    background-size: 100% auto;
+    position: relative;
+    .sub-menu-main-content {
+      position: absolute;
+      display: flex;
+      flex-direction: column;
+      top: 172px;
+      left: 30px;
+      .sub-menu-item {
+        width: 185px;
+        height: 66px;
         display: flex;
         align-items: center;
-        height: 44px;
-        line-height: 1;
-        user-select: none;
-        font-size: 14px;
-        font-family: Microsoft YaHei;
-        font-weight: 400;
-        color: #FFFFFF;
-        .menu-logo {
-          margin: 0 13px 0 15px;
+        position: relative;
+        &:after {
+          content: '';
+          position: absolute;
+          bottom: 0;
+          width: 100%;
+          height: 2px;
+          background: linear-gradient(270deg, rgba(51,146,255,0) 0%, #3392FF 51%, rgba(51,146,255,0) 100%);
         }
-        .menu-expend {
-          margin: 0 12px 0 auto;
-          transition: 0.2s;
-          &.active {
-            transform: rotate(90deg) !important;
+        &.active {
+          &:before {
+            content: '';
+            position: absolute;
+            width: 167px;
+            height: 42px;
+            background: linear-gradient(90deg, rgba(0,242,254,0) 0%, #00F2FE 39%, #00F2FE 61%, rgba(0,242,254,0) 95%);
+            z-index: 1;
+            opacity: 0.4;
+          }
+          .sub-menu-item-content {
+            text-shadow: 0px 2px 4px rgba(0,0,0,0.4);
+            color: #FFFFFF;
+            .icon {
+              background-color: #75fbff;
+              box-shadow: 0px 0px 20px 3px #75fbff;
+            }
           }
         }
-      }
-      .smm-son {
-        .s-item {
-          height: 44px;
-          padding-left: 46px;
-          display: flex;
-          align-items: center;
-          line-height: 1.2;
-          user-select: none;
-          font-size: 14px;
-          font-family: Microsoft YaHei;
-          font-weight: 400;
-          color: #FFFFFF;
-        }
-      }
-    }
-    .smm-parent-not-expend {
-      height: 44px;
-      display: flex;
-      align-items: center;
-      .menu-logo {
-        margin: 0 13px 0 15px;
-      }
-    }
-    :deep(.smm-parent-son) {
-      background: #0a369f;
-      border: none;
-      padding: 0;
-      width: auto !important;
-      min-width: 0;
-      .el-popper__arrow::before {
-        background: #0a369f;
-        border-color: #0a369f;
-      }
-      .smm-son {
-        .s-item {
-          padding: 0 20px;
-          height: 44px;
+        .sub-menu-item-content {
+          height: 42px;
+          font-size: 20px;
+          font-family: Microsoft YaHei-Bold, Microsoft YaHei;
+          font-weight: bold;
+          color: rgba(255,255,255,0.5);
           display: flex;
           align-items: center;
-          line-height: 1.2;
-          user-select: none;
-          font-size: 14px;
-          font-family: Microsoft YaHei;
-          font-weight: 400;
-          color: #FFFFFF;
+          padding-left: 30px;
+          z-index: 2;
+          .icon {
+            width: 16px;
+            height: 16px;
+            background-color: rgba(42, 187, 255, 0.3);
+            margin-right: 10px;
+            transform: rotate(45deg);
+          }
         }
       }
     }

+ 10 - 2
src/router/index.ts

@@ -7,6 +7,7 @@ import * as api from '@/api/index'
 import RouterViewCom from "@/layout/router-view.vue";
 import {stagingRouterMap, stagingRouter} from './modules/staging'
 import {systemRouterMap, systemRouter} from './modules/system'
+import {ElMessage} from "element-plus";
 
 export const RoutersMap = new Map([
   ...stagingRouterMap,
@@ -89,10 +90,17 @@ export const toLogin = () => {
 
 export const initMainRouter = async () => {
     if (sessionStorage.getItem("sg_token") && location.pathname !== '/login') {
+        store.dispatch('app/LOAD_TIMESTAMP')
         await Promise.all([
             store.dispatch('app/LOAD_USER_INFO'),
-        ]).then(async ([u]) => {
-            setRouters()
+        ]).then(async ([{u, r}]) => {
+            console.log(r)
+            if (r.some(v => ['ZBY', 'ZBGL'].includes(v.permissionValue))) {
+                setRouters()
+            } else {
+                ElMessage.warning('该账号无系统角色!')
+                toLogin()
+            }
         })
     }
 

+ 25 - 6
src/store/modules/app.ts

@@ -1,11 +1,13 @@
 import * as api from '@/api/index'
-import {getUserInfo} from "@/api/modules/ztpt";
+import {getUserInfo, getUserRoleList} from "@/api/modules/ztpt";
 
 const state = {
 	apiProxy: {
 		ztptApi: 'api-ztpt',	// 总体平台基本接口
 	},
 	userInfo: <any>{},
+	userRoleList: [],
+	timestamp: new Date().getTime()
 }
 
 const getters = {
@@ -15,18 +17,31 @@ const mutations = {
 	SET_USER_INFO(state: any, data: object) {
 		state.userInfo = data
 	},
+	SET_USER_ROLE(state: any, data: object) {
+		state.userRoleList = data
+	},
+	SET_TIMESTAMP(state: any, data: any) {
+		state.timestamp = new Date(data).getTime()
+		setInterval(() => {
+			state.timestamp += 1000
+		}, 1000)
+	},
 }
 
 const actions = {
 	LOAD_USER_INFO({ commit }: any, refresh: boolean = false) {
 		return new Promise((resolve, reject) => {
 			if (refresh || !state.userInfo?.userId) {
-				getUserInfo().then((res: any) => {
-					if (res.code === 0) {
-						commit('SET_USER_INFO', res.userInfo)
-						resolve(state.userInfo)
+				Promise.all([
+					getUserInfo(),
+					getUserRoleList()
+				]).then(([u, r]) => {
+					if (u.code === 0 && r.code === 0) {
+						commit('SET_USER_INFO', u.userInfo)
+						commit('SET_USER_ROLE', r.userRoleList)
+						resolve({u: u.userInfo, r: r.userRoleList})
 					} else {
-						reject(res.msg)
+						reject(u.msg || r.msg)
 					}
 				})
 			} else {
@@ -34,6 +49,10 @@ const actions = {
 			}
 		})
 	},
+	LOAD_TIMESTAMP({ commit }: any) {
+		const date = new Date('2022-09-18 10:20:32')
+		commit('SET_TIMESTAMP', date)
+	},
 }
 
 export default {

+ 4 - 4
src/views/global/login.vue

@@ -48,6 +48,7 @@ import {useStore} from 'vuex'
 import {useRouter, useRoute} from 'vue-router'
 import {ElMessage, FormInstance} from "element-plus";
 import { v4 } from "uuid";
+import {getUserRoleList} from "@/api/modules/ztpt";
 export default defineComponent({
   name: '',
   components: {},
@@ -59,8 +60,8 @@ export default defineComponent({
     const state = reactive({
       form: {
         deviceId: '',
-        username: 'onlytest',
-        password: 'nw_L28s~ck92j',
+        username: 'sg_songpeijie',
+        password: 'SONGPEIJIE@sh*8',
         validCode: ''
       },
       codeImg: '',
@@ -78,9 +79,8 @@ export default defineComponent({
               ElMessage.success(res.msg)
               sessionStorage.setItem('sg_token', res.sessionToken)
               location.replace('/')
-              // store.dispatch('app/LOAD_USER_INFO').then(info => {
-              // })
             } else {
+              initCode()
               ElMessage.warning(res.msg)
             }
             state.loadingForm = false

+ 1 - 0
src/views/staging/index.vue

@@ -1,4 +1,5 @@
 <template>
+  asdas
 </template>
 
 <script lang="ts">