Pārlūkot izejas kodu

feat(inspectionWork): 请样弹窗检测内容多选与虚拟表格自适应

- 选择类型检测内容支持多选,结果逗号拼接写回 qualityResultContent,提交时清理临时字段

- 虚拟表格列宽改 fr 自适应,内容允许折行,编码列保持单行

- 换班组时同步清空执行人名称
lihaiting 3 dienas atpakaļ
vecāks
revīzija
54aca10941

+ 35 - 12
src/views/inspectionWork/components/baseInfo.vue

@@ -596,14 +596,16 @@
         this.$set(this.form, 'executeUserId', '');
         // 换班组后执行人清空, 重新默认报工人(当前登录用户, 须在新班组成员内)
         this.$set(this.form, 'executeUserIdList', []);
+        this.$set(this.form, 'executeUserName', '');
         const userInfo = this.$store?.state?.user?.info;
         const reporter = (item.userVOList || []).find(
           (u) => u.id == userInfo?.userId
         );
         if (reporter) {
-          this.$set(this.form, 'executeUserIdList', [userInfo.userId]);
-          this.$set(this.form, 'executeUserName', userInfo.name);
-          this.$set(this.form, 'executeUserId', String(userInfo.userId));
+          // 用候选项自身的 id/name, 保证 el-option 的 value 类型一致, 回显和提交都不出错
+          this.$set(this.form, 'executeUserIdList', [reporter.id]);
+          this.$set(this.form, 'executeUserName', reporter.name);
+          this.$set(this.form, 'executeUserId', String(reporter.id));
         }
       },
       getCode() {
@@ -774,11 +776,26 @@
       //选择部门(搜索)
       searchDeptNodeClick(info, row) {
         this.form.executeUserId = '';
-        this.$set(this.form, 'executeUserName', ' item.name');
-        this.$set(this.form, 'executeUserIdList', '');
+        this.$set(this.form, 'executeUserName', '');
+        this.$set(this.form, 'executeUserIdList', []);
         if (info) {
           const params = { groupId: info };
-          this.getUserList(params);
+          this.getUserList(params).then(() => {
+            // 换部门后人员范围变化, 登录人在新部门人员列表内则重新默认执行人
+            const userInfo = this.$store?.state?.user?.info;
+            if (!userInfo || !userInfo.userId) {
+              return;
+            }
+            const hit = (this.executorList || []).find(
+              (u) => u.id == userInfo.userId
+            );
+            if (!hit) {
+              return;
+            }
+            this.$set(this.form, 'executeUserIdList', [hit.id]);
+            this.$set(this.form, 'executeUserName', hit.name);
+            this.$set(this.form, 'executeUserId', String(hit.id));
+          });
           this.form.executeDeptName = row.name;
         } else {
           this.form.executeDeptId = null;
@@ -824,9 +841,10 @@
               (item) => item.id == userInfo.userId
             );
             if (reporter) {
-              this.$set(this.form, 'executeUserIdList', [userInfo.userId]);
-              this.$set(this.form, 'executeUserName', userInfo.name);
-              this.$set(this.form, 'executeUserId', String(userInfo.userId));
+              // 取候选项自身 id/name, 与 el-option 的 value 类型完全一致
+              this.$set(this.form, 'executeUserIdList', [reporter.id]);
+              this.$set(this.form, 'executeUserName', reporter.name);
+              this.$set(this.form, 'executeUserId', String(reporter.id));
             } else {
               console.warn(
                 '[报工] 当前登录人不在执行班组成员中, 执行人无法默认为报工人',
@@ -835,9 +853,14 @@
               );
             }
           } else {
-            this.$set(this.form, 'executeUserIdList', [userInfo.userId]);
-            this.$set(this.form, 'executeUserName', userInfo.name);
-            this.$set(this.form, 'executeUserId', String(userInfo.userId));
+            const matched = (this.executorList || []).find(
+              (item) => item.id == userInfo.userId
+            );
+            const id = matched ? matched.id : userInfo.userId;
+            const name = matched ? matched.name : userInfo.name;
+            this.$set(this.form, 'executeUserIdList', [id]);
+            this.$set(this.form, 'executeUserName', name);
+            this.$set(this.form, 'executeUserId', String(id));
           }
         }
         // 执行部门: 未指定时默认当前登录用户所属公司(检验方案模式没有执行部门, 不处理)

+ 60 - 4
src/views/inspectionWork/components/sampleListDialog.vue

@@ -120,7 +120,30 @@
                     />
                   </div>
                   <div class="cell input-col">
+                    <!-- 选择类型: 检测内容 = 从检测项定义的候选项里多选, 结果写 qualityResultContent -->
+                    <el-select
+                      v-if="item.textType == 2"
+                      v-model="item.__selectedValues"
+                      multiple
+                      collapse-tags
+                      placeholder="请选择"
+                      style="width: 100%"
+                      :disabled="
+                        type == 'detail' ||
+                        (!pageName && props.row.correlationId)
+                      "
+                      @change="qualityContentSelectChange(item)"
+                    >
+                      <el-option
+                        v-for="opt in item.__selectOptions"
+                        :key="opt"
+                        :label="opt"
+                        :value="opt"
+                      >
+                      </el-option>
+                    </el-select>
                     <el-input
+                      v-else
                       :class="item.qualityResults === 2 ? 'warn' : ''"
                       v-model="item.qualityResultContent"
                       placeholder="请输入内容"
@@ -609,6 +632,19 @@
         }
         newTpl.forEach((el) => {
           if (!el.qualityResults) el.qualityResults = 1;
+          // 选择类型: 检测内容列渲染为多选下拉, 候选项 = 工单模板行自身
+          // defaultValue 按逗号拆分(该值由后端随模板接口返回); 已选初始值 =
+          // 检测内容(qualityResultContent) 已存的值, 与候选池求交集
+          if (el.textType == 2) {
+            const opts = String(el.defaultValue || '')
+              .split(',')
+              .filter((v) => v !== '');
+            el.__selectOptions = opts;
+            el.__selectedValues = (el.qualityResultContent
+              ? String(el.qualityResultContent).split(',')
+              : []
+            ).filter((v) => opts.includes(v));
+          }
         });
 
         this.$set(
@@ -662,6 +698,15 @@
         this.sourceMap = new Map();
         this.tableData = [];
       },
+      // 选择类型: 检测内容多选结果写回 qualityResultContent(逗号拼接, 提交不加新字段)
+      qualityContentSelectChange(item) {
+        this.$set(
+          item,
+          'qualityResultContent',
+          (item.__selectedValues || []).join(',')
+        );
+      },
+
       handleConfirm() {
         // 立刻关弹框(用户体验优先),耗时的清理 + emit 推迟到 raf
         this.visible = false;
@@ -676,7 +721,8 @@
             // 清理虚拟列表的辅助字段,避免污染返回数据
             const cleaned = this.tableData.map((s) => {
               const tpl = (s.qualitySampleTemplateList || []).map((t) => {
-                const { __vsKey, ...rest } = t;
+                const { __vsKey, __selectOptions, __selectedValues, ...rest } =
+                  t;
                 return rest;
               });
               return { ...s, qualitySampleTemplateList: tpl };
@@ -739,8 +785,9 @@
 
   .virtual-table-header,
   .virtual-row {
+    /* 自适应列宽: 编码/工艺参数加宽, 检测结果收窄到刚好放下下拉框 */
     display: grid;
-    grid-template-columns: 120px 120px 100px 100px 120px 220px 120px 360px 120px;
+    grid-template-columns: 1.5fr 1fr 0.7fr 1.5fr 1fr 2.2fr 0.9fr 1.8fr 1fr;
     box-sizing: border-box;
   }
 
@@ -790,8 +837,9 @@
       text-align: center;
       border-right: 1px solid #ebeef5;
       overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
+      /* 允许折行完整显示 */
+      white-space: normal;
+      word-break: break-all;
       display: flex;
       align-items: center;
       justify-content: center;
@@ -821,6 +869,14 @@
       }
     }
 
+    /* 两个编码列保持单行完整显示, 不折行 */
+    .cell:nth-child(1),
+    .cell:nth-child(4) {
+      white-space: nowrap;
+      font-size: 12px;
+      padding: 4px 2px;
+    }
+
     .cell.wide {
       padding: 4px 8px;
       min-width: 0;