zhouwx
2024-08-15 d815fbd281d6bb9c1fff1712614bf9738fd32d73
工作台
已修改6个文件
已添加2个文件
583 ■■■■■ 文件已修改
package.json 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/hazardousChemicals/count.js 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/hazardousChemicals/warning.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Sidebar/menu.js 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hazardousChemicals/homePage/index.vue 428 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hazardousChemicals/overdueWarning/index.vue 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hazardousChemicals/traceableQuery/index.vue 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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"
  },
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
    })
}
src/api/hazardousChemicals/warning.js
@@ -14,3 +14,11 @@
        method: 'delete'
    })
}
export function handleWarning(params) {
    return request({
        url: `/warning/markWarning`,
        method: 'put',
        data: params
    })
}
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',
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',
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>
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()
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>