forked from drone/command-center-dashboard

chenyao
2025-04-12 d643050ffd11f45b4512865c09f4da6754ea90d2
feat: 修改任务管理功能
8 files modified
5 files added
480 ■■■■ changed files
src/assets/images/task/other-total.png patch | view | raw | blame | history
src/assets/images/task/task-event-total.png patch | view | raw | blame | history
src/assets/images/task/task-num-total.png patch | view | raw | blame | history
src/assets/images/task/title.png patch | view | raw | blame | history
src/assets/images/task/total.png patch | view | raw | blame | history
src/views/Home/AINowFly.vue 15 ●●●● patch | view | raw | blame | history
src/views/TaskManage/SearchBox.vue 72 ●●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskIntermediateContent/TaskIntermediateContent.vue 15 ●●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskTop/TaskEvent.vue 60 ●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskTop/TaskIndustry.vue 118 ●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskTop/TaskTime.vue 54 ●●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskTop/TaskTop.vue 37 ●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskTop/TaskTotal.vue 109 ●●●● patch | view | raw | blame | history
src/assets/images/task/other-total.png
src/assets/images/task/task-event-total.png
src/assets/images/task/task-num-total.png
src/assets/images/task/title.png
src/assets/images/task/total.png
src/views/Home/AINowFly.vue
@@ -1,6 +1,6 @@
<template>
    <div class="AINowFly">
        <div class="title">指点飞行<img @click="closeClick" src="@/assets/images/aiNowFly/close.png"/></div>
        <div class="title">智引即飞<img @click="closeClick" src="@/assets/images/aiNowFly/close.png"/></div>
        <el-form ref="ruleFormRef" :model="params" :rules="rules" label-width="auto" size="small" status-icon>
            <el-form-item label="任务名称" prop="name">
                <el-input v-model="params.name" />
@@ -23,7 +23,7 @@
        <div class="title-list">可飞行机巢列表:</div>
        <el-table :data="list" height="120" @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="40" />
            <el-table-column type="selection" />
            <!-- <el-table-column type="index" label="序号" /> -->
            <el-table-column prop="nickname" label="机巢名称" />
            <el-table-column prop="minute" label="可飞行时间" />
@@ -317,6 +317,14 @@
        width: 300px;
        height: 120px;
        margin: 0 0 0 11px;
        overflow: hidden;
        :deep(.el-scrollbar__wrap) {
            overflow-x: hidden !important;
        }
        :deep(.el-table__body-wrapper) {
            overflow-x: hidden !important;
        }
        :deep(.el-table__header-wrapper) {
            th {
                font-size: 12px;
@@ -328,7 +336,8 @@
        }
        :deep(.el-table__empty-block) {
            background-color: #0A1734;
            height: auto !important;  // 移除固定高度
        min-height: 60px;        // 设置最小高度
            .el-table__empty-text {
                color: #FFFFFF;
            }
src/views/TaskManage/SearchBox.vue
@@ -1,10 +1,10 @@
<template>
  <div class="search-box" :class="{ 'is-expand': isExpand }">
    <el-form :model="searchForm" inline>
      <div class="search-row">
        <div class="search-items">
          <el-form-item label="名称/编号">
            <el-input v-model="searchForm.key_word" placeholder="请输入任务名称/编号" clearable />
      <!-- <div class="search-row"> -->
        <!-- <div class="search-items"> -->
          <el-form-item>
            <el-input v-model="searchForm.key_word" placeholder="请输入任务/机巢名称" clearable />
          </el-form-item>
          <el-form-item label="区域">
            <el-select v-model="searchForm.area_code" @change="deptChange" placeholder="请选择部门" clearable>
@@ -16,8 +16,12 @@
              <el-option v-for="item in machineData" :key="item.device_sn" :label="item.nickname" :value="item.device_sn" />
            </el-select>
          </el-form-item>
        </div>
        <div class="search-btns">
          <el-form-item>
            <CommonDateTime v-model="newTime" @change="getData" />
          </el-form-item>
        <!-- </div> -->
        <!-- <div class="search-btns">
          <el-form-item>
            <el-button type="primary" @click="handleSearch">查询</el-button>
            <el-button @click="handleReset">重置</el-button>
@@ -29,12 +33,12 @@
              </el-icon>
            </el-button>
          </el-form-item>
        </div>
      </div>
        </div> -->
      <!-- </div> -->
    <!-- 展开后显示的更多搜索条件 -->
    <div v-show="isExpand" class="search-more">
      <div class="search-row">
        <el-form-item label="周期类型">
    <!-- <div v-show="isExpand" class="search-more"> -->
      <!-- <div class="search-row"> -->
        <!-- <el-form-item label="周期类型">
          <el-select v-model="searchForm.date_enum" placeholder="请选择状态" clearable>
            <el-option label="日" value="DAY" />
            <el-option label="周" value="CURRENT_WEEK" />
@@ -51,16 +55,16 @@
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
        </el-form-item> -->
        <el-form-item label="任务算法">
          <!-- <el-select v-model="searchForm.ai_types" placeholder="请选择算法" clearable>
            <el-option v-for="item in taskAlgorithm" :key="item.id" :label="item.dictValue" :value="item.dictKey" />
          </el-select> -->
          <TaskAlgorithmBusiness :showAlgorithm="true" @algorithmChange="algorithmChange"/>
        </el-form-item>
      </div>
      <div class="search-row">
        <el-form-item label="所属部门">
      <!-- </div> -->
      <!-- <div class="search-row"> -->
        <!-- <el-form-item label="所属部门">
          <el-select v-model="searchForm.create_dept" placeholder="请选择部门" clearable>
            <el-option v-for="item in deptData" :key="item.id" :label="item.deptName" :value="item.id" />
          </el-select>
@@ -71,17 +75,16 @@
          </el-select>
        </el-form-item>
        <el-form-item label="任务类型">
          <!-- <el-select v-model="searchForm.industry_type" placeholder="请选择类型" clearable>
            <el-option v-for="item in taskBusiness" :key="item.id" :label="item.dictValue" :value="item.dictKey" />
          </el-select> -->
          <TaskAlgorithmBusiness :showBusiness="true" @businessChange="businessChange"/>
        </el-form-item>
      </div>
    </div>
        </el-form-item> -->
      <!-- </div> -->
    <!-- </div> -->
    </el-form>
  </div>
</template>
<script setup>
import { pxToRem } from '@/utils/rem'
import CommonDateTime from '@/components/CommonDateTime.vue'
import { deptsByAreaCode, getDockInfo } from '@/api/home/common';
import TaskAlgorithmBusiness from './components/TaskAlgorithmBusiness.vue';
@@ -135,19 +138,6 @@
  emit('addTask');
};
// let taskAlgorithm = ref([]);
// let taskBusiness = ref([]);
// 请求字典字段
// const requestDictionary = () => {
//   getDictionary('SF,HYLB').then((res) => {
//     if (res.code !== 0) {
//       // 处理数据
//       taskAlgorithm.value = res.data.data['SF'];
//       taskBusiness.value = res.data.data['HYLB'];
//     }
//   });
// };
const algorithmChange = (val) => {
  searchForm.ai_types = val;
};
@@ -199,18 +189,10 @@
<style lang="scss" scoped>
.search-box {
  position: absolute;
  top: 340px;
  left: 40px;
  width: calc(100% - 80px);
  height: 60px;
  line-height: 60px;
  background: rgba(31, 62, 122, 0.95);
  // padding: 10px 20px;
  transition: all 0.3s;
  &.is-expand {
    height: auto;
  }
  // &.is-expand {
  //   height: auto;
  // }
  .search-row {
    display: flex;
    // justify-content: space-between;
src/views/TaskManage/TaskIntermediateContent/TaskIntermediateContent.vue
@@ -1,7 +1,7 @@
<!-- 任务统计表格 -->
<template>
  <SearchBox @search="searchClick" @addTask="handleAddTask"></SearchBox>
  <div class="task-intermediate-content">
    <SearchBox @search="searchClick" @addTask="handleAddTask"></SearchBox>
    <el-table :data="jobListData" style="width: 100%" height="calc(100vh - 180px)">
      <el-table-column label="序号" width="60">
        <template #default="scope">
@@ -121,16 +121,13 @@
<style lang="scss" scoped>
.task-intermediate-content {
  position: absolute;
  top: 400px;
  width: calc(100% - 80px);
  left: 40px;
  height: 500px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  margin-left: 38px;
  margin-top: 16px;
  background: linear-gradient( 27deg, #1F3E7A 0%, rgba(31,62,122,0.35) 79%, rgba(31,62,122,0) 100%);
  padding: 14px 18px;
  
  :deep(.el-table) {
    margin-top: 12px;
    background-color: transparent;
    --el-table-tr-bg-color: transparent;
    --el-table-border-color: rgba(255, 255, 255, 0.1);
src/views/TaskManage/TaskTop/TaskEvent.vue
@@ -1,13 +1,12 @@
<!-- 任务事件统计 -->
<!-- 任务事件数量比统计 -->
<template>
  <!-- <common-title title="任务事件统计"></common-title> -->
  <div class="task-event">
    <div class="title">任务事件数量比统计</div>
    <div class="chart" ref="chartRef"></div>
  </div>
 </template>
<script setup>
import CommonTitle from '@/components/CommonTitle.vue';
import * as echarts from 'echarts';
import { jobEventBar } from '@/api/home/task';
import dayjs from 'dayjs';
@@ -24,20 +23,22 @@
    trigger: 'axis',
    axisPointer: {
      type: 'shadow'
    }
    },
    formatter: '{b}: {c} 件'
  },
  legend: {
    data: ['任务', '事件'],
    top: '2%',
    textStyle: {
      color: '#fff'
      color: '#6B90B5',
      fontSize: 12,
    },
    bottom: '5%'
  },
  grid: {
    top: '15%',
    left: '3%',
    right: '4%',
    bottom: '15%',
    bottom: '2%',
    containLabel: true
  },
  xAxis: {
@@ -55,6 +56,7 @@
  },
  yAxis: {
    type: 'value',
    name: '单位:件',
    axisLine: {
      lineStyle: {
        color: '#fff'
@@ -73,22 +75,22 @@
    {
      name: '任务',
      type: 'bar',
      barWidth: '20%',
      barWidth: '6px',
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#1EE7E7' },
          { offset: 1, color: 'rgba(30, 231, 231, 0.1)' }
          { offset: 0, color: '#1EE7C5' },
          { offset: 1, color: '#84EDFF' }
        ])
      }
    },
    {
      name: '事件',
      type: 'bar',
      barWidth: '20%',
      barWidth: '6px',
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#0070FF' },
          { offset: 1, color: 'rgba(0, 112, 255, 0.1)' }
          { offset: 0, color: '#69BCFF' },
          { offset: 1, color: '#183FFF' }
        ])
      }
    }
@@ -104,12 +106,6 @@
    option.series[1].data = res.data?.data.map(item => item.data[1].value);
    chart.setOption(option);
  });
};
// 生成随机颜色
const getRandomColor = () => {
  const colors = ['#1890FF', '#36CBCB', '#4ECB73', '#FBD437', '#F2637B', '#975FE5'];
  return colors[Math.floor(Math.random() * colors.length)];
};
onBeforeUnmount(() => {
@@ -140,21 +136,21 @@
<style lang="scss" scoped>
.task-event {
  font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
  // margin-left: 29px;
  // padding: 16px 16px;
  width: 340px;
  height: 200px;
  background: linear-gradient(
    270deg,
    rgba(31, 62, 122, 0) 0%,
    rgba(31, 62, 122, 0.35) 21%,
    #1f3e7a 100%
  );
  border-radius: 0px 0px 0px 0px;
  opacity: 0.85;
  width: 660px;
  height: 100%;
  margin-left: 40px;
  .title {
    margin-top: 10px;
    width: 660px;
    height: 28.6px;
    background: url('@/assets/images/task/task-event-total.png') no-repeat center / 100% 100%;
    color: #CFEAFF;
    padding-left: 44px;
    line-height: 8px;
  }
  .chart {
    width: 100%;
    height: 100%;
    height: 200px;
  }
}
</style>
src/views/TaskManage/TaskTop/TaskIndustry.vue
@@ -1,13 +1,12 @@
<!-- 业务统计 -->
<!-- 任务算法统计 -->
 <template>
  <!-- <common-title title="行业统计" :style="{ marginLeft: pxToRem(14) }"></common-title> -->
  <div class="task-industry">
    <div class="title">任务算法统计</div>
    <div class="chart" ref="chartRef"></div>
  </div>
 </template>
<script setup>
import CommonTitle from '@/components/CommonTitle.vue';
import * as echarts from 'echarts';
import { industryJobNumPieChart } from '@/api/home/task';
const chartRef = ref(null);
@@ -21,52 +20,44 @@
  legend: {
    orient: 'horizontal',
    left: 'center',
    bottom: '5%',
    bottom: '2%',
    textStyle: {
      color: '#fff',
      color: '#6B90B5',
      fontSize: 12
    },
    itemWidth: 10,
    itemHeight: 10,
    itemGap: 10,
    formatter: function(name) {
      let data = option.series[0].data;
      let total = 0;
      let tarValue = 0;
      for (let i = 0; i < data.length; i++) {
        total += data[i].value;
        if (data[i].name === name) {
          tarValue = data[i].value;
        }
      }
      let percentage = ((tarValue / total) * 100).toFixed(1);
      return `${name} ${percentage}%`;
    }
    itemWidth: 2,        // 减小图例标记的宽度
    itemHeight: 3,       // 减小图例标记的高度
    itemGap: 8,          // 减小图例项之间的间距
    formatter: '{name}'  // 简化图例文本
  },
  series: [
    {
      name: '行业统计',
      type: 'pie',
      radius: '60%',
      center: ['35%', '50%'],
      itemStyle: {
        borderRadius: 4,
        borderColor: 'rgba(255,255,255,0.2)',
        borderWidth: 1
      },
      roseType: 'radius',
      radius: ['20%', '70%'],
      center: ['50%', '45%'],
      data: [
        { name: '国土类', value: 0, itemStyle: { color: '#3D7FFF' } },
        { name: '城管类', value: 0, itemStyle: { color: '#8277E9' } },
        { name: '消防类', value: 0, itemStyle: { color: '#FFB77E' } },
        { name: '林业类', value: 0, itemStyle: { color: '#44D7B6' } },
        { name: '公安类', value: 0, itemStyle: { color: '#62F4FF' } }
      ],
      label: {
        show: true,
        position: 'inside',
        position: 'outside',
        formatter: '{c}',
        fontSize: 12,
        color: '#fff'
      },
      labelLine: {
        show: false
      },
      emphasis: {
        scale: true,
        scaleSize: 10
        show: true,
        length: 5,
        length2: 8,
        lineStyle: {
          color: '#fff'
        }
      }
    }
  ]
@@ -76,23 +67,33 @@
const getIndustryJobNumPieChart = () => {
  industryJobNumPieChart().then(res => {
    if (res.data.code !== 0) return;
    const data = res.data.data.map(item => ({
      name: item.name,
      value: item.value,
      itemStyle: {
        color: getRandomColor()
    option.series[0].data.forEach(item => {
      const matchData = res.data.data.find(d => d.name === item.name);
      if (matchData) {
        item.value = matchData.value;
      }
    }));
    option.series[0].data = data;
    });
    chart.setOption(option);
  });
};
// 生成随机颜色
const getRandomColor = () => {
  const colors = ['#1890FF', '#36CBCB', '#4ECB73', '#FBD437', '#F2637B', '#975FE5'];
  return colors[Math.floor(Math.random() * colors.length)];
};
// 获取行业统计数据
// const getIndustryJobNumPieChart = () => {
//   industryJobNumPieChart().then(res => {
//     if (res.data.code !== 0) return;
//     const data = res.data.data.map(item => ({
//       name: item.name,
//       value: item.value,
//       itemStyle: {
//         color: getRandomColor()
//       }
//     }));
//     option.series[0].data = data;
//     chart.setOption(option);
//   });
// };
onMounted(() => {
  chart = echarts.init(chartRef.value);
@@ -112,21 +113,20 @@
<style lang="scss" scoped>
.task-industry {
  font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
  // margin-left: 29px;
  // padding: 16px 16px;
  width: 340px;
  height: 200px;
  background: linear-gradient(
    270deg,
    rgba(31, 62, 122, 0) 0%,
    rgba(31, 62, 122, 0.35) 21%,
    #1f3e7a 100%
  );
  border-radius: 0px 0px 0px 0px;
  opacity: 0.85;
  width: 244px;
  height: 100%;
  .title {
    margin-top: 10px;
    width: 244px;
    height: 26px;
    background: url('@/assets/images/task/title.png') no-repeat center / 100% 100%;
    color: #CFEAFF;
    padding-left: 38px;
    line-height: 8px;
  }
  .chart {
    width: 100%;
    height: 100%;
    height: 200px;
  }
}
</style>
src/views/TaskManage/TaskTop/TaskTime.vue
@@ -1,13 +1,12 @@
<!-- 任务事件统计 -->
<!-- 任务数量统计 -->
<template>
  <!-- <common-title title="任务时间统计"></common-title> -->
  <div class="task-time">
    <div class="title">任务数量统计</div>
    <div class="chart" ref="chartRef"></div>
  </div>
 </template>
<script setup>
import CommonTitle from '@/components/CommonTitle.vue';
import * as echarts from 'echarts';
import { jobNumBar } from '@/api/home/task';
import dayjs from 'dayjs';
@@ -24,13 +23,21 @@
    trigger: 'axis',
    axisPointer: {
      type: 'shadow'
    },
    formatter: '{b}: {c} 件'
  },
  legend: {
    top: '2%',
    textStyle: {
      color: '#6B90B5',
      fontSize: 12,
    }
  },
  grid: {
    top: '15%',
    left: '3%',
    right: '4%',
    bottom: '3%',
    bottom: '2%',
    containLabel: true
  },
  xAxis: {
@@ -48,6 +55,12 @@
  },
  yAxis: {
    type: 'value',
    name: '单位:件',
    nameTextStyle: {
      color: '#E6F7FF',
      fontSize: 12,
      padding: [0, 0, 0, 0]  // 调整单位文字位置
    },
    axisLine: {
      lineStyle: {
        color: '#fff'
@@ -64,12 +77,13 @@
  },
  series: [
    {
      name: '任务数量',
      type: 'bar',
      barWidth: '40%',
      barWidth: '6px',
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#1EE7E7' },
          { offset: 1, color: 'rgba(30, 231, 231, 0.1)' }
          { offset: 0, color: '#0EECE4' },
          { offset: 1, color: '#058FE7' }
        ])
      }
    }
@@ -111,21 +125,21 @@
<style lang="scss" scoped>
.task-time {
  font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
  // margin-left: 29px;
  // padding: 16px 16px;
  width: 340px;
  height: 200px;
  background: linear-gradient(
    270deg,
    rgba(31, 62, 122, 0) 0%,
    rgba(31, 62, 122, 0.35) 21%,
    #1f3e7a 100%
  );
  border-radius: 0px 0px 0px 0px;
  opacity: 0.85;
  width: 502px;
  height: 100%;
  margin-left: 14px;
  .title {
    margin-top: 10px;
    width: 502px;
    height: 28.6px;
    background: url('@/assets/images/task/task-num-total.png') no-repeat center / 100% 100%;
    color: #CFEAFF;
    padding-left: 44px;
    line-height: 8px;
  }
  .chart {
    width: 100%;
    height: 100%;
    height: 200px;
  }
}
</style>
src/views/TaskManage/TaskTop/TaskTop.vue
@@ -1,13 +1,20 @@
<template>
  <div class="task-left">
    <TaskTotal />
    <TaskIndustry />
    <TaskTime />
    <TaskEvent />
  <div class="task-top">
    <!--时间 天气-->
    <common-weather/>
    <UserOperate/>
    <div class="statistical-chart">
      <TaskTotal />
      <TaskIndustry />
      <TaskTime />
      <TaskEvent />
    </div>
  </div>
</template>
<script setup>
import CommonWeather from '@/components/CommonWeather.vue';
import UserOperate from '@/components/UserOperate.vue';
import TaskTotal from './TaskTotal.vue';
import TaskIndustry from './TaskIndustry.vue';
import TaskTime from './TaskTime.vue';
@@ -15,10 +22,22 @@
</script>
<style lang="scss" scoped>
.task-left {
.task-top {
  position: relative;
  display: flex;
  justify-content: space-between;
  margin: 40px;
  .statistical-chart {
    display: flex;
    width: 1848px;
    height: 238px;
    background: linear-gradient(
      270deg,
      rgba(31, 62, 122, 0) 0%,
      rgba(31, 62, 122, 0.35) 21%,
      #1f3e7a 100%
    );
    border-radius: 0px 0px 0px 0px;
    opacity: 0.85;
    margin-left: 38px;
    margin-right: 29px;
  }
}
</style>
src/views/TaskManage/TaskTop/TaskTotal.vue
@@ -1,11 +1,15 @@
<!-- 任务统计 -->
<template>
  <!-- <common-title title="任务统计" :style="{ marginLeft: pxToRem(14) }"></common-title> -->
  <div class="task-total">
    <div class="card" v-for="item in list">
      <div>
        <div class="value">{{ item.value }}</div>
        <div class="name">{{item.name}}</div>
    <div class="total">
      <div class="txt">总任务数</div>
      <div class="num">{{ total }}</div>
      <img src="@/assets/images/task/total.png" alt="">
    </div>
    <div class="other-total">
      <div class="total" v-for="item in list">
        <div class="value" :style="{ color:item.color }">{{ item.value }}</div>
        <div class="name">{{ item.name }}</div>
      </div>
    </div>
  </div>
@@ -13,23 +17,22 @@
<script setup>
import { pxToRem } from '@/utils/rem';
import CommonTitle from '@/components/CommonTitle.vue';
import { totalJobNum, jobStatistics  } from "@/api/home/task";
const total = ref(0);
const list = ref([
  { name: '总任务数', value: '1888'},
  { name: '计划执行', value: '18'},
  { name: '执行中', value: '999'},
  { name: '待执行', value: '8888'},
  { name: '已执行', value: '666'},
  { name: '执行失败', value: '2222'},
  { name: '计划执行', value: '0', color: '#FFFFFF'},
  { name: '执行中', value: '0', color: '#FFA768'},
  { name: '待执行', value: '0', color: '#FFE17E'},
  { name: '已执行', value: '0', color: '#8EFFAC'},
  { name: '执行失败', value: '0', color: '#FF8E8E'},
]);
// 获取任务统计总数
const getTotalJobNum = () => {
  totalJobNum().then((res) => {
    if (res.data.code !== 0) returen;
    list.value[0].value = res.data.data;
    total.value = res.data.data;
  });
};
// 获取其他任务统计
@@ -53,48 +56,46 @@
<style lang="scss" scoped>
.task-total {
  font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
  // margin-left: 29px;
  // padding: 16px 16px;
  width: 340px;
  height: 200px;
  left: 40px;
  background: linear-gradient(
    270deg,
    rgba(31, 62, 122, 0) 0%,
    rgba(31, 62, 122, 0.35) 21%,
    #1f3e7a 100%
  );
  border-radius: 0px 0px 0px 0px;
  opacity: 0.85;
  margin-bottom: 12px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 10px;
  padding: 20px;
  .card {
    /* position: absolute;
            top: 8px;
            right: 10px;
            width: 200px; */
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            justify-content: flex-start;
            line-height: 22px;
            padding: 0 10px 10px 0;
      color: #ffffff;
    .name {
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 400;
      font-size: 14px;
  display: flex;
  justify-content: space-between;
  color: #ffffff;
  .total {
    position: relative;
    text-align: center;
    left: 18px;
    .txt {
      font-size: 16px;
      margin-bottom: 14px;
      margin-top: 40px;
    }
    .value {
      font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
      font-weight: 400;
      font-size: 26px;
    img { width: 160px; height: 110px;}
    .num {
      position: absolute;
      font-size: 32px;
      top: 94px;
      left: 56px;
    }
  }
  .other-total {
    width: 256px;
    height: 188px;
    background: url('@/assets/images/task/other-total.png') no-repeat center / 100% 100%;
    margin-top: 22px;
    padding: 20px;
    display: flex;
    flex-wrap: wrap;
    align-content: space-around;
    .total {
      position: static;
      width: 30%;
      text-align: center;
      left: 0;
      .name {
        font-size: 14px;
      }
      .value {
        font-size: 26px;
      }
    }
  }
}