Riku
2025-06-15 31980b06d50d530feb2c0f1db9daf24bd3b8797a
2025.6.15
已修改3个文件
已添加1个文件
569 ■■■■ 文件已修改
src/api/index.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/inspection/TaskItem.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/management/TaskSummary copy.vue 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/management/TaskSummary.vue 392 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js
@@ -1,13 +1,13 @@
import axios from 'axios'
import { ElMessage } from 'element-plus'
const debug = true
const debug = false
var IP = '47.100.191.150'
var PORT = '9005'
if (debug) {
  IP = '192.168.0.103'
  // IP = 'localhost'
  // IP = '192.168.0.103'
  IP = 'localhost'
  PORT = '9001'
}
src/components/inspection/TaskItem.vue
@@ -4,7 +4,7 @@
  </el-row>
  <div>
    <el-text>总量</el-text>
    <el-text size="small">{{ completetask + '/' + totaltask }}</el-text>
    <el-text size="default">{{ completetask + '/' + totaltask }}</el-text>
    <el-progress
      style="width: 300px"
      type="line"
src/views/management/TaskSummary copy.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,169 @@
<template>
  <!-- <BaseCard> -->
  <el-row> å·¡æŸ¥æ±‡æ€» </el-row>
  <el-segmented v-model="value" :options="options" block />
  <div><el-text tag="i"> è¯„ä¼° </el-text></div>
  <el-row justify="space-evenly">
    <div>
      <el-statistic title="总计" :value="10"> </el-statistic>
      <div class="statistic-footer">
        <div class="footer-item">
          <span>对比昨日</span>
          <span class="green">
            24%
            <el-icon>
              <CaretTop />
            </el-icon>
          </span>
        </div>
      </div>
    </div>
    <el-statistic title="高风险" :value="2" :value-style="styleRed"> </el-statistic>
    <el-statistic title="中风险" :value="6" :value-style="styleYellow"> </el-statistic>
    <el-statistic title="低风险" :value="2" :value-style="styleGreen"> </el-statistic>
  </el-row>
  <div><el-text tag="i"> å¤æ ¸ </el-text></div>
  <el-row justify="space-evenly">
    <div>
      <el-statistic title="需复核" :value="2"> </el-statistic>
      <div class="statistic-footer">
        <div class="footer-item">
          <span>对比昨日</span>
          <span class="green">
            24%
            <el-icon>
              <CaretTop />
            </el-icon>
          </span>
        </div>
      </div>
    </div>
    <el-statistic title="已完成" :value="2" :value-style="styleGreen"> </el-statistic>
  </el-row>
  <div><el-text tag="i"> é—®é¢˜ </el-text></div>
  <el-row justify="space-evenly">
    <div>
      <el-statistic title="总计" :value="10"> </el-statistic>
      <div class="statistic-footer">
        <div class="footer-item">
          <span>对比昨日</span>
          <span class="green">
            24%
            <el-icon>
              <CaretTop />
            </el-icon>
          </span>
        </div>
      </div>
    </div>
    <el-statistic title="待审核" :value="2" :value-style="styleRed"> </el-statistic>
    <el-statistic title="已审核" :value="6" :value-style="styleYellow"> </el-statistic>
    <el-statistic title="待整改" :value="2" :value-style="styleGreen"> </el-statistic>
    <el-statistic title="已整改" :value="2" :value-style="styleGreen"> </el-statistic>
    <el-statistic title="待确认" :value="2" :value-style="styleGreen"> </el-statistic>
  </el-row>
  <!-- </BaseCard> -->
</template>
<script setup>
import { ref, onMounted } from 'vue'
import dayjs from 'dayjs'
import taskApi from '@/api/fysp/taskApi.js'
const props = defineProps({
  height: String
})
const emits = defineEmits(['update:height'])
const value = '今日汇总'
const options = ['今日汇总', '周度汇总', '月度汇总', '季度汇总', '年度汇总']
const styleRed = 'color:var(--el-color-danger);'
const styleYellow = 'color:var(--el-color-warning);'
const styleGreen = 'color:var(--el-color-success);'
const subtaskToday = ref([])
const subtaskWeek = ref([])
const subtaskMonth = ref([])
function getParams(type) {
  const d = dayjs()
  return {
    starttime: d.startOf(type).format('YYYY-MM-DD HH:mm:ss'),
    endtime: d.endOf(type).format('YYYY-MM-DD HH:mm:ss')
  }
}
function fetchSubtaskToday() {
  const area = getParams('day')
  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
    subtaskToday.value = res.data
  })
}
function fetchSubtaskThisWeek() {
  const area = getParams('week')
  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
    subtaskWeek.value = res.data
  })
}
function fetchSubtaskThisMonth() {
  const area = getParams('month')
  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
    subtaskMonth.value = res.data
  })
}
onMounted(() => {
  // fetchSubtaskToday()
  // fetchSubtaskThisWeek()
  fetchSubtaskThisMonth()
})
</script>
<style scoped>
/* .el-segmented {
  --el-segmented-item-selected-color: var(--el-text-color-primary);
  --el-segmented-item-selected-bg-color: #ffd100;
  --el-border-radius-base: 16px;
} */
.el-statistic {
  --el-statistic-content-font-size: var(--el-font-size-base);
  /* background-color: aliceblue; */
}
.statistic-footer {
  background-color: #ffd100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--el-text-color-regular);
  /* margin-top: 16px; */
}
.statistic-footer .footer-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.statistic-footer .footer-item span:last-child {
  display: inline-flex;
  align-items: center;
  margin-left: 4px;
}
.green {
  color: var(--el-color-success);
}
.red {
  color: var(--el-color-error);
}
</style>
src/views/management/TaskSummary.vue
@@ -1,72 +1,23 @@
<template>
  <!-- <BaseCard> -->
  <el-row> å·¡æŸ¥æ±‡æ€» </el-row>
  <el-segmented v-model="value" :options="options" block />
  <div><el-text tag="i"> è¯„ä¼° </el-text></div>
  <el-row justify="space-evenly">
    <div>
      <el-statistic title="总计" :value="10"> </el-statistic>
      <div class="statistic-footer">
        <div class="footer-item">
          <span>对比昨日</span>
          <span class="green">
            24%
            <el-icon>
              <CaretTop />
            </el-icon>
          </span>
        </div>
      </div>
    </div>
    <el-statistic title="高风险" :value="2" :value-style="styleRed"> </el-statistic>
    <el-statistic title="中风险" :value="6" :value-style="styleYellow"> </el-statistic>
    <el-statistic title="低风险" :value="2" :value-style="styleGreen"> </el-statistic>
  </el-row>
  <div><el-text tag="i"> å¤æ ¸ </el-text></div>
  <el-row justify="space-evenly">
    <div>
      <el-statistic title="需复核" :value="2"> </el-statistic>
      <div class="statistic-footer">
        <div class="footer-item">
          <span>对比昨日</span>
          <span class="green">
            24%
            <el-icon>
              <CaretTop />
            </el-icon>
          </span>
        </div>
      </div>
    </div>
    <el-statistic title="已完成" :value="2" :value-style="styleGreen"> </el-statistic>
  </el-row>
  <div><el-text tag="i"> é—®é¢˜ </el-text></div>
  <el-row justify="space-evenly">
    <div>
      <el-statistic title="总计" :value="10"> </el-statistic>
      <div class="statistic-footer">
        <div class="footer-item">
          <span>对比昨日</span>
          <span class="green">
            24%
            <el-icon>
              <CaretTop />
            </el-icon>
          </span>
        </div>
      </div>
    </div>
    <el-statistic title="待审核" :value="2" :value-style="styleRed"> </el-statistic>
    <el-statistic title="已审核" :value="6" :value-style="styleYellow"> </el-statistic>
    <el-statistic title="待整改" :value="2" :value-style="styleGreen"> </el-statistic>
    <el-statistic title="已整改" :value="2" :value-style="styleGreen"> </el-statistic>
    <el-statistic title="待确认" :value="2" :value-style="styleGreen"> </el-statistic>
  </el-row>
  <!-- </BaseCard> -->
  <div v-show="value == '今日汇总'">
    <div ref="echart1" class="bar-chart"></div>
  </div>
  <div v-show="value == '本周汇总'">
    <div ref="echart2" class="bar-chart"></div>
  </div>
  <div v-show="value == '上周汇总'">
    <div ref="echart3" class="bar-chart"></div>
  </div>
  <div v-show="value == '月度汇总'">
    <div ref="echart4" class="bar-chart"></div>
  </div>
</template>
<script setup>
import { ref } from 'vue'
import * as echarts from 'echarts'
import { ref, onMounted } from 'vue'
import dayjs from 'dayjs'
import taskApi from '@/api/fysp/taskApi.js'
@@ -76,22 +27,312 @@
const emits = defineEmits(['update:height'])
const alue = '今日汇总'
const ptions = ['今日汇总', '周度汇总', '月度汇总', '季度汇总', '年度汇总']
const tyleRed = 'color:var(--el-color-danger);'
const tyleYellow = 'color:var(--el-color-warning);'
const tyleGreen = 'color:var(--el-color-success);'
const value = ref('月度汇总')
const options = ['今日汇总', '本周汇总', '上周汇总', '月度汇总']
function name(params) {
const subtaskToday = ref([])
const subtaskWeek = ref([])
const subtaskLastWeek = ref([])
const subtaskMonth = ref([])
const echart1 = ref()
const echart2 = ref()
const echart3 = ref()
const echart4 = ref()
let echartToday
let echartWeek
let echartLastWeek
let echartMonth
function getParams(type) {
  const d = dayjs()
  const area = {
    starttime: d.startOf('day').format('YYYY-MM-DD HH:mm:ss'),
  return {
    starttime: d.startOf(type).format('YYYY-MM-DD HH:mm:ss'),
    endtime: d.endOf(type).format('YYYY-MM-DD HH:mm:ss')
  }
}
  taskApi.fetchSubtaskSummaryByArea(this.area).then((res) => {
    this.subtaskList = res.data
function fetchSubtaskToday() {
  const area = getParams('day')
  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
    subtaskToday.value = res.data
    const series = refreshChartData(res.data)
    setOption(echartToday, series)
  })
}
function fetchSubtaskThisWeek() {
  const area = getParams('week')
  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
    subtaskWeek.value = res.data
    const series = refreshChartData(res.data)
    setOption(echartWeek, series)
  })
}
function fetchSubtaskLastWeek() {
  const area = getParams('week')
  area.starttime = dayjs(area.starttime).add(-7, 'day').format('YYYY-MM-DD HH:mm:ss')
  area.endtime = dayjs(area.endtime).add(-7, 'day').format('YYYY-MM-DD HH:mm:ss')
  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
    subtaskLastWeek.value = res.data
    const series = refreshChartData(res.data)
    setOption(echartLastWeek, series)
  })
}
function fetchSubtaskThisMonth() {
  const area = getParams('month')
  taskApi.fetchSubtaskSummaryByArea(area).then((res) => {
    subtaskMonth.value = res.data
    const series = refreshChartData(res.data)
    setOption(echartMonth, series)
  })
}
onMounted(() => {
  echartToday = echarts.init(echart1.value)
  echartWeek = echarts.init(echart2.value)
  echartLastWeek = echarts.init(echart3.value)
  echartMonth = echarts.init(echart4.value)
  fetchSubtaskToday()
  fetchSubtaskThisWeek()
  fetchSubtaskLastWeek()
  fetchSubtaskThisMonth()
})
/**chart**********************************************************************/
function setOption(echart, series) {
  const option = {
    textStyle: {
      color: 'white'
    },
    legend: {
      textStyle: {
        color: 'white'
      }
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: [
      {
        type: 'value'
      }
    ],
    yAxis: [
      {
        type: 'category',
        data: ['整改数', '问题数', '完成量']
      }
    ],
    series: series
  }
  echart.setOption(option)
}
function refreshChartData(dataList) {
  // ä»»åŠ¡é‡ã€é—®é¢˜æ•°ã€æ•´æ”¹æ•°
  // ä»»åŠ¡é‡
  const totalCount = {
    numByTotal: {},
    numByDistrict: {},
    numByScene: {},
    numByUser: {}
  }
  // é—®é¢˜æ•°
  const proCount = {
    numByTotal: {},
    numByDistrict: {},
    numByScene: {},
    numByUser: {}
  }
  // æ•´æ”¹æ•°
  const changeCount = {
    numByTotal: {},
    numByDistrict: {},
    numByScene: {},
    numByUser: {}
  }
  // // æŒ‰ç”¨æˆ·åˆ†ç±»
  // const userCount = {
  //   numByTotal: {},
  //   numByDistrict: {},
  //   numByScene: {},
  //   numByUser: {}
  // }
  dataList.forEach((d) => {
    const tName = '总计'
    const dName = d.subtask.districtname
    const sType = d.sceneType
    const uName = d.subtask.deployerrealname
    // ä»»åŠ¡é‡æ€»è®¡
    totalCount.numByTotal[tName] = totalCount.numByTotal[tName]
      ? totalCount.numByTotal[tName] + 1
      : 1
    // ä»»åŠ¡é‡åˆ†åŒºåŽ¿
    totalCount.numByDistrict[dName] = totalCount.numByDistrict[dName]
      ? totalCount.numByDistrict[dName] + 1
      : 1
    // ä»»åŠ¡é‡åˆ†åœºæ™¯ç±»åž‹
    totalCount.numByScene[sType] = totalCount.numByScene[sType]
      ? totalCount.numByScene[sType] + 1
      : 1
    // ä»»åŠ¡é‡åˆ†ç”¨æˆ·
    totalCount.numByUser[uName] = totalCount.numByUser[uName] ? totalCount.numByUser[uName] + 1 : 1
    // é—®é¢˜æ•°æ€»è®¡
    proCount.numByTotal[tName] = proCount.numByTotal[tName]
      ? proCount.numByTotal[tName] + d.proCheckedNum
      : d.proCheckedNum
    // é—®é¢˜æ•°åˆ†åŒºåŽ¿
    proCount.numByDistrict[dName] = proCount.numByDistrict[dName]
      ? proCount.numByDistrict[dName] + d.proCheckedNum
      : d.proCheckedNum
    // é—®é¢˜æ•°åˆ†åœºæ™¯ç±»åž‹
    proCount.numByScene[sType] = proCount.numByScene[sType]
      ? proCount.numByScene[sType] + d.proCheckedNum
      : d.proCheckedNum
    // é—®é¢˜æ•°åˆ†ç”¨æˆ·
    proCount.numByUser[uName] = proCount.numByUser[uName]
      ? proCount.numByUser[uName] + d.proCheckedNum
      : d.proCheckedNum
    // æ•´æ”¹æ•°æ€»è®¡
    changeCount.numByTotal[tName] = changeCount.numByTotal[tName]
      ? changeCount.numByTotal[tName] + d.changeCheckedNum
      : d.changeCheckedNum
    // æ•´æ”¹æ•°åˆ†åŒºåŽ¿
    changeCount.numByDistrict[dName] = changeCount.numByDistrict[dName]
      ? changeCount.numByDistrict[dName] + d.changeCheckedNum
      : d.changeCheckedNum
    // æ•´æ”¹æ•°åˆ†åœºæ™¯ç±»åž‹
    changeCount.numByScene[sType] = changeCount.numByScene[sType]
      ? changeCount.numByScene[sType] + d.changeCheckedNum
      : d.changeCheckedNum
    // æ•´æ”¹æ•°åˆ†ç”¨æˆ·
    changeCount.numByUser[uName] = changeCount.numByUser[uName]
      ? changeCount.numByUser[uName] + d.changeCheckedNum
      : d.changeCheckedNum
  })
  let series = {}
  totalCount
  proCount
  changeCount
  parseSeries(series, changeCount)
  parseSeries(series, proCount)
  parseSeries(series, totalCount)
  const res = []
  for (const key in series) {
    const e = series[key]
    res.push(e)
  }
  return res
}
function parseSeries(series, c) {
  // c.numByTotal
  // c.numByDistrict
  // c.numByScene
  // c.numByUser
  for (const key in c.numByTotal) {
    const value = c.numByTotal[key]
    if (series[key]) {
      series[key].data.push(value)
    } else {
      series[key] = {
        name: key,
        type: 'bar',
        emphasis: {
          focus: 'series'
        },
        label: {
          show: true,
          formatter: '{c}'
          // position: [0, 10],
        },
        data: [value]
      }
    }
  }
  for (const key in c.numByDistrict) {
    const value = c.numByDistrict[key]
    if (series[key]) {
      series[key].data.push(value)
    } else {
      series[key] = {
        name: `区县:${key}`,
        type: 'bar',
        stack: 'district',
        emphasis: {
          focus: 'series'
        },
        label: {
          show: true,
          formatter: '{c}'
          // position: [0, 10],
        },
        data: [value]
      }
    }
  }
  for (const key in c.numByScene) {
    const value = c.numByScene[key]
    if (series[key]) {
      series[key].data.push(value)
    } else {
      series[key] = {
        name: `场景:${key}`,
        type: 'bar',
        stack: 'scene',
        emphasis: {
          focus: 'series'
        },
        label: {
          show: true,
          formatter: '{c}'
          // position: [0, 10],
        },
        data: [value]
      }
    }
  }
  for (const key in c.numByUser) {
    const value = c.numByUser[key]
    if (series[key]) {
      series[key].data.push(value)
    } else {
      series[key] = {
        name: `用户:${key}`,
        type: 'bar',
        stack: 'user',
        emphasis: {
          focus: 'series'
        },
        label: {
          show: true,
          formatter: '{c}'
          // position: [0, 10],
        },
        data: [value]
      }
    }
  }
  return series
}
</script>
@@ -136,4 +377,9 @@
.red {
  color: var(--el-color-error);
}
.bar-chart {
  width: 400px;
  height: 600px;
}
</style>