Parcourir la source

feat: 总览管理规定部分

wyf il y a 6 mois
Parent
commit
8f7300fb0a

+ 33 - 0
src/api/security-confidentiality-overview/index.ts

@@ -0,0 +1,33 @@
+import { http } from '@/utils/http/axios';
+
+import type { PersonOverview, VehicleOverview, RegulationItem } from '@/views/security-confidentiality/overview/types';
+
+export async function getPersonOverview() {
+  return http.request<PersonOverview>({
+    url: '/overview/queryOverviewVisitorStatistics',
+    method: 'get',
+  });
+}
+
+export async function getVehicleOverview() {
+  return http.request<VehicleOverview>({
+    url: '/overview/queryVehicleEntryRecordOverview',
+    method: 'get',
+  });
+}
+
+// 查询保卫规定与通知列表总览
+export async function getSecurityOverview() {
+  return http.request<RegulationItem[]>({
+    url: '/overview/queryDefenseRuleNoticeInfoOverview',
+    method: 'get',
+  });
+}
+
+// 查询保密规定与通知列表总览
+export async function getConfidentialityOverview() {
+  return http.request<RegulationItem[]>({
+    url: '/overview/querySecrecyRuleNoticeInfoOverview',
+    method: 'get',
+  });
+}

BIN
src/assets/images/security-confidientiality/overview-more.png


+ 1 - 1
src/views/security-confidentiality/overview/charts/OuterPersonChart.vue

@@ -7,7 +7,7 @@
   import { PieChart } from 'echarts/charts';
   import { CanvasRenderer } from 'echarts/renderers';
   import { onMounted, ref, watch } from 'vue';
-  import type { PieChartData } from './types';
+  import type { PieChartData } from '../types';
 
   const props = defineProps<{
     data: PieChartData[];

+ 1 - 1
src/views/security-confidentiality/overview/charts/OuterPersonChartLegend.vue

@@ -10,7 +10,7 @@
 </template>
 
 <script setup lang="ts">
-  import type { PieChartData } from './types';
+  import type { PieChartData } from '../types';
 
   const props = defineProps<{
     data: PieChartData[];

+ 15 - 7
src/views/security-confidentiality/overview/charts/VehicleChart.vue

@@ -7,7 +7,7 @@
   import { BarChart } from 'echarts/charts';
   import { CanvasRenderer } from 'echarts/renderers';
   import { onMounted, ref, watch } from 'vue';
-  import type { BarChartData } from './types';
+  import type { BarChartData } from '../types';
 
   const props = defineProps<{
     data: BarChartData;
@@ -28,9 +28,14 @@
 
   const drawDoughnut = (doughnut) => {
     const doughnutOption = {
+      xAxis: [
+        {
+          data: props.data.category,
+        },
+      ],
       series: [
         {
-          data: props.data,
+          data: props.data.value,
         },
       ],
     };
@@ -40,6 +45,7 @@
   const initDoughnut = (doughnut) => {
     const doughnutOption = {
       tooltip: {
+        show: true,
         trigger: 'axis',
         axisPointer: {
           type: 'shadow',
@@ -85,7 +91,7 @@
       ],
       series: [
         {
-          name: 'vehicle',
+          name: '车流量',
           type: 'bar',
           barWidth: '30%',
           data: props.data.value,
@@ -95,10 +101,12 @@
               { offset: 1, color: '#1777FF' },
             ]),
           },
-          label: {
-            show: true,
-            position: 'top',
-            color: '#38C3FE',
+          emphasis: {
+            label: {
+              show: true,
+              position: 'top',
+              color: '#38C3FE',
+            },
           },
         },
       ],

+ 0 - 11
src/views/security-confidentiality/overview/charts/types.ts

@@ -1,11 +0,0 @@
-export interface PieChartData {
-  name: string;
-  value: number;
-  id: number;
-  color: string;
-}
-
-export interface BarChartData {
-  category: string[];
-  value: number[];
-}

+ 15 - 6
src/views/security-confidentiality/overview/components/OuterPerson.vue

@@ -4,19 +4,28 @@
       <span class="line"></span>
       <span class="title">外部人员管理</span>
     </div>
-    <OuterPersonChart class="chart-container" id="OuterPersonChart" :data="pieData"></OuterPersonChart>
-    <OuterPersonChartLegend class="chart-legend" :data="pieData"></OuterPersonChartLegend>
+    <OuterPersonChart
+      v-if="pieData.length > 0"
+      class="chart-container"
+      id="OuterPersonChart"
+      :data="pieData"
+    ></OuterPersonChart>
+    <OuterPersonChartLegend v-if="pieData.length > 0" class="chart-legend" :data="pieData"></OuterPersonChartLegend>
   </div>
 </template>
 
 <script setup lang="ts">
+  import { onMounted, ref } from 'vue';
   import OuterPersonChart from '../charts/OuterPersonChart.vue';
   import OuterPersonChartLegend from '../charts/OuterPersonChartLegend.vue';
+  import { getPersonOverviewChartData } from '../hooks';
+  import type { PieChartData } from '../types';
 
-  const pieData = [
-    { value: 90, name: '非外籍访客', id: 1, color: '#3777FD' },
-    { value: 200, name: '外籍访客', id: 2, color: '#F1C7A3' },
-  ];
+  const pieData = ref<PieChartData[]>([]);
+
+  onMounted(async () => {
+    pieData.value = await getPersonOverviewChartData();
+  });
 </script>
 
 <style scoped lang="scss">

+ 126 - 1
src/views/security-confidentiality/overview/components/RegulationAndNotice.vue

@@ -4,10 +4,96 @@
       <span class="line"></span>
       <span class="title">管理规定与通知</span>
     </div>
+    <div class="tab-content">
+      <el-tabs v-model="activeName">
+        <el-tab-pane label="保卫" name="security">
+          <div class="item-content">
+            <div class="regulation-item" v-for="item in securityRegulationData" :key="item.id">
+              <div class="round" @click="handleItemRedirect(item)"> </div>
+              <div class="item-name" @click="handleItemRedirect(item)">{{ item.name }}</div>
+            </div>
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="保密" name="confidentiality">
+          <div class="item-content">
+            <div class="regulation-item" v-for="item in confidentialityRegulationData" :key="item.id">
+              <div class="round" @click="handleItemRedirect(item)"> </div>
+              <div class="item-name" @click="handleItemRedirect(item)">{{ item.name }}</div>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+    <div class="more">
+      <span style="padding-right: 5px; cursor: pointer" @click="handleMoreRedirect">更多</span>
+      <img
+        style="cursor: pointer"
+        @click="handleMoreRedirect"
+        src="@/assets/images/security-confidientiality/overview-more.png"
+        alt=""
+      />
+    </div>
   </div>
 </template>
 
-<script setup lang="ts"></script>
+<script setup lang="ts">
+  import { onUnmounted, ref, watch } from 'vue';
+  import { useRouter } from 'vue-router';
+  import type { RegulationItem } from '../types';
+  import { getSecurityOverview, getConfidentialityOverview } from '@/api/security-confidentiality-overview';
+
+  const router = useRouter();
+  const activeName = ref(sessionStorage.getItem('security-confidentiality-overview-active') || 'security');
+
+  const securityRegulationData = ref<RegulationItem[]>([]);
+  const confidentialityRegulationData = ref<RegulationItem[]>([]);
+
+  async function getSecurityRegulationData() {
+    securityRegulationData.value = await getSecurityOverview();
+  }
+
+  async function getConfidentialityRegulationData() {
+    confidentialityRegulationData.value = await getConfidentialityOverview();
+  }
+
+  onUnmounted(() => {
+    sessionStorage.setItem('security-confidentiality-overview-active', activeName.value);
+  });
+
+  watch(
+    () => activeName.value,
+    (val) => {
+      if (val === 'security') {
+        getSecurityRegulationData();
+      } else if (val === 'confidentiality') {
+        getConfidentialityRegulationData();
+      }
+    },
+    {
+      immediate: true,
+    },
+  );
+
+  function handleItemRedirect(item: RegulationItem) {
+    sessionStorage.setItem(`${activeName.value}-regulation-active`, 'regulation');
+    if (item.managementType === 1) {
+      router.push({
+        path: `/security-confidentiality/${activeName.value}-regulation-notice`,
+      });
+    } else if (item.managementType === 2) {
+      router.push({
+        path: `/security-confidentiality/${activeName.value}-regulation-notice-item`,
+        query: { id: item.id, operate: 'notice-view' },
+      });
+    }
+  }
+  function handleMoreRedirect() {
+    sessionStorage.setItem(`${activeName.value}-regulation-active`, 'regulation');
+    router.push({
+      path: `/security-confidentiality/${activeName.value}-regulation-notice`,
+    });
+  }
+</script>
 
 <style scoped lang="scss">
   .container-title {
@@ -35,4 +121,43 @@
     height: 100%;
     padding-top: 14px;
   }
+  .tab-content {
+    height: calc(100% - 50px);
+    padding: 0 10px;
+  }
+  .regulation-item {
+    padding: 7px 0;
+    display: flex;
+    align-items: center;
+  }
+  .round {
+    width: 6px;
+    height: 6px;
+    background: #1777ff;
+    border-radius: 50%;
+    margin-right: 6px;
+    cursor: pointer;
+  }
+  .item-name {
+    max-width: calc(100% - 12px);
+    color: rgba($color: #000000, $alpha: 0.85);
+    font-size: 12px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    cursor: pointer;
+  }
+  .more {
+    text-align: end;
+    color: #007bff;
+    font-size: 12px;
+    padding: 0 10px;
+  }
+
+  :deep(.el-tabs__header) {
+    margin: 0;
+  }
+  :deep(.el-tabs__item) {
+    font-size: 14px !important;
+  }
 </style>

+ 10 - 7
src/views/security-confidentiality/overview/components/VehicleManagement.vue

@@ -9,20 +9,23 @@
       <span class="vehicle-flow-label">今日车流量</span>
       <span class="vehicle-flow-value">{{ lastDayFlow }}</span>
     </div>
-    <VehicleChart class="chart-container" :data="chartData" id="VehicleChart" />
+    <VehicleChart v-if="barData" class="chart-container" :data="barData" id="VehicleChart" />
   </div>
 </template>
 
 <script setup lang="ts">
+  import { onMounted, ref } from 'vue';
   import VehicleChart from '../charts/VehicleChart.vue';
-  import type { BarChartData } from '../charts/types';
+  import { getVehicleOverviewChartData, getLastDayFlow } from '../hooks';
+  import type { BarChartData } from '../types';
 
-  const chartData: BarChartData = {
-    category: ['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04', '2022-01-05', '2022-01-06', '2022-01-07'],
-    value: [10, 20, 30, 40, 50, 60, 70],
-  };
+  const barData = ref<BarChartData>();
+  const lastDayFlow = ref<number>(0);
 
-  const lastDayFlow = 99999;
+  onMounted(async () => {
+    barData.value = await getVehicleOverviewChartData();
+    lastDayFlow.value = await getLastDayFlow();
+  });
 </script>
 
 <style scoped lang="scss">

+ 36 - 0
src/views/security-confidentiality/overview/hooks.ts

@@ -0,0 +1,36 @@
+import { getPersonOverview, getVehicleOverview } from '@/api/security-confidentiality-overview';
+import type { PersonOverview, PieChartData, VehicleOverview, BarChartData } from './types';
+import dayjs from 'dayjs';
+import { getVehicleRecordList } from '@/api/security-confidentiality-vehicle';
+
+export async function getPersonOverviewChartData() {
+  const personOverview: PersonOverview = await getPersonOverview();
+  return [
+    { name: '非外籍访客', value: personOverview.nonForeignVisitorCount, id: 1, color: '#3777FD' },
+    { name: '外籍访客', value: personOverview.foreignVisitorCount, id: 2, color: '#F1C7A3' },
+  ] as PieChartData[];
+}
+
+export async function getVehicleOverviewChartData() {
+  const vehicleOverview: VehicleOverview = await getVehicleOverview();
+  return {
+    category: vehicleOverview.vehicleEntryRecordList.map((item) => item.date),
+    value: vehicleOverview.vehicleEntryRecordList.map((item) => item.vehicleCount),
+  } as BarChartData;
+}
+
+export async function getLastDayFlow() {
+  const searchTime = [
+    dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss'),
+    dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss'),
+  ];
+  const list = await getVehicleRecordList({
+    pageNumber: 1,
+    pageSize: 1,
+    queryParam: {
+      startTime: searchTime[0],
+      endTime: searchTime[1],
+    },
+  });
+  return list.totalRow;
+}

+ 29 - 0
src/views/security-confidentiality/overview/types.ts

@@ -0,0 +1,29 @@
+export interface PieChartData {
+  name: string;
+  value: number;
+  id: number;
+  color: string;
+}
+
+export interface BarChartData {
+  category: string[];
+  value: number[];
+}
+
+export interface PersonOverview {
+  nonForeignVisitorCount: number;
+  foreignVisitorCount: number;
+}
+
+export interface VehicleOverview {
+  vehicleEntryRecordList: {
+    date: string;
+    vehicleCount: number;
+  }[];
+}
+
+export interface RegulationItem {
+  id: number;
+  managementType: number;
+  name: string;
+}