From d815fbd281d6bb9c1fff1712614bf9738fd32d73 Mon Sep 17 00:00:00 2001
From: zhouwx <1175765986@qq.com>
Date: 星期四, 15 八月 2024 17:29:12 +0800
Subject: [PATCH] 工作台

---
 src/layout/components/Sidebar/menu.js                 |   34 +++
 src/api/hazardousChemicals/count.js                   |   38 +++
 package.json                                          |    3 
 src/api/hazardousChemicals/warning.js                 |    8 
 src/views/hazardousChemicals/overdueWarning/index.vue |   37 +++
 src/views/hazardousChemicals/traceableQuery/index.vue |   21 +-
 src/views/hazardousChemicals/homePage/index.vue       |  428 ++++++++++++++++++++++++++++++++++++++++++
 src/router/index.js                                   |   14 +
 8 files changed, 560 insertions(+), 23 deletions(-)

diff --git a/package.json b/package.json
index 7c2504d..1d3e356 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
     "@wangeditor/editor-for-vue": "^5.1.12",
     "@wangeditor/plugin-upload-attachment": "^1.1.0",
     "axios": "0.27.2",
-    "echarts": "5.4.0",
+    "echarts": "^5.4.0",
     "element-plus": "2.2.27",
     "file-saver": "2.0.5",
     "fuse.js": "6.6.2",
@@ -43,6 +43,7 @@
     "vue-qr": "^4.0.9",
     "vue-quill-editor": "^3.0.6",
     "vue-router": "4.1.4",
+    "vue3-count-to": "^1.1.2",
     "vue3-json-excel": "^1.0.10-alpha",
     "wangeditor5-for-vue3": "^0.1.0"
   },
diff --git a/src/api/hazardousChemicals/count.js b/src/api/hazardousChemicals/count.js
new file mode 100644
index 0000000..cb84b3d
--- /dev/null
+++ b/src/api/hazardousChemicals/count.js
@@ -0,0 +1,38 @@
+import request from "@/utils/request";
+
+export function getHoData() {
+    return request({
+        url: '/statistic/homeDataStatistic',
+        method: 'get',
+    })
+}
+
+export function getEntryData() {
+    return request({
+        url: '/statistic/entryStatistic',
+        method: 'get',
+    })
+}
+
+export function getUseData() {
+    return request({
+        url: '/statistic/useStatistic',
+        method: 'get',
+    })
+}
+
+export function getMaxUseData() {
+    return request({
+        url: '/statistic/maxUseStatistic',
+        method: 'get',
+    })
+}
+
+
+export function getHazmatUseList(params) {
+    return request({
+        url: '/statistic/hazmatUseStatistic',
+        method: 'get',
+        data: params
+    })
+}
diff --git a/src/api/hazardousChemicals/warning.js b/src/api/hazardousChemicals/warning.js
index e26e81f..c442af6 100644
--- a/src/api/hazardousChemicals/warning.js
+++ b/src/api/hazardousChemicals/warning.js
@@ -14,3 +14,11 @@
         method: 'delete'
     })
 }
+
+export function handleWarning(params) {
+    return request({
+        url: `/warning/markWarning`,
+        method: 'put',
+        data: params
+    })
+}
diff --git a/src/layout/components/Sidebar/menu.js b/src/layout/components/Sidebar/menu.js
index 28af68b..b017f9e 100644
--- a/src/layout/components/Sidebar/menu.js
+++ b/src/layout/components/Sidebar/menu.js
@@ -2,6 +2,19 @@
 const menu = {
     adminMenu: [
         {
+            path: '/homePage',
+            redirect: '/homePage',
+            meta: { title: '首页',icon: 'server'},
+            children: [
+
+                {
+                    path: 'homePage',
+                    name: 'company',
+                    meta: { title: '工作台',icon: 'server'}
+                } ,
+            ]
+        },
+        {
             path: '/warehouseManage',
             name: 'warehouseManage',
             meta: { title: '入库管理',icon: 'form',affix: true }
@@ -35,12 +48,12 @@
         {
             path: '/basicInfo',
             name: 'basicInfo',
-            meta: { title: '危化品基础信息',icon: 'server',affix: true }
+            meta: { title: '危化品基础信息',icon: 'monitor',affix: true }
         },
         {
             path: '/finishedBasicInfo',
             name: 'finishedBasicInfo',
-            meta: { title: '成品基础信息',icon: 'server',affix: true }
+            meta: { title: '成品基础信息',icon: 'monitor',affix: true }
         },
         {
             path: '/systemManage',
@@ -71,6 +84,19 @@
         },
     ],
     companyMenu: [
+        {
+            path: '/homePage',
+            redirect: '/homePage',
+            meta: { title: '首页',icon: 'server'},
+            children: [
+
+                {
+                    path: 'homePage',
+                    name: 'company',
+                    meta: { title: '工作台',icon: 'server'}
+                } ,
+            ]
+        },
         {
             path: '/warehouseManage',
             name: 'warehouseManage',
@@ -104,12 +130,12 @@
         {
             path: '/basicInfo',
             name: 'basicInfo',
-            meta: { title: '危化品基础信息',icon: 'server',affix: true }
+            meta: { title: '危化品基础信息',icon: 'monitor',affix: true }
         },
         {
             path: '/finishedBasicInfo',
             name: 'finishedBasicInfo',
-            meta: { title: '成品基础信息',icon: 'server',affix: true }
+            meta: { title: '成品基础信息',icon: 'monitor',affix: true }
         },
         {
             path: '/systemManage',
diff --git a/src/router/index.js b/src/router/index.js
index 00443bb..f215420 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -183,6 +183,20 @@
     ]
   },
   {
+    path: '/homePage',
+    component: Layout,
+    redirect: '/homePage',
+    meta: { title: '首页'},
+    children: [
+      {
+        path: 'homePage',
+        component: () => import('@/views/hazardousChemicals/homePage/index.vue'),
+        name: 'homePage',
+        meta: { title: '工作台',icon: 'form'}
+      },
+    ]
+  },
+  {
     path: '/systemManage',
     component: Layout,
     redirect: '/systemManage/warehouse',
diff --git a/src/views/hazardousChemicals/homePage/index.vue b/src/views/hazardousChemicals/homePage/index.vue
new file mode 100644
index 0000000..ea7e813
--- /dev/null
+++ b/src/views/hazardousChemicals/homePage/index.vue
@@ -0,0 +1,428 @@
+<template>
+  <div class="homePage">
+    <el-row :gutter="20" justify="space-between" style="margin-bottom: 15px">
+      <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" v-for="(item,index) in data.cardList" :key="index">
+        <el-card style="margin-bottom: 5px">
+          <div class="cardContent">
+            <img :src='item.imgUrl' :class="index !== 3 ? 'imgW' :'imgT' " />
+            <div class="cardRight">
+              <span style="font-size: 17px">{{item.title}}</span>
+              <countTo
+                  style="font-weight: 700;font-size: 22px"
+                  :startVal="item.startVal"
+                  :endVal="item.endVal"
+                  :duration="item.duration"
+              >
+              </countTo>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+    <div>
+      <el-row :gutter="20" justify="space-between" style="margin-bottom: 15px">
+        <el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
+          <el-card style="margin-bottom: 5px">
+            <div :id="pieChart" style="width: 100%;height: 300px"></div>
+          </el-card>
+        </el-col>
+        <el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
+          <el-card class="right">
+            <div :id="barChart" style="width: 100%;height: 300px"></div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+    <div>
+      <el-row :gutter="20" justify="space-between" style="margin-bottom: 15px">
+        <el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
+          <el-card style="margin-bottom: 5px">
+            <div :id="lineChart" style="width: 100%;height: 300px"></div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+    <div>
+      <el-row :gutter="20" justify="space-between" style="margin-bottom: 15px">
+        <el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
+          <el-card>
+            <span style="font-size: 18px;font-weight: 600;margin-left: 45%">超期预警</span>
+            <el-table height="320" v-loading="data.wloading" :data="data.warningData" style="margin-top: 15px">
+              <el-table-column label="序号" type="index" align="center" width="80" />
+              <el-table-column label="生成时间" prop="createTime" align="center"  />
+              <el-table-column label="领用人" prop="createName" align="center" />
+              <el-table-column label="领用时间" prop="useTime" align="center" />
+              <el-table-column label="最后流转时间" prop="updateTime" align="center" width="180"  />
+              <el-table-column label="处理时间" prop="handleTime" align="center" />
+              <el-table-column label="状态" prop="name" align="center" >
+                <template #default="scope">
+                  <span>{{scope.row.state === 0 ? '未处理':'已处理'}}</span>
+                </template>
+              </el-table-column>
+            </el-table>
+            <pagination
+                :total="data.wTotal"
+                v-model:page="data.warningQueryParams.pageNum"
+                v-model:limit="data.warningQueryParams.pageSize"
+                @pagination="getWarningData"
+            />
+          </el-card>
+
+        </el-col>
+        <el-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
+          <el-card>
+            <span style="font-size: 18px;font-weight: 600;margin-left: 45%">危化品使用</span>
+            <el-table height="320" v-loading="data.hloading" :data="data.hazmatData" style="margin-top: 15px">
+              <el-table-column label="名称" prop="name" align="center" />
+              <el-table-column label="产品编号" prop="hazmatBasic.productSn" align="center"  />
+              <el-table-column label="CAS" prop="hazmatBasic.cas" align="center"/>
+              <el-table-column label="试剂类型" prop="hazmatBasic.hazmatType" align="center"/>
+              <el-table-column label="危险性质" prop="hazmatBasic.hazmatCharacter" align="center"/>
+              <el-table-column label="供应商" prop="hazmatBasic.supplier" align="center"/>
+              <el-table-column label="厂家" prop="hazmatBasic.manufacturer" align="center"/>
+              <el-table-column label="规格" prop="hazmatBasic.hazmatCharacter" align="center"/>
+              <el-table-column label="包装" prop="hazmatBasic.metering" align="center">
+                <template #default="scope">
+                  <span>{{scope.row.hazmatBasic.metering}}{{scope.row.hazmatBasic.unit}}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="含税售价" prop="hazmatBasic.price" align="center"/>
+              <el-table-column label="每箱数量" prop="hazmatBasic.perBox" align="center"/>
+              <el-table-column label="最小包装类型" prop="minPackage" align="center" width="220">
+                <template #default="scope">
+                  <span>{{scope.row.hazmatBasic.minPackage == 0 ? '瓶' :scope.row.hazmatBasic.minPackage == 1?'袋':scope.row.hazmatBasic.minPackage == 2?'桶 ':scope.row.hazmatBasic.minPackage == 3?'盒':scope.row.hazmatBasic.minPackage == 4?'箱':'其他'}}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="安全库存" prop="hazmatBasic.safeNum" align="center"/>
+              <el-table-column label="超期阈值(小时)" prop="hazmatBasic.threshold" align="center" width="220"/>
+            </el-table>
+            <pagination
+                :total="data.hTotal"
+                v-model:page="data.hazmatQueryParams.pageNum"
+                v-model:limit="data.hazmatQueryParams.pageSize"
+                @pagination="getHazmatUseData"
+            />
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+  </div>
+</template>
+<script setup>
+import { CountTo } from 'vue3-count-to'
+import img1 from '@/assets/images/file.png'
+import hazmat from '@/assets/logo/hazmat.png'
+import warehouse from '@/assets/logo/warehouse.png'
+import warning from '@/assets/logo/warning1.png'
+import used from '@/assets/logo/used.png'
+import * as echarts from 'echarts';
+import {nextTick, onMounted, onUnmounted, reactive, ref, shallowRef} from "vue";
+import {getFinishBasicList} from "@/api/hazardousChemicals/finishedBasicInfo";
+import {ElMessage} from "element-plus";
+import {getEntryData, getHazmatUseList, getHoData, getMaxUseData, getUseData} from "@/api/hazardousChemicals/count";
+import {getWarning} from "@/api/hazardousChemicals/warning";
+const data = reactive({
+  cardList: [
+    {
+      title: '危化品数量',
+      imgUrl: hazmat,
+      startVal: 0,
+      endVal: null,
+      duration: 1500
+    },
+    {
+      title: '使用量',
+      imgUrl: used,
+      startVal: 0,
+      endVal: null,
+      duration: 1500
+    },
+    {
+      title: '仓库数量',
+      imgUrl: warehouse,
+      startVal: 0,
+      endVal: null,
+      duration: 1500
+    },
+    {
+      title: '预警量',
+      imgUrl: warning,
+      startVal: 0,
+      endVal: null,
+      duration: 1500
+    },
+  ],
+  maxUseList: [],
+  useXData: [],
+  useYData: [],
+  entryXData: [],
+  entryYData: [],
+  warningData: [],
+  warningQueryParams: {
+    pageNum: 1,
+    pageSize: 5
+  },
+  wTotal: 0,
+  wloading: false,
+  hTotal: 0,
+  hloading: false,
+  hazmatQueryParams: {
+    pageNum: 1,
+    pageSize: 10
+  },
+  hazmatData: []
+
+});
+const myChart = shallowRef(null)
+const pieChart = ref("eChartPieN" + Date .now() + Math .random())
+const myBarChart = shallowRef(null)
+const barChart = ref("eChartBarN" + Date .now() + Math .random())
+const myLineChart = shallowRef(null)
+const lineChart = ref("eChartBarN" + Date .now() + Math .random())
+
+onMounted(async () => {
+  await getHomeData()
+  await entryData()
+  await useData()
+  await maxUseData()
+  await getWarningData()
+  await getHazmatUseData()
+});
+const getWarningData = async () => {
+  data.wloading = true
+  const res = await getWarning(data.warningQueryParams)
+  if(res.code == 200){
+    data.warningData =res.data.list
+    data.wTotal = res.data.total
+  }else{
+    ElMessage.warning(res.message)
+  }
+  data.wloading = false
+}
+const getHazmatUseData = async () => {
+  data.hloading = true
+  const res = await getHazmatUseList(data.hazmatQueryParams)
+  if(res.code == 200){
+    data.hazmatData =res.data.list
+    data.hTotal = res.data.total
+  }else{
+    ElMessage.warning(res.message)
+  }
+  data.hloading = false
+}
+const getHomeData = async () => {
+  const res = await getHoData(data.queryParams)
+  if(res.code == 200){
+    data.cardList[0].endVal = res.data.hazmatCount
+    data.cardList[1].endVal = res.data.usedCount
+    data.cardList[2].endVal = res.data.warehouseCount
+    data.cardList[3].endVal = res.data.warningCount
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+const entryData = async () => {
+  const res = await getEntryData()
+  if(res.code == 200){
+    data.entryXData = res.data.map(item => item.month+'月' + item.day+'日')
+    data.entryYData = res.data.map(item =>item.count)
+    await getLineChart()
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+const useData = async () => {
+  const res = await getUseData()
+  if(res.code == 200){
+    data.useXData = res.data.map(item => item.day+'日')
+    data.useYData = res.data.map(item =>item.count)
+    await getBarChart()
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+const maxUseData = async () => {
+  const res = await getMaxUseData()
+  if(res.code == 200){
+    data.maxUseList = res.data.map(item => {
+      return{
+        value: item.count,
+        name: item.name
+      }
+    })
+    await getPieChart()
+  }else{
+    ElMessage.warning(res.message)
+  }
+}
+const getPieChart = () => {
+  if (myChart.value != null && myChart.value != "" && myChart.value != undefined) {
+    myChart.value.dispose();
+  }
+  myChart.value = echarts.init(document.getElementById(pieChart.value));
+  const option = {
+    title: {
+      text: '近一周频繁使用的危化品量',
+      left: 'center'
+    },
+    tooltip: {
+      trigger: 'item'
+    },
+    legend: {
+      orient: 'vertical',
+      left: 'left'
+    },
+    series: [
+      {
+        name: 'Access From',
+        type: 'pie',
+        radius: '50%',
+        data: data.maxUseList,
+        emphasis: {
+          itemStyle: {
+            shadowBlur: 10,
+            shadowOffsetX: 0,
+            shadowColor: 'rgba(0, 0, 0, 0.5)'
+          }
+        }
+      }
+    ]
+  };
+  // 使用刚指定的配置项和数据显示图表。
+  myChart.value.setOption(option,true);
+  //自适应宽度
+  window.addEventListener('resize',function () {
+    myChart.value.resize();
+  })
+}
+
+const getBarChart = () => {
+  if (myBarChart.value != null && myBarChart.value != "" && myBarChart.value != undefined) {
+    myChart.value.dispose();
+  }
+  myBarChart.value = echarts.init(document.getElementById(barChart.value));
+  const option = {
+    title: {
+      text: '近一周使用量',
+      left: 'center'
+    },
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      data: data.useXData,
+      axisTick: {
+        alignWithLabel: true
+      }
+    },
+    yAxis: {
+      type: 'value'
+    },
+    series: [
+      {
+        data: data.useYData,
+        type: 'bar',
+        barWidth: '60%',
+      }
+    ]
+  };
+  // 使用刚指定的配置项和数据显示图表。
+  myBarChart.value.setOption(option,true);
+  //自适应宽度
+  window.addEventListener('resize',function () {
+    myBarChart.value.resize();
+  })
+}
+
+
+const getLineChart = () => {
+  if (myLineChart.value != null && myLineChart.value != "" && myLineChart.value != undefined) {
+    myLineChart.value.dispose();
+  }
+  myLineChart.value = echarts.init(document.getElementById(lineChart.value));
+  const option = {
+    tooltip: {
+      trigger: 'axis'
+    },
+    title: {
+      text: '近30天入库量',
+      left: 'center'
+    },
+    grid: {
+      left: '3%',
+      right: '4%',
+      bottom: '3%',
+      top: '150px',
+      containLabel: true
+    },
+    xAxis: {
+      type: 'category',
+      data: data.entryXData
+    },
+    yAxis: {
+      type: 'value'
+    },
+    series: [
+      {
+        data: data.entryYData,
+        type: 'line',
+        smooth: true
+      }
+    ]
+  };
+  // 使用刚指定的配置项和数据显示图表。
+  myLineChart.value.setOption(option,true);
+  //自适应宽度
+  window.addEventListener('resize',function () {
+    myLineChart.value.resize();
+  })
+}
+
+
+</script>
+<style scoped lang="scss">
+.homePage{
+  padding: 20px;
+  background-color: white;
+  .imgW{
+      width: 50px;
+      height: 50px;
+    }
+  .imgT{
+    width: 70px;
+    height: 70px;
+  }
+    .cardContent{
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      .cardRight{
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        line-height: 35px
+      }
+    }
+
+  .content{
+    display: flex;
+    flex-wrap: wrap;
+    .right{
+      flex: 1;
+    }
+
+  }
+
+}
+
+</style>
diff --git a/src/views/hazardousChemicals/overdueWarning/index.vue b/src/views/hazardousChemicals/overdueWarning/index.vue
index de7dd3e..4b06f26 100644
--- a/src/views/hazardousChemicals/overdueWarning/index.vue
+++ b/src/views/hazardousChemicals/overdueWarning/index.vue
@@ -39,11 +39,11 @@
     <!-- 表格数据 -->
     <el-table v-loading="loading" :data="dataList" :border="true">
       <el-table-column label="序号" type="index" align="center" width="80" />
-      <el-table-column label="生成时间" prop="creditCode" align="center"  />
-      <el-table-column label="领用人" prop="name" align="center" />
-      <el-table-column label="领用时间" prop="name" align="center" />
-      <el-table-column label="最后流转时间" prop="name" align="center" />
-      <el-table-column label="处理时间" prop="name" align="center" />
+      <el-table-column label="生成时间" prop="createTime" align="center"  />
+      <el-table-column label="领用人" prop="createName" align="center" />
+      <el-table-column label="领用时间" prop="useTime" align="center" />
+      <el-table-column label="最后流转时间" prop="updateTime" align="center" />
+      <el-table-column label="处理时间" prop="handleTime" align="center" />
       <el-table-column label="状态" prop="name" align="center" >
         <template #default="scope">
           <span>{{scope.row.state === 0 ? '未处理':'已处理'}}</span>
@@ -51,7 +51,7 @@
       </el-table-column>
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200" >
         <template #default="scope">
-          <el-button link type="primary" v-if="scope.row.state === 0">标记处理</el-button>
+          <el-button link type="primary" v-if="scope.row.state === 0" @click="markWarn(scope.row)">标记处理</el-button>
           <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
         </template>
       </el-table-column>
@@ -71,7 +71,7 @@
 <script setup>
 import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
 import {ElMessage, ElMessageBox} from "element-plus";
-import {delWarning, getWarning} from "@/api/hazardousChemicals/warning";
+import {delWarning, getWarning, handleWarning} from "@/api/hazardousChemicals/warning";
 const { proxy } = getCurrentInstance();
 const loading = ref(false);
 const dialogRef = ref();
@@ -140,6 +140,29 @@
         }
       })
 }
+
+const markWarn = (val) => {
+  ElMessageBox.confirm(
+      '确定处理此条标签?',
+      '提示',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+      .then( async() => {
+        const res = await handleWarning(val.id)
+        if(res.code == 200){
+          ElMessage.success('处理成功')
+          await getList()
+        }else{
+          ElMessage.warning(res.message)
+        }
+      })
+}
+
+
+
 const toDetail = () => {
   data.queryParams.state = 0;
   getList()
diff --git a/src/views/hazardousChemicals/traceableQuery/index.vue b/src/views/hazardousChemicals/traceableQuery/index.vue
index c2c67d4..5210f24 100644
--- a/src/views/hazardousChemicals/traceableQuery/index.vue
+++ b/src/views/hazardousChemicals/traceableQuery/index.vue
@@ -16,14 +16,14 @@
         </el-form-item>
 
       </el-form>
-      <div style="display: flex;justify-content: center">
-        <div  class="content">
-          <flow-deail ref="flowRef" v-if="data.showData"></flow-deail>
-          <el-empty description="暂无数据" style="margin-top: 10%" v-else></el-empty>
-        </div>
+      <div style="display: flex;justify-content: center;margin-top: 20px">
+        <el-card :style="{ height: '650px' ,overflow: 'auto'}">
+          <div  class="content">
+            <flow-deail ref="flowRef" v-if="data.showData"></flow-deail>
+            <el-empty description="暂无数据" style="margin-top: 10%" v-else></el-empty>
+          </div>
+        </el-card>
       </div>
-
-
     </div>
   </div>
 
@@ -68,11 +68,10 @@
 <style scoped lang="scss">
 .query{
   .content{
-    margin-top: 40px;
     width: 650px;
-    height: 650px;
-    border: 1px solid black;
-    overflow-y: scroll;
+    //height: 650px;
+    //border: 1px solid #c2bfbf;
+
   }
 }
 </style>

--
Gitblit v1.9.2