Преглед изворни кода

服务工单(安装工单)-优化表格样式,完成查询接口对接

aiwenzhu пре 1 месец
родитељ
комит
d39cf638ff

+ 108 - 0
src/api/productManagement/installation.js

@@ -0,0 +1,108 @@
+import request from '@/utils/request'
+
+// 获取安装工单列表
+export function getInstallationList(query) {
+  return request({
+    url: '/productManagement/installation/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 获取安装工单详细信息
+export function getInstallationDetail(id) {
+  return request({
+    url: `/productManagement/installation/${id}`,
+    method: 'get'
+  })
+}
+
+// 新增安装工单
+export function addInstallation(data) {
+  return request({
+    url: '/productManagement/installation',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改安装工单
+export function updateInstallation(data) {
+  return request({
+    url: '/productManagement/installation',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除安装工单
+export function deleteInstallation(id) {
+  return request({
+    url: `/productManagement/installation/${id}`,
+    method: 'delete'
+  })
+}
+
+// 导出安装工单
+export function exportInstallation(query) {
+  return request({
+    url: '/productManagement/installation/export',
+    method: 'get',
+    params: query,
+    responseType: 'blob'
+  })
+}
+
+// 派单
+export function dispatchInstallation(data) {
+  return request({
+    url: '/productManagement/installation/dispatch',
+    method: 'post',
+    data: data
+  })
+}
+
+// 接单驳回
+export function rejectInstallation(data) {
+  return request({
+    url: '/productManagement/installation/reject',
+    method: 'post',
+    data: data
+  })
+}
+
+// 每日填写
+export function dailyWrite(data) {
+  return request({
+    url: '/productManagement/installation/daily',
+    method: 'post',
+    data: data
+  })
+}
+
+// 完成
+export function completeInstallation(data) {
+  return request({
+    url: '/productManagement/installation/complete',
+    method: 'post',
+    data: data
+  })
+}
+
+// 接单
+export function acceptInstallation(data) {
+  return request({
+    url: '/productManagement/installation/accept',
+    method: 'post',
+    data: data
+  })
+}
+
+// 验收
+export function checkInstallation(data) {
+  return request({
+    url: '/productManagement/installation/check',
+    method: 'post',
+    data: data
+  })
+} 

+ 19 - 0
src/icons/svg/工单管理.svg

@@ -0,0 +1,19 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg t="1600764537714" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13015" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
+  <!-- 基础框架 -->
+  <path d="M832 64H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32z m-40 824H232V136h560v752z" fill="#ffffff"/>
+  
+  <!-- 工单顶部标记 -->
+  <path d="M724 64v40H300V64h-48v40h-32c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h576c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8h-32V64h-40z" fill="#ffffff"/>
+  
+  <!-- 工单内容线条 -->
+  <path d="M312 412h400c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H312c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z" fill="#ffffff"/>
+  <path d="M312 544h400c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H312c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z" fill="#ffffff"/>
+  <path d="M312 676h400c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H312c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z" fill="#ffffff"/>
+  
+  <!-- 底部签名栏 -->
+  <path d="M608 788H416c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h192c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8z" fill="#ffffff"/>
+  
+  <!-- 右上角订单标记 -->
+  <path d="M780 220l-36-36c-3.1-3.1-8.2-3.1-11.3 0L684 232.7l47.3 47.3 48.7-48.7c3.1-3.1 3.1-8.2 0-11.3z" fill="#ffffff"/>
+</svg> 

+ 12 - 0
src/icons/svg/服务工单.svg

@@ -0,0 +1,12 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg t="1600764537714" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13015" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
+  <!-- 工单基础框架 -->
+  <path d="M832 112H724V72c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v40H372V72c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v40H192c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32z m-40 728H232V272h560v568z" fill="#ffffff"/>
+  
+  <!-- 扳手图标 -->
+  <path d="M650 380c-8.8-89.4-84.2-159.9-175.9-159.9-97.2 0-176 78.8-176 176 0 91.7 70.5 167.1 159.9 175.9-0.3 2.7-0.4 5.3-0.4 8.1 0 44.2 35.8 80 80 80 44.2 0 80-35.8 80-80 0-2.7-0.1-5.4-0.4-8.1C706.5 563.1 777 487.7 777 396c0-97.2-78.8-176-176-176-91.7 0-167.1 70.5-175.9 159.9-2.7-0.3-5.3-0.4-8.1-0.4-44.2 0-80 35.8-80 80s35.8 80 80 80c2.7 0 5.4-0.1 8.1-0.4z" fill="#ffffff"/>
+  
+  <!-- 底部文本线条 -->
+  <path d="M320 544h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z" fill="#ffffff"/>
+  <path d="M320 688h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z" fill="#ffffff"/>
+</svg> 

+ 0 - 0
src/icons/svg/安装总览.svg → src/icons/svg/服务总览.svg


+ 0 - 0
src/icons/svg/生产总览.svg → src/icons/svg/生产看板.svg


+ 268 - 0
src/views/productManagement/installationOrder/components/AddDialog.vue

@@ -0,0 +1,268 @@
+<!-- 新增服务计划弹窗 -->
+<template>
+  <el-dialog
+    title="新增服务计划"
+    :visible.sync="visible"
+    width="1000px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    @close="handleDialogClose"
+  >
+    <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+      <el-row :gutter="10">
+        <el-col :span="8">
+          <el-form-item label="服务单号" prop="serviceNo">
+            <el-input v-model="form.serviceNo" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="下单人" prop="orderer">
+            <el-select v-model="form.orderer" placeholder="请选择下单人" style="width: 100%">
+              <el-option label="默认当前登录账号" value="default" disabled />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="下单时间" prop="orderTime">
+            <el-date-picker
+              v-model="form.orderTime"
+              type="datetime"
+              placeholder="选择日期时间"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="10">
+        <el-col :span="8">
+          <el-form-item label="服务项目" prop="serviceProject">
+            <el-select v-model="form.serviceProject" placeholder="请选择服务项目" style="width: 100%">
+              <el-option label="请选择服务项目" value="" disabled />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="服务人员" prop="serviceStaff">
+            <el-select v-model="form.serviceStaff" placeholder="请选择服务人员" style="width: 100%">
+              <el-option label="张三" value="张三" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="预计完成时间" prop="estimatedCompleteTime">
+            <el-date-picker
+              v-model="form.estimatedCompleteTime"
+              type="date"
+              placeholder="选择日期"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="10">
+        <el-col :span="8">
+          <el-form-item label="发货单号" prop="deliveryNo">
+            <el-input v-model="form.deliveryNo" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="合同" prop="contract">
+            <el-input v-model="form.contract" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="客户" prop="customer">
+            <el-input v-model="form.customer" disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-form-item label="备注" prop="remark">
+        <el-input
+          type="textarea"
+          v-model="form.remark"
+          :rows="2"
+          placeholder="请输入备注信息"
+        />
+      </el-form-item>
+
+      <el-form-item label="货品" prop="products">
+        <el-table :data="form.products" border style="width: 100%">
+          <el-table-column type="index" label="序号" width="50" align="center" />
+          <el-table-column prop="code" label="货品编号" align="center" />
+          <el-table-column prop="name" label="货品名称" align="center" />
+          <el-table-column prop="spec" label="货品规格" align="center" />
+          <el-table-column prop="image" label="货品图片" align="center" />
+          <el-table-column prop="unit" label="计量单位" align="center" />
+          <el-table-column prop="stock" label="现有库存" align="center" />
+          <el-table-column prop="orderQuantity" label="订单数量" align="center" />
+          <el-table-column prop="shippedQuantity" label="已发货数量" align="center" />
+          <el-table-column prop="unshippedQuantity" label="未发货数量" align="center" />
+          <el-table-column prop="remark" label="备注" align="center" />
+          <el-table-column label="操作" align="center" width="100">
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                type="text"
+                style="color: #F56C6C"
+                @click="handleRemoveProduct(scope.$index)"
+              >删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form-item>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="handleSubmit">保存并关闭</el-button>
+      <el-button @click="handleCancel">取 消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  name: 'AddDialog',
+  props: {
+    visible: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      // 表单数据
+      form: {
+        serviceNo: 'FW' + new Date().getTime(),
+        orderer: 'default',
+        orderTime: new Date(),
+        serviceProject: '',
+        serviceStaff: '',
+        estimatedCompleteTime: '',
+        deliveryNo: 'FH202410230001',
+        contract: 'HT202410230001',
+        customer: '根据发货单自动带出',
+        remark: '',
+        products: []
+      },
+      
+      // 表单校验规则
+      rules: {
+        serviceProject: [
+          { required: true, message: '请选择服务项目', trigger: 'change' }
+        ],
+        serviceStaff: [
+          { required: true, message: '请选择服务人员', trigger: 'change' }
+        ],
+        estimatedCompleteTime: [
+          { required: true, message: '请选择预计完成时间', trigger: 'change' }
+        ]
+      }
+    }
+  },
+  methods: {
+    // 关闭弹窗
+    handleDialogClose() {
+      this.$emit('update:visible', false)
+      this.$refs.form && this.$refs.form.resetFields()
+    },
+    // 取消
+    handleCancel() {
+      this.handleDialogClose()
+    },
+    // 移除货品
+    handleRemoveProduct(index) {
+      this.form.products.splice(index, 1)
+    },
+    // 提交表单
+    handleSubmit() {
+      this.$refs.form.validate(async (valid) => {
+        if (valid) {
+          try {
+            // TODO: 调用新增API
+            this.$message.success('保存成功')
+            this.handleDialogClose()
+            this.$emit('success')
+          } catch (error) {
+            console.error('保存失败:', error)
+            this.$message.error('保存失败')
+          }
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+:deep(.el-dialog) {
+  border-radius: 8px;
+  
+  .el-dialog__header {
+    padding: 20px;
+    border-bottom: 1px solid #ebeef5;
+    margin-right: 0;
+    
+    .el-dialog__title {
+      font-size: 16px;
+      font-weight: 500;
+      color: #333;
+    }
+  }
+
+  .el-dialog__body {
+    padding: 20px;
+    
+    .el-form {
+      .el-form-item {
+        margin-bottom: 18px;
+        
+        .el-form-item__label {
+          font-weight: normal;
+          color: #606266;
+        }
+      }
+      
+      .el-input, .el-select, .el-date-picker {
+        width: 180px !important;
+      }
+      
+      .el-textarea {
+        width: 100%;
+      }
+      
+      .el-table {
+        margin-top: 8px;
+        
+        th {
+          background-color: #f5f7fa;
+          color: #333;
+          font-weight: 500;
+          padding: 8px 0;
+        }
+        
+        td {
+          padding: 8px 0;
+        }
+      }
+    }
+  }
+
+  .el-dialog__footer {
+    padding: 15px 20px;
+    border-top: 1px solid #ebeef5;
+    text-align: right;
+    
+    .el-button {
+      padding: 9px 20px;
+      font-size: 13px;
+      border-radius: 4px;
+      
+      & + .el-button {
+        margin-left: 10px;
+      }
+    }
+  }
+}
+</style> 

+ 943 - 177
src/views/productManagement/installationOrder/index.vue

@@ -1,197 +1,469 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<!-- <?xml version="1.0" encoding="UTF-8"?> -->
 <template>
-  <div class="installation-order">
-    <!-- 筛选条件 -->
-    <el-card class="filter-container">
-      <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="100px">
-        <el-form-item label="安装人员">
-          <el-input v-model="queryParams.installer" placeholder="请输入安装人员" clearable size="small"/>
-        </el-form-item>
-        <el-form-item label="客户名称">
-          <el-input v-model="queryParams.customerName" placeholder="请输入客户名称" clearable size="small"/>
-        </el-form-item>
-        <el-form-item label="处理状态">
-          <el-select v-model="queryParams.status" placeholder="请选择处理状态" clearable size="small">
-            <el-option
-              v-for="dict in statusOptions"
-              :key="dict.value"
-              :label="dict.label"
-              :value="dict.value"
-            />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="项目名称">
-          <el-select v-model="queryParams.projectName" placeholder="请选择项目名称" clearable size="small">
-            <el-option
-              v-for="dict in projectOptions"
-              :key="dict.value"
-              :label="dict.label"
-              :value="dict.value"
-            />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="下单时间">
-          <el-date-picker
-            v-model="queryParams.orderTimeRange"
-            type="daterange"
-            range-separator="至"
-            start-placeholder="开始日期"
-            end-placeholder="结束日期"
-            size="small"
+  <div class="app-container">
+    <!-- 搜索栏 -->
+    <el-form :model="queryParams" ref="queryForm" :inline="true" class="demo-form-inline">
+      <el-form-item>
+        <el-select
+          v-model="queryParams.installer"
+          placeholder="服务人员"
+          clearable
+          filterable
+          size="small"
+          style="width: 120px"
+        >
+          <el-option
+            v-for="item in installerOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
           />
-        </el-form-item>
-        <el-form-item label="完成时间">
-          <el-date-picker
-            v-model="queryParams.completeTimeRange"
-            type="daterange"
-            range-separator="至"
-            start-placeholder="开始日期"
-            end-placeholder="结束日期"
-            size="small"
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-input
+          v-model="queryParams.customerName"
+          placeholder="客户名称"
+          clearable
+          size="small"
+          style="width: 120px"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-select
+          v-model="queryParams.status"
+          placeholder="处理状态"
+          clearable
+          size="small"
+          style="width: 120px"
+        >
+          <el-option
+            v-for="dict in statusOptions"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
           />
-        </el-form-item>
-        <el-form-item>
-          <el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button>
-          <el-button type="success" icon="el-icon-download" size="small" @click="handleExport">导出</el-button>
-        </el-form-item>
-      </el-form>
-    </el-card>
-
-    <!-- 操作按钮 -->
-    <el-card class="operation-container">
-      <el-button type="primary" icon="el-icon-plus" size="small" @click="handleAdd">新增计划</el-button>
-      <el-radio-group v-model="queryParams.viewType" size="small" @change="handleViewTypeChange">
-        <el-radio-button label="all">全部</el-radio-button>
-        <el-radio-button label="pending">待处理</el-radio-button>
-        <el-radio-button label="processed">已处理</el-radio-button>
-      </el-radio-group>
-    </el-card>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-select
+          v-model="queryParams.projectId"
+          placeholder="项目名称"
+          clearable
+          size="small"
+          style="width: 120px"
+        >
+          <el-option
+            v-for="dict in projectOptions"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-date-picker
+          v-model="queryParams.orderTimeRange"
+          class="inputDatetime"
+          type="daterange"
+          size="small"
+          range-separator="至"
+          start-placeholder="下单开始日期"
+          end-placeholder="下单结束日期"
+          style="width: 250px"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-date-picker
+          v-model="queryParams.completeTimeRange"
+          class="inputDatetime"
+          type="daterange"
+          size="small"
+          range-separator="至"
+          start-placeholder="完成开始日期"
+          end-placeholder="完成结束日期"
+          style="width: 250px"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button size="small" class="successBorder" icon="el-icon-search" @click="handleQuery">搜索</el-button>
+        <el-button size="small" class="successBorder" icon="el-icon-download" @click="handleExport">导出</el-button>
+        <el-button size="small" type="primary" icon="el-icon-plus" @click="handleAdd">新增计划</el-button>
+        <el-radio-group v-model="queryParams.viewType" size="small" @change="handleViewTypeChange" style="margin-left: 8px">
+          <el-radio-button label="">全部</el-radio-button>
+          <el-radio-button label="待处理">待处理<el-badge v-if="pendingCount > 0" :value="pendingCount" class="pending-badge" /></el-radio-button>
+          <el-radio-button label="已完成">已完成</el-radio-button>
+        </el-radio-group>
+      </el-form-item>
+    </el-form>
 
     <!-- 表格 -->
-    <el-card>
-      <el-table v-loading="loading" :data="tableData" border>
-        <el-table-column type="index" label="序号" width="50" align="center"/>
-        <el-table-column prop="orderNo" label="安装单号" align="center"/>
-        <el-table-column prop="projectName" label="项目名称" align="center"/>
-        <el-table-column prop="customerName" label="客户名称" align="center"/>
-        <el-table-column prop="product" label="货品" align="center"/>
-        <el-table-column prop="totalQuantity" label="安装总数量" align="center"/>
-        <el-table-column prop="installedQuantity" label="已安装数量" align="center"/>
-        <el-table-column prop="uninstalledQuantity" label="未安装数量" align="center"/>
-        <el-table-column prop="progress" label="安装进度" align="center">
-          <template slot-scope="scope">
-            <el-progress :percentage="scope.row.progress"/>
-          </template>
-        </el-table-column>
-        <el-table-column prop="dispatcher" label="派单人" align="center"/>
-        <el-table-column prop="serviceStaff" label="服务人员" align="center"/>
-        <el-table-column prop="orderTime" label="下单时间" align="center"/>
-        <el-table-column prop="acceptTime" label="接单时间" align="center"/>
-        <el-table-column prop="estimatedCompleteTime" label="预估完成时间" align="center"/>
-        <el-table-column prop="remainingTime" label="距预估完成时间还剩" align="center"/>
-        <el-table-column prop="actualCompleteTime" label="实际完成时间" align="center"/>
-        <el-table-column prop="status" label="处理状态" align="center">
-          <template slot-scope="scope">
-            <el-tag :type="getStatusType(scope.row.status)">{{ scope.row.statusText }}</el-tag>
-          </template>
-        </el-table-column>
-        <el-table-column prop="remark" label="备注" align="center"/>
-        <el-table-column label="操作" width="400" align="center">
-          <template slot-scope="scope">
-            <el-button size="mini" type="text" @click="handleView(scope.row)">查看</el-button>
-            <el-button size="mini" type="text" @click="handleEdit(scope.row)">编辑</el-button>
-            <el-button size="mini" type="text" @click="handleDelete(scope.row)">删除</el-button>
-            <el-button size="mini" type="text" @click="handleDispatch(scope.row)">派单</el-button>
-            <el-button size="mini" type="text" @click="handleReject(scope.row)">接单驳回</el-button>
-            <el-button size="mini" type="text" @click="handleDailyWrite(scope.row)">每日填写</el-button>
-            <el-button size="mini" type="text" @click="handleComplete(scope.row)">完成</el-button>
-            <el-button size="mini" type="text" @click="handleAccept(scope.row)">接单</el-button>
-            <el-button size="mini" type="text" @click="handleCheck(scope.row)">验收</el-button>
+    <el-table
+      v-loading="loading"
+      element-loading-text="数据加载中..."
+      element-loading-spinner="el-icon-loading"
+      element-loading-background="rgba(255, 255, 255, 0.8)"
+      :data="tableData"
+      border
+      style="width: 100%; margin-top: 15px;"
+      :empty-text="'暂无数据'"
+    >
+      <el-table-column label="序号" width="50" align="center">
+        <template slot-scope="scope">
+          {{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="orderNo" label="服务单号" align="center" />
+      <el-table-column prop="projectName" label="项目名称" align="center" />
+      <el-table-column prop="customerName" label="客户名称" align="center" width="120" />
+      <el-table-column prop="product" label="货品" align="center" width="150" >
+        <template slot-scope="scope">
+          <div class="product-tags">
+            <template v-if="scope.row.product">
+              <el-tag
+                v-for="(item, index) in scope.row.product.split(';')"
+                :key="index"
+                size="mini"
+                :type="['success', 'warning', 'danger', 'primary'][index % 4]"
+                effect="light"
+                :class="{ 'long-text': item.length > 10 }"
+              >
+                {{ item }}
+              </el-tag>
+            </template>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column prop="totalQuantity" label="服务总数量" align="center" width="100" />
+      <el-table-column prop="installedQuantity" label="已服务数量" align="center" width="100" />
+      <el-table-column prop="uninstalledQuantity" label="未服务数量" align="center" width="100" />
+      <el-table-column prop="progress" label="服务进度" align="center" width="120">
+        <template slot-scope="scope">
+          <div class="progress-wrapper">
+            <span class="progress-text">{{ scope.row.progress }}%</span>
+            <el-progress :percentage="Number(scope.row.progress)" :stroke-width="15" />
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column prop="dispatcher" label="派单人" align="center" width="100" />
+      <el-table-column prop="serviceStaff" label="服务人员" align="center" width="120">
+        <template slot-scope="scope">
+          <div class="staff-tags">
+            <template v-if="scope.row.serviceStaff">
+              <el-tag
+                v-for="(item, index) in scope.row.serviceStaff.split(';')"
+                :key="index"
+                size="mini"
+                :type="['primary', 'success', 'warning', 'danger'][index % 4]"
+                effect="light"
+                :class="{ 'long-text': item.length > 10 }"
+              >
+                {{ item }}
+              </el-tag>
+            </template>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column prop="orderTime" label="下单时间" align="center" width="140" />
+      <el-table-column prop="acceptTime" label="接单时间" align="center" width="140" />
+      <el-table-column prop="estimatedCompleteTime" label="预估完成时间" align="center" width="140" />
+      <el-table-column prop="remainingTime" label="距预估完成时间还剩" align="center" width="160">
+        <template slot-scope="scope">
+          <template v-if="scope.row.remainingTime !== null && scope.row.remainingTime !== undefined">
+            <span 
+              :class="{
+                'normal-time': scope.row.remainingTime > 3,
+                'warning-time': scope.row.remainingTime >= 0 && scope.row.remainingTime <= 3,
+                'overdue-time': scope.row.remainingTime < 0
+              }"
+            >
+              <template v-if="scope.row.remainingTime < 0">
+                已逾期 {{ Math.abs(scope.row.remainingTime) }} 天
+              </template>
+              <template v-else>
+                {{ scope.row.remainingTime }} 天
+              </template>
+            </span>
           </template>
-        </el-table-column>
-      </el-table>
-      
-      <!-- 分页 -->
-      <pagination
-        v-show="total > 0"
-        :total="total"
-        :page.sync="queryParams.pageNum"
-        :limit.sync="queryParams.pageSize"
-        @pagination="getList"
-      />
-    </el-card>
+        </template>
+      </el-table-column>
+      <el-table-column prop="actualCompleteTime" label="实际完成时间" align="center" width="140" />
+      <el-table-column prop="status" label="处理状态" align="center" width="100">
+        <template slot-scope="scope">
+          <el-tag :type="getStatusType(scope.row.statusText)">{{ scope.row.statusText }}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="remark" label="备注" align="center" min-width="120" />
+      <el-table-column label="操作" align="center" width="220" fixed="right">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            style="color: #333"
+            @click="handleView(scope.row)"
+          >查看</el-button>
+          <el-button
+            size="mini"
+            type="primary"
+            @click="handleEdit(scope.row)"
+          >编辑</el-button>
+          <el-dropdown trigger="click" @command="(command) => handleCommand(command, scope.row)">
+            <el-button size="mini" type="success">
+              更多<i class="el-icon-arrow-down el-icon--right"></i>
+            </el-button>
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item command="delete" class="dropdown-danger">删除</el-dropdown-item>
+              <el-dropdown-item command="dispatch" class="dropdown-success">派单</el-dropdown-item>
+              <el-dropdown-item command="reject" class="dropdown-danger">驳回</el-dropdown-item>
+              <el-dropdown-item command="dailyWrite" class="dropdown-info">填写</el-dropdown-item>
+              <el-dropdown-item command="complete" class="dropdown-success">完成</el-dropdown-item>
+              <el-dropdown-item command="accept" class="dropdown-primary">接单</el-dropdown-item>
+              <el-dropdown-item command="check" class="dropdown-warning">验收</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <pagination
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      :page-sizes="[10, 20, 30, 50]"
+      @pagination="getList"
+    />
+
+    <!-- 新增服务计划弹窗 -->
+    <add-dialog
+      :visible.sync="dialogVisible"
+      @success="getList"
+    />
   </div>
 </template>
 
 <script>
+import Pagination from "@/components/Pagination";
+import { GetDataByName, GetDataByNames } from '@/api/common'
+import AddDialog from './components/AddDialog'
+
 export default {
   name: 'InstallationOrder',
+  components: {
+    Pagination,
+    AddDialog
+  },
   data() {
     return {
+      // 表格高度
+      tableHeight: window.innerHeight - 300,
       // 遮罩层
       loading: false,
       // 总条数
       total: 0,
       // 表格数据
       tableData: [],
+      // 服务人员选项
+      installerOptions: [],
       // 查询参数
       queryParams: {
         pageNum: 1,
         pageSize: 10,
-        installer: undefined,
-        customerName: undefined,
-        status: undefined,
-        projectName: undefined,
+        installer: '',
+        customerName: '',
+        status: '',
+        projectName: '',
+        projectId: '',
         orderTimeRange: [],
         completeTimeRange: [],
-        viewType: 'all'
+        viewType: ''
       },
       // 状态选项
       statusOptions: [
-        { label: '待处理', value: 'pending' },
-        { label: '处理中', value: 'processing' },
-        { label: '已完成', value: 'completed' },
-        { label: '已驳回', value: 'rejected' }
+        { label: '待处理', value: '待处理' },
+        { label: '处理中', value: '处理中' },
+        { label: '已完成', value: '已完成' },
+        { label: '已驳回', value: '已驳回' }
       ],
       // 项目选项
-      projectOptions: [
-        { label: '项目A', value: 'A' },
-        { label: '项目B', value: 'B' }
-      ]
+      projectOptions: [],
+      // 日期选择器快捷选项
+      pickerOptions: {
+        shortcuts: [{
+          text: '最近一周',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '最近一个月',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
+            picker.$emit('pick', [start, end])
+          }
+        }]
+      },
+      pendingCount: 0,
+      // 弹窗显示控制
+      dialogVisible: false
     }
   },
   created() {
     this.getList()
+    this.getSelectOptions()
+    // 添加resize事件监听
+    this.resizeHandler = this.debounce(() => {
+      this.tableHeight = window.innerHeight - 300
+    }, 100)
+    window.addEventListener('resize', this.resizeHandler)
+  },
+  beforeDestroy() {
+    // 移除resize事件监听
+    window.removeEventListener('resize', this.resizeHandler)
   },
   methods: {
+    // 添加防抖函数
+    debounce(fn, delay) {
+      let timer = null
+      return function() {
+        const context = this
+        const args = arguments
+        clearTimeout(timer)
+        timer = setTimeout(() => {
+          fn.apply(context, args)
+        }, delay)
+      }
+    },
+    // 获取列表数据
     getList() {
-      this.loading = true
-      // TODO: 调用接口获取数据
-      setTimeout(() => {
-        this.loading = false
-      }, 1000)
+      this.loading = true;
+      // 处理日期范围
+      let orderStartTime = '';
+      let orderEndTime = '';
+      let completeStartTime = '';
+      let completeEndTime = '';
+
+      if (this.queryParams.orderTimeRange && this.queryParams.orderTimeRange.length === 2) {
+        orderStartTime = this.formatDate(this.queryParams.orderTimeRange[0]);
+        orderEndTime = this.formatDate(this.queryParams.orderTimeRange[1]);
+      }
+      if (this.queryParams.completeTimeRange && this.queryParams.completeTimeRange.length === 2) {
+        completeStartTime = this.formatDate(this.queryParams.completeTimeRange[0]);
+        completeEndTime = this.formatDate(this.queryParams.completeTimeRange[1]);
+      }
+
+      // 构造查询参数
+      const send_data = {
+        name: 'getInstallationOrderList',
+        page: this.queryParams.pageNum,
+        offset: this.queryParams.pageNum,
+        pagecount: this.queryParams.pageSize,
+        returntype: 'Map',
+        parammaps: {
+          installer: this.queryParams.installer || '',
+          customerName: this.queryParams.customerName || '',
+          status: this.queryParams.status || '',
+          projectId: this.queryParams.projectId || '',
+          orderNo: this.queryParams.orderNo || '',
+          orderStartTime,
+          orderEndTime,
+          completeStartTime,
+          completeEndTime,
+        }
+      };
+
+      GetDataByName(send_data).then(response => {
+        this.tableData = response.data.list || [];
+        this.total = response.data.total || 0;
+        this.loading = false;
+      }).catch(error => {
+        console.error('获取服务工单列表失败:', error);
+        this.loading = false;
+      });
+    },
+    // 获取下拉框选项数据
+    getSelectOptions() {
+      const send_select_list = [
+        {
+          name: 'getUsersSelect',
+          offset: 0,
+          pagecount: 0,
+          parammaps: {
+            enable: '1'
+          }
+        },
+        {
+          name: 'getDictListSelect',
+          offset: 0,
+          pagecount: 0,
+          parammaps: {
+            pid: '79'
+          }
+        },
+        {
+          name: 'getInstallationOrderToDoNum',
+          offset: 0,
+          pagecount: 0,
+          parammaps: {
+          }
+        }
+      ]
+      
+      GetDataByNames(send_select_list).then(response => {
+        // 处理服务人员数据
+        const installerList = response.data.getUsersSelect.list || []
+        this.installerOptions = installerList.map(item => ({
+          value: item.id,
+          label: item.name
+        }))
+        console.log('服务人员下拉框', this.installerOptions)
+
+        // 处理项目数据
+        const projectList = response.data.getDictListSelect.list || []
+        this.projectOptions = projectList.map(item => ({
+          value: item.id,
+          label: item.name
+        }))
+        console.log('项目下拉框', this.projectOptions)
+
+         // 获取处理工单数量
+         this.pendingCount = response.data.getInstallationOrderToDoNum.list[0].num
+
+      }).catch(error => {
+        console.error('获取下拉框数据失败:', error)
+      })
     },
     handleQuery() {
       this.queryParams.pageNum = 1
       this.getList()
     },
-    handleExport() {
-      // TODO: 实现导出功能
-    },
     handleAdd() {
-      // TODO: 实现新增功能
+      this.dialogVisible = true
     },
     handleViewTypeChange(value) {
+      this.queryParams.status = value
       this.getList()
     },
     getStatusType(status) {
       const statusMap = {
-        pending: 'info',
-        processing: 'warning',
-        completed: 'success',
-        rejected: 'danger'
+        '待处理': 'warning',
+        '处理中': 'primary',
+        '已完成': 'success',
+        '已驳回': 'danger'
       }
-      return statusMap[status]
+      console.log('状态类型', status)
+      return statusMap[status] || 'info'
     },
     handleView(row) {
       // TODO: 实现查看功能
@@ -199,57 +471,551 @@ export default {
     handleEdit(row) {
       // TODO: 实现编辑功能
     },
-    handleDelete(row) {
-      // TODO: 实现删除功能
+    // 删除
+    async handleDelete(row) {
+      try {
+        await this.$confirm('是否确认删除服务工单?', '警告', {
+          type: 'warning'
+        })
+        const response = await deleteInstallation(row.id)
+        if (response.code === 200) {
+          this.$message.success('删除成功')
+          this.getList()
+        } else {
+          this.$message.error(response.msg || '删除失败')
+        }
+      } catch (error) {
+        console.error('删除失败:', error)
+        if (error !== 'cancel') {
+          this.$message.error('删除失败')
+        }
+      }
+    },
+    // 派单
+    async handleDispatch(row) {
+      try {
+        const response = await dispatchInstallation({ id: row.id })
+        if (response.code === 200) {
+          this.$message.success('派单成功')
+          this.getList()
+        } else {
+          this.$message.error(response.msg || '派单失败')
+        }
+      } catch (error) {
+        console.error('派单失败:', error)
+        this.$message.error('派单失败')
+      }
+    },
+    // 接单驳回
+    async handleReject(row) {
+      try {
+        const response = await rejectInstallation({ id: row.id })
+        if (response.code === 200) {
+          this.$message.success('驳回成功')
+          this.getList()
+        } else {
+          this.$message.error(response.msg || '驳回失败')
+        }
+      } catch (error) {
+        console.error('驳回失败:', error)
+        this.$message.error('驳回失败')
+      }
     },
-    handleDispatch(row) {
-      // TODO: 实现派单功能
+    // 每日填写
+    async handleDailyWrite(row) {
+      try {
+        const response = await dailyWrite({ id: row.id })
+        if (response.code === 200) {
+          this.$message.success('填写成功')
+          this.getList()
+        } else {
+          this.$message.error(response.msg || '填写失败')
+        }
+      } catch (error) {
+        console.error('填写失败:', error)
+        this.$message.error('填写失败')
+      }
     },
-    handleReject(row) {
-      // TODO: 实现接单驳回功能
+    // 完成
+    async handleComplete(row) {
+      try {
+        const response = await completeInstallation({ id: row.id })
+        if (response.code === 200) {
+          this.$message.success('操作成功')
+          this.getList()
+        } else {
+          this.$message.error(response.msg || '操作失败')
+        }
+      } catch (error) {
+        console.error('操作失败:', error)
+        this.$message.error('操作失败')
+      }
     },
-    handleDailyWrite(row) {
-      // TODO: 实现每日填写功能
+    // 接单
+    async handleAccept(row) {
+      try {
+        const response = await acceptInstallation({ id: row.id })
+        if (response.code === 200) {
+          this.$message.success('接单成功')
+          this.getList()
+        } else {
+          this.$message.error(response.msg || '接单失败')
+        }
+      } catch (error) {
+        console.error('接单失败:', error)
+        this.$message.error('接单失败')
+      }
     },
-    handleComplete(row) {
-      // TODO: 实现完成功能
+    // 验收
+    async handleCheck(row) {
+      try {
+        const response = await checkInstallation({ id: row.id })
+        if (response.code === 200) {
+          this.$message.success('验收成功')
+          this.getList()
+        } else {
+          this.$message.error(response.msg || '验收失败')
+        }
+      } catch (error) {
+        console.error('验收失败:', error)
+        this.$message.error('验收失败')
+      }
     },
-    handleAccept(row) {
-      // TODO: 实现接单功能
+    // 处理下拉菜单命令
+    handleCommand(command, row) {
+      switch (command) {
+        case 'delete':
+          this.handleDelete(row)
+          break
+        case 'dispatch':
+          this.handleDispatch(row)
+          break
+        case 'reject':
+          this.handleReject(row)
+          break
+        case 'dailyWrite':
+          this.handleDailyWrite(row)
+          break
+        case 'complete':
+          this.handleComplete(row)
+          break
+        case 'accept':
+          this.handleAccept(row)
+          break
+        case 'check':
+          this.handleCheck(row)
+          break
+      }
     },
-    handleCheck(row) {
-      // TODO: 实现验收功能
+    // 格式化日期为yyyy-MM-dd
+    formatDate(date) {
+      if (!date) return '';
+      const d = new Date(date);
+      const year = d.getFullYear();
+      const month = String(d.getMonth() + 1).padStart(2, '0');
+      const day = String(d.getDate()).padStart(2, '0');
+      return `${year}-${month}-${day}`;
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-.installation-order {
-  padding: 20px;
-  
-  .filter-container {
-    margin-bottom: 20px;
+.app-container {
+  padding: 15px;
+  background-color: #f5f7fa;
+
+  .el-table {
+    // 表格整体样式
+    border-radius: 4px;
+    box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+    
+    // 表头样式
+    :deep(.el-table__header-wrapper) {
+      .el-table__header {
+        thead {
+          tr {
+            th {
+              background-color: #f5f7fa;
+              color: #333;
+              font-weight: 500;
+              height: 44px;
+              padding: 8px 0;
+              
+              &.is-leaf {
+                border-bottom: 1px solid #e8e8e8;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    // 表格内容样式
+    :deep(.el-table__body-wrapper) {
+      .el-table__body {
+        td {
+          padding: 12px 0;
+          height: 50px;
+        }
+      }
+    }
+
+    // 斑马纹样式
+    :deep(.el-table__row--striped) {
+      td {
+        background-color: #fafafa;
+      }
+    }
+
+    // 鼠标悬停效果
+    :deep(.el-table__body tr:hover) {
+      td {
+        background-color: #f0f7ff !important;
+      }
+    }
+
+    // 移除之前的按钮样式,添加新的美化样式
+    :deep(.el-button--mini) {
+      margin: 2px 3px;
+      padding: 6px 12px;
+      height: 28px;
+      border-radius: 4px;
+      font-size: 12px;
+      font-weight: 500;
+      transition: all 0.3s;
+      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+
+      &:hover {
+        transform: translateY(-1px);
+        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+      }
+
+      &.el-button--primary {
+        background-color: #409EFF;
+        border-color: #409EFF;
+        &:hover {
+          background-color: #66b1ff;
+          border-color: #66b1ff;
+        }
+      }
+
+      &.el-button--success {
+        background-color: #67C23A;
+        border-color: #67C23A;
+        &:hover {
+          background-color: #85ce61;
+          border-color: #85ce61;
+        }
+      }
+
+      &.el-button--warning {
+        background-color: #E6A23C;
+        border-color: #E6A23C;
+        &:hover {
+          background-color: #ebb563;
+          border-color: #ebb563;
+        }
+      }
+
+      &.el-button--danger {
+        background-color: #F56C6C;
+        border-color: #F56C6C;
+        &:hover {
+          background-color: #f78989;
+          border-color: #f78989;
+        }
+      }
+
+      &.el-button--info {
+        background-color: #909399;
+        border-color: #909399;
+        &:hover {
+          background-color: #a6a9ad;
+          border-color: #a6a9ad;
+        }
+      }
+
+      // 所有按钮文字颜色设为白色
+      color: #fff;
+      
+      // 禁用状态样式
+      &.is-disabled {
+        &:hover {
+          transform: none;
+          box-shadow: none;
+        }
+      }
+    }
+
+    // 进度条样式
+    :deep(.progress-wrapper) {
+      display: flex;
+      flex-direction: column;
+      
+      .progress-text {
+        width: 100%;
+        text-align: center;
+        margin-bottom: 5px;
+      }
+
+      .el-progress {
+        width: 90%;
+        margin-left: 10px;
+        
+        .el-progress-bar {
+          padding-right: 0;
+          margin-right: 0;
+          width: 100%;
+        }
+        
+        .el-progress__text {
+          display: none;
+        }
+      }
+    }
+
+    // 状态标签样式
+    :deep(.el-tag) {
+      border-radius: 2px;
+      padding: 0 8px;
+      height: 24px;
+      line-height: 22px;
+    }
+
+    // 空数据样式
+    :deep(.el-table__empty-block) {
+      min-height: 200px;
+
+      .el-table__empty-text {
+        color: #909399;
+        font-size: 14px;
+        line-height: 200px;
+        text-align: left;
+      }
+    }
+
+    // 固定列样式
+    :deep(.el-table__fixed-right) {
+      height: 100% !important;
+      box-shadow: -2px 0 8px rgba(0, 0, 0, 0.05);
+    }
+
+    // 表格边框样式
+    :deep(.el-table--border) {
+      border: 1px solid #e8e8e8;
+      
+      &::after {
+        background-color: #e8e8e8;
+      }
+      
+      th, td {
+        border-right: 1px solid #e8e8e8;
+      }
+    }
+
+    // 下拉菜单项样式
+    :deep(.el-dropdown-menu__item) {
+      padding: 8px 20px;
+      font-size: 13px;
+      
+      &:hover {
+        background-color: #f5f7fa;
+      }
+
+      &.dropdown-primary {
+        color: #409EFF;
+      }
+
+      &.dropdown-success {
+        color: #67C23A;
+      }
+
+      &.dropdown-warning {
+        color: #E6A23C;
+      }
+
+      &.dropdown-danger {
+        color: #F56C6C;
+      }
+
+      &.dropdown-info {
+        color: #909399;
+      }
+    }
+
+    // 更多按钮样式
+    :deep(.el-dropdown) {
+      margin-left: 2px;
+      
+      .el-button {
+        display: inline-flex;
+        align-items: center;
+        justify-content: center;
+        
+        i {
+          margin-left: 3px;
+        }
+      }
+    }
+  }
+
+  // 其他已有样式保持不变
+  .pagination-container {
+    padding: 15px 0;
+    text-align: left;
+  }
+
+  .demo-form-inline {
+    background-color: #fff;
+    padding: 15px 15px;
+    border-radius: 4px;
+    box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+
+    :deep(.el-form-item) {
+      margin-bottom: 0;
+      margin-top: 3px;
+      margin-bottom: 3px;
+      margin-right: 5px;
+      display: inline-flex;
+      align-items: center;
+      vertical-align: top;
+    }
+
+    :deep(.el-input__inner) {
+      height: 32px;
+      line-height: 32px;
+    }
+
+    :deep(.el-range-editor.el-input__inner) {
+      padding: 0 10px;
+      margin: 0;
+    }
+
+    :deep(.el-button), :deep(.el-radio-button__inner) {
+      height: 32px;
+      padding: 0 15px;
+      line-height: 30px;
+      vertical-align: top;
+    }
+
+    :deep(.el-radio-group) {
+      display: inline-flex;
+      vertical-align: top;
+    }
+    :deep(.el-input) {
+    margin-left: 0 !important;  // 强制覆盖左边距
+  }
+    :deep(.el-form-item__content) {
+      line-height: 32px;
+      display: inline-flex;
+      align-items: center;
+    }
+
+    :deep(.pending-badge) {
+      position: absolute;
+      top: -8px;
+      right: -3px;
+      z-index: 2;
+      
+      .el-badge__content {
+        height: 16px;
+        line-height: 16px;
+        padding: 0 4px;
+        border: none;
+        font-size: 12px;
+        background-color: #F56C6C;
+      }
+    }
+
+    :deep(.el-range-separator) {
+      color: #606266;
+      line-height: 30px;
+      font-size: 13px;
+      padding: 0 3px;
+    }
+  }
+
+  :deep(.el-loading-mask) {
+    .el-loading-spinner {
+      .el-icon-loading {
+        font-size: 30px;
+        color: #409EFF;
+      }
+      .el-loading-text {
+        font-size: 14px;
+        margin-top: 10px;
+        color: #606266;
+      }
+    }
   }
-  
-  .operation-container {
-    margin-bottom: 20px;
+
+  // 货品标签样式
+  :deep(.product-tags) {
     display: flex;
-    justify-content: space-between;
+    flex-wrap: wrap;
+    gap: 4px;
+    justify-content: center;
+    padding: 2px;
+
+    .el-tag {
+      margin: 2px;
+      max-width: 150px;
+      white-space: normal;
+      height: auto;
+      padding: 2px 6px;
+      line-height: 16px;
+      word-break: break-all;
+      text-align: center;
+
+      &.long-text {
+        font-size: 11px;
+      }
+    }
+  }
+
+  // 服务人员标签样式
+  :deep(.staff-tags) {
+    display: flex;
+    flex-direction: column;
     align-items: center;
+    gap: 2px;
+    padding: 1px;
+
+    .el-tag {
+      margin: 1px;
+      min-width: 70px;
+      max-width: 100px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      height: 20px;
+      padding: 0 6px;
+      line-height: 20px;
+      font-size: 11px;
+
+      &.long-text {
+        font-size: 10px;
+      }
+    }
   }
-  
-  .el-card {
-    margin-bottom: 20px;
+
+  // 时间显示样式
+  :deep(.normal-time) {
+    color: #606266;
+    font-size: 13px;
   }
-  
-  :deep(.el-table) {
-    margin-top: 10px;
-    
-    .el-button {
-      padding: 2px 0;
-      margin: 0 5px;
-    }
+
+  :deep(.warning-time) {
+    color: #F56C6C;
+    font-size: 15px;
+    font-weight: bold;
+  }
+
+  :deep(.overdue-time) {
+    color: #F56C6C;
+    font-size: 15px;
+    font-weight: bold;
   }
 }
 </style> 

+ 2 - 14
src/views/productManagement/productionSummary/components/ProductionStatusChart.vue

@@ -38,10 +38,12 @@
 <script>
 import * as echarts from 'echarts'
 import _ from 'lodash'
+import resize from './mixins/resize'
 // import { getProductList } from '@/api/production' // 后续需要添加此API
 
 export default {
   name: 'MonthlyChart',
+  mixins: [resize],
   props: {
     chartData: {
       type: Object,
@@ -81,15 +83,12 @@ export default {
       this.initChart()
       this.initProductOptions()
     })
-    window.addEventListener('resize', this.resizeHandler)
   },
   beforeDestroy() {
     if (this.chart) {
       this.chart.dispose()
       this.chart = null
     }
-    window.removeEventListener('resize', this.resizeHandler)
-    this.clearResizeHandler()
   },
   watch: {
     month() {
@@ -110,17 +109,6 @@ export default {
       this.chart = echarts.init(this.$refs.chartRef)
       this.setChartOption(this.localChartData)
     },
-    // 防抖处理resize
-    resizeHandler: _.debounce(function() {
-      if (this.chart) {
-        this.chart.resize()
-      }
-    }, 100),
-    clearResizeHandler() {
-      if (this.resizeHandler) {
-        this.resizeHandler.cancel()
-      }
-    },
     setChartOption(data) {
       if (!this.chart) return
       

+ 8 - 7
src/views/productManagement/productionSummary/components/mixins/resize.js

@@ -3,16 +3,10 @@ import { debounce } from '@/utils'
 export default {
   data() {
     return {
-      $_sidebarElm: null,
-      $_resizeHandler: null
+      $_sidebarElm: null
     }
   },
   mounted() {
-    this.$_resizeHandler = debounce(() => {
-      if (this.chart) {
-        this.chart.resize()
-      }
-    }, 100)
     this.$_initResizeEvent()
     this.$_initSidebarResizeEvent()
   },
@@ -29,6 +23,13 @@ export default {
     this.$_destroySidebarResizeEvent()
   },
   methods: {
+    $_resizeHandler() {
+      return debounce(() => {
+        if (this.chart) {
+          this.chart.resize()
+        }
+      }, 100)()
+    },
     $_initResizeEvent() {
       window.addEventListener('resize', this.$_resizeHandler)
     },