zxl
8 天以前 516b908d7d2df5e0eeb36f2f5ca3ccb103d1e14b
首页工作台
3个文件已修改
1个文件已添加
1850 ■■■■■ 已修改文件
src/api/index/index.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/workbench/workbench.js 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index-nongtou.vue 1125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/workbench.vue 622 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index/index.js
@@ -13,3 +13,32 @@
    method:"GET"
  })
}
export const getTaskStatus = (params) =>{
  return request({
    url:"/index/taskStatus",
    method:"POST",
    data:params
  })
}
export const getProjectSelectList = (params) =>{
  return request({
    url:"/index/getSelect",
    method:"GET"
  })
}
export const getStageCount = () =>{
  return request({
    url:"/index/stageCount",
    method:"GET"
  })
}
export const getProjectAdvanceCheckPoint = ()=>{
  return request({
    url:"/index/getProjectAdvanceCheckPoint",
    method:"GET"
  })
}
src/api/workbench/workbench.js
New file
@@ -0,0 +1,74 @@
import request from '@/utils/request'
export const getCountAchievements =() =>{
  return request({
    url:"/work-station-schedule/countAchievements",
    method:"GET"
  })
}
export const getProjectList =() =>{
  return request({
    url:"/work-station-schedule/getProjectList",
    method:"GET"
  })
}
export const getWaitTaskList =(params) =>{
  return request({
    url:"/work-station-schedule/getWaitTaskList",
    method:"GET",
    params:params
  })
}
export const add =(data) =>{
  return request({
    url:"/work-station-schedule",
    method:"POST",
    data:data
  })
}
export const update = (data)=>{
  return request({
    url:"/work-station-schedule",
    method:"PUT",
    data:data
  })
}
export const del = (params)=>{
  return request({
    url:"/work-station-schedule/" +params,
    method:"DELETE",
  })
}
// export const page =(params) =>{
//   return request({
//     url:"/work-station-schedule/page",
//     method:"GET",
//     params:params
//   })
// }
export const listByDate =(params) =>{
  return request({
    url:"/work-station-schedule/listByDate",
    method:"GET",
    params:params
  })
}
export const countTodayTask = () =>{
  return request({
    url:"/work-station-schedule/countTodayTask",
    method:"GET"
  })
}
export const auditHistoryPage = (params)=>{
  return request({
    url:"/work-station-schedule/auditHistoryPage",
    method:"GET",
    params:params
  })
}
src/views/index-nongtou.vue
@@ -60,19 +60,15 @@
          <div slot="header" class="clearfix row">
            <div style="flex: 1">项目进度统计</div>
            <div style="flex: 3;display: flex;justify-content: flex-end">
              <el-select
              <el-date-picker
                v-model="selectedMonth"
                type="month"
                placeholder="选择月份"
                style="width: 120px; margin-right: 10px;"
                style="width: 180px; margin-right: 10px;"
                @change="updateProgressChart"
              >
                <el-option
                  v-for="month in months"
                  :key="month.value"
                  :label="month.label"
                  :value="month.value"
                ></el-option>
              </el-select>
                format="yyyy-MM"
                value-format="yyyy-MM"
              ></el-date-picker>
              <el-select
                v-model="selectedProjects"
                multiple
@@ -88,7 +84,7 @@
                  :value="project.id"
                ></el-option>
              </el-select>
              <el-button type="text" @click="showDetail">详情</el-button>
<!--              <el-button type="text" @click="showDetail">详情</el-button>-->
            </div>
          </div>
          <div class="chart-container" ref="progressChart" style="height: 400px;"></div>
@@ -99,17 +95,17 @@
          <div slot="header" class="clearfix row">
            <div style="flex: 1">推进卡点</div>
            <div style="flex: 3; display: flex; justify-content: flex-end">
              <el-button type="text">全部</el-button>
<!--              <el-button type="text">全部</el-button>-->
            </div>
          </div>
          <el-table :data="blockingTasks" style="width: 100%" height="250">
            <el-table-column prop="taskName" label="任务名称" width="180"></el-table-column>
            <el-table-column prop="project" label="所属项目"></el-table-column>
            <el-table-column prop="owner" label="负责人" width="100"></el-table-column>
            <el-table-column prop="checkPointInfo.projectName" label="所属项目"></el-table-column>
            <el-table-column prop="customerTaskInfo.promoterName" label="负责人" width="100"></el-table-column>
            <el-table-column prop="startTime" label="开始时间" width="120"></el-table-column>
            <el-table-column prop="deadline" label="截止日期" width="120"></el-table-column>
            <el-table-column prop="overTime" label="已超时" width="120"></el-table-column>
            <el-table-column prop="totalOverTimes" label="累计超时次数" width="120" align="center"></el-table-column>
            <el-table-column prop="endTime" label="截止日期" width="120"></el-table-column>
            <el-table-column prop="totalOverTime" label="已超时" width="120"></el-table-column>
            <el-table-column prop="overTimeCount" label="累计超时次数" width="120" align="center"></el-table-column>
            <el-table-column label="操作" width="80">
              <template slot-scope="scope">
                <el-button size="mini" @click="handleTaskDetail(scope.row)">查看</el-button>
@@ -141,7 +137,7 @@
                  :value="project.id"
                ></el-option>
              </el-select>
              <el-button type="text" @click="showFundDetail">详情</el-button>
<!--              <el-button type="text" @click="showFundDetail">详情</el-button>-->
            </div>
          </div>
          <div class="chart-container" ref="fundChart" style="height: 400px;"></div>
@@ -152,7 +148,7 @@
          <div slot="header" class="clearfix row">
            <div style="flex:1">项目阶段统计</div>
            <div style="flex:3;display: flex;justify-content: flex-end">
              <el-button type="text">详情</el-button>
<!--              <el-button type="text">详情</el-button>-->
            </div>
          </div>
          <div class="chart-container" ref="stageChart" style="height: 250px;"></div>
@@ -164,66 +160,52 @@
<script>
import * as echarts from 'echarts';
import {getCodingCount ,getFundingStatus } from '@/api/index/index.js'
import {
  getCodingCount,
  getFundingStatus,
  getTaskStatus,
  getProjectSelectList,
  getStageCount,
  getProjectAdvanceCheckPoint
} from '@/api/index/index.js'
export default {
  name: 'ProjectManagement',
  data() {
    return {
      pathMap:{
        '在库': { path: '/projectEngineering/project/projectLibrary' },
        '储备': {
          path: '/projectEngineering/project/reserveProjects',
          query: { projectPhase: 1 }
        },
        '前期': {
          path:'/projectEngineering/project/previousProjects',
          query: { projectPhase: 2 }
        },
        '实施': {
          path:'/projectEngineering/project/implementationProject',
          query: { projectPhase: 3 }
        },
        '竣工': {
          path:'/projectEngineering/project/completedProjects',
          query: { projectPhase: 4 }
        }
      },
      userName: '张经理',
      userAvatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
      overviewData: {
        totalProjects: 42,
        inProgress: 28,
        atRisk: 7,
        delayed: 5
        totalProjects: 0,
        inProgress: 0,
        atRisk: 0,
        delayed: 0
      },
      blockingTasks: [
        {
          taskName: '取得土地权属',
          project: '射洪市酒粮基地建设项目',
          owner: '李四',
          startTime: '2025-05-15',
          overTime: '10天06小时',
          deadline: '2025-06-05',
          totalOverTimes: 4,
          status: '紧急'
        },
        {
          taskName: '可行性研究报告申请',
          project: '射洪市酒粮基地建设项目',
          owner: '王五',
          startTime: '2025-05-21',
          overTime: '8天',
          deadline: '2025-05-30',
          totalOverTimes: '5',
          status: '高风险'
        },
        {
          taskName: '建设工程竣工验收申请',
          project: '射洪市宜居宜业和美乡村建设项目',
          owner: '赵六',
          startTime: '2025-05-24',
          overTime: '4天14小时',
          deadline: '2025-06-04',
          totalOverTimes: '4',
          status: '延期'
        },
        {
          taskName: '生产建设项目水土保持方案编制',
          project: '射洪市宜居宜业和美乡村建设项目',
          owner: '钱七',
          startTime: '2025-06-01',
          overTime: '4天',
          deadline: '2025-06-07',
          totalOverTimes: '6',
          status: '进行中'
        },
      ],
      progressChart: null,
      fundChart: null,
      stageChart: null,
      // 筛选数据
      selectedMonth: '2025-06',
      selectedMonth: this.getCurrentMonth(),
      months: [
        { value: '2025-05', label: '2025年5月' },
        { value: '2025-06', label: '2025年6月' },
@@ -233,134 +215,15 @@
      selectedProjects: [],
      fundSelectedProjects: [],
      allProjects: [
        { id: 'p1', name: '射洪市国家储备林建设项目(一期)' },
        { id: 'p2', name: '射洪市白羽肉鸡产业建设项目' },
        { id: 'p3', name: '遂宁市射洪2024—2027年度东北片区高标准农田建设项目' },
        { id: 'p4', name: '射洪市现代种业示范基地建设项目' },
        { id: 'p5', name: '射洪市宜居宜业和美乡村建设项目' },
        { id: 'p6', name: '射洪市沱牌镇综合水利设施建设项目' }
      ],
      // 项目进度模拟数据
      progressData: {
        '2025-05': {
          'p1': { completed: 30, inProgress: 50, notStarted: 20 },
          'p2': { completed: 40, inProgress: 40, notStarted: 20 },
          'p3': { completed: 10, inProgress: 60, notStarted: 30 },
          'p4': { completed: 60, inProgress: 30, notStarted: 10 },
          'p5': { completed: 25, inProgress: 45, notStarted: 30 },
          'p6': { completed: 35, inProgress: 35, notStarted: 30 }
        },
        '2025-06': {
          'p1': { completed: 50, inProgress: 40, notStarted: 10 },
          'p2': { completed: 60, inProgress: 30, notStarted: 10 },
          'p3': { completed: 30, inProgress: 50, notStarted: 20 },
          'p4': { completed: 80, inProgress: 15, notStarted: 5 },
          'p5': { completed: 45, inProgress: 35, notStarted: 20 },
          'p6': { completed: 55, inProgress: 25, notStarted: 20 }
        },
        '2025-07': {
          'p1': { completed: 70, inProgress: 25, notStarted: 5 },
          'p2': { completed: 80, inProgress: 15, notStarted: 5 },
          'p3': { completed: 50, inProgress: 40, notStarted: 10 },
          'p4': { completed: 90, inProgress: 10, notStarted: 0 },
          'p5': { completed: 65, inProgress: 25, notStarted: 10 },
          'p6': { completed: 75, inProgress: 15, notStarted: 10 }
        },
        '2025-08': {
          'p1': { completed: 90, inProgress: 10, notStarted: 0 },
          'p2': { completed: 95, inProgress: 5, notStarted: 0 },
          'p3': { completed: 70, inProgress: 25, notStarted: 5 },
          'p4': { completed: 100, inProgress: 0, notStarted: 0 },
          'p5': { completed: 85, inProgress: 10, notStarted: 5 },
          'p6': { completed: 90, inProgress: 5, notStarted: 5 }
        }
      },
      // 资金使用模拟数据
      fundData: {
        'p1': {
          total: 5000,
          allocated: 3500,
          remaining: 1500,
          completed: 2800,
          sources: {
            projectCapital: 2000,
            countyInvestment: 1500,
            otherInvestment: 1000,
            governmentInvestment: 500
          }
        },
        'p2': {
          total: 3200,
          allocated: 2500,
          remaining: 700,
          completed: 1800,
          sources: {
            projectCapital: 1200,
            countyInvestment: 1000,
            governmentInvestment: 1000
          }
        },
        'p3': {
          total: 4200,
          allocated: 3000,
          remaining: 1200,
          completed: 2200,
          sources: {
            projectCapital: 1500,
            otherInvestment: 1200,
            governmentInvestment: 1500
          }
        },
        'p4': {
          total: 2800,
          allocated: 2000,
          remaining: 800,
          completed: 1500,
          sources: {
            projectCapital: 1000,
            countyInvestment: 800,
            otherInvestment: 500,
            governmentInvestment: 500
          }
        },
        'p5': {
          total: 3800,
          allocated: 3000,
          remaining: 800,
          completed: 2500,
          sources: {
            projectCapital: 1500,
            countyInvestment: 1000,
            governmentInvestment: 1300
          }
        },
        'p6': {
          total: 4500,
          allocated: 3500,
          remaining: 1000,
          completed: 3000,
          sources: {
            projectCapital: 2000,
            countyInvestment: 1500,
            otherInvestment: 500,
            governmentInvestment: 500
          }
        }
      }
      progressData: {},
      fundData: {}
    };
  },
  mounted() {
    getCodingCount().then(res =>{
    this.initData();
    })
    getFundingStatus().then(res=>{
    })
    this.selectedProjects = this.allProjects.map(p => p.id); // 默认全选
    this.fundSelectedProjects = this.allProjects.map(p => p.id); // 默认全选
    this.initCharts();
    window.addEventListener('resize', this.handleResize);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleResize);
@@ -375,6 +238,52 @@
    }
  },
  methods: {
    getCurrentMonth() {
      const now = new Date();
      const year = now.getFullYear();
      const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要+1
      return `${year}-${month}`;
    },
    async initData(){
      await this.initSelect();
      await this.initCodingCount();
      await this.initCharts();
      await this.initProjectAdvanceCheckPoint();
      window.addEventListener('resize', this.handleResize);
    },
    initProjectAdvanceCheckPoint(){
      getProjectAdvanceCheckPoint().then(res =>{
        if (res.code === 200){
          this.blockingTasks = res.data;
        }
      })
    },
    initCodingCount(){
      getCodingCount().then(res =>{
        if(res.code === 200){
          this.overviewData.totalProjects = res.data.total;
          this.overviewData.inProgress = res.data.green;
          this.overviewData.atRisk = res.data.yellow;
          this.overviewData.delayed = res.data.red;
        }
      })
    },
    initSelect(){
      getProjectSelectList().then(res =>{
        if (res.code === 200){
          this.allProjects = Object.entries(res.data).map(([id, name]) => ({
            id: id,          // 项目ID(如"151")
            name: name       // 项目名称(如"射洪市万林钢厂片区棚户区改造项目")
          }));
          this.selectedProjects = this.allProjects.slice(0, 5).map(p => p.id);
          this.fundSelectedProjects = this.allProjects.slice(0, 5).map(p => p.id);
        }
      })
    },
    initCharts() {
      // 初始化项目进度图表
      this.progressChart = echarts.init(this.$refs.progressChart);
@@ -386,329 +295,560 @@
      // 初始化项目阶段统计图表
      this.stageChart = echarts.init(this.$refs.stageChart);
      this.stageChart.setOption({
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: ['在库', '储备', '前期', '实施', '竣工'],
          axisLine: {
            lineStyle: {
              color: '#409EFF'
            }
          }
        },
        yAxis: {
          type: 'value',
          axisLine: {
            lineStyle: {
              color: '#409EFF'
            }
          }
        },
        series: [
          {
            data: [15, 12, 10, 8, 6, 4, 2],
            type: 'line',
            smooth: true,
            lineStyle: {
              width: 3,
              color: '#409EFF'
            },
            itemStyle: {
              color: '#409EFF'
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: 'rgba(64, 158, 255, 0.5)'
                },
                {
                  offset: 1,
                  color: 'rgba(64, 158, 255, 0.1)'
                }
              ])
            }
          }
        ]
      });
    },
      this.updateStageChart();
    },
    updateStageChart(){
      if (!this.stageChart) return;
      getStageCount().then(res =>{
        if (res.code ===200){
          const xData = res.data.xData || [];
          const yData = res.data.yData || [];
          this.stageChart.setOption({
            tooltip: {
              trigger: 'axis',
              triggerOn: 'mousemove',
              axisPointer: {
                type: 'shadow'
              }
            },
            grid: {
              left: '3%',
              right: '4%',
              bottom: '3%',
              containLabel: true
            },
            xAxis: {
              type: 'category',
              data: xData,
              axisLine: {
                lineStyle: {
                  color: '#409EFF'
                }
              }
            },
            yAxis: {
              type: 'value',
              axisLine: {
                lineStyle: {
                  color: '#409EFF'
                }
              }
            },
            series: [
              {
                data: yData,
                type: 'line',
                smooth: true,
                lineStyle: {
                  width: 3,
                  color: '#409EFF'
                },
                itemStyle: {
                  color: '#409EFF'
                },
                emphasis: {
                  itemStyle: {
                    color: '#1989fa',
                    size: 10
                  },
                  lineStyle: {
                    width: 4
                  },
                  // 整个系列区域hover都显示手型
                  cursor: 'pointer',
                  areaStyle: {
                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                      { offset: 0, color: 'rgba(25, 137, 250, 0.6)' },
                      { offset: 1, color: 'rgba(25, 137, 250, 0.2)' }
                    ])
                  }
                },
                areaStyle: {
                  color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    {
                      offset: 0,
                      color: 'rgba(64, 158, 255, 0.5)'
                    },
                    {
                      offset: 1,
                      color: 'rgba(64, 158, 255, 0.1)'
                    }
                  ])
                },
                triggerLineEvent: true,
                triggerAreaEvent: true
              }
            ]
          });
          this.stageChart.off('click');
          this.stageChart.on('click', (params) => {
            console.log('图表点击参数:', params);
            // 仅点击系列区域时处理
            if (params.componentType === 'series') {
              // 1. 将点击的像素坐标转换为X轴索引
              const pointInPixel = [params.event.offsetX, params.event.offsetY];
              const xAxisIndex = 0; // X轴索引(只有一个X轴,固定为0)
              const xAxisValue = this.stageChart.convertFromPixel({ seriesIndex: 0, axisIndex: xAxisIndex }, pointInPixel)[0];
              // 2. 计算所属的X轴标签索引(取整)
              const targetIndex = Math.max(0, Math.min(xData.length - 1, Math.floor(xAxisValue)));
              // 3. 获取对应标签
              const targetLabel = xData[targetIndex];
              // 4. 匹配pathMap跳转(无匹配则走默认)
              if (targetLabel && Object.keys(this.pathMap).includes(targetLabel)) {
                console.log(targetLabel)
                const targetRoute = this.pathMap[targetLabel] || { path: '/projectEngineering/project/projectLibrary' };
                this.$router.push(targetRoute);
              }
            }
          });
        }
      })
    },
    // 更新项目进度图表数据
    updateProgressChart() {
      if (!this.progressChart) return;
      const form ={
        startTime:this.selectedMonth
      }
      getTaskStatus(form).then(res => {
        if (res.code === 200) {
          // 从响应数据中提取流程统计信息
          const processStatistics = res.data || [];
      const monthData = this.progressData[this.selectedMonth];
      const filteredProjects = this.allProjects.filter(p =>
        this.selectedProjects.includes(p.id)
      );
      const categories = filteredProjects.map(p => p.name);
      const completedData = filteredProjects.map(p => monthData[p.id].completed);
      const inProgressData = filteredProjects.map(p => monthData[p.id].inProgress);
      const notStartedData = filteredProjects.map(p => monthData[p.id].notStarted);
          // 将后端数据转换为前端需要的格式
          const monthData = {};
          processStatistics.forEach(item => {
            // 假设后端返回的项目ID字段是 projectId,需要和前端的 allProjects 中的 id 匹配
            monthData[item.id] = {
              completed: item.completed || 0,
              inProgress: item.inProgress || 0,
              notStarted: item.notStarted || 0
            };
          });
          // 筛选选中的项目
          const filteredProjects = this.allProjects.filter(p =>
            this.selectedProjects.includes(p.id)
          );
      this.progressChart.setOption({
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          },
          formatter: function(params) {
            let result = params[0].name + '<br/>';
            params.forEach(param => {
              result += `${param.seriesName}: ${param.value}%<br/>`;
            });
            result += `总计: ${params.reduce((sum, param) => sum + param.value, 0)}%`;
            return result;
          }
        },
        legend: {
          data: ['已完成事项', '进行中事项', '未开始事项']
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'value',
          max: 100,
          axisLabel: {
            formatter: '{value}%'
          }
        },
        yAxis: {
          type: 'category',
          data: categories
        },
        series: [
          {
            name: '已完成事项',
            type: 'bar',
            stack: 'total',
            emphasis: {
              focus: 'series'
          // 准备图表数据
          const categories = filteredProjects.map(p => p.name);
          const completedData = filteredProjects.map(p => monthData[p.id]?.completed || 0);
          const inProgressData = filteredProjects.map(p => monthData[p.id]?.inProgress || 0);
          const notStartedData = filteredProjects.map(p => monthData[p.id]?.notStarted || 0);
          // 更新图表配置
          this.progressChart.setOption({
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'shadow'
              },
              formatter: function(params) {
                let result = params[0].name + '<br/>';
                params.forEach(param => {
                  result += `${param.seriesName}: ${param.value}%<br/>`;
                });
                // result += `总计: ${params.reduce((sum, param) => sum + param.value, 0)}%`;
                return result;
              }
            },
            data: completedData,
            itemStyle: {
              color: '#67C23A'
            legend: {
              data: ['已完成事项', '进行中事项', '未开始事项']
            },
            label: {
              show: true,
              position: 'inside',
              formatter: '{c}%'
            }
          },
          {
            name: '进行中事项',
            type: 'bar',
            stack: 'total',
            emphasis: {
              focus: 'series'
            grid: {
              left: '3%',
              right: '4%',
              bottom: '3%',
              containLabel: true
            },
            data: inProgressData,
            itemStyle: {
              color: '#409EFF'
            xAxis: {
              type: 'value',
              max: 100,
              axisLabel: {
                formatter: '{value}%'
              }
            },
            label: {
              show: true,
              position: 'inside',
              formatter: '{c}%'
            }
          },
          {
            name: '未开始事项',
            type: 'bar',
            stack: 'total',
            emphasis: {
              focus: 'series'
            yAxis: {
              type: 'category',
              data: categories
            },
            data: notStartedData,
            itemStyle: {
              color: '#E6A23C'
            },
            label: {
              show: true,
              position: 'inside',
              formatter: '{c}%'
            }
          }
        ]
            series: [
              {
                name: '已完成事项',
                type: 'bar',
                stack: 'total',
                emphasis: {
                  focus: 'series'
                },
                data: completedData,
                itemStyle: {
                  color: '#67C23A'
                },
                label: {
                  show: true,
                  position: 'inside',
                  formatter: '{c}%'
                }
              },
              {
                name: '进行中事项',
                type: 'bar',
                stack: 'total',
                emphasis: {
                  focus: 'series'
                },
                data: inProgressData,
                itemStyle: {
                  color: '#409EFF'
                },
                label: {
                  show: true,
                  position: 'inside',
                  formatter: '{c}%'
                }
              },
              {
                name: '未开始事项',
                type: 'bar',
                stack: 'total',
                emphasis: {
                  focus: 'series'
                },
                data: notStartedData,
                itemStyle: {
                  color: '#E6A23C'
                },
                label: {
                  show: true,
                  position: 'inside',
                  formatter: '{c}%'
                }
              }
            ]
          });
        }
      }).catch(error => {
        // 错误处理
        this.progressChart.hideLoading();
        console.error('获取任务状态数据失败:', error);
        // 可以显示错误提示或使用默认数据
      });
    },
    // 更新资金使用图表数据
    updateFundChart() {
      if (!this.fundChart) return;
      getFundingStatus().then(res=> {
        if (res.code === 200) {
          const fundingData = res.data || [];
          const data = {};
          fundingData.forEach(item => {
            // 仅组装 SQL 查询返回的 9 个字段,字段名与 VO 一致
            data[item.projectId] = {
              id: item.projectId || '', // 项目ID(关联键)
              totalInvestment: item.totalInvestment || '0', // 项目总投资额
              principal: item.principal || '0', // 项目本金
              governmentInvestmentTotal: item.governmentInvestmentTotal || '0', // 政府投资总额
              centralInvestmentTotal: item.centralInvestmentTotal || '0', // 中央投资总额
              provincialInvestmentTotal: item.provincialInvestmentTotal || '0', // 省级投资总额
              cityInvestmentTotal: item.cityInvestmentTotal || '0', // 市(州)投资总额
              countyInvestmentTotal: item.countyInvestmentTotal || '0', // 县(市、区)投资总额
              otherInvestmentTotal: item.otherInvestmentTotal || '0', // 其他投资总额
              enterpriseSelfRaisedTotal: item.enterpriseSelfRaisedTotal || '0',
              foreignInvestmentTotal: item.foreignInvestmentTotal || '0',
              bankLoan: item.bankLoan || '0',//银行贷款
              domesticLoanTotal: item.domesticLoanTotal || '0',
            };
          });
          console.log(data)
          const filteredProjects = this.allProjects.filter(p =>
            this.fundSelectedProjects.includes(p.id)
          );
          const categories = filteredProjects.map(p => p.name);
          // console.log(categories)
          // const allocatedData = filteredProjects.map(p => data[p.id].allocated);
          // console.log(allocatedData)
          // const remainingData = filteredProjects.map(p => data[p.id].remaining);
          // console.log(remainingData)
      const filteredProjects = this.allProjects.filter(p =>
        this.fundSelectedProjects.includes(p.id)
      );
          // 资金来源数据 本金
          const projectCapitalData = filteredProjects.map(p =>
            data[p.id].principal || 0
          );
          //总投资
          const totalInvestmentData = filteredProjects.map(p =>
            data[p.id].totalInvestment || 0
          );
          // 县(市、区)投资总额
          const countyInvestmentData = filteredProjects.map(p =>
            data[p.id].countyInvestmentTotal || 0
          );
          // 市(州)投资总额
          const  cityInvestmentTotalData = filteredProjects.map(p =>
          data[p.id].cityInvestmentTotal || 0)
          // 省级投资总额
          const  provincialInvestmentTotalData = filteredProjects.map(p =>
            data[p.id].provincialInvestmentTotal || 0)
          //政府投资
          const governmentInvestmentData = filteredProjects.map(p =>
            data[p.id].governmentInvestmentTotal || 0
          );
          //其他投资
          const otherInvestmentData = filteredProjects.map(p =>
            data[p.id].otherInvestmentTotal || 0
          );
          //中央
          const centralInvestmentTotalData = filteredProjects.map(p =>
            data[p.id].centralInvestmentTotal || 0
          );
          //企业自筹
          const enterpriseSelfRaisedTotalData = filteredProjects.map(p =>
            data[p.id].enterpriseSelfRaisedTotal || 0
          );
          //外商投资
          const foreignInvestmentTotalData = filteredProjects.map(p =>
            data[p.id].foreignInvestmentTotal || 0
          );
          const bankLoanData = filteredProjects.map(p =>
            data[p.id].bankLoan || 0
          );
          const domesticLoanTotalData = filteredProjects.map(p =>
            data[p.id].domesticLoanTotal || 0
          );
      const categories = filteredProjects.map(p => p.name);
      const allocatedData = filteredProjects.map(p => this.fundData[p.id].allocated);
      const remainingData = filteredProjects.map(p => this.fundData[p.id].remaining);
      // 资金来源数据
      const projectCapitalData = filteredProjects.map(p =>
        this.fundData[p.id].sources.projectCapital || 0
      );
      const countyInvestmentData = filteredProjects.map(p =>
        this.fundData[p.id].sources.countyInvestment || 0
      );
      const otherInvestmentData = filteredProjects.map(p =>
        this.fundData[p.id].sources.otherInvestment || 0
      );
      const governmentInvestmentData = filteredProjects.map(p =>
        this.fundData[p.id].sources.governmentInvestment || 0
      );
          this.fundChart.setOption({
            tooltip: {
              trigger: 'axis',
              confine: true,
              axisPointer: {
                type: 'shadow'
              },
              zIndex: 9999,
      this.fundChart.setOption({
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          },
          formatter: function(params) {
            let result = params[0].name + '<br/>';
            // 资金拨付和剩余
            result += `资金拨付: ${params[0].value}万元<br/>`;
            result += `剩余金额: ${params[1].value}万元<br/>`;
            result += `总金额: ${params[0].value + params[1].value}万元<br/>`;
            result += `完成投资: ${params[0].axisValueLabel}万元<br/><br/>`;
            // 资金来源
            result += '<strong>资金来源构成:</strong><br/>';
            result += `项目本金: ${params[2].value}万元<br/>`;
            result += `县(市、区)投资: ${params[3].value}万元<br/>`;
            result += `其他投资: ${params[4].value}万元<br/>`;
            result += `政府投资: ${params[5].value}万元<br/>`;
            return result;
          }
        },
        legend: {
          data: ['剩余金额', '资金拨付', '项目本金', '县(市、区)投资', '政府投资', '其他投资']
        },
        grid: {
          top: '30%',
          left: '3%',
          right: '4%',
          bottom: '5%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: categories,
          axisLabel: {
            interval: 0,
            rotate: 30
          }
        },
        yAxis: {
          type: 'value',
          name: '金额(万元)'
        },
        series: [
          {
            name: '资金拨付',
            type: 'bar',
            stack: 'total',
            emphasis: {
              focus: 'series'
              formatter: function(params) {
                let result = params[0].name + '<br/>';
                // 资金拨付和剩余
                // result += `资金拨付: ${params[0].value}万元<br/>`;
                // result += `剩余金额: ${params[1].value}万元<br/>`;
                const value1 = Number(params[0].value) || 0;
                const value2 = Number(params[1].value) || 0;
                result += `总金额: ${value1 + value2}万元<br/>`;
                // result += `完成投资: ${params[0].axisValueLabel}万元<br/><br/>`;
                //
                // // 资金来源
                result += '<strong>资金来源构成:</strong><br/>';
                result += `项目本金: ${params[0].value}万元<br/>`;
                result += `县(市、区)投资: ${params[2].value}万元<br/>`;
                result += `市(州)投资: ${params[3].value}万元<br/>`;
                result += `省级投资: ${params[4].value}万元<br/>`;
                result += `中央投资: ${params[5].value}万元<br/>`;
                result += `政府投资: ${params[6].value}万元<br/>`;
                result += `其他投资: ${params[7].value}万元<br/>`;
                result += `企业自筹: ${params[8].value}万元<br/>`;
                result += `外商投资: ${params[9].value}万元<br/>`;
                result += `银行贷款: ${params[10].value}万元<br/>`;
                result += `国内贷款: ${params[11].value}万元<br/>`;
                return result;
              }
            },
            data: allocatedData,
            itemStyle: {
              color: '#409EFF'
            legend: {
              data: [
                // '剩余金额', '资金拨付',
                '项目本金','项目总投资', '县(市、区)投资','市(州)投资','省级投资','中央投资', '政府投资', '其他投资',
                '企业自筹', '外商投资', '银行贷款', '国内贷款',]
            },
            label: {
              show: true,
              position: 'inside',
              formatter: '{c}'
            }
          },
          {
            name: '剩余金额',
            type: 'bar',
            stack: 'total',
            emphasis: {
              focus: 'series'
            grid: {
              top: '30%',
              left: '3%',
              right: '4%',
              bottom: '5%',
              containLabel: true
            },
            data: remainingData,
            itemStyle: {
              color: '#E6A23C'
            xAxis: {
              type: 'category',
              data: categories,
              axisLabel: {
                interval: 0,
                rotate: 30
              }
            },
            label: {
              show: true,
              position: 'inside',
              formatter: '{c}'
            }
          },
          {
            name: '项目本金',
            type: 'bar',
            stack: 'sources',
            emphasis: {
              focus: 'series'
            yAxis: {
              type: 'value',
              name: '金额(万元)'
            },
            data: projectCapitalData,
            itemStyle: {
              color: '#67C23A'
            }
          },
          {
            name: '县(市、区)投资',
            type: 'bar',
            stack: 'sources',
            emphasis: {
              focus: 'series'
            },
            data: countyInvestmentData,
            itemStyle: {
              color: '#F56C6C'
            }
          },
          {
            name: '其他投资',
            type: 'bar',
            stack: 'sources',
            emphasis: {
              focus: 'series'
            },
            data: otherInvestmentData,
            itemStyle: {
              color: '#909399'
            }
          },
          {
            name: '政府投资',
            type: 'bar',
            stack: 'sources',
            emphasis: {
              focus: 'series'
            },
            data: governmentInvestmentData,
            itemStyle: {
              color: '#8E44AD'
            }
          }
        ]
            series: [
              {
                name: '项目本金',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: projectCapitalData,
                itemStyle: {
                  color: '#42B983' // 主绿色:项目核心自有资金
                }
              },
              {
                name: '项目总投资',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: totalInvestmentData,
                itemStyle: {
                  color: '#36CFC9' // 青绿色:总投资汇总数据
                }
              },
              {
                name: '县(市、区)投资',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: countyInvestmentData,
                itemStyle: {
                  color: '#A0D911' // 浅黄绿色:县级投资
                }
              },
              {
                name: '市(州)投资',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: cityInvestmentTotalData,
                itemStyle: {
                  color: '#7CB305' // 亮绿色:市州级投资
                }
              },
              {
                name: '省级投资',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: provincialInvestmentTotalData,
                itemStyle: {
                  color: '#40A9FF' // 中蓝色:省级投资
                }
              },
              {
                name: '中央投资',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: centralInvestmentTotalData,
                itemStyle: {
                  color: '#1890FF' // 深蓝色:中央投资(层级最高)
                }
              },
              {
                name: '政府投资',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: governmentInvestmentData,
                itemStyle: {
                  color: '#8E44AD' // 紫色:政府投资总额(汇总项)
                }
              },{
                name: '其他投资',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: otherInvestmentData,
                itemStyle: {
                  color: '#909399' // 深灰色:其他投资
                }
              },
              {
                name: '企业自筹',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: enterpriseSelfRaisedTotalData,
                itemStyle: {
                  color: '#e6cb6d' // 深灰色:其他投资
                }
              },
              {
                name: '外商投资',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: foreignInvestmentTotalData,
                itemStyle: {
                  color: '#f443b9' // 深灰色:其他投资
                }
              },{
                name: '银行贷款',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: bankLoanData,
                itemStyle: {
                  color: '#bd5fd8' // 深灰色:其他投资
                }
              },{
                name: '国内贷款',
                type: 'bar',
                stack: 'sources',
                emphasis: {
                  focus: 'series'
                },
                data: domesticLoanTotalData,
                itemStyle: {
                  color: '#4373d3' // 深灰色:其他投资
                }
              }
            ]
          });
          this.fundChart.on('click', (params) => { // 这里改为箭头函数
            const clickedProject = filteredProjects[params.dataIndex];
            const projectId = clickedProject ? clickedProject.id : '无';
            const audit = 1;
            // 此时 this 指向 Vue 组件,可正常访问 $router
            this.$router.push({
              path: '/projectEngineering/project/ProjectDetails',
              query: { projectId: projectId, disabled: 'true', audit: audit }
            });
          });
        }
      });
    },
    },
    removeStore() {
      localStorage.removeItem("projectForm")
      localStorage.removeItem("investmentForm")
      localStorage.removeItem("investmentFundsForm")
      localStorage.removeItem("legalPersonForm")
      localStorage.removeItem("policyInfoForm")
      localStorage.removeItem("documentsInfoForm")
    },
    // 更新所有图表
    updateCharts() {
      this.updateProgressChart();
@@ -736,7 +876,28 @@
      return map[status] || '';
    },
    handleTaskDetail(task) {
      this.$message.info(`查看任务详情: ${task.taskName}`);
    console.log(task)
      const queryParams= {
        taskName: '',
        taskType: 'todo',
        pageSize: 5,
        currentPage: 1,
        projectId: null,
        processDefId: null,
        processInsId: null,
        deployId: null,
        processName: '' // 流程名称
      }
      this.$router.push({ path: '/flowable/task/myProcess/detail/index',
        query: {
          projectName: task.checkPointInfo.projectName,
          flowName: task.checkPointInfo.processName,
          procInsId: task.checkPointInfo.processInstanceId,
          deployId: task.checkPointInfo.deployId,
          taskId: task.id,
          projectId: task.checkPointInfo.id,
          goBackParams: queryParams
        }})
    },
    showDetail() {
      this.$message.info(`查看${this.selectedMonth}月份的项目进度详情`);
src/views/workbench.vue
@@ -3,7 +3,7 @@
    <!-- 顶部导航栏 -->
    <div class="top-navbar">
      <div class="welcome-message">
        <h2>早安,{{ this.$store.state.user.name }}!</h2>
        <h2>{{ getCurrentTimePeriod() }},{{ this.$store.state.user.name }}!</h2>
        <p>今天是{{ currentDate }},祝您工作愉快!</p>
      </div>
      <div class="quick-stats">
@@ -16,8 +16,8 @@
          <span class="stat-label">今日日程</span>
        </div>
        <div class="stat-item">
          <span class="stat-number">{{ unreadMessages }}</span>
          <span class="stat-label">未读消息</span>
          <span class="stat-number">{{ totalActiveTasks }}</span>
          <span class="stat-label">今日处理</span>
        </div>
      </div>
      <div class="user-profile">
@@ -52,15 +52,15 @@
            <el-menu-item
              v-for="project in projects"
              :key="project.id"
              :index="project.id">
              :index="project.id +''">
              <i class="el-icon-folder"></i>
              <span slot="title" class="project-name" :title="project.name">
                {{ project.name }}
              <span slot="title" class="project-name" :title="project.projectName">
                {{ project.projectName }}
              </span>
            </el-menu-item>
          </el-menu>
          <div class="project-actions">
            <el-button type="primary" icon="el-icon-plus" size="small">新建项目</el-button>
            <el-button type="primary" icon="el-icon-plus" size="small" @click="addProject">新建项目</el-button>
          </div>
        </div>
      </div>
@@ -71,73 +71,88 @@
        <div class="task-section">
          <div class="section-header">
            <h3>待办任务</h3>
            <el-button type="text" icon="el-icon-refresh">刷新</el-button>
            <el-button type="text" icon="el-icon-refresh" @click="getWaitTaskList()" :disabled="waitTaskRefreshing">刷新</el-button>
          </div>
          <el-table
            :data="tasks"
            border
            style="width: 100%"
          <div>
            <el-table
              v-loading="loading"
              :data="tasks"
              border
              style="width: 100%"
            >
            <el-table-column
              prop="name"
              label="任务名称"
              width="240">
            </el-table-column>
            <el-table-column
              prop="project"
              label="所属项目"
              show-overflow-tooltip
              width="300">
            </el-table-column>
            <el-table-column
              prop="startTime"
              label="开始时间"
              align="center"
              width="160">
            </el-table-column>
            <el-table-column
              prop="deadline"
              label="截止时间"
              align="center"
              width="160">
            </el-table-column>
            <el-table-column
              prop="status"
              label="状态"
              align="center"
              width="100">
              <template slot-scope="scope">
                <el-tag :type="scope.row.status === '待完成' ? 'success' : 'warning'" size="small">
                  {{ scope.row.status }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column
              label="操作"
              fixed="right"
              width="120">
              <template slot-scope="scope">
                <el-button size="mini" @click="handleTaskEdit(scope.row)">办理</el-button>
              </template>
            </el-table-column>
          </el-table>
              <el-table-column
                prop="taskName"
                label="任务名称"
                width="240">
              </el-table-column>
              <el-table-column
                prop="checkPointInfo.projectName"
                label="所属项目"
                show-overflow-tooltip
                width="300">
              </el-table-column>
              <el-table-column
                prop="startTime"
                label="开始时间"
                align="center"
                width="160">
              </el-table-column>
              <el-table-column
                prop="endTime"
                label="截止时间"
                align="center"
                width="160">
              </el-table-column>
              <el-table-column
                prop="status"
                label="状态"
                align="center"
                width="100">
                <template slot-scope="scope">
                  <el-tag :type="scope.row.taskType === '待完成' ? 'success' : 'warning'" size="small">
                    {{ scope.row.taskType }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column
                label="操作"
                fixed="right"
              >
                <template slot-scope="scope">
                  <el-button size="mini" @click="handleTaskEdit(scope.row)">办理</el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </div>
        <!-- 项目办理日志 -->
        <div class="log-section">
          <div class="section-header">
            <h3>项目办理日志</h3>
            <el-button type="text" icon="el-icon-refresh">刷新</el-button>
            <el-button type="text" icon="el-icon-refresh" @click="getAuditHistoryPage" :disabled="auditHistoryRefreshing">刷新</el-button>
          </div>
          <div class="log-list">
          <div class="log-list"  v-loading="auditHistoryLoading">
            <div v-for="log in logs" :key="log.id" class="log-item">
              <div class="log-time">{{ log.time }}</div>
              <div class="log-content">
                <span class="log-project">{{ log.project }}</span>
                <span class="log-action">{{ log.action }}</span>
                <span class="log-detail">{{ log.detail }}</span>
                <span class="log-project">{{ log.projectName }}</span>
                <span class="log-action">{{ getAuditTypeText(log.auditType) }}</span>
                <span class="log-detail">{{ log.content }}</span>
              </div>
            </div>
          </div>
          <div class="pagination-container">
            <el-pagination
              @current-change="auditHistoryHandleCurrentChange"
              :current-page="auditHistoryQuery.currentPage"
              :page-size="auditHistoryQuery.pageSize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="auditHistoryTotal"
            >
            </el-pagination>
          </div>
        </div>
      </div>
@@ -189,11 +204,12 @@
            <h3>日程列表</h3>
            <div>
              <el-button type="text" icon="el-icon-plus" @click="handleAddSchedule">新增</el-button>
              <el-button type="text" icon="el-icon-refresh">刷新</el-button>
              <el-button type="text" icon="el-icon-refresh" @click="getScheduleList" :disabled="scheduleRefreshing">刷新</el-button>
            </div>
          </div>
          <div class="schedule-list">
            <el-table
              v-loading="scheduleLoading"
              :data="filteredSchedules"
              style="width: 100%"
              height="250">
@@ -217,40 +233,161 @@
              </el-table-column>
            </el-table>
          </div>
          <div class="pagination-container">
            <el-pagination
              @current-change="handleCurrentChange"
              :current-page="waitTaskQuery.currentPage"
              :page-size="waitTaskQuery.pageSize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="waitTaskTotal"
            >
            </el-pagination>
          </div>
        </div>
      </div>
    </div>
    <el-dialog
      :title="diaLogTitle"
      :visible.sync="scheduleDialogVisible"
      width="500px"
      @close="resetScheduleForm"
    >
      <el-form
        ref="scheduleFormRef"
        :model="scheduleForm"
        :rules="scheduleRules"
        label-width="80px"
      >
        <el-form-item label="选择项目" prop="projectId">
          <el-select
            v-model="scheduleForm.projectId"
            clearable
            placeholder="选择项目"
            style="width: 100%"
          >
            <el-option
              v-for="project in allProjects"
              :key="project.id"
              :label="project.name"
              :value="project.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <!-- 工作内容 -->
        <el-form-item label="工作内容" prop="content">
          <el-input
            v-model="scheduleForm.content"
            type="textarea"
            placeholder="请输入工作内容"
            rows="3"
          ></el-input>
        </el-form-item>
        <!-- 完成日期 -->
        <el-form-item label="完成日期" prop="completedTime">
          <el-date-picker
            v-model="scheduleForm.completedTime"
            type="datetime"
            placeholder="请选择完成日期"
            value-format="yyyy-MM-dd HH:mm:ss"
            style="width: 100%;"
          ></el-date-picker>
        </el-form-item>
      </el-form>
      <template v-slot:footer>
        <el-button @click="scheduleDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitSaveSchedule">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import {
  getCountAchievements,
  getProjectList,
  getWaitTaskList,
  add,
  auditHistoryPage,
  listByDate,
  update,
  del,
  countTodayTask,
} from "@/api/workbench/workbench"
import {getTaskIsAuditing} from "@/api/projectProcess/projectProcess";
import {getProjectSelectList} from "@/api/index";
export default {
  data() {
    return {
      diaLogTitle:"",
      allProjects:[],
      scheduleDialogVisible: false,
      // 新增:新增日程表单数据(对应WorkStationSchedule实体)
      scheduleForm: {
        id:'',
        content: '', // 工作内容
        completedTime: '',
        projectId:''
      },
      // 新增:表单校验规则
      scheduleRules: {
        content: [
          {required: true, message: '请输入工作内容', trigger: 'blur'},
          {max: 500, message: '工作内容最多500个字符', trigger: 'blur'}
        ],
        completedTime: [
          {required: true, message: '请选择完成日期', trigger: 'change'}
        ],
        projectId:[
          {required:true,message: '请选择项目', trigger: 'change'}
        ]
      },
      queryParams: {
        taskName: '',
        taskType: 'todo',
        pageSize: 5,
        currentPage: 1,
        projectId: null,
        processDefId: null,
        processInsId: null,
        deployId: null,
        processName: '' // 流程名称
      },
      waitTaskRefreshing:false,
      scheduleRefreshing:false,
      auditHistoryRefreshing:false,
      loading:false,
      scheduleLoading:false,
      auditHistoryLoading:false,
      waitTaskQuery:{
        pageSize:5,
        currentPage:1,
      },
      auditHistoryQuery:{
        pageSize:5,
        currentPage:1,
      },
      waitTaskTotal:0,
      auditHistoryTotal:0,
      projectId:null,
      userInfo: {
        name: '张工程师',
        avatar: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png',
        department: '项目部'
      },
      currentDate: this.formatDate(new Date()),
      todayTasks: 5,
      todaySchedules: 3,
      unreadMessages: 2,
      todayTasks: 0,
      todaySchedules: 0,
      totalActiveTasks: 0,
      activeProject: 'all',
      projects: [
        { id: '1', name: '射洪市沱牌镇综合水利设施建设项目' },
        { id: '2', name: '射洪市国家储备林建设项目(一期)' },
        { id: '3', name: '射洪市白羽肉鸡产业建设项目' },
        { id: '4', name: '遂宁市射洪2024—2027年度东北片区高标准农田建设项目' },
        { id: '5', name: '射洪市现代种业示范基地建设项目' },
      ],
      tasks: [
        { id: 1, name: '审核施工图纸', project: '射洪市国家储备林建设项目(一期)', startTime: '2025-05-05', deadline: '2025-06-15', status: '待完成' },
        { id: 2, name: '采购材料清单', project: '射洪市白羽肉鸡产业建设项目', startTime: '2025-05-14', deadline: '2025-06-18', status: '待完成' },
        { id: 3, name: '现场安全检查', project: '遂宁市射洪2024—2027年度东北片区高标准农田建设项目', startTime: '2025-05-10', deadline: '2025-06-12', status: '容缺中' },
        { id: 4, name: '项目进度报告', project: '射洪市现代种业示范基地建设项目', startTime: '2025-05-23', deadline: '2025-06-20', status: '待完成' },
        { id: 5, name: '供应商会议', project: '射洪市沱牌镇综合水利设施建设项目', startTime: '2025-05-14', deadline: '2025-06-14', status: '容缺中' }
      ],
      projects: [],
      tasks: [],
      logs: [
        { id: 1, time: '09:30', project: '射洪市国家储备林建设项目(一期)', action: '提交', detail: '提交了施工图纸审核申请' },
        { id: 2, time: '10:15', project: '射洪市白羽肉鸡产业建设项目', action: '更新', detail: '更新了材料采购清单' },
@@ -259,20 +396,13 @@
        { id: 5, time: '16:45', project: '射洪市沱牌镇综合水利设施建设项目', action: '审批', detail: '审批通过了安全方案' }
      ],
      achievements: {
        completedTasks: 128,
        avgDuration: 3.5,
        totalSchedules: 89,
        completedSchedules: 76
        completedTasks: 0,
        avgDuration: 0,
        totalSchedules: 0,
        completedSchedules: 0
      },
      calendarDate: new Date(),
      schedules: [
        { id: 1, date: '2025-05-10', time: '09:00', title: '项目启动会议', project: '射洪市国家储备林建设项目(一期)' },
        { id: 2, date: '2025-05-10', time: '14:00', title: '供应商洽谈', project: '射洪市白羽肉鸡产业建设项目' },
        { id: 3, date: '2025-05-11', time: '10:30', title: '现场勘察', project: '遂宁市射洪2024—2027年度东北片区高标准农田建设项目' },
        { id: 4, date: '2025-05-12', time: '09:00', title: '安全培训', project: '射洪市现代种业示范基地建设项目' },
        { id: 5, date: '2025-05-12', time: '15:00', title: '进度汇报', project: '射洪市沱牌镇综合水利设施建设项目' },
        { id: 6, date: '2025-05-15', time: '13:00', title: '设备验收', project: '射洪市白羽肉鸡产业建设项目' }
      ]
      schedules: []
    }
  },
  computed: {
@@ -281,7 +411,242 @@
      return this.schedules.filter(schedule => schedule.date === selectedDate);
    }
  },
  mounted() {
    this.initData();
    this.initSelect();
    this.getScheduleList();
    this.countTodayTask();
    this.getAuditHistoryPage();
  },
  methods: {
    getAuditTypeText(auditType) {
      // 映射关系:后端值 → 前端汉字
      const typeMap = {
        Submit: '提交',
        Review: '审核',
        Reject: '驳回',
        Forward: '转交'
      };
      // 兜底:未知值返回“未知操作”
      return typeMap[auditType] || '未知操作';
    },
    countTodayTask(){
      countTodayTask().then(res =>{
        if (res.code === 200){
          this.todayTasks = res.data.todayTasks;
          this.todaySchedules = res.data.todaySchedules;
          this.totalActiveTasks = res.data.totalActiveTasks;
        }
      })
    },
    initSelect(){
      getProjectSelectList().then(res =>{
        if (res.code === 200){
          this.allProjects = Object.entries(res.data).map(([id, name]) => ({
            id: id,          // 项目ID(如"151")
            name: name       // 项目名称(如"射洪市万林钢厂片区棚户区改造项目")
          }));
        }
      })
    },
    getScheduleList(){
      if (this.scheduleRefreshing){
        return
      }
      const form ={
        completedTime:this.formatDateToFrontend(this.calendarDate),
        projectId:this.activeProject
      }
      this.scheduleLoading = true
      this.scheduleRefreshing = true
      listByDate(form).then(res =>{
        this.scheduleRefreshing = false
        this.scheduleLoading = false
        if (res.code === 200){
          this.schedules = res.data;
        }
      })
    },
    formatDateToFrontend(date) {
      if (!date) return '';
      const d = new Date(date);
      const year = d.getFullYear();
      const month = (d.getMonth() + 1).toString().padStart(2, '0');
      const day = d.getDate().toString().padStart(2, '0');
      const hour = d.getHours().toString().padStart(2, '0');
      const minute = d.getMinutes().toString().padStart(2, '0');
      const second = d.getSeconds().toString().padStart(2, '0');
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
    },
    async submitSaveSchedule(){
      this.$refs.scheduleFormRef.validate((valid, fields) => {
        if (valid) {
          console.log(this.scheduleForm.id)
          if (this.scheduleForm.id === null || this.scheduleForm.id ==='' || this.scheduleForm.id === undefined){
            const submitData = {
              content: this.scheduleForm.content,
              completedTime: this.formatDateToFrontend(this.scheduleForm.completedTime),
              projectId:this.scheduleForm.projectId
            };
            this.$message.success('表单提交成功!');
            add(submitData).then(res =>{
              if (res.code === 200){
                this.scheduleDialogVisible = false;
                this.$message.success('新增日程成功')
                //刷新列表
                this.getScheduleList();
              }
            })
          }else {
            const submitData = {
              id:this.scheduleForm.id,
              content: this.scheduleForm.content,
              completedTime: this.formatDateToFrontend(this.scheduleForm.completedTime),
              projectId:this.scheduleForm.projectId
            };
            this.$message.success('表单提交成功!');
            update(submitData).then(res =>{
              if (res.code === 200){
                this.scheduleDialogVisible = false;
                this.$message.success('编辑日程成功')
                //刷新列表
                this.getScheduleList();
              }
            })
          }
        }else {
          const firstError = Object.values(fields)[0][0].message;
          this.$message.error(firstError);
        }
      });
    },
    handleAddSchedule() {
      this.resetScheduleForm();
      this.scheduleDialogVisible = true;
      this.diaLogTitle = "新增日志"
    },
    handleEditSchedule(row){
      this.resetScheduleForm();
      this.scheduleDialogVisible = true;
      this.diaLogTitle = "编辑日志"
      //赋值
      this.scheduleForm.id = row.id;
      this.scheduleForm.content = row.title;
      this.scheduleForm.projectId = row.projectId +"";
      this.scheduleForm.completedTime = new Date(row.completedTime);
      console.log(row)
    },
    // 新增:重置新增表单
    resetScheduleForm() {
      this.scheduleForm = {
        if:'',
        content: '',
        completedTime: ''
      };
      // 重置表单校验状态
      if (this.$refs.scheduleFormRef) {
        this.$refs.scheduleFormRef.resetFields();
      }
    },
    addProject(){
      this.$router.push({path: '/projectEngineering/project/ProjectDetails'});
    },
    handleSizeChange(val) {
      this.waitTaskQuery.pageSize = val;
    },
    handleCurrentChange(val) {
      this.waitTaskQuery.currentPage = val;
      this.getWaitTaskList();
    },
    auditHistoryHandleCurrentChange(val) {
      this.auditHistoryTotal.currentPage = val;
      this.getAuditHistoryPage();
    },
    getAuditHistoryPage(){
      if (this.auditHistoryRefreshing)return;
      this.auditHistoryLoading = true;
      const form ={
        pageSize:this.auditHistoryQuery.pageSize,
        currentPage:this.auditHistoryQuery.currentPage,
        projectId:this.activeProject
      }
      this.auditHistoryRefreshing = true
      auditHistoryPage(form).then(res =>{
        this.auditHistoryLoading = false;
        this.auditHistoryRefreshing = false;
        if (res.code === 200){
          this.logs = res.data;
          this.auditHistoryTotal = res.total;
        }
      })
    },
    getWaitTaskList(){
      if (this.waitTaskRefreshing) return;
      this.waitTaskRefreshing = true;
      const form ={
        pageSize:this.waitTaskQuery.pageSize,
        currentPage:this.waitTaskQuery.currentPage,
        id:this.activeProject
      }
      this.loading = true;
      getWaitTaskList(form).then(res=>{
        this.loading = false;
        this.waitTaskRefreshing = false;
        if (res.code === 200){
          this.tasks = res.data.data;
          this.waitTaskTotal = res.data.total;
        }
      })
    },
    getProjectList(){
      getProjectList().then(res =>{
        if (res.code === 200){
          this.projects = res.data;
        }
      })
    },
    initData() {
      this.getProjectList();
      this.getWaitTaskList();
      this.getCountAchievements();
    },
    getCountAchievements(){
      getCountAchievements().then(res =>{
        // 个人成就
        if (res.code === 200){
          this.achievements = res.data;
        }
      })
    },
    getCurrentTimePeriod() {
      // 获取当前时间的小时和分钟
      const now = new Date();
      const hours = now.getHours();
      // 按区间判断
      if (hours >= 0 && hours < 6) {
        // 0:00 - 5:59 为凌晨
        return "凌晨好";
      } else if (hours >= 6 && hours < 12) {
        // 6:00 - 11:59 为早上
        return "早上好";
      } else if (hours >= 12 && hours < 14) {
        // 12:00 - 13:59 为中午
        return "中午好";
      } else if (hours >= 14 && hours < 18) {
        // 14:00 - 17:59 为下午
        return "下午好";
      } else {
        // 18:00 - 23:59 为晚上
        return "晚上好";
      }
    },
    // 截断过长的项目名称
    truncateProjectName(name) {
      const maxLength = 10; // 最大显示长度
@@ -305,6 +670,8 @@
    },
    handleProjectSelect(index) {
      this.activeProject = index;
      console.log(this.activeProject)
      this.getWaitTaskList();
      // 这里可以添加项目筛选逻辑
    },
    getPriorityType(priority) {
@@ -315,19 +682,55 @@
        default: return 'info';
      }
    },
    handleTaskEdit(task) {
      console.log('编辑任务:', task);
      this.$message.info(`开始处理任务: ${task.name}`);
    handleTaskEdit(row) {
      console.log(row)
      if (row.taskType === '容缺') {
        this.$router.push({
          path: '/flowable/task/myProcess/send/index',
          query: {
            deployId: row.checkPointInfo.deployId,
            procDefId: row.checkPointInfo.processDefinitionId,
            procInsId: row.checkPointInfo.processInstanceId,
            processName: row.taskName,
            flowName: row.checkPointInfo.processName,
            projectName: row.checkPointInfo.projectName,
            taskId: row.id,
            showAuditing: false,
            projectId: row.checkPointInfo.id,
            isWait: true,
            goBackParams: this.queryParams
          }
        })
      } else {
        // 查询该任务是否配置了需要审批
        let params = {
          processDefId: row.checkPointInfo.processDefinitionId,
          taskId: row.id
        }
        getTaskIsAuditing(params).then(res => {
          console.log("row",row)
          this.$router.push({
            path: '/flowable/task/myProcess/send/index',
            query: {
              deployId: row.checkPointInfo.deployId,
              procDefId: row.checkPointInfo.processDefinitionId,
              procInsId: row.checkPointInfo.processInstanceId,
              processName: row.taskName,
              flowName: row.checkPointInfo.processName,
              projectName: row.checkPointInfo.projectName,
              taskId: row.id,
              showAuditing: res.data,
              projectId: row.checkPointInfo.id,
              isWait: false,
              goBackParams: this.queryParams
            }
          })
        })
      }
    },
    getScheduleCount(date) {
      const dateStr = this.formatCalendarDate(date);
      return this.schedules.filter(s => s.date === dateStr).length;
    },
    handleAddSchedule() {
      this.$message.info('新增日程');
    },
    handleEditSchedule(schedule) {
      this.$message.info(`编辑日程: ${schedule.title}`);
    },
    handleDeleteSchedule(schedule) {
      this.$confirm('确定删除该日程吗?', '提示', {
@@ -335,7 +738,12 @@
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$message.success('删除成功');
        del(schedule.id).then(res =>{
          if (res.code === 200){
            this.$message.success('删除成功!');
          }
          this.getScheduleList()
        })
      }).catch(() => {
        this.$message.info('已取消删除');
      });
@@ -345,6 +753,12 @@
</script>
<style scoped>
.pagination-container {
  margin-top: 20px;
  padding-right: 5px;
  text-align: center;
  width: 100%;
}
.dashboard-container {
  font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;
  height: 100vh;
@@ -453,6 +867,7 @@
}
.center-content {
  flex: 1;
  padding: 15px;
  overflow-y: auto;
@@ -476,13 +891,14 @@
.task-section {
  margin-bottom: 20px;
  height: 350px;
  height: 450px;
}
.log-list {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 10px;
  min-height: 100px;
}
.log-item {
@@ -569,7 +985,7 @@
}
.schedule-count {
  font-size: 12px;
  font-size: 10px;
  color: #1e88e5;
  margin-top: 2px;
}
@@ -582,7 +998,7 @@
}
.calendar-section >>> .el-calendar-table .el-calendar-day {
  height: 40px !important; /* 设置每日单元格高度 */
  height: 45px !important; /* 设置每日单元格高度 */
  padding: 0 !important;
}
.calendar-section >>> .el-calendar__header {