From f8219fe94a3299398836e111c23da9e1c8a3ced4 Mon Sep 17 00:00:00 2001
From: zzw <228544128@qq.com>
Date: 星期三, 07 十月 2026 17:17:11 +0800
Subject: [PATCH] feat: inline completion quality scoring

---
 emergency-repair-web/src/views/completion/CompletionList.vue |  104 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 80 insertions(+), 24 deletions(-)

diff --git a/emergency-repair-web/src/views/completion/CompletionList.vue b/emergency-repair-web/src/views/completion/CompletionList.vue
index 687ab32..f78944d 100644
--- a/emergency-repair-web/src/views/completion/CompletionList.vue
+++ b/emergency-repair-web/src/views/completion/CompletionList.vue
@@ -27,7 +27,7 @@
     </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>
@@ -59,17 +59,23 @@
       </el-table>
     </div>
 
-    <el-dialog title="rk_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(() => {
@@ -119,20 +146,26 @@
       }).catch(() => {})
     },
     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 })
     }
   }
@@ -142,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>

--
Gitblit v1.9.1