yusheng 1 месяц назад
Родитель
Сommit
a004bddd90

+ 6 - 1
src/views/bpm/doneTickets/index.vue

@@ -25,6 +25,7 @@
 
 <script>
   import patrolInspection from './patrolInspection';
+  import service from './service';
   import maintenance from './maintenance';
   import delivery from './delivery';
   import repair from './repair';
@@ -36,7 +37,7 @@
       patrolInspection,
       maintenance,
       delivery,
-      repair,
+      repair,service,
       inspectionWork,
       productions,
       work
@@ -47,6 +48,7 @@
         tabOptions: [
           { key: 'patrolInspection', name: '巡点检工单' },
           { key: 'maintenance', name: '保养工单' },
+          { key: 'service', name: '检修工单' },
           { key: 'repair', name: '维修工单' },
           { key: 'productions', name: '生产工单' },
           { key: 'inspectionWork', name: '质检工单' },
@@ -65,6 +67,9 @@
         case '保养工单':
           this.activeComp = 'maintenance';
           break;
+        case '检修工单':
+          this.activeComp = 'service';
+          break;
         case '量具送检工单':
           this.activeComp = 'delivery';
           break;

+ 587 - 0
src/views/bpm/doneTickets/service/detail.vue

@@ -0,0 +1,587 @@
+<template>
+  <div class="page" v-loading="pageLoading">
+    <el-form label-width="130px">
+      <div class="content-detail" v-show="num == 1">
+        <div class="basic-details">
+          <HeaderTitle title="基本信息" size="16px">
+            <el-button
+              type="primary"
+              @click="
+                $router.push({
+                  path: '/doneTickets',
+                  query: { title: '检修工单' }
+                })
+              "
+              >返回</el-button
+            >
+          </HeaderTitle>
+          <el-row>
+            <el-col :span="12">
+              <el-col :span="12">
+                <el-form-item label="计划单号">
+                  <span> {{ infoData.planCode }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="来源计划配置单号">
+                  <span> {{ infoData.planConfigCode }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="名称">
+                  <span> {{ infoData.planName }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="部门">
+                  <span>
+                    {{ infoData.executeGroupName }}
+                  </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="人员">
+                  <span>
+                    {{ infoData.executeUserName }}
+                  </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="计划完成时长">
+                  <span v-if="infoData.duration >= 0"
+                    >{{ infoData.duration }}分钟</span
+                  >
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="周期">
+                  <span v-if="infoData.ruleInfo">
+                    {{ infoData.ruleInfo.cycleValue
+                    }}{{
+                      getDictValue('巡点检周期', infoData.ruleInfo.cycleType)
+                    }}
+                  </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="设备分类">
+                  <span> {{ infoData.categoryLevelName }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="规则名称">
+                  <span>
+                    {{ infoData.ruleName }}
+                  </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="创建部门">
+                  <span> {{ infoData.createGroupName }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="创建人">
+                  <span> {{ infoData.createUserName }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="创建时间">
+                  <span> {{ infoData.createTime }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="备注">
+                  <span> {{ infoData.remark }} </span>
+                </el-form-item>
+              </el-col>
+            </el-col>
+            <el-col :span="12">
+              <img :src="data.imageUrl" alt="" />
+            </el-col>
+          </el-row>
+        </div>
+
+        <!-- 巡点检、保养设备 -->
+        <div class="maintain_equipment_info">
+          <HeaderTitle title="设备" size="16px"></HeaderTitle>
+          <div class="maintain_equipment_info_content">
+            <div
+              class="equipment_item"
+              v-for="item in infoData.deviceList"
+              :key="item.id"
+            >
+              <div class="equipment_info" v-if="item.substance">
+                <div class="item_info">
+                  <span class="item_label">设备编码</span>
+                  <span class="item_value">{{ item.substance.code }}</span>
+                </div>
+                <div class="item_info">
+                  <span class="item_label">设备名称</span>
+                  <span class="item_value">{{ item.substance.name }}</span>
+                </div>
+                <div class="item_info">
+                  <span class="item_label">设备型号</span>
+                  <span class="item_value">{{ item.substance.model }}</span>
+                </div>
+                <div class="item_info">
+                  <span class="item_label">设备位置</span>
+                  <span class="item_value">{{
+                    item.substance.positionNames
+                  }}</span>
+                </div>
+              </div>
+              <p>操作事项</p>
+              <div class="ruleMatters_box">
+                <el-table :data="item.workItems" border>
+                  <el-table-column label="序号" width="50">
+                    <template slot-scope="scope">
+                      <span>{{ scope.$index + 1 }}</span>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="事项" prop="name" width="100">
+                    <template slot-scope="scope">
+                      <div>
+                        <span>{{ scope.row.name }}</span>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="内容" prop="content" width="300">
+                    <template slot-scope="scope">
+                      <div>
+                        <span>{{ scope.row.content }}</span>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="操作指导" prop="operationGuide">
+                    <template slot-scope="scope">
+                      <div class="operationGuide_box">
+                        <div class="left_content">
+                          <template v-if="scope.row.operationGuide">
+                            <div
+                              v-for="(item, index) in scope.row.operationGuide
+                                .toolList"
+                              :key="item.id"
+                              >{{ index + 1 }}.{{ item.name }}</div
+                            >
+                          </template>
+                        </div>
+                        <div class="line"></div>
+                        <div class="right_content">
+                          <template v-if="scope.row.operationGuide">
+                            <div
+                              v-for="(item, index) in scope.row.operationGuide
+                                .procedureList"
+                              :key="item.id"
+                              >{{ index + 1 }}.{{ item.content }}</div
+                            >
+                          </template>
+                        </div>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="标准" prop="norm" width="100">
+                    <template slot-scope="scope">
+                      <div>
+                        <span>{{ scope.row.norm }}</span>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="状态" prop="status" width="100">
+                    <template slot-scope="scope">
+                      <div>
+                        <span>{{ options[scope.row.status] }}</span>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="结果" prop="result" width="200">
+                  </el-table-column>
+                </el-table>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </el-form>
+  </div>
+</template>
+
+<script>
+  import dictMixins from '@/mixins/dictMixins';
+  import { getWordOrderDetail } from '@/api/tickets';
+  export default {
+    mixins: [dictMixins],
+    data() {
+      return {
+        options: {
+          1: '正常',
+          '-1': '缺陷'
+        },
+        num: 1,
+        infoData: {},
+        dialogVisible: false,
+        data: {},
+        repairNotes: {},
+        pageLoading: false,
+        typeValue: null,
+        contract_type: [],
+        status: [
+          {
+            value: true,
+            label: '失效'
+          },
+          {
+            value: false,
+            label: '生效'
+          }
+        ],
+        ruleItem: [],
+        cause: '',
+        showtext: false,
+        from: null
+      };
+    },
+    created() {
+      this.requestDict('巡点检周期');
+      this.getInfo();
+    },
+    methods: {
+      // getStatus: useDictLabel(patrolMatterStatus),
+      delete() {},
+      // 点击切换事件
+      tab(index) {
+        this.num = index;
+      },
+
+      // 表格数据
+      getInfo() {
+        this.pageLoading = true;
+        getWordOrderDetail(this.$route.query.id)
+          .then((data) => {
+            this.infoData = data;
+
+            this.pageLoading = false;
+          })
+          .catch(() => {
+            this.pageLoading = false;
+          });
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  // @import '@/assets/css/oaa.scss';
+  .page {
+    padding: 10px;
+  }
+  .page-title {
+    background: #fff;
+    font-size: 18px;
+    padding: 6px 20px;
+    font-weight: 500;
+    .page-title-div {
+      margin: 5px 0;
+      height: 30px;
+      line-height: 30px;
+      border-bottom: 1px solid #eaeefb;
+      .title-div-no {
+        margin-left: 10px;
+        font-weight: 400;
+        color: #909090;
+        font-size: 14px;
+      }
+    }
+  }
+  .page-data {
+    padding-top: 10px;
+  }
+  .content-detail {
+    background: #fff;
+    padding: 20px;
+  }
+  .flows {
+    .flow-left {
+      width: 156px;
+      height: 70px;
+      border: 1px dashed #ccc;
+      padding: 10px;
+    }
+    .row {
+      margin-top: 13px;
+    }
+  }
+  .basic-details-title {
+    margin-bottom: 12px;
+    margin-top: 20px;
+    border-bottom: 1px solid #1890ff;
+    padding-bottom: 8px;
+    display: flex;
+    justify-content: space-between;
+  }
+  .basic-details-title .border-span {
+    height: 18px;
+    font-size: 16px;
+    border-left: 4px solid #1890ff;
+    padding-left: 8px;
+
+    font-weight: 500;
+  }
+  .heade-right {
+    // float: right;
+    .heade-right-content {
+      margin-right: 12px;
+      font-size: 14px;
+      display: inline-block;
+      .content-key {
+        color: #3e3e3e;
+        margin-right: 12px;
+        font-weight: 500;
+      }
+      .content-value {
+        color: #000;
+      }
+    }
+  }
+  .list-title {
+    font-size: 14px;
+    color: #3e3e3e;
+    margin: 10px 0px;
+  }
+  .goods {
+    background: #a30014;
+    border: 1px solid #a30014;
+  }
+  .details-title {
+    display: inline-block;
+    color: #6e6e6e;
+    font-size: 14px;
+    font-weight: bold;
+    margin-right: 13px;
+    width: 70px;
+    text-align: right;
+  }
+  .details-con {
+    color: #3e3e3e;
+    font-size: 14px;
+  }
+  .detailed-tab {
+    margin-left: 10px;
+    margin-top: 10px;
+  }
+  ::v-deep .el-form-item--medium .el-form-item__label {
+    color: #6e6e6e;
+    font-size: 14px;
+    font-weight: bold;
+  }
+  .warehouse {
+    display: block;
+    border-bottom: 1px solid #eaeefb;
+    padding: 10px 0;
+  }
+  .box-card {
+    .store-box {
+      width: 80%;
+      .store-box-span {
+        display: inline-block;
+        font-size: 14px;
+        height: 50px;
+        width: 50px;
+        text-align: center;
+        line-height: 50px;
+        color: #fff;
+        margin: 2px;
+      }
+    }
+  }
+  .vacant {
+    background: #3196fb;
+  }
+  .inUse {
+    background: #157a2c;
+  }
+  .invalid {
+    background: #cccccc;
+  }
+  .full {
+    background: #cc3300;
+  }
+
+  .maintain_equipment_info {
+    .maintain_equipment_info_title {
+      border-bottom: 1px solid #1890ff;
+      padding-bottom: 3px;
+      margin-bottom: 20px;
+      > span {
+        display: inline-block;
+        line-height: 16px;
+        border-left: 6px solid #1890ff;
+        padding-left: 6px;
+      }
+    }
+    .maintain_equipment_info_content {
+      padding: 0 30px;
+      .equipment_item {
+        border: 1px solid #ccc;
+        font-size: 14px;
+        padding: 15px;
+        margin-bottom: 30px;
+        .equipment_info {
+          display: flex;
+          flex-wrap: wrap;
+          border: 1px solid #ddd;
+          .item_info {
+            width: 33.33%;
+            height: 24px;
+            line-height: 24px;
+            display: flex;
+            .item_label {
+              width: 90px;
+              text-align: center;
+              background-color: #f2f2f2;
+              font-weight: 700;
+            }
+            .item_value {
+              border-bottom: 1px solid #f2f2f2;
+              flex: 1;
+              padding-left: 5px;
+            }
+            &:last-child {
+              width: 100%;
+              .item_value {
+                border: 0;
+              }
+            }
+          }
+        }
+        > p {
+          margin-top: 20px;
+          color: #797979;
+        }
+        .matter_info {
+          ::v-deep .el-table {
+            th.el-table__cell {
+              background-color: #f2f2f2;
+              padding: 0;
+            }
+            td.el-table__cell {
+              padding: 0;
+            }
+          }
+        }
+        .ruleMatters_box {
+          flex: 3;
+          height: 100%;
+          display: flex;
+          flex-direction: column;
+          .divider {
+            flex: 0 0 50px;
+            .title {
+              height: 35px;
+            }
+          }
+          .el-table {
+            overflow: auto;
+            .operationGuide_box {
+              width: 100%;
+              display: flex;
+              position: relative;
+              .left_content {
+                flex: 0 0 300px;
+                padding: 10px;
+                margin-right: 10px;
+                overflow-y: auto;
+              }
+              .line {
+                position: absolute;
+                top: -10px;
+                left: 300px;
+                bottom: -10px;
+                height: 110%;
+                width: 1px;
+                background-color: #ededed;
+              }
+              .right_content {
+                flex: 1;
+                padding: 10px;
+                overflow-y: auto;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  .execute_info {
+    margin: 30px 0;
+    .execute_info_title {
+      border-bottom: 1px solid #1890ff;
+      padding-bottom: 3px;
+      margin-bottom: 20px;
+      display: flex;
+      justify-content: space-between;
+      > span:first-child {
+        line-height: 16px;
+        border-left: 6px solid #1890ff;
+        padding-left: 6px;
+      }
+    }
+    .execute_row {
+      padding: 0 30px;
+      .column {
+        display: flex;
+        font-size: 14px;
+        margin-bottom: 20px;
+        .label {
+          // width: 110px;
+          text-align: center;
+          font-weight: 700;
+        }
+      }
+    }
+  }
+  .repair_notes {
+    .repair_notes_title {
+      border-bottom: 1px solid #1890ff;
+      padding-bottom: 3px;
+      margin-bottom: 20px;
+      > span {
+        display: inline-block;
+        line-height: 16px;
+        border-left: 6px solid #1890ff;
+        padding-left: 6px;
+      }
+    }
+    .repair_notes_equipment_item {
+      padding: 0 20px;
+      .equipment_item_tilte {
+        background-color: #f7f7f7;
+        height: 36px;
+        line-height: 36px;
+        .label {
+          font-weight: 700;
+        }
+      }
+      .main_info {
+        font-size: 14px;
+        margin-top: 15px;
+        > div {
+          margin-bottom: 10px;
+        }
+      }
+    }
+  }
+  .btnbox {
+    display: flex;
+    justify-content: center;
+  }
+  ::v-deep .el-button {
+    padding: 10px 20px;
+    margin-right: 10px;
+  }
+  .textbtnbox {
+    margin-top: 10px;
+    display: flex;
+    justify-content: center;
+  }
+</style>

+ 431 - 0
src/views/bpm/doneTickets/service/index.vue

@@ -0,0 +1,431 @@
+<!-- 点巡检工单 -->
+
+<template>
+  <div>
+    <div class="ele-body">
+      <el-card shadow="never">
+        <div class="filter-container">
+          <el-form
+            label-width="100px"
+            class="ele-form-search"
+            @keyup.enter.native="reload"
+            @submit.native.prevent
+          >
+            <el-row :gutter="15">
+              <el-col
+                v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }"
+              >
+                <el-form-item label="工单编号">
+                  <el-input
+                    v-model="searchForm.code"
+                    placeholder="请输入"
+                    size="small"
+                  ></el-input>
+                </el-form-item>
+              </el-col>
+
+              <el-col
+                v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }"
+              >
+                <el-form-item label="规则名称">
+                  <el-select
+                    v-model="searchForm.ruleId"
+                    size="small"
+                    clearable
+                    style="width: 100%"
+                    filterable
+                  >
+                    <el-option
+                      v-for="item in ruleNameList"
+                      :key="item.id"
+                      :value="item.id"
+                      :label="item.name"
+                    ></el-option> </el-select
+                ></el-form-item>
+              </el-col>
+
+              <el-col :md="4" :sm="16" :xs="16" style="text-align: right">
+                <el-button
+                  icon="el-icon-refresh-left"
+                  size="small"
+                  @click="reload('reset')"
+                  >重置</el-button
+                >
+                <el-button
+                  type="primary"
+                  icon="el-icon-search"
+                  size="small"
+                  @click="reload('search')"
+                  >搜索</el-button
+                ></el-col
+              >
+            </el-row>
+          </el-form>
+        </div>
+        <ele-pro-table
+          ref="table"
+          :columns="columns"
+          :datasource="datasource"
+          maxHeight="580"
+          :pageSize="20"
+        >
+          <!-- 操作列 -->
+
+          <!-- 工单编号slot -->
+          <template v-slot:code="{ row }">
+            <el-link
+              type="primary"
+              :underline="false"
+              @click="openDetail({ id: row.id })"
+            >
+              {{ row.code }}
+            </el-link>
+          </template>
+        </ele-pro-table>
+      </el-card>
+    </div>
+  </div>
+</template>
+<script>
+  import { ticketStatus, resultStatus } from '@/utils/dict/tickets';
+  import { getWorkOrderPage, getRule } from '@/api/tickets';
+
+  // 修改
+  import {
+    notifyMessagePageAPI,
+    updateNotifyMessageReadByIdAPI
+  } from '@/api/bpm/task';
+  import { mapGetters } from 'vuex';
+  export default {
+    components: {},
+    data() {
+      return {
+        ruleNameList: [],
+        userId: '',
+        ticketStatus: [],
+        resultStatus,
+        //
+        addOrEditDialogFlag: false,
+        columns: [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 60,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+          {
+            prop: 'code',
+            label: '工单编号',
+            minWidth: '200',
+            align: 'center',
+            slot: 'code'
+          },
+          {
+            prop: 'planCode',
+            label: '计划单号',
+            minWidth: '200',
+            align: 'center'
+          },
+          {
+            prop: 'planName',
+            label: '名称',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'ruleName',
+            label: '规则名称',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'createUserName',
+            label: '创建人',
+            align: 'center',
+            minWidth: '150',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'createTime',
+            label: '创建时间',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'acceptTime',
+            label: '开始时间',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'finishTime',
+            label: '结束时间',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'planFinishTime',
+            label: '计划完成时间',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'isAbnormal',
+            label: '执行结果',
+            align: 'center',
+            showOverflowTooltip: true,
+            formatter: (_row, _column, cellValue) => {
+              return { 0: '缺陷', 1: '正常' }[_row.isAbnormal];
+            }
+          },
+          {
+            prop: 'orderStatus',
+            label: '状态',
+            align: 'center',
+            showOverflowTooltip: true,
+            formatter: (_row, _column, cellValue) => {
+              return ticketStatus.filter(
+                (item) => item.id == _row.orderStatus
+              )[0]?.label;
+            }
+          },
+          {
+            prop: 'practicalTime',
+            label: '实际工时',
+            align: 'center',
+            showOverflowTooltip: true,
+            formatter: (_row, _column, cellValue) => {
+              let _this = this;
+              return _this.time_interval(_row.acceptTime, _row.finishTime);
+            }
+          },
+
+          {
+            columnKey: 'action',
+            label: '操作',
+            minWidth: 200,
+            align: 'center',
+            slot: 'action',
+            fixed: 'right'
+          }
+        ],
+        searchForm: {
+          code: '',
+          orderStatus: 3,
+          ruleId: '',
+          date: '',
+          startTime: '',
+          endTime: '',
+          type: 7,
+          executeUserId: ''
+        },
+        tableData: [],
+        size: 10,
+        page: 1,
+        total: 0
+      };
+    },
+    computed: {
+      ...mapGetters(['user']),
+      // 是否开启响应式布局
+      styleResponsive() {
+        return this.$store.state.theme.styleResponsive;
+      }
+    },
+    methods: {
+      //新增或修改模板
+      async handleAddOrEdit(row) {
+        await updateNotifyMessageReadByIdAPI([row.id]);
+        this.$refs.table.reload();
+      },
+      reload(type) {
+        if (type == 'reset') {
+          this.searchForm.code = '';
+          // this.searchForm.orderStatus = '';
+          this.searchForm.ruleId = '';
+          this.searchForm.date = '';
+          this.searchForm.startTime = '';
+          this.searchForm.endTime = '';
+          this.searchForm.type = 7;
+        }
+        let params = Object.assign({}, this.searchForm);
+        delete params.date;
+        this.$refs.table.reload({ page: 1, where: params });
+      },
+
+      // 获取table数据
+      async datasource({ page, where, limit, ...row }) {
+        this.searchForm.executeUserId = this.userId;
+        let params = Object.assign({}, this.searchForm);
+        delete params.date;
+        const res = await getWorkOrderPage({
+          ...params,
+          ...where,
+          pageNum: page,
+          size: limit,
+          userId: this.user.info.userId
+        });
+        console.log(res);
+        this.total = res.total;
+        this.$emit('recount');
+        return res;
+      },
+
+      // 获取规则名列表(设备维修)
+      async getRuleNameList() {
+        const res = await getRule({
+          status: 1,
+          type: 7,
+          pageNum: 1,
+          size: -1
+        });
+        if (res.list) {
+          this.ruleNameList = res.list || [];
+        }
+      },
+
+      // 报工
+      toSigningUpWork(row) {
+        this.$refs.signingUpWorkRef.open(row);
+      },
+      openDetail({ id }) {
+        this.$router.push({
+          path: '/doneTickets/service/detail',
+          query: {
+            id
+          }
+        });
+      },
+      getData() {
+        let par = {
+          ...this.pages,
+          ...this.searchForm,
+          executeUserId: this.userId,
+          statusType: 0
+        };
+        if (this.searchForm.date) {
+          par.startTime = this.searchForm.date[0];
+          par.endTime = this.searchForm.date[1];
+        }
+        delete par.date;
+        getWorkOrderPage(par).then((res) => {
+          this.tableData = res.list;
+          this.total = res.total;
+        });
+        this.$emit('recount');
+      },
+      // 计算实际工时
+      time_interval(dt1, dt2) {
+        if (!dt1 || !dt2) {
+          return '';
+        }
+        if (typeof dt1 == 'string') {
+          dt1 = new Date(dt1.replace(/-/, '/'));
+          dt2 = new Date(dt2.replace(/-/, '/'));
+        }
+        var res = dt2 - dt1;
+        if (isNaN(res)) throw Error('invalid dates arguments');
+        let re = res / (1000 * 60 * 60);
+
+        var h = parseInt(re);
+        var m = parseInt((re - h) * 60);
+        let result = '';
+        if (h) {
+          result += `${h} 小时`;
+        }
+        if (m) {
+          result += `${m} 分钟`;
+        }
+        return result;
+      },
+      changeDate(val) {
+        if (val === null) {
+          this.searchForm.startTime = '';
+          this.searchForm.endTime = '';
+          return;
+        }
+        this.searchForm.startTime = val[0];
+        this.searchForm.endTime = val[1];
+      }
+    },
+    created() {
+      this.userId = localStorage.getItem('userId');
+      this.getRuleNameList();
+      this.ticketStatus = ticketStatus.filter((item) => {
+        return [0, 2, 3].includes(item.id);
+      });
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  // 步骤条边线显示
+  // ::v-deep .el-step__head.is-process .el-step__icon.is-text {
+  //   border: none !important;
+  //   background: none !important;
+  // }
+  // ::v-deep .el-step:last-of-type .el-step__line {
+  //   display: block !important;
+  //   width: 3px !important;
+  // }
+  // ::v-deep .el-steps:last-child .el-step__line {
+  //   display: none !important;
+  // }
+  // .patrolInspection {
+  //   height: 100%;
+  //   width: 100%;
+  //   display: flex;
+  //   flex-direction: column;
+  //   .search {
+  //     flex: 0 0 50px;
+  //   }
+  //   .table {
+  //     flex: 1;
+  //     .el-table {
+  //       width: 100%;
+  //       display: flex;
+  //       flex-direction: column;
+  //     }
+  //   }
+  //   .table-footer {
+  //     flex: 0 0 30px;
+  //     display: flex;
+  //     justify-content: flex-end;
+  //   }
+  // }
+
+  // 修改
+  ::v-deep .el-card__body {
+    padding: 0;
+  }
+
+  .app-container {
+    background: #f0f3f3;
+    min-height: calc(100vh - 84px);
+  }
+
+  .zw-page-table {
+    background: #ffffff;
+    padding-top: 20px;
+  }
+
+  .pagination-wrap {
+    display: flex;
+    justify-content: flex-end;
+    padding: 10px 0;
+  }
+
+  .table {
+    width: 100%;
+    margin-top: 10px;
+  }
+</style>

+ 38 - 35
src/views/bpm/tickets/index.vue

@@ -29,18 +29,15 @@
 <script>
   import { statistics } from '@/api/bpm/components/inspectionManage';
   import patrolInspection from './patrolInspection';
+  import service from './service';
   import maintenance from './maintenance';
   import delivery from './delivery';
   import repair from './repair';
   import inspectionWork from './inspectionWork';
   import productions from './productions';
   import work from './work';
-  import {
-    getMyPage,
-  } from '@/api/mes/produceOrder/index.js';
-  import {
-    getList
-  } from '@/api/qms/inspectionWork/index.js';
+  import { getMyPage } from '@/api/mes/produceOrder/index.js';
+  import { getList } from '@/api/qms/inspectionWork/index.js';
   import { getPlanOrderList } from '@/api/warehouseManagement/inventory';
   export default {
     components: {
@@ -50,6 +47,7 @@
       repair,
       inspectionWork,
       productions,
+      service,
       work
     },
     data() {
@@ -58,7 +56,7 @@
         tabOptions: [
           { key: 'patrolInspection', name: '巡点检工单' },
           { key: 'maintenance', name: '保养工单' },
-          // { key: 'delivery', name: '量具送检工单' },
+          { key: 'service', name: '检修工单' },
           { key: 'repair', name: '维修工单' },
           { key: 'productions', name: '生产工单' },
           { key: 'inspectionWork', name: '质检工单' },
@@ -77,6 +75,9 @@
         case '保养工单':
           this.activeComp = 'maintenance';
           break;
+        case '检修工单':
+          this.activeComp = 'service';
+          break;
         case '量具送检工单':
           this.activeComp = 'delivery';
           break;
@@ -104,47 +105,49 @@
           size: 1,
           statusList: [4, 5, 7],
           workCenterIds: this.$store.state.user.info.workCenterIds
-        })
+        });
 
         const inspectionWorkRes = await getList({
           pageNum: 1,
           size: 1,
           currentLoginUserId: this.$store.state.user.info.userId,
-          status: 0,
-        })
+          status: 0
+        });
 
         const workRes = await getPlanOrderList({
           pageNum: 1,
           size: 1,
           executorId: this.$store.state.user.info.userId,
-          status: 0,
-        })
+          status: 0
+        });
 
-        const eamRes = await statistics()
+        const eamRes = await statistics();
         console.log('productionsRes~~~', productionsRes);
         // statistics().then((data) => {
-          this.tabOptions = this.tabOptions.map((item) => {
-            console.log(item);
-            switch (item.key) {
-              case 'maintenance':
-                return { ...item, count: eamRes.maintenanceNum };
-              case 'patrolInspection':
-                return { ...item, count: eamRes.patrolInspection };
-              case 'delivery':
-                return { ...item, count: eamRes.quantityNum };
-              case 'repair':
-                return { ...item, count: eamRes.repairsNum };
-              case 'productions':
-                return { ...item, count: productionsRes.count || 0 };
-              case 'inspectionWork':
-                return { ...item, count: inspectionWorkRes.count || 0 };
-              case 'work':
-                return { ...item, count: workRes.count || 0 }; 
-              default:
-                return item;
-            }
-          });
-          console.log('tabOptions~~~', this.tabOptions);
+        this.tabOptions = this.tabOptions.map((item) => {
+          console.log(item);
+          switch (item.key) {
+            case 'maintenance':
+              return { ...item, count: eamRes.maintenanceNum };
+            case 'patrolInspection':
+              return { ...item, count: eamRes.patrolInspection };
+            case 'service':
+              return { ...item, count: eamRes.serviceNum };
+            case 'delivery':
+              return { ...item, count: eamRes.quantityNum };
+            case 'repair':
+              return { ...item, count: eamRes.repairsNum };
+            case 'productions':
+              return { ...item, count: productionsRes.count || 0 };
+            case 'inspectionWork':
+              return { ...item, count: inspectionWorkRes.count || 0 };
+            case 'work':
+              return { ...item, count: workRes.count || 0 };
+            default:
+              return item;
+          }
+        });
+        console.log('tabOptions~~~', this.tabOptions);
         // });
       }
     }

+ 587 - 0
src/views/bpm/tickets/service/detail.vue

@@ -0,0 +1,587 @@
+<template>
+  <div class="page" v-loading="pageLoading">
+    <el-form label-width="130px">
+      <div class="content-detail" v-show="num == 1">
+        <div class="basic-details">
+          <HeaderTitle title="基本信息" size="16px">
+            <el-button
+              type="primary"
+              @click="
+                $router.push({
+                  path: '/tickets',
+                  query: { title: '检修工单' }
+                })
+              "
+              >返回</el-button
+            >
+          </HeaderTitle>
+          <el-row>
+            <el-col :span="12">
+              <el-col :span="12">
+                <el-form-item label="计划单号">
+                  <span> {{ infoData.planCode }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="来源计划配置单号">
+                  <span> {{ infoData.planConfigCode }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="名称">
+                  <span> {{ infoData.planName }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="部门">
+                  <span>
+                    {{ infoData.executeGroupName }}
+                  </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="人员">
+                  <span>
+                    {{ infoData.executeUserName }}
+                  </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="计划完成时长">
+                  <span v-if="infoData.duration >= 0"
+                    >{{ infoData.duration }}分钟</span
+                  >
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="周期">
+                  <span v-if="infoData.ruleInfo">
+                    {{ infoData.ruleInfo.cycleValue
+                    }}{{
+                      getDictValue('巡点检周期', infoData.ruleInfo.cycleType)
+                    }}
+                  </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="设备分类">
+                  <span> {{ infoData.categoryLevelName }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="规则名称">
+                  <span>
+                    {{ infoData.ruleName }}
+                  </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="创建部门">
+                  <span> {{ infoData.createGroupName }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="创建人">
+                  <span> {{ infoData.createUserName }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="创建时间">
+                  <span> {{ infoData.createTime }} </span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="24">
+                <el-form-item label="备注">
+                  <span> {{ infoData.remark }} </span>
+                </el-form-item>
+              </el-col>
+            </el-col>
+            <el-col :span="12">
+              <img :src="data.imageUrl" alt="" />
+            </el-col>
+          </el-row>
+        </div>
+
+        <!-- 巡点检、保养设备 -->
+        <div class="maintain_equipment_info">
+          <HeaderTitle title="设备" size="16px"></HeaderTitle>
+          <div class="maintain_equipment_info_content">
+            <div
+              class="equipment_item"
+              v-for="item in infoData.deviceList"
+              :key="item.id"
+            >
+              <div class="equipment_info" v-if="item.substance">
+                <div class="item_info">
+                  <span class="item_label">设备编码</span>
+                  <span class="item_value">{{ item.substance.code }}</span>
+                </div>
+                <div class="item_info">
+                  <span class="item_label">设备名称</span>
+                  <span class="item_value">{{ item.substance.name }}</span>
+                </div>
+                <div class="item_info">
+                  <span class="item_label">设备型号</span>
+                  <span class="item_value">{{ item.substance.model }}</span>
+                </div>
+                <div class="item_info">
+                  <span class="item_label">设备位置</span>
+                  <span class="item_value">{{
+                    item.substance.positionNames
+                  }}</span>
+                </div>
+              </div>
+              <p>操作事项</p>
+              <div class="ruleMatters_box">
+                <el-table :data="item.workItems" border>
+                  <el-table-column label="序号" width="50">
+                    <template slot-scope="scope">
+                      <span>{{ scope.$index + 1 }}</span>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="事项" prop="name" width="100">
+                    <template slot-scope="scope">
+                      <div>
+                        <span>{{ scope.row.name }}</span>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="内容" prop="content" width="300">
+                    <template slot-scope="scope">
+                      <div>
+                        <span>{{ scope.row.content }}</span>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="操作指导" prop="operationGuide">
+                    <template slot-scope="scope">
+                      <div class="operationGuide_box">
+                        <div class="left_content">
+                          <template v-if="scope.row.operationGuide">
+                            <div
+                              v-for="(item, index) in scope.row.operationGuide
+                                .toolList"
+                              :key="item.id"
+                              >{{ index + 1 }}.{{ item.name }}</div
+                            >
+                          </template>
+                        </div>
+                        <div class="line"></div>
+                        <div class="right_content">
+                          <template v-if="scope.row.operationGuide">
+                            <div
+                              v-for="(item, index) in scope.row.operationGuide
+                                .procedureList"
+                              :key="item.id"
+                              >{{ index + 1 }}.{{ item.content }}</div
+                            >
+                          </template>
+                        </div>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="标准" prop="norm" width="100">
+                    <template slot-scope="scope">
+                      <div>
+                        <span>{{ scope.row.norm }}</span>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="状态" prop="status" width="100">
+                    <template slot-scope="scope">
+                      <div>
+                        <span>{{ options[scope.row.status] }}</span>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="结果" prop="result" width="200">
+                  </el-table-column>
+                </el-table>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </el-form>
+  </div>
+</template>
+
+<script>
+  import dictMixins from '@/mixins/dictMixins';
+  import { getWordOrderDetail } from '@/api/tickets';
+  export default {
+    mixins: [dictMixins],
+    data() {
+      return {
+        options: {
+          1: '正常',
+          '-1': '缺陷'
+        },
+        num: 1,
+        infoData: {},
+        dialogVisible: false,
+        data: {},
+        repairNotes: {},
+        pageLoading: false,
+        typeValue: null,
+        contract_type: [],
+        status: [
+          {
+            value: true,
+            label: '失效'
+          },
+          {
+            value: false,
+            label: '生效'
+          }
+        ],
+        ruleItem: [],
+        cause: '',
+        showtext: false,
+        from: null
+      };
+    },
+    created() {
+      this.requestDict('巡点检周期');
+      this.getInfo();
+    },
+    methods: {
+      // getStatus: useDictLabel(patrolMatterStatus),
+      delete() {},
+      // 点击切换事件
+      tab(index) {
+        this.num = index;
+      },
+
+      // 表格数据
+      getInfo() {
+        this.pageLoading = true;
+        getWordOrderDetail(this.$route.query.id)
+          .then((data) => {
+            this.infoData = data;
+
+            this.pageLoading = false;
+          })
+          .catch(() => {
+            this.pageLoading = false;
+          });
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  // @import '@/assets/css/oaa.scss';
+  .page {
+    padding: 10px;
+  }
+  .page-title {
+    background: #fff;
+    font-size: 18px;
+    padding: 6px 20px;
+    font-weight: 500;
+    .page-title-div {
+      margin: 5px 0;
+      height: 30px;
+      line-height: 30px;
+      border-bottom: 1px solid #eaeefb;
+      .title-div-no {
+        margin-left: 10px;
+        font-weight: 400;
+        color: #909090;
+        font-size: 14px;
+      }
+    }
+  }
+  .page-data {
+    padding-top: 10px;
+  }
+  .content-detail {
+    background: #fff;
+    padding: 20px;
+  }
+  .flows {
+    .flow-left {
+      width: 156px;
+      height: 70px;
+      border: 1px dashed #ccc;
+      padding: 10px;
+    }
+    .row {
+      margin-top: 13px;
+    }
+  }
+  .basic-details-title {
+    margin-bottom: 12px;
+    margin-top: 20px;
+    border-bottom: 1px solid #1890ff;
+    padding-bottom: 8px;
+    display: flex;
+    justify-content: space-between;
+  }
+  .basic-details-title .border-span {
+    height: 18px;
+    font-size: 16px;
+    border-left: 4px solid #1890ff;
+    padding-left: 8px;
+
+    font-weight: 500;
+  }
+  .heade-right {
+    // float: right;
+    .heade-right-content {
+      margin-right: 12px;
+      font-size: 14px;
+      display: inline-block;
+      .content-key {
+        color: #3e3e3e;
+        margin-right: 12px;
+        font-weight: 500;
+      }
+      .content-value {
+        color: #000;
+      }
+    }
+  }
+  .list-title {
+    font-size: 14px;
+    color: #3e3e3e;
+    margin: 10px 0px;
+  }
+  .goods {
+    background: #a30014;
+    border: 1px solid #a30014;
+  }
+  .details-title {
+    display: inline-block;
+    color: #6e6e6e;
+    font-size: 14px;
+    font-weight: bold;
+    margin-right: 13px;
+    width: 70px;
+    text-align: right;
+  }
+  .details-con {
+    color: #3e3e3e;
+    font-size: 14px;
+  }
+  .detailed-tab {
+    margin-left: 10px;
+    margin-top: 10px;
+  }
+  ::v-deep .el-form-item--medium .el-form-item__label {
+    color: #6e6e6e;
+    font-size: 14px;
+    font-weight: bold;
+  }
+  .warehouse {
+    display: block;
+    border-bottom: 1px solid #eaeefb;
+    padding: 10px 0;
+  }
+  .box-card {
+    .store-box {
+      width: 80%;
+      .store-box-span {
+        display: inline-block;
+        font-size: 14px;
+        height: 50px;
+        width: 50px;
+        text-align: center;
+        line-height: 50px;
+        color: #fff;
+        margin: 2px;
+      }
+    }
+  }
+  .vacant {
+    background: #3196fb;
+  }
+  .inUse {
+    background: #157a2c;
+  }
+  .invalid {
+    background: #cccccc;
+  }
+  .full {
+    background: #cc3300;
+  }
+
+  .maintain_equipment_info {
+    .maintain_equipment_info_title {
+      border-bottom: 1px solid #1890ff;
+      padding-bottom: 3px;
+      margin-bottom: 20px;
+      > span {
+        display: inline-block;
+        line-height: 16px;
+        border-left: 6px solid #1890ff;
+        padding-left: 6px;
+      }
+    }
+    .maintain_equipment_info_content {
+      padding: 0 30px;
+      .equipment_item {
+        border: 1px solid #ccc;
+        font-size: 14px;
+        padding: 15px;
+        margin-bottom: 30px;
+        .equipment_info {
+          display: flex;
+          flex-wrap: wrap;
+          border: 1px solid #ddd;
+          .item_info {
+            width: 33.33%;
+            height: 24px;
+            line-height: 24px;
+            display: flex;
+            .item_label {
+              width: 90px;
+              text-align: center;
+              background-color: #f2f2f2;
+              font-weight: 700;
+            }
+            .item_value {
+              border-bottom: 1px solid #f2f2f2;
+              flex: 1;
+              padding-left: 5px;
+            }
+            &:last-child {
+              width: 100%;
+              .item_value {
+                border: 0;
+              }
+            }
+          }
+        }
+        > p {
+          margin-top: 20px;
+          color: #797979;
+        }
+        .matter_info {
+          ::v-deep .el-table {
+            th.el-table__cell {
+              background-color: #f2f2f2;
+              padding: 0;
+            }
+            td.el-table__cell {
+              padding: 0;
+            }
+          }
+        }
+        .ruleMatters_box {
+          flex: 3;
+          height: 100%;
+          display: flex;
+          flex-direction: column;
+          .divider {
+            flex: 0 0 50px;
+            .title {
+              height: 35px;
+            }
+          }
+          .el-table {
+            overflow: auto;
+            .operationGuide_box {
+              width: 100%;
+              display: flex;
+              position: relative;
+              .left_content {
+                flex: 0 0 300px;
+                padding: 10px;
+                margin-right: 10px;
+                overflow-y: auto;
+              }
+              .line {
+                position: absolute;
+                top: -10px;
+                left: 300px;
+                bottom: -10px;
+                height: 110%;
+                width: 1px;
+                background-color: #ededed;
+              }
+              .right_content {
+                flex: 1;
+                padding: 10px;
+                overflow-y: auto;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  .execute_info {
+    margin: 30px 0;
+    .execute_info_title {
+      border-bottom: 1px solid #1890ff;
+      padding-bottom: 3px;
+      margin-bottom: 20px;
+      display: flex;
+      justify-content: space-between;
+      > span:first-child {
+        line-height: 16px;
+        border-left: 6px solid #1890ff;
+        padding-left: 6px;
+      }
+    }
+    .execute_row {
+      padding: 0 30px;
+      .column {
+        display: flex;
+        font-size: 14px;
+        margin-bottom: 20px;
+        .label {
+          // width: 110px;
+          text-align: center;
+          font-weight: 700;
+        }
+      }
+    }
+  }
+  .repair_notes {
+    .repair_notes_title {
+      border-bottom: 1px solid #1890ff;
+      padding-bottom: 3px;
+      margin-bottom: 20px;
+      > span {
+        display: inline-block;
+        line-height: 16px;
+        border-left: 6px solid #1890ff;
+        padding-left: 6px;
+      }
+    }
+    .repair_notes_equipment_item {
+      padding: 0 20px;
+      .equipment_item_tilte {
+        background-color: #f7f7f7;
+        height: 36px;
+        line-height: 36px;
+        .label {
+          font-weight: 700;
+        }
+      }
+      .main_info {
+        font-size: 14px;
+        margin-top: 15px;
+        > div {
+          margin-bottom: 10px;
+        }
+      }
+    }
+  }
+  .btnbox {
+    display: flex;
+    justify-content: center;
+  }
+  ::v-deep .el-button {
+    padding: 10px 20px;
+    margin-right: 10px;
+  }
+  .textbtnbox {
+    margin-top: 10px;
+    display: flex;
+    justify-content: center;
+  }
+</style>

+ 429 - 0
src/views/bpm/tickets/service/index.vue

@@ -0,0 +1,429 @@
+<!-- 点巡检工单 -->
+
+<template>
+  <div>
+    <div class="ele-body">
+      <el-card shadow="never">
+        <div class="filter-container">
+          <seekPage
+            :seekList="seekList"
+            :formLength="3"
+            @search="search"
+          ></seekPage>
+        </div>
+        <ele-pro-table
+          ref="table"
+          :columns="columns"
+          :datasource="datasource"
+          maxHeight="580"
+          :pageSize="20"
+        >
+          <!-- 操作列 -->
+          <template v-slot:action="{ row }">
+            <el-link
+              v-if="row.orderStatus == 0"
+              type="primary"
+              :underline="false"
+              icon="el-icon-edit"
+              @click="startExecuting(row)"
+            >
+              接收
+            </el-link>
+            <el-link
+              v-if="
+                row.orderStatus !== 3 &&
+                row.orderStatus !== 4 &&
+                row.orderStatus != 0
+              "
+              type="primary"
+              :underline="false"
+              icon="el-icon-edit"
+              @click="toSigningUpWork(row)"
+            >
+              报工
+            </el-link>
+            <el-link
+              v-if="
+                row.orderStatus !== 3 &&
+                row.orderStatus !== 4 &&
+                row.isGroup != 1
+              "
+              type="primary"
+              :underline="false"
+              icon="el-icon-edit"
+              @click="toRedeploy(row)"
+            >
+              转派
+            </el-link>
+          </template>
+        </ele-pro-table>
+      </el-card>
+    </div>
+
+    <!-- 转派弹窗 -->
+    <redeployOther ref="redeployOtherRef" @refresh="getData" />
+    <!-- 报工弹框 -->
+    <signingUpWork ref="signingUpWorkRef" @refresh="getData" />
+  </div>
+</template>
+<script>
+  import redeployOther from '../components/redeployOther.vue';
+  import signingUpWork from '../components/signingUpWork.vue';
+  import { ticketStatus, resultStatus } from '@/utils/dict/tickets';
+  import { getWorkOrderPage, getRule, startExecuting } from '@/api/tickets';
+  import pagenation from '@/components/Pagination';
+
+  // 修改
+  import { updateNotifyMessageReadByIdAPI } from '@/api/bpm/task';
+  import { mapGetters } from 'vuex';
+  export default {
+    components: {
+      pagenation,
+      redeployOther,
+      signingUpWork
+    },
+    data() {
+      return {
+        ruleNameList: [],
+        userId: '',
+        ticketStatus: [],
+        resultStatus,
+        //
+        addOrEditDialogFlag: false,
+
+        columns: [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 60,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+          {
+            prop: 'code',
+            label: '工单编号',
+            minWidth: '200',
+            align: 'center'
+          },
+          {
+            prop: 'planCode',
+            label: '计划单号',
+            minWidth: '200',
+            align: 'center'
+          },
+          {
+            prop: 'planName',
+            label: '名称',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'ruleName',
+            label: '规则名称',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'createUserName',
+            label: '创建人',
+            align: 'center',
+            minWidth: '150',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'createTime',
+            label: '创建时间',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'acceptTime',
+            label: '开始时间',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'finishTime',
+            label: '结束时间',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'planFinishTime',
+            label: '计划完成时间',
+            align: 'center',
+            minWidth: '180',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'isAbnormal',
+            label: '执行结果',
+            align: 'center',
+            showOverflowTooltip: true,
+            formatter: (_row, _column, cellValue) => {
+              return { 0: '缺陷', 1: '正常' }[_row.isAbnormal];
+            }
+          },
+          {
+            prop: 'orderStatus',
+            label: '状态',
+            align: 'center',
+            showOverflowTooltip: true,
+            formatter: (_row, _column, cellValue) => {
+              return ticketStatus.filter(
+                (item) => item.id == _row.orderStatus
+              )[0]?.label;
+            }
+          },
+          {
+            prop: 'practicalTime',
+            label: '实际工时',
+            align: 'center',
+            showOverflowTooltip: true,
+            formatter: (_row, _column, cellValue) => {
+              let _this = this;
+              return _this.time_interval(_row.acceptTime, _row.finishTime);
+            }
+          },
+
+          {
+            columnKey: 'action',
+            label: '操作',
+            minWidth: 200,
+            align: 'center',
+            slot: 'action',
+            fixed: 'right'
+          }
+        ],
+        searchForm: {
+          code: '',
+          orderStatus: '',
+          ruleId: '',
+          date: '',
+          startTime: '',
+          endTime: '',
+          type: 1,
+          isQueryTodo: 1,
+          executeUserId: ''
+        },
+        tableData: [],
+        size: 10,
+        page: 1,
+        total: 0
+      };
+    },
+    computed: {
+      ...mapGetters(['user']),
+      // 是否开启响应式布局
+      styleResponsive() {
+        return this.$store.state.theme.styleResponsive;
+      },
+      seekList() {
+        return [
+          {
+            label: '工单编号',
+            value: 'code',
+            type: 'input',
+            placeholder: ' '
+          },
+          {
+            label: '规则名称:',
+            value: 'ruleId',
+            type: 'select',
+            placeholder: '  ',
+            planList: this.ruleNameList.map((item) => {
+              return { label: item.name, value: item.id };
+            })
+          },
+          {
+            label: '状态',
+            value: 'orderStatus',
+            type: 'select',
+            planList: ticketStatus.map((item) => {
+              return { label: item.label, value: item.id };
+            }),
+            placeholder: ' '
+          }
+
+          // {
+          //   label: '开始结束时间:',
+          //   value: 'createTime',
+          //   type: 'date',
+          //   dateType: 'datetimerange',
+          //   placeholder: '',
+          //   width: 380,
+          //   labelWidth: '130px',
+          //   valueAr: ['startTime', 'endTime']
+          // }
+        ];
+      }
+    },
+    methods: {
+      //新增或修改模板
+      async handleAddOrEdit(row) {
+        await updateNotifyMessageReadByIdAPI([row.id]);
+        this.$refs.table.reload();
+      },
+      search(e) {
+        this.searchForm = e;
+        this.$refs.table.reload({ page: 1, where: e });
+      },
+
+      // 获取table数据
+      async datasource({ page, where, limit, ...row }) {
+        const res = await getWorkOrderPage({
+          ...where,
+          pageNum: page,
+          size: limit,
+          // executeUserId: this.userId,
+          userId: this.user.info.userId,
+          type: 7,
+          isQueryTodo: 1
+        });
+        console.log(res);
+        this.total = res.total;
+        this.$emit('recount');
+        return res;
+      },
+
+      // 获取规则名列表(设备维修)
+      async getRuleNameList() {
+        const res = await getRule({
+          status: 1,
+          type: 7,
+          pageNum: 1,
+          size: -1
+        });
+        if (res.list) {
+          this.ruleNameList = res.list || [];
+        }
+      },
+
+      // 转派
+      toRedeploy(row) {
+        this.$refs.redeployOtherRef.open(row);
+      },
+      // 报工
+      toSigningUpWork(row) {
+        this.$refs.signingUpWorkRef.open(row);
+      },
+      openDetail({ id }) {
+        this.$router.push({
+          path: '/tickets/service/detail',
+          query: {
+            id
+          }
+        });
+      },
+      getData() {
+        this.search(this.searchForm);
+      },
+      startExecuting(row) {
+        startExecuting({ id: row.id }).then((res) => {
+          this.getData();
+        });
+      },
+      // 计算实际工时
+      time_interval(dt1, dt2) {
+        if (!dt1 || !dt2) {
+          return '';
+        }
+        if (typeof dt1 == 'string') {
+          dt1 = new Date(dt1.replace(/-/, '/'));
+          dt2 = new Date(dt2.replace(/-/, '/'));
+        }
+        var res = dt2 - dt1;
+        if (isNaN(res)) throw Error('invalid dates arguments');
+        let re = res / (1000 * 60 * 60);
+
+        var h = parseInt(re);
+        var m = parseInt((re - h) * 60);
+        let result = '';
+        if (h) {
+          result += `${h} 小时`;
+        }
+        if (m) {
+          result += `${m} 分钟`;
+        }
+        return result;
+      }
+    },
+    created() {
+      this.userId = localStorage.getItem('userId');
+      this.getRuleNameList();
+      this.ticketStatus = ticketStatus.filter((item) => {
+        return [0, 2, 3].includes(item.id);
+      });
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  // 步骤条边线显示
+  // ::v-deep .el-step__head.is-process .el-step__icon.is-text {
+  //   border: none !important;
+  //   background: none !important;
+  // }
+  // ::v-deep .el-step:last-of-type .el-step__line {
+  //   display: block !important;
+  //   width: 3px !important;
+  // }
+  // ::v-deep .el-steps:last-child .el-step__line {
+  //   display: none !important;
+  // }
+  // .patrolInspection {
+  //   height: 100%;
+  //   width: 100%;
+  //   display: flex;
+  //   flex-direction: column;
+  //   .search {
+  //     flex: 0 0 50px;
+  //   }
+  //   .table {
+  //     flex: 1;
+  //     .el-table {
+  //       width: 100%;
+  //       display: flex;
+  //       flex-direction: column;
+  //     }
+  //   }
+  //   .table-footer {
+  //     flex: 0 0 30px;
+  //     display: flex;
+  //     justify-content: flex-end;
+  //   }
+  // }
+
+  // 修改
+  ::v-deep .el-card__body {
+    padding: 0;
+  }
+
+  .app-container {
+    background: #f0f3f3;
+    min-height: calc(100vh - 84px);
+  }
+
+  .zw-page-table {
+    background: #ffffff;
+    padding-top: 20px;
+  }
+
+  .pagination-wrap {
+    display: flex;
+    justify-content: flex-end;
+    padding: 10px 0;
+  }
+
+  .table {
+    width: 100%;
+    margin-top: 10px;
+  }
+</style>