gaoluyang
7 小时以前 b93657ca98a9f1ced3aacc255c3fa09b7d39cca4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
<template>
  <div>
    <el-dialog :title="operationType === 'add' ? '新增质控项目' : '编辑质控项目'" v-model="formDia"
               :close-on-click-modal="false"
               :close-on-press-escape="false"
               width="80%" @close="closeDia">
      <el-form :model="form" :rules="rules" ref="form" label-width="140px">
        <el-col :span="12">
          <el-form-item label="序号" prop="sortNo">
            <el-input-number v-model="form.sortNo" :min="1" style="width:100%" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="质控项目" prop="monitorProject">
            <el-input v-model="form.monitorProject" size="small" clearable></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="技术标准" prop="technicalStandardText">
            <el-input v-model="form.technicalStandardText" size="small" clearable placeholder="标准编号及名称;非检测类可填写程序文件或/" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="质控方式" prop="monitorWayList">
            <el-select v-model="form.monitorWayList" multiple filterable allow-create default-first-option
                       size="small" style="width: 100%" placeholder="可多选,也可输入其他方式">
              <el-option v-for="item in monitorWayOptions" :key="item" :label="item" :value="item" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="完成时限" prop="completionMonth">
            <el-date-picker v-model="form.completionMonth" type="month" value-format="YYYY-MM" format="YYYY.MM" style="width:100%" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="负责人" prop="responsibleUserId">
            <el-select v-model="form.responsibleUserId" filterable style="width:100%">
              <el-option v-for="item in userOptions" :key="item.id" :value="item.id" :label="item.name" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="事项类别" prop="itemKind">
            <el-select v-model="form.itemKind" style="width: 100%">
              <el-option label="非检测类" value="OTHER" />
              <el-option label="检测类" value="INSPECTION" />
            </el-select>
          </el-form-item>
        </el-col>
        <template v-if="form.itemKind === 'INSPECTION'">
          <el-col :span="12"><el-form-item label="检测标准" prop="standardMethodId">
            <el-select v-model="form.standardMethodId" filterable style="width: 100%" placeholder="请选择检测标准" @change="handleStandardChange">
              <el-option v-for="item in standardOptions" :key="item.id" :value="item.id" :label="`${item.code || ''} ${item.name || ''}`" />
            </el-select>
          </el-form-item></el-col>
          <el-col :span="12"><el-form-item label="原始记录模板" prop="templateIds">
            <el-select v-model="form.templateIds" multiple collapse-tags filterable style="width: 100%"
              :loading="templateBindingLoading" :disabled="!form.standardMethodId"
              :placeholder="form.standardMethodId ? '请选择原始记录模板' : '请先选择检测标准'"
              :no-data-text="form.standardMethodId ? '该检测标准暂未绑定原始记录模板' : '请先选择检测标准'">
              <el-option v-for="item in templateOptions" :key="item.id" :value="item.id" :label="item.name" />
            </el-select>
            <div v-if="form.standardMethodId && !templateBindingLoading && templateOptions.length === 0"
              style="font-size: 12px; line-height: 18px; color: var(--el-color-warning); margin-top: 4px;">
              该检测标准在标准库中尚未绑定原始记录模板,请先在标准库中完成绑定。
            </div>
          </el-form-item></el-col>
          <el-col :span="12"><el-form-item label="样品名称"><el-input v-model="form.sampleName" /></el-form-item></el-col>
          <el-col :span="12"><el-form-item label="样品规格"><el-input v-model="form.sampleSpec" /></el-form-item></el-col>
          <el-col :span="12"><el-form-item label="检测员"><el-select v-model="form.inspectorUserId" filterable style="width: 100%">
            <el-option v-for="item in userOptions" :key="item.id" :value="item.id" :label="item.name" />
          </el-select></el-form-item></el-col>
          <el-col :span="12"><el-form-item label="评价人"><el-select v-model="form.evaluatorUserId" filterable style="width: 100%">
            <el-option v-for="item in userOptions" :key="item.id" :value="item.id" :label="item.name" />
          </el-select></el-form-item></el-col>
          <el-col :span="12"><el-form-item label="任务截止日">
            <el-date-picker v-model="form.dueDate" type="date" value-format="YYYY-MM-DD" style="width: 100%" />
          </el-form-item></el-col>
        </template>
      </el-form>
      <template #footer><span  class="dialog-footer">
                    <el-button @click="closeDia">取 消</el-button>
                    <el-button type="primary" @click="submitForm" :loading="upLoad">确 定</el-button>
        </span></template>
    </el-dialog>
  </div>
</template>
 
<script>
import {
  addQualityMonitorDetail,
  updateQualityMonitorDetail
} from "@/api/cnas/process/ensureResults/qualityMonitor";
import { selectStandardMethodList } from '@/api/cnas/process/method/standardMethod';
import { selectStandardTemplatePageList } from '@/api/standard/model';
import { selectTemplateBindingsByStandardMethod } from '@/api/standard/standardLibrary';
import { selectUserCondition } from '@/api/performance/class';
 
export default {
  name: 'detailFormDialog',
  // import 引入的组件需要注入到对象中才能使用
  components: {},
  props: ['qualityMonitorId'],
  data() {
    // 这里存放数据
    return {
      formDia: false,
      // LMSY-CX30-2024《质量控制程序》4.1 规定的常用质量控制手段,可多选
      monitorWayOptions: [
        '人员比对', '设备比对', '方法比对', '盲样检测',
        '留样再测', '标准物质监控', '实验室间比对', '能力验证',
      ],
      form: {
        qualityMonitorDetailsId: '',
        sortNo: null,
        technicalStandardText: '',
        completionMonth: '',
        responsibleUserId: null,
        monitorPurpose: '',
        plannedTime: '',
        monitorProject: '',
        participant: '',
        budget: '',
        organization: '',
        monitorWay: '',
        monitorWayList: [],
        itemKind: 'OTHER',
        standardMethodId: null,
        templateId: null,
        templateIds: [],
        sampleName: '',
        sampleSpec: '',
        inspectorUserId: null,
        evaluatorUserId: null,
        dueDate: null,
      },
      standardOptions: [],
      allTemplateOptions: [],
      templateOptions: [],
      templateBindingLoading: false,
      userOptions: [],
      rules: {
        monitorProject: [{ required: true, message: '请输入质控项目', trigger: 'blur' }],
        technicalStandardText: [{ required: true, message: '请输入技术标准', trigger: 'blur' }],
        monitorWayList: [{ required: true, type: 'array', min: 1, message: '请选择质控方式', trigger: 'change' }],
        completionMonth: [{ required: true, message: '请选择完成时限', trigger: 'change' }],
        responsibleUserId: [{ required: true, message: '请选择负责人', trigger: 'change' }],
        templateIds: [{ required: true, type: 'array', min: 1, message: '请至少选择一个原始记录模板', trigger: 'change' }],
      },
      upLoad: false,
      operationType: '',
    };
  },
  // 方法集合
  methods: {
    openDia(type, row) {
      this.formDia = true
      this.operationType = type
      this.form.monitorWayList = []
      this.templateOptions = []
      this.allTemplateOptions = []
      this.templateBindingLoading = false
      selectStandardMethodList({ current: 1, size: 1000 }).then(res => { this.standardOptions = res.data?.records || res.data || [] })
      selectStandardTemplatePageList({ current: 1, size: 1000 }).then(res => { this.allTemplateOptions = res.data?.records || res.data || [] })
      selectUserCondition({ type: 1 }).then(res => { this.userOptions = res.data || [] })
      if (type === 'edit') {
        this.searchInfo(row)
        if (row.itemKind === 'INSPECTION' && row.standardMethodId) {
          this.loadBoundTemplates(row.standardMethodId, this.form.templateIds)
        }
      }
    },
    searchInfo (row) {
      const templateIds = row.templateIds
        ? String(row.templateIds).split(',').filter(Boolean).map(id => Number(id))
        : (row.templateId ? [Number(row.templateId)] : [])
      this.form = {
        ...row,
        itemKind: row.itemKind || 'OTHER',
        templateIds,
        monitorWayList: row.monitorWay ? String(row.monitorWay).split(/[、,,;;]/).map(item => item.trim()).filter(Boolean) : [],
      }
    },
    handleStandardChange(id) {
      const standard = this.standardOptions.find(item => Number(item.id) === Number(id))
      if (standard) this.form.technicalStandardText = `${standard.code || ''} ${standard.name || ''}`.trim()
      this.form.templateIds = []
      this.form.templateId = null
      // 和委托下单保持一致:选择检测标准后,只展示该标准在标准库中已绑定的原始记录模板
      this.loadBoundTemplates(id)
    },
    loadBoundTemplates(standardMethodId, selectedIds = null) {
      const currentIds = Array.isArray(selectedIds) ? selectedIds.map(Number) : null
      this.templateOptions = []
      if (currentIds === null) this.form.templateIds = []
      if (!standardMethodId) return
      this.templateBindingLoading = true
      selectTemplateBindingsByStandardMethod({ standardMethodId }).then(res => {
        const bound = (res.data || []).map(item => ({ id: Number(item.templateId), name: item.name }))
        this.templateOptions = bound
        if (currentIds === null) {
          // 新增或切换检测标准时,默认选中该标准已绑定的全部模板
          this.form.templateIds = bound.map(item => item.id)
          return
        }
        // 编辑时保留原选择;若模板后来被解绑,补充名称避免下拉框只显示 ID
        const boundIds = new Set(bound.map(item => item.id))
        currentIds.forEach(id => {
          if (!boundIds.has(id)) {
            const template = this.allTemplateOptions.find(item => Number(item.id) === id)
            if (template) this.templateOptions.push({ id: Number(template.id), name: template.name })
          }
        })
        this.form.templateIds = currentIds
      }).catch(() => {
        this.templateOptions = []
      }).finally(() => {
        this.templateBindingLoading = false
      })
    },
    buildEntity () {
      const entity = this.HaveJson(this.form)
      const templateIds = Array.isArray(this.form.templateIds)
        ? this.form.templateIds.map(id => Number(id)).filter(id => Number.isInteger(id) && id > 0)
        : []
      entity.templateIds = templateIds.join(',') || null
      entity.templateId = templateIds.length ? templateIds[0] : null
      entity.monitorWay = (this.form.monitorWayList || []).map(item => item.trim()).filter(Boolean).join('、')
      delete entity.monitorWayList
      entity.reviewerUserId = null
      return entity
    },
    // 提交表单
    submitForm () {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          if (this.form.itemKind === 'INSPECTION') {
            const required = ['standardMethodId','sampleName','inspectorUserId','evaluatorUserId','dueDate']
            if (required.some(key => !this.form[key])) {
              this.$message.warning('请补齐检测标准、模板、样品、检测员、评价人和任务截止日')
              return
            }
            if (!Array.isArray(this.form.templateIds) || !this.form.templateIds.length) {
              this.$message.warning('请至少选择一个原始记录模板')
              return
            }
            if (this.form.inspectorUserId === this.form.evaluatorUserId) {
              this.$message.warning('检测员不能同时担任评价人')
              return
            }
            if (this.form.dueDate.slice(0, 7) > this.form.completionMonth) {
              this.$message.warning('任务截止日不能晚于计划完成月份')
              return
            }
          }
          if (this.operationType === 'add') {
            this.handleAdd()
          } else {
            this.handleEdit()
          }
        }
      })
    },
    // 提交新增
    handleAdd () {
      let entity = this.buildEntity()
      entity.qualityMonitorId = this.qualityMonitorId
      this.upLoad = true
      addQualityMonitorDetail(entity).then(res => {
        this.upLoad = false
        this.$message.success('新增成功')
        this.closeDia()
      }).catch(err => {
        console.log('err---', err);
        this.upLoad = false
      })
    },
    // 提交修改
    handleEdit () {
      const entity = this.buildEntity()
      this.upLoad = true
      updateQualityMonitorDetail(entity).then(res => {
        this.upLoad = false
        this.$message.success('修改成功')
        this.closeDia()
      }).catch(err => {
        console.log('err---', err);
        this.upLoad = false
      })
    },
    // 关闭弹框
    closeDia () {
      this.$refs.form.resetFields();
      this.formDia = false
      this.$emit('closeDia')
    },
  }
};
</script>
 
<style scoped>
:deep(.el-dialog__body) {
  max-height: 720px;
  overflow-y: auto;
}
</style>