ソースを参照

管理员工作台右侧列表

CzRger 1 年間 前
コミット
1ce9ac3aa3

BIN
src/assets/images/business/clue-icon.png


BIN
src/assets/images/business/notice-tz.png


BIN
src/assets/images/business/notice-xx.png


BIN
src/assets/images/business/sign-false.png


BIN
src/assets/images/business/sign-true.png


+ 1 - 0
src/style/index.scss

@@ -5,6 +5,7 @@
 * {
   outline: none;  // dom元素选中带边框
   -webkit-user-drag: none;
+  line-height: 1;
 }
 
 html, body {

+ 8 - 1
src/views/staging/common/base-block.vue

@@ -53,8 +53,9 @@ export default defineComponent({
     width: 100%;
     display: flex;
     flex-direction: column;
+    $h: 48px;
     .base-block-title {
-      height: 48px;
+      height: $h;
       width: 100%;
       display: flex;
       align-items: center;
@@ -93,14 +94,20 @@ export default defineComponent({
         position: relative;
         display: flex;
         align-items: center;
+        justify-content: flex-end;
         &:after {
           content: '';
           position: absolute;
           width: 100%;
           height: 20px;
           background-color: rgba(0,133,247,0.2);
+          z-index: -1;
         }
       }
     }
+    .base-block-content {
+      width: 100%;
+      height: calc(100% - #{$h});
+    }
   }
 </style>

+ 2 - 2
src/views/staging/common/base.scss

@@ -7,7 +7,7 @@
   box-sizing: border-box;
   .staging-left {
     width: 438px;
-    height: 100%;
+    margin-bottom: 24px;
   }
   .staging-center {
     width: 925px;
@@ -15,6 +15,6 @@
   }
   .staging-right {
     width: 438px;
-    height: 100%;
+    margin-bottom: 24px;
   }
 }

+ 47 - 2
src/views/staging/common/button-switch.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="button-switch">
     <template v-for="item in options">
-      <div class="button-switch-item" :class="{[`button-switch-item-${type}`]: true, active: item.value === activeV}" @click="$emit('update:activeV', item.value)">
+      <div class="button-switch-item __hover" :class="{[`button-switch-item-${type}`]: true, active: item.value === active}" @click="$emit('update:active', item.value), $emit('buttonClick', item)">
         {{item.label}}
       </div>
     </template>
@@ -37,7 +37,7 @@ export default defineComponent({
     options: {
       default: () => []
     },
-    activeV: {
+    active: {
       default: ''
     }
   },
@@ -56,4 +56,49 @@ export default defineComponent({
 </script>
 
 <style scoped lang="scss">
+  .button-switch {
+    display: flex;
+    align-items: center;
+    .button-switch-item {
+      padding: v-bind(padding);
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      box-sizing: border-box;
+      line-height: 1;
+      &.button-switch-item-type1 {
+        border: 1px solid rgba(0, 133, 247, 0.2);
+        background-color: #08294b;
+        font-size: 12px;
+        font-family: FZLanTingHeiS-DB-GB;
+        font-weight: 400;
+        color: rgba(255, 255, 255, 0.4);
+        margin-right: 10px;
+        &:last-child {
+          margin-right: 0;
+        }
+        &.active {
+          border-color: #0085F7;
+          color: #E2EBF1;
+        }
+      }
+      &.button-switch-item-type2 {
+        background-color: rgba(12,78,134,0.3);
+        border: 1px solid #2C85FF;
+        margin-right: 10px;
+        transform: skewX(-20deg);
+        font-size: 12px;
+        font-family: Microsoft YaHei;
+        font-weight: 400;
+        &:last-child {
+          margin-right: 0;
+        }
+        &.active {
+          border-color: #3FECFF;
+          background-color: #0C4E86;
+          color: #3FECFF;
+        }
+      }
+    }
+  }
 </style>

+ 9 - 0
src/views/staging/common/handle.ts

@@ -0,0 +1,9 @@
+export const formatDate = (d) => {
+  const _date = new Date(d)
+  const Y = _date.getFullYear()
+  const M = _date.getMonth() + 1
+  const D = _date.getDate()
+  const H = `${_date.getHours() < 10 ? `0${_date.getHours()}` : _date.getHours()}`;
+  const m = `${_date.getMinutes() < 10 ? `0${_date.getMinutes()}` : _date.getMinutes()}`;
+  return `${Y}/${M}/${D} ${H}:${m}`;
+}

+ 32 - 6
src/views/staging/zbgly/index.vue

@@ -4,8 +4,12 @@
       <CalendarCom class="calendar-main"/>
       <AnalysisCom class="analysis-main"/>
     </div>
-    <div class="staging-center">2</div>
-    <div class="staging-right">3</div>
+<!--    <div class="staging-center">2</div>-->
+    <div class="staging-right">
+      <NoticeCom class="notice-main"/>
+      <ClueCom class="clue-main"/>
+      <AttendanceCom class="attendance-main"/>
+    </div>
   </div>
 </template>
 
@@ -26,12 +30,18 @@ import {useStore} from 'vuex'
 import {useRouter, useRoute} from 'vue-router'
 import AnalysisCom from "./left/analysis-com.vue";
 import CalendarCom from "./left/calendar-com.vue";
+import NoticeCom from "./right/notice-com.vue";
+import ClueCom from "./right/clue-com.vue";
+import AttendanceCom from "./right/attendance-com.vue";
 
 export default defineComponent({
   name: '',
   components: {
     AnalysisCom,
-    CalendarCom
+    CalendarCom,
+    NoticeCom,
+    ClueCom,
+    AttendanceCom
   },
   setup(props, {emit}) {
     const store = useStore();
@@ -47,8 +57,24 @@ export default defineComponent({
 </script>
 
 <style scoped lang="scss">
-.charts {
-  width: 100%;
-  height: 400px;
+.staging-left {
+  display: flex;
+  flex-direction: column;
+  .calendar-main {
+    width: 100%;
+    height: calc(100% / 3 * 2);
+  }
+  .analysis-main {
+    width: 100%;
+    height: calc(100% / 3);
+  }
+}
+.staging-right {
+  display: flex;
+  flex-direction: column;
+  >div {
+    width: 100%;
+    height: calc(100% / 3);
+  }
 }
 </style>

+ 37 - 2
src/views/staging/zbgly/left/analysis-com.vue

@@ -1,4 +1,21 @@
 <template>
+  <BaseBlockCom title="趋势分析">
+    <template #title>
+      <ButtonSwitchCom style="margin-right: 14px" :options="[
+          {label: '考勤', value: '1'},
+          {label: '日志', value: '2'},
+          {label: '周报', value: '3'},
+      ]" padding="6px 20px" type="type2" v-model:active="sourceType"/>
+    </template>
+    <div class="content">
+      <ButtonSwitchCom class="buttons" :options="[
+          {label: '日', value: '1'},
+          {label: '月', value: '2'},
+          {label: '年', value: '3'},
+      ]" padding="3px 12px" v-model:active="dateType"/>
+      <TrendAnalysisChart class="charts"/>
+    </div>
+  </BaseBlockCom>
 </template>
 
 <script lang="ts">
@@ -18,19 +35,24 @@ import {useStore} from 'vuex'
 import {useRouter, useRoute} from 'vue-router'
 import BaseBlockCom from '../../common/base-block.vue'
 import ButtonSwitchCom from '../../common/button-switch.vue'
+import TrendAnalysisChart from './trend-analysis-chart.vue'
 
 export default defineComponent({
   name: '',
   components: {
     BaseBlockCom,
-    ButtonSwitchCom
+    ButtonSwitchCom,
+    TrendAnalysisChart
   },
   setup(props, {emit}) {
     const store = useStore();
     const router = useRouter();
     const route = useRoute();
     const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
-    const state = reactive({})
+    const state = reactive({
+      sourceType: '1',
+      dateType: '1'
+    })
     return {
       ...toRefs(state)
     }
@@ -39,4 +61,17 @@ export default defineComponent({
 </script>
 
 <style scoped lang="scss">
+.content {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  height: 100%;
+  width: 100%;
+  .buttons {
+    margin-top: 16px;
+  }
+  .charts {
+    flex: 1;
+  }
+}
 </style>

+ 0 - 1
src/views/staging/zbgly/left/calendar-com.vue

@@ -1,6 +1,5 @@
 <template>
   <BaseBlockCom title="日历提醒">
-
   </BaseBlockCom>
 </template>
 

+ 2 - 2
src/views/staging/zbgly/left/trend-analysis-chart.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="chart-main">
-    <div class="chart" ref="ref_chart"/>
+    <div class="chart-ref" ref="ref_chart"/>
   </div>
 </template>
 
@@ -140,7 +140,7 @@ export default defineComponent({
   .chart-main {
     width: 100%;
     height: 100%;
-    .chart {
+    .chart-ref {
       width: 100%;
       height: 100%;
     }

+ 204 - 0
src/views/staging/zbgly/right/attendance-com.vue

@@ -0,0 +1,204 @@
+<template>
+  <BaseBlockCom title="考勤情况" style="position: relative;">
+    <template #title>
+      <div class="more">查看更多》</div>
+    </template>
+    <ButtonSwitchCom class="buttons" :options="[
+          {label: '昨日', value: '1'},
+          {label: '上周', value: '2'},
+          {label: '上月', value: '3'},
+          {label: '自定义', value: '4'},
+      ]" padding="3px 12px" v-model:active="dateType" @buttonClick="handleButtonClick"/>
+    <div class="list">
+      <template v-for="(item, index) in list">
+        <div class="item">
+          <div class="index">{{index < 9 ? '0' : ''}}{{index + 1}}</div>
+          <div class="title __text-ellipsis">{{item.title}}</div>
+          <template v-if="item.status === 1">
+            <div class="status status-true">
+              已签到({{item.total}}次)
+            </div>
+          </template>
+          <template v-else-if="item.status === 2">
+            <div class="status status-false">
+              <template v-if="item.type === 1">
+                迟到
+              </template>
+              <template v-else-if="item.type === 2">
+                缺勤
+              </template>
+              <template v-else-if="item.type === 3">
+                早退({{item.total}}次)
+              </template>
+            </div>
+          </template>
+        </div>
+      </template>
+    </div>
+<!--    <div class="opacity-block"/>-->
+    <CusDialog
+        title="考勤情况"
+        v-model:show="showTimeDialog"
+        @submit="showTimeDialog = false"
+        footAlign="right"
+        height="180px"
+        width="400px"
+    >
+      <div class="__normal-form">
+        <CusForm labelWidth="100px" ref="ref_form">
+          <CusFormColumn
+              :span="24"
+              label="自定义日期:"
+              link="date"
+              type="daterange"
+              v-model:param="cusDate"/>
+        </CusForm>
+      </div>
+    </CusDialog>
+  </BaseBlockCom>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  computed,
+  onMounted,
+  ref,
+  reactive,
+  watch,
+  getCurrentInstance,
+  ComponentInternalInstance,
+  toRefs,
+  nextTick
+} from 'vue'
+import {useStore} from 'vuex'
+import {useRouter, useRoute} from 'vue-router'
+import BaseBlockCom from '../../common/base-block.vue'
+import ButtonSwitchCom from '../../common/button-switch.vue'
+import * as Handle from '../../common/handle'
+
+export default defineComponent({
+  name: '',
+  components: {
+    BaseBlockCom,
+    ButtonSwitchCom,
+  },
+  setup(props, {emit}) {
+    const store = useStore();
+    const router = useRouter();
+    const route = useRoute();
+    const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
+    const state = reactive({
+      Handle: Handle,
+      list: [
+        {status: 1, title: '太极计算机股份有限公司', total: 20},
+        {status: 1, title: '太极计算机股份有限公司', total: 2},
+        {status: 2, title: '中电科国海信通科技(海南)有限公司中电科国海信通科技(海南)有限公司', type: 3, total: 20},
+        {status: 2, title: '消防总队', type: 1},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+        {status: 2, title: '消防总队', type: 2},
+      ],
+      dateType: '1',
+      showTimeDialog: false,
+      cusDate: ''
+    })
+    const handleButtonClick = (val) => {
+      if (val.value === '4') {
+        console.log(val)
+        state.showTimeDialog = true
+      }
+    }
+    return {
+      ...toRefs(state),
+      handleButtonClick
+    }
+  },
+})
+</script>
+
+<style scoped lang="scss">
+.more {
+  font-size: 12px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #2EB8FF;
+  margin-right: 10px;
+}
+$buttonsHeight: 30px;
+.buttons {
+  height: $buttonsHeight;
+  justify-content: center;
+}
+.list {
+  width: 100%;
+  height: calc(100% - #{$buttonsHeight});
+  display: flex;
+  flex-direction: column;
+  padding-left: 10px;
+  box-sizing: border-box;
+  overflow-y: auto;
+  position: relative;
+  .item {
+    display: flex;
+    align-items: center;
+    font-size: 14px;
+    font-family: Microsoft YaHei;
+    font-weight: 400;
+    color: #C5D0D4;
+    width: 100%;
+    margin-bottom: 8px;
+    &:last-child {
+      margin-bottom: 0;
+    }
+    .index {
+      margin-left: 27px;
+      width: 50px;
+    }
+    .title {
+      max-width: 230px;
+    }
+    .status {
+      width: 87px;
+      height: 26px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background-repeat: no-repeat;
+      background-size: 100% 100%;
+      font-size: 12px;
+      font-family: Adobe Heiti Std;
+      font-weight: normal;
+      margin-left: auto;
+      &.status-true {
+        background-image: url("@/assets/images/business/sign-true.png");
+        color: #3EFFBB;
+      }
+      &.status-false {
+        background-image: url("@/assets/images/business/sign-false.png");
+        color: #E5004F;
+      }
+    }
+  }
+}
+//.opacity-block {
+//  width: 100%;
+//  height: 100px;
+//  position: absolute;
+//  bottom: 0;
+//  background: linear-gradient(180deg, rgba(5, 26, 50, 0.5) 0%, rgba(5, 26, 50, 1) 100%);
+//
+//}
+</style>

+ 118 - 0
src/views/staging/zbgly/right/clue-com.vue

@@ -0,0 +1,118 @@
+<template>
+  <BaseBlockCom title="线索及研判报告">
+    <template #title>
+      <ButtonSwitchCom style="margin-right: 14px" :options="[
+          {label: '日报', value: '1'},
+          {label: '周报', value: '2'},
+      ]" padding="6px 16px" type="type2" v-model:active="sourceType"/>
+      <div class="more">查看更多》</div>
+    </template>
+    <ButtonSwitchCom class="buttons" :options="[
+          {label: '按日', value: '1'},
+          {label: '按周', value: '2'},
+          {label: '按月', value: '3'},
+      ]" padding="3px 12px" v-model:active="dateType"/>
+    <div class="list">
+      <template v-for="item in list">
+        <div class="item">
+          <img src="@/assets/images/business/clue-icon.png"/>
+          <div class="title __text-ellipsis">{{item.title}}</div>
+          <div class="time">{{Handle.formatDate(item.time)}}</div>
+        </div>
+      </template>
+    </div>
+  </BaseBlockCom>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  computed,
+  onMounted,
+  ref,
+  reactive,
+  watch,
+  getCurrentInstance,
+  ComponentInternalInstance,
+  toRefs,
+  nextTick
+} from 'vue'
+import {useStore} from 'vuex'
+import {useRouter, useRoute} from 'vue-router'
+import BaseBlockCom from '../../common/base-block.vue'
+import ButtonSwitchCom from '../../common/button-switch.vue'
+import * as Handle from '../../common/handle'
+
+export default defineComponent({
+  name: '',
+  components: {
+    BaseBlockCom,
+    ButtonSwitchCom,
+  },
+  setup(props, {emit}) {
+    const store = useStore();
+    const router = useRouter();
+    const route = useRoute();
+    const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
+    const state = reactive({
+      Handle: Handle,
+      list: [
+        {type: 1, title: '系统新版本升级V1.1通知,新功能系统新版本升级V1.1通知,新功能', time: '2023-09-01 13:22:33'},
+        {type: 2, title: '系统新版本升级V1.1通知,新功能系统新版本升级V1.1通知,新功能', time: '2023-11-22 13:22:33'},
+        {type: 1, title: '系统新版本升级V1.1通知', time: '2023-11-01 13:22:33'},
+        {type: 1, title: '系统新版本升级V1.1通知', time: '2023-11-01 13:22:33'},
+        {type: 1, title: '系统新版本升级V1.1通知', time: '2023-11-01 13:22:33'},
+        {type: 2, title: '系统新版本升级V1.1通知', time: '2023-11-01 13:22:33'},
+        {type: 1, title: '系统新版本升级V1.1通知', time: '2023-11-01 13:22:33'},
+      ],
+      sourceType: '1',
+      dateType: '1'
+    })
+    return {
+      ...toRefs(state)
+    }
+  },
+})
+</script>
+
+<style scoped lang="scss">
+.more {
+  font-size: 12px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #2EB8FF;
+  margin-right: 10px;
+}
+$buttonsHeight: 30px;
+.buttons {
+  height: $buttonsHeight;
+  justify-content: center;
+}
+.list {
+  width: 100%;
+  height: calc(100% - #{$buttonsHeight});
+  overflow: hidden;
+  display: grid;
+  grid-template-rows: repeat(7, 1fr);
+  padding: 0 10px;
+  box-sizing: border-box;
+  .item {
+    display: flex;
+    align-items: center;
+    font-size: 14px;
+    font-family: Microsoft YaHei;
+    font-weight: 400;
+    color: #C5D0D4;
+    width: 100%;
+    >img {
+      margin-right: 8px;
+    }
+    .title {
+      max-width: 260px;
+    }
+    .time {
+      margin-left: auto;
+    }
+  }
+}
+</style>

+ 131 - 0
src/views/staging/zbgly/right/notice-com.vue

@@ -0,0 +1,131 @@
+<template>
+  <BaseBlockCom title="通知公告">
+    <template #title>
+      <div class="more">查看更多》</div>
+    </template>
+    <div class="list">
+      <template v-for="item in list">
+        <div class="item __hover" @click="onView(item)">
+          <div class="type" :class="`type-${item.type}`">{{item.type === 1 ? '消息' : '通知'}}</div>
+          <div class="title __text-ellipsis">{{item.title}}</div>
+          <div class="time">{{Handle.formatDate(item.time)}}</div>
+        </div>
+      </template>
+    </div>
+    <NoticeDetailCom v-model:show="showDetail" :transfer="transfer"/>
+  </BaseBlockCom>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  computed,
+  onMounted,
+  ref,
+  reactive,
+  watch,
+  getCurrentInstance,
+  ComponentInternalInstance,
+  toRefs,
+  nextTick
+} from 'vue'
+import {useStore} from 'vuex'
+import {useRouter, useRoute} from 'vue-router'
+import BaseBlockCom from '../../common/base-block.vue'
+import * as Handle from '../../common/handle'
+import NoticeDetailCom from '@/views/system/notice-announcement/detail.vue'
+
+export default defineComponent({
+  name: '',
+  components: {
+    BaseBlockCom,
+    NoticeDetailCom
+  },
+  setup(props, {emit}) {
+    const store = useStore();
+    const router = useRouter();
+    const route = useRoute();
+    const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
+    const state = reactive({
+      Handle: Handle,
+      list: [
+        {type: 1, title: '系统新版本升级V1.1通知,新功能系统新版本升级V1.1通知,新功能', time: '2023-09-01 13:22:33'},
+        {type: 2, title: '系统新版本升级V1.1通知,新功能系统新版本升级V1.1通知,新功能', time: '2023-11-22 13:22:33'},
+        {type: 1, title: '系统新版本升级V1.1通知', time: '2023-11-01 13:22:33'},
+        {type: 1, title: '系统新版本升级V1.1通知', time: '2023-11-01 13:22:33'},
+        {type: 1, title: '系统新版本升级V1.1通知', time: '2023-11-01 13:22:33'},
+        {type: 2, title: '系统新版本升级V1.1通知', time: '2023-11-01 13:22:33'},
+        {type: 1, title: '系统新版本升级V1.1通知', time: '2023-11-01 13:22:33'},
+      ],
+      showDetail: false,
+      transfer: {}
+    })
+    const onView = (val) => {
+      state.transfer = {
+        method: 'view',
+        detail: val
+      }
+      state.showDetail = true
+    }
+    return {
+      ...toRefs(state),
+      onView
+    }
+  },
+})
+</script>
+
+<style scoped lang="scss">
+.more {
+  font-size: 12px;
+  font-family: Microsoft YaHei;
+  font-weight: 400;
+  color: #2EB8FF;
+  margin-right: 10px;
+}
+.list {
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  display: grid;
+  grid-template-rows: repeat(7, 1fr);
+  padding: 0 10px;
+  box-sizing: border-box;
+  .item {
+    display: flex;
+    align-items: center;
+    font-size: 14px;
+    font-family: Microsoft YaHei;
+    font-weight: 400;
+    color: #C5D0D4;
+    width: 100%;
+    .type {
+      width: 46px;
+      height: 25px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background-repeat: no-repeat;
+      background-size: 100% 100%;
+      font-size: 12px;
+      padding-bottom: 2px;
+      box-sizing: border-box;
+      margin-right: 8px;
+      &.type-1 {
+        color: #20D9AA;
+        background-image: url("@/assets/images/business/notice-xx.png");
+      }
+      &.type-2 {
+        color: #F2C347;
+        background-image: url("@/assets/images/business/notice-tz.png");
+      }
+    }
+    .title {
+      max-width: 230px;
+    }
+    .time {
+      margin-left: auto;
+    }
+  }
+}
+</style>