zzw
13 小时以前 f8219fe94a3299398836e111c23da9e1c8a3ced4
emergency-repair-web/src/views/completion/CompletionList.vue
@@ -3,7 +3,7 @@
    <div class="page-title">
      <div>
        <h2>完工情况处理</h2>
        <p>每一行代表一张派工单,只允许勾选一行;完工状态由业务按钮维护</p>
        <p>每一行代表一张派工单,只允许勾选一行;点“完工”只更新完工状态,完工信息由承修单位用户另行填报</p>
      </div>
      <el-button icon="el-icon-refresh" @click="load">刷新</el-button>
    </div>
@@ -19,15 +19,15 @@
    </div>
    <div class="toolbar action-toolbar">
      <el-button type="success" icon="el-icon-finished" :disabled="!selectedRow || selectedRow.completionStatus === 'COMPLETED'" @click="goCompletion">完工</el-button>
      <el-button type="success" icon="el-icon-finished" :disabled="!selectedRow || selectedRow.completionStatus === 'COMPLETED'" @click="setStatus('COMPLETED')">完工</el-button>
      <el-button type="primary" icon="el-icon-time" :disabled="!canSetStatus" @click="setStatus('WAIT_TEST')">完工待试验</el-button>
      <el-button icon="el-icon-refresh-left" :disabled="!canSetStatus" @click="setStatus('UNFINISHED')">未完工</el-button>
      <el-button type="warning" icon="el-icon-box" :disabled="!canSetStatus" @click="setStatus('WAIT_PARTS')">待备件</el-button>
      <el-button type="primary" plain icon="el-icon-star-on" :disabled="!selectedRow" @click="openScore">T员评分</el-button>
      <el-button type="primary" plain icon="el-icon-star-on" :disabled="!selectedRow" @click="openScore">rk_T员评分</el-button>
    </div>
    <div class="table-panel">
      <el-table :data="rows" border stripe height="calc(100vh - 325px)" highlight-current-row @current-change="selectedRow = $event">
      <el-table :data="rows" border stripe :height="scorePanelVisible ? 'calc(100vh - 515px)' : 'calc(100vh - 325px)'" highlight-current-row @current-change="onCurrentChange">
        <el-table-column width="46" align="center">
          <template slot-scope="{ row }"><el-radio v-model="selectedId" :label="row.id" @change="selectRow(row)"><span></span></el-radio></template>
        </el-table-column>
@@ -35,15 +35,15 @@
        <el-table-column prop="completionStatus" label="完工状态" width="115" fixed>
          <template slot-scope="{ row }"><el-tag size="mini" :type="completionMeta(row.completionStatus).type">{{ completionMeta(row.completionStatus).text }}</el-tag></template>
        </el-table-column>
        <el-table-column prop="xNo" label="X号" width="64"></el-table-column>
        <el-table-column prop="equipmentName" label="装备名称" min-width="210" show-overflow-tooltip></el-table-column>
        <el-table-column prop="xNo" label="rk_X号" width="64"></el-table-column>
        <el-table-column prop="equipmentName" label="设备名称" min-width="210" show-overflow-tooltip></el-table-column>
        <el-table-column prop="contractorName" label="派单单位" min-width="160"></el-table-column>
        <el-table-column prop="engineeringMajor" label="工程专业" width="100"></el-table-column>
        <el-table-column prop="teamMajor" label="T队专业" width="100"></el-table-column>
        <el-table-column prop="teamMajor" label="rk_T队专业" width="100"></el-table-column>
        <el-table-column prop="parentSystem" label="所属上级系统" min-width="130"></el-table-column>
        <el-table-column prop="reportUnit" label="上报单位" min-width="120"></el-table-column>
        <el-table-column prop="reportDate" label="上报时间" width="110"></el-table-column>
        <el-table-column prop="reviewTime" label="XCB审核时间" width="160">
        <el-table-column prop="reviewTime" label="rk_XCB审核时间" width="160">
          <template slot-scope="{ row }">{{ formatTime(row.reviewTime) }}</template>
        </el-table-column>
        <el-table-column prop="owner" label="负责人" width="90"></el-table-column>
@@ -59,17 +59,23 @@
      </el-table>
    </div>
    <el-dialog title="T员评分" :visible.sync="scoreVisible" width="520px" append-to-body>
      <el-form :model="scoreForm" label-width="100px">
        <el-form-item label="派工单"><b>{{ scoreForm.workOrderNo }}</b></el-form-item>
        <el-form-item label="修后质量评分"><el-rate v-model="scoreForm.score" show-text :texts="['很差','较差','一般','良好','优秀']"></el-rate></el-form-item>
        <el-form-item label="修后质量意见"><el-input v-model="scoreForm.opinion" type="textarea" :rows="3"></el-input></el-form-item>
    <div v-if="scorePanelVisible" class="score-panel">
      <div class="score-panel-title">
        <span>rk_T员评分</span>
        <b>{{ scoreForm.workOrderNo }}</b>
        <div class="spacer"></div>
        <el-button size="small" @click="closeScore">关闭</el-button>
        <el-button size="small" type="primary" :loading="saving" @click="saveScore">保存评分</el-button>
      </div>
      <el-form :model="scoreForm" label-width="110px" class="score-form">
        <el-form-item label="修后质量评分">
          <el-rate v-model="scoreForm.score"></el-rate>
        </el-form-item>
        <el-form-item label="修后质量意见">
          <el-input v-model="scoreForm.opinion" type="textarea" :rows="4" placeholder="请填写修后质量意见"></el-input>
        </el-form-item>
      </el-form>
      <template slot="footer">
        <el-button @click="scoreVisible = false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="saveScore">保存评分</el-button>
      </template>
    </el-dialog>
    </div>
  </div>
</template>
<script>
@@ -85,9 +91,9 @@
      status: '',
      selectedId: null,
      selectedRow: null,
      scoreVisible: false,
      scorePanelVisible: false,
      saving: false,
      scoreForm: { id: null, workOrderNo: '', score: 5, opinion: '' }
      scoreForm: { id: null, workOrderNo: '', score: 0, opinion: '' }
    }
  },
  computed: {
@@ -102,13 +108,34 @@
    load() {
      api.get('/work-orders', { params: { keyword: this.keyword, status: this.status } }).then(res => {
        this.rows = res.data || []
        if (this.selectedId && !this.rows.some(item => item.id === this.selectedId)) {
        const current = this.rows.find(item => item.id === this.selectedId)
        if (current) {
          this.selectedRow = current
          if (this.scorePanelVisible) this.fillScoreForm(current)
        } else {
          this.selectedId = null
          this.selectedRow = null
          this.scorePanelVisible = false
        }
      })
    },
    selectRow(row) { this.selectedRow = row },
    onCurrentChange(row) {
      if (row) this.selectRow(row)
    },
    selectRow(row) {
      if (!row) return
      this.selectedId = row.id
      this.selectedRow = row
      if (this.scorePanelVisible) this.fillScoreForm(row)
    },
    fillScoreForm(row) {
      this.scoreForm = {
        id: row.id,
        workOrderNo: row.workOrderNo,
        score: row.score || 0,
        opinion: row.qualityOpinion || ''
      }
    },
    setStatus(status) {
      const action = this.completionMeta(status).text
      this.$confirm(`确定将 ${this.selectedRow.workOrderNo} 设置为“${action}”吗?`, '状态设置').then(() => {
@@ -118,24 +145,27 @@
        this.load()
      }).catch(() => {})
    },
    goCompletion() {
      this.$router.push({ path: '/completion/report', query: { workOrderId: this.selectedRow.id } })
    },
    openScore() {
      this.scoreForm = {
        id: this.selectedRow.id,
        workOrderNo: this.selectedRow.workOrderNo,
        score: this.selectedRow.score || 5,
        opinion: this.selectedRow.qualityOpinion || ''
      }
      this.scoreVisible = true
      this.fillScoreForm(this.selectedRow)
      this.scorePanelVisible = true
    },
    closeScore() {
      this.scorePanelVisible = false
    },
    saveScore() {
      if (!this.scoreForm.score) {
        this.$message.warning('请选择修后质量评分')
        return
      }
      this.saving = true
      api.post('/work-orders/score', this.scoreForm).then(() => {
        const row = this.rows.find(item => item.id === this.scoreForm.id)
        if (row) {
          row.score = this.scoreForm.score
          row.qualityOpinion = this.scoreForm.opinion
          this.selectedRow = row
        }
        this.$message.success('评分已写入派工单')
        this.scoreVisible = false
        this.load()
      }).finally(() => { this.saving = false })
    }
  }
@@ -145,4 +175,27 @@
.action-toolbar { background: #f8fafc; }
.selection-tip { color: #6d7f91; font-size: 13px; }
.el-radio ::v-deep .el-radio__label { display: none; }
.score-panel {
  margin-top: 12px;
  padding: 12px 14px 4px;
  border: 1px solid #dce4ec;
  border-radius: 4px;
  background: #fff;
}
.score-panel-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid #edf1f5;
  color: #31465d;
}
.score-panel-title b { color: #1769aa; }
.score-panel-title .spacer { flex: 1; }
.score-form ::v-deep .el-rate__icon {
  margin-right: 8px;
  font-size: 34px;
}
.score-form ::v-deep .el-textarea__inner { min-height: 96px; }
</style>