zouyu
2026-01-16 30dc46174a37613366081bd1abab8eb71c171f7f
src/views/reportAnalysis/reportManagement/index.vue
@@ -16,22 +16,13 @@
                  @change="handleFilterChange"
               />
            </el-form-item>
            <el-form-item label="报表类型">
               <el-select v-model="filterForm.reportType" placeholder="请选择报表类型" @change="handleFilterChange" style="width: 300px">
                  <el-option label="样品进度报表" value="sample" />
                  <el-option label="设备使用报表" value="equipment" />
                  <el-option label="检测项目报表" value="inspection" />
                  <el-option label="领用记录报表" value="usage" />
               </el-select>
            </el-form-item>
            <el-form-item>
               <el-button type="primary" @click="handleFilterChange">查询</el-button>
               <el-button @click="resetFilter">重置</el-button>
               <el-button type="success" @click="exportReport">导出报表</el-button>
            </el-form-item>
         </el-form>
      </el-card>
      <!-- 统计卡片 -->
      <div class="statistics-cards">
         <el-row :gutter="20">
@@ -43,7 +34,7 @@
                     </div>
                     <div class="stat-info">
                        <div class="stat-number">{{ statistics.totalSamples }}</div>
                        <div class="stat-label">总样品数</div>
                        <div class="stat-label">总订单数</div>
                     </div>
                  </div>
               </el-card>
@@ -56,7 +47,7 @@
                     </div>
                     <div class="stat-info">
                        <div class="stat-number">{{ statistics.activeEquipment }}</div>
                        <div class="stat-label">在用设备</div>
                        <div class="stat-label">待生产数量</div>
                     </div>
                  </div>
               </el-card>
@@ -69,7 +60,7 @@
                     </div>
                     <div class="stat-info">
                        <div class="stat-number">{{ statistics.completedInspections }}</div>
                        <div class="stat-label">已完成检测</div>
                        <div class="stat-label">已生产数量</div>
                     </div>
                  </div>
               </el-card>
@@ -82,14 +73,14 @@
                     </div>
                     <div class="stat-info">
                        <div class="stat-number">{{ statistics.totalUsage }}</div>
                        <div class="stat-label">总领用次数</div>
                        <div class="stat-label">总核算工时</div>
                     </div>
                  </div>
               </el-card>
            </el-col>
         </el-row>
      </div>
      <!-- 图表区域 -->
      <div class="charts-container">
         <el-row :gutter="20">
@@ -98,69 +89,37 @@
               <el-card class="chart-card" shadow="hover">
                  <template #header>
                     <div class="card-header">
                        <span>样品进度统计</span>
                        <el-button link @click="refreshSampleChart">刷新</el-button>
                        <span>生产报工统计</span>
                     </div>
                  </template>
                  <div ref="sampleChartRef" class="chart-container"></div>
               </el-card>
            </el-col>
            <!-- 设备使用图表 -->
            <el-col :span="12">
               <el-card class="chart-card" shadow="hover">
                  <template #header>
                     <div class="card-header">
                        <span>设备使用率统计</span>
                        <el-button link @click="refreshEquipmentChart">刷新</el-button>
                        <span>生产核算统计</span>
                     </div>
                  </template>
                  <div ref="equipmentChartRef" class="chart-container"></div>
               </el-card>
            </el-col>
         </el-row>
         <el-row :gutter="20" style="margin-top: 20px;">
            <!-- 检测项目统计 -->
            <el-col :span="12">
               <el-card class="chart-card" shadow="hover">
                  <template #header>
                     <div class="card-header">
                        <span>检测项目分布</span>
                        <el-button link @click="refreshInspectionChart">刷新</el-button>
                     </div>
                  </template>
                  <div ref="inspectionChartRef" class="chart-container"></div>
               </el-card>
            </el-col>
            <!-- 领用记录趋势 -->
            <el-col :span="12">
               <el-card class="chart-card" shadow="hover">
                  <template #header>
                     <div class="card-header">
                        <span>领用记录趋势</span>
                        <el-button link @click="refreshUsageChart">刷新</el-button>
                     </div>
                  </template>
                  <div ref="usageChartRef" class="chart-container"></div>
               </el-card>
            </el-col>
         </el-row>
      </div>
      <!-- 详细数据表格 -->
      <el-card class="table-card" shadow="hover">
         <template #header>
            <div class="card-header">
               <span>详细数据</span>
               <span>生产报工详情</span>
               <div>
                  <el-button type="primary" size="small" @click="refreshTable">刷新</el-button>
                  <el-button type="success" size="small" @click="exportTable">导出</el-button>
               </div>
            </div>
         </template>
         <el-table
            :data="tableData"
            style="width: 100%"
@@ -169,40 +128,28 @@
            border
         >
            <el-table-column prop="id" label="编号" width="80" />
            <el-table-column prop="name" label="名称" />
            <el-table-column prop="orderNo" label="生产订单号" />
            <el-table-column prop="productCategory" label="产品大类" />
            <el-table-column prop="specificationModel" label="规格型号" />
            <el-table-column prop="unit" label="单位" />
            <el-table-column prop="schedulingUserName" label="排产人" />
            <el-table-column prop="schedulingDate" label="排产日期" />
            <el-table-column prop="process" label="工序" />
            <el-table-column prop="schedulingNum" label="排产数量" />
            <el-table-column prop="finishedNum" label="生产数量" />
        <el-table-column prop="pendingFinishNum" label="待生产数量" >
          <template #default="scope">
            <span>{{ scope.row.schedulingNum - scope.row.finishedNum }}</span>
          </template>
        </el-table-column>
            <el-table-column prop="status" label="状态">
               <template #default="scope">
                  <el-tag :type="getStatusType(scope.row.status)">
                     {{ scope.row.status }}
                  <el-tag :type="getStatusType(scope.row.status).type">
                     {{ getStatusType(scope.row.status).label }}
                  </el-tag>
               </template>
            </el-table-column>
            <el-table-column prop="progress" label="进度">
               <template #default="scope">
                  <el-progress :percentage="scope.row.progress" :status="getProgressStatus(scope.row.progress)" />
               </template>
            </el-table-column>
            <el-table-column prop="createTime" label="创建时间" width="180" />
            <el-table-column prop="updateTime" label="更新时间" width="180" />
            <el-table-column label="操作" width="150" fixed="right">
               <template #default="scope">
                  <el-button link size="small" @click="viewDetail(scope.row)">查看</el-button>
                  <el-button link size="small" @click="editItem(scope.row)">编辑</el-button>
               </template>
            </el-table-column>
         </el-table>
         <div class="pagination-container">
            <el-pagination
               v-model:current-page="pagination.currentPage"
               v-model:page-size="pagination.pageSize"
               :page-sizes="[10, 20, 50, 100]"
               :total="pagination.total"
               layout="total, sizes, prev, pager, next, jumper"
               @size-change="handleSizeChange"
               @current-change="handleCurrentChange"
            />
         </div>
      </el-card>
   </div>
</template>
@@ -212,6 +159,7 @@
import { ElMessage, ElMessageBox } from 'element-plus'
import * as echarts from 'echarts'
import { Box, Tools, Document, ShoppingCart } from '@element-plus/icons-vue'
import {reportAnalysis} from '@/api/productionManagement/productionOrder'
// 响应式数据
const filterForm = reactive({
@@ -220,25 +168,18 @@
})
const statistics = reactive({
   totalSamples: 1250,
   activeEquipment: 45,
   completedInspections: 890,
   totalUsage: 2340
  totalSamples: 0,
  activeEquipment: 0,
  completedInspections: 0,
  totalUsage: 0
})
const tableData = ref([])
const tableLoading = ref(false)
const pagination = reactive({
   currentPage: 1,
   pageSize: 20,
   total: 0
})
// 图表引用
const sampleChartRef = ref(null)
const equipmentChartRef = ref(null)
const inspectionChartRef = ref(null)
const usageChartRef = ref(null)
// 图表实例
let sampleChart = null
@@ -248,60 +189,34 @@
// 初始化数据
const initData = () => {
   // 模拟表格数据
   tableData.value = [
      {
         id: 'SP001',
         name: '样品A-001',
         type: '金属材料',
         status: '检测中',
         progress: 75,
         createTime: '2025-01-15 09:30:00',
         updateTime: '2025-01-20 14:20:00'
      },
      {
         id: 'SP002',
         name: '样品B-002',
         type: '塑料制品',
         status: '已完成',
         progress: 100,
         createTime: '2025-01-10 10:15:00',
         updateTime: '2025-01-18 16:45:00'
      },
      {
         id: 'SP003',
         name: '样品C-003',
         type: '电子元件',
         status: '待检测',
         progress: 0,
         createTime: '2025-01-22 08:45:00',
         updateTime: '2025-01-22 08:45:00'
      },
      {
         id: 'EQ001',
         name: '检测设备A',
         type: '光谱仪',
         status: '使用中',
         progress: 60,
         createTime: '2025-01-05 14:20:00',
         updateTime: '2025-01-20 11:30:00'
      },
      {
         id: 'EQ002',
         name: '检测设备B',
         type: '显微镜',
         status: '空闲',
         progress: 0,
         createTime: '2025-01-08 16:10:00',
         updateTime: '2025-01-19 09:15:00'
      }
   ]
   pagination.total = tableData.value.length
  let startDate=null,endDate=null;
  if(filterForm.dateRange && filterForm.dateRange.length===2){
    startDate = filterForm.dateRange[0];
    endDate = filterForm.dateRange[1];
  }
  reportAnalysis({startDate:startDate,endDate:endDate}).then(res=>{
    statistics.totalSamples = res.data.totalData.totalOrderNum
    statistics.activeEquipment = res.data.totalData.tobeProduced
    statistics.completedInspections = res.data.totalData.finishProduced
    statistics.totalUsage = res.data.totalData.totalWorkhours
    // 初始化图表
    let chartData = res.data.productData?res.data.productData:{
      finishProduced:0,
      inProduced:0,
      tobeProduced:0
    };
    initSampleChart([
      { value: chartData.finishProduced, name: '已完成' },
      { value: chartData.inProduced, name: '生产中' },
      { value: chartData.tobeProduced, name: '待报工' },
    ])
    initEquipmentChart(res.data.workHours)
    tableData.value = res.data.productDetails
  })
}
// 初始化样品进度图表
const initSampleChart = () => {
const initSampleChart = (charData) => {
   if (sampleChartRef.value) {
      sampleChart = echarts.init(sampleChartRef.value)
      const option = {
@@ -336,12 +251,7 @@
               labelLine: {
                  show: false
               },
               data: [
                  { value: 450, name: '已完成' },
                  { value: 320, name: '检测中' },
                  { value: 280, name: '待检测' },
                  { value: 200, name: '已暂停' }
               ]
               data: charData
            }
         ]
      }
@@ -350,8 +260,16 @@
}
// 初始化设备使用图表
const initEquipmentChart = () => {
const initEquipmentChart = (chartData) => {
   if (equipmentChartRef.value) {
    let processData = [];
    let workHoursData = [];
    if(chartData){
      chartData.forEach(item=>{
        processData.push(item.process);
        workHoursData.push(item.workHours);
      })
    }
      equipmentChart = echarts.init(equipmentChartRef.value)
      const option = {
         title: {
@@ -365,22 +283,23 @@
         },
         xAxis: {
            type: 'category',
            data: ['光谱仪', '显微镜', '硬度计', '拉力机', '冲击机', '金相仪']
            data: processData,
        name: '工序'
         },
         yAxis: {
            type: 'value',
            name: '使用率(%)'
            name: '核算工时'
         },
         series: [
            {
               name: '使用率',
               name: '核算工时',
               type: 'bar',
               data: [85, 60, 75, 90, 45, 70],
               data: workHoursData,
               itemStyle: {
                  color: function(params) {
                     const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#9C27B0']
                     return colors[params.dataIndex]
                  }
                  // color: function(params) {
                  //    const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#9C27B0']
                  //    return colors[params.dataIndex]
                  // }
               }
            }
         ]
@@ -389,92 +308,10 @@
   }
}
// 初始化检测项目图表
const initInspectionChart = () => {
   if (inspectionChartRef.value) {
      inspectionChart = echarts.init(inspectionChartRef.value)
      const option = {
         title: {
            show: false
         },
         tooltip: {
            trigger: 'item'
         },
         legend: {
            orient: 'vertical',
            left: 'left'
         },
         series: [
            {
               name: '检测项目',
               type: 'pie',
               radius: '50%',
               data: [
                  { value: 335, name: '物理性能' },
                  { value: 310, name: '化学分析' },
                  { value: 234, name: '尺寸测量' },
                  { value: 135, name: '外观检查' },
                  { value: 148, name: '其他检测' }
               ],
               emphasis: {
                  itemStyle: {
                     shadowBlur: 10,
                     shadowOffsetX: 0,
                     shadowColor: 'rgba(0, 0, 0, 0.5)'
                  }
               }
            }
         ]
      }
      inspectionChart.setOption(option)
   }
}
// 初始化领用记录图表
const initUsageChart = () => {
   if (usageChartRef.value) {
      usageChart = echarts.init(usageChartRef.value)
      const option = {
         title: {
            show: false
         },
         tooltip: {
            trigger: 'axis'
         },
         legend: {
            data: ['领用次数', '归还次数']
         },
         xAxis: {
            type: 'category',
            boundaryGap: false,
            data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
         },
         yAxis: {
            type: 'value'
         },
         series: [
            {
               name: '领用次数',
               type: 'line',
               stack: 'Total',
               data: [120, 132, 101, 134, 90, 230, 210, 182, 191, 234, 290, 330]
            },
            {
               name: '归还次数',
               type: 'line',
               stack: 'Total',
               data: [110, 125, 95, 128, 85, 220, 200, 175, 185, 225, 280, 320]
            }
         ]
      }
      usageChart.setOption(option)
   }
}
// 事件处理函数
const handleFilterChange = () => {
   ElMessage.success('筛选条件已更新')
   // 这里可以根据筛选条件重新加载数据
   initData()
}
const resetFilter = () => {
@@ -483,62 +320,13 @@
   ElMessage.info('筛选条件已重置')
}
const exportReport = () => {
   ElMessage.success('报表导出功能开发中...')
}
const refreshSampleChart = () => {
   initSampleChart()
   ElMessage.success('样品进度图表已刷新')
}
const refreshEquipmentChart = () => {
   initEquipmentChart()
   ElMessage.success('设备使用图表已刷新')
}
const refreshInspectionChart = () => {
   initInspectionChart()
   ElMessage.success('检测项目图表已刷新')
}
const refreshUsageChart = () => {
   initUsageChart()
   ElMessage.success('领用记录图表已刷新')
}
const refreshTable = () => {
   tableLoading.value = true
   setTimeout(() => {
      tableLoading.value = false
      ElMessage.success('表格数据已刷新')
   }, 1000)
}
const exportTable = () => {
   ElMessage.success('表格导出功能开发中...')
}
const handleSizeChange = (val) => {
   pagination.pageSize = val
   // 重新加载数据
}
const handleCurrentChange = (val) => {
   pagination.currentPage = val
   // 重新加载数据
}
const getStatusType = (status) => {
   const statusMap = {
      '已完成': 'success',
      '检测中': 'warning',
      '待检测': 'info',
      '已暂停': 'danger',
      '使用中': 'primary',
      '空闲': 'info'
      '3': {type:'success',label:'已完成'},
      '2': {type:'warning',label:'生产中'},
      '1': {type:'info',label:'待生产'}
   }
   return statusMap[status] || 'info'
   return statusMap[status] || {type:'info',label:'未知状态'}
}
const getProgressStatus = (progress) => {
@@ -548,24 +336,9 @@
   return 'exception'
}
const viewDetail = (row) => {
   ElMessage.info(`查看详情: ${row.name}`)
}
const editItem = (row) => {
   ElMessage.info(`编辑项目: ${row.name}`)
}
// 生命周期
onMounted(() => {
   initData()
   nextTick(() => {
      initSampleChart()
      initEquipmentChart()
      initInspectionChart()
      initUsageChart()
   })
   // 监听窗口大小变化,重新调整图表大小
   window.addEventListener('resize', () => {
      sampleChart?.resize()
@@ -581,11 +354,6 @@
   padding: 20px;
   background-color: #f5f5f5;
   min-height: 100vh;
}
.page-header {
   margin-bottom: 20px;
   text-align: center;
}
.page-header h2 {
@@ -684,11 +452,6 @@
.table-card {
   margin-bottom: 20px;
}
.pagination-container {
   margin-top: 20px;
   text-align: right;
}
:deep(.el-card__header) {