<!-- 设备校准记录弹窗(添加/查看),设备校准页与设备校准计划页共用 -->
|
<template>
|
<el-dialog :close-on-click-modal="false" :close-on-press-escape="false" v-model="visible" title="添加校准记录" top="5vh"
|
width="80%" @close="resetCalibrationRecord">
|
<div style="height: 70vh;overflow-y: auto;overflow-x: hidden;">
|
<h4>
|
<div style="display: flex;align-items: center;">
|
<span class="line"></span>
|
<span>添加设备校准记录</span>
|
</div>
|
</h4>
|
<el-form ref="calibrationRecord" :model="calibrationRecord" :rules="formRules" label-position="right"
|
label-width="120px">
|
<el-row>
|
<el-col :span="6">
|
<el-form-item label="校准服务机构:" prop="unitOfMeasure">
|
<el-select v-model="calibrationRecord.unitOfMeasure" :disabled="operationType === 'view'" clearable filterable
|
size="small" style="width: 100%">
|
<el-option v-for="name in calibrationServiceOptions" :key="name" :label="name" :value="name"></el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="8">
|
<el-form-item label="校准日期:" prop="calibrationDate">
|
<el-date-picker v-model="calibrationRecord.calibrationDate" :disabled="operationType === 'view'"
|
format="YYYY-MM-DD" placeholder="选择日期" size="small" style="width: 90%" type="date"
|
value-format="YYYY-MM-DD" @change="getNextCalibrationDate">
|
</el-date-picker>
|
</el-form-item>
|
</el-col>
|
<el-col :span="10">
|
<el-form-item label="下次校准日期:" label-width="140px">
|
<el-date-picker v-model="calibrationRecord.nextCalibrationDate" disabled format="YYYY-MM-DD"
|
placeholder="选择日期" size="small" style="width: 90%" type="date" value-format="YYYY-MM-DD">
|
</el-date-picker>
|
</el-form-item>
|
</el-col>
|
<el-col :span="6">
|
<el-form-item label="计量器具:" prop="calculatingApparatus">
|
<el-input v-model="calibrationRecord.calculatingApparatus" :disabled="operationType === 'view'"
|
size="small"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="8">
|
<el-form-item label="计量标准量程:" prop="standardRange">
|
<el-input v-model="calibrationRecord.standardRange" :disabled="operationType === 'view'" size="small"
|
style="width: 90%"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="10">
|
<el-form-item label="计量标准不确定度:" label-width="140px" prop="calibrationStandardUncertainty">
|
<el-input v-model="calibrationRecord.calibrationStandardUncertainty"
|
:disabled="operationType === 'view'" size="small" style="width: 90%"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="6">
|
<el-form-item label="所依据文件:" prop="byDocument">
|
<el-input v-model="calibrationRecord.byDocument" :disabled="operationType === 'view'"
|
size="small"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="8">
|
<el-form-item label="证书编号:" prop="certificateSerialNumber">
|
<el-input v-model="calibrationRecord.certificateSerialNumber" :disabled="operationType === 'view'"
|
size="small" style="width: 90%"></el-input>
|
</el-form-item>
|
</el-col>
|
<el-col :span="10">
|
<el-form-item label="状态:" label-width="140px" prop="status" required>
|
<el-radio-group v-model="calibrationRecord.status" :disabled="operationType === 'view'">
|
<el-radio value="0yes">合格</el-radio>
|
<el-radio value="1no">不合格</el-radio>
|
<el-radio value="2other">其他</el-radio>
|
</el-radio-group>
|
</el-form-item>
|
</el-col>
|
<el-col :span="6">
|
<el-form-item label="确认日期:">
|
<el-date-picker v-model="calibrationRecord.confirmDate" :disabled="operationType === 'view'"
|
format="YYYY-MM-DD HH:mm:ss" placeholder="选择日期" size="small" style="width: 100%" type="datetime"
|
value-format="YYYY-MM-DD HH:mm:ss">
|
</el-date-picker>
|
</el-form-item>
|
</el-col>
|
<el-col :span="17">
|
<el-form-item label="附件:" prop="fileName">
|
<el-input v-model="calibrationRecord.fileName"
|
:style="`width: ${operationType === 'add' ? '85%' : '100%'}`" disabled size="small">
|
<template #append><el-button v-if="operationType === 'add'" :icon="$icon('el-icon-delete-solid')"
|
@click="deleteFile"></el-button></template>
|
</el-input>
|
<el-upload v-if="operationType === 'add'" ref="upload" :action="action" :before-upload="beforeUpload"
|
:headers="uploadHeader" :limit="1" :on-error="onError" :on-success="handleSuccessUp"
|
:show-file-list="false" style="float: right;">
|
<el-button :loading="upLoading" size="small" style="position: relative; top: -4px;"
|
type="primary">附件上传
|
</el-button>
|
</el-upload>
|
</el-form-item>
|
</el-col>
|
<el-col :span="24">
|
<el-form-item label="备注:">
|
<el-input v-model="calibrationRecord.remark" :disabled="operationType === 'view'" :rows="3" size="small"
|
style="width: 96%" type="textarea"></el-input>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
<h4>
|
<span style="display: flex;align-items: center;">
|
<span class="line"></span><span>校准条目确认结果</span>
|
</span>
|
</h4>
|
<el-table ref="calibrateTable" :data="calibrateParams" border>
|
<el-table-column label="编号" type="index" width="60"></el-table-column>
|
<el-table-column label="计量参数" prop="measurementParameter"></el-table-column>
|
<el-table-column label="量程范围" prop="rangeOfMeasurement"></el-table-column>
|
<el-table-column label="最大允许误差" prop="maxPermissibleError"></el-table-column>
|
<el-table-column label="判定标准" prop="judgmentCriteria"></el-table-column>
|
<el-table-column label="是否校准" prop="isCalibration">
|
<template #header="scope">
|
<span class="required-span">* </span>是否校准
|
</template>
|
<template #default="scope">
|
<el-radio-group v-model="scope.row.isCalibration" :disabled="operationType === 'view'">
|
<el-radio value="0yes">是</el-radio>
|
<el-radio value="1no">否</el-radio>
|
</el-radio-group>
|
</template>
|
</el-table-column>
|
<el-table-column label="判定结果" min-width="140" prop="result">
|
<template #header="scope">
|
<span class="required-span">* </span>判定结果
|
</template>
|
<template #default="scope">
|
<el-radio-group v-model="scope.row.result" :disabled="operationType === 'view'" @change="checkRadio()">
|
<el-radio value="0yes">合格</el-radio>
|
<el-radio value="1no">不合格</el-radio>
|
<el-radio value="2other">其他</el-radio>
|
</el-radio-group>
|
</template>
|
</el-table-column>
|
<el-table-column label="单项结果说明" prop="singleResultStatement">
|
<template #default="scope">
|
<el-input v-model="scope.row.singleResultStatement" :disabled="operationType === 'view'"
|
size="small"></el-input>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
<template #footer><span class="dialog-footer">
|
<el-button v-if="operationType === 'add'" @click="visible = false">取 消</el-button>
|
<el-button v-if="operationType === 'view'" @click="visible = false">关 闭</el-button>
|
<el-button v-if="operationType === 'add'" :loading="addRecordLoading" type="primary" @click="addRecord">确
|
定</el-button>
|
</span></template>
|
</el-dialog>
|
</template>
|
|
<script>
|
import {
|
showDeviceMetricsCopy,
|
deleteCNASFile,
|
selectDeviceMetric,
|
addOrUpdateDeviceMetricRecord,
|
getDeviceById
|
} from '@/api/cnas/resourceDemand/device.js'
|
import dayjs from 'dayjs'
|
import { selectQualifiedSupplierManagementPage } from '@/api/cnas/externalService/supplierManage/supplierManage'
|
import { mapGetters } from "@/utils/store-compat";
|
export default {
|
name: "calibration-record-dia",
|
data() {
|
return {
|
visible: false,
|
deviceId: null,
|
operationType: '',
|
calibrationCycle: 12,
|
calibrateParams: [],
|
calibrateParamsLoading: false,
|
addRecordLoading: false,
|
upLoading: false,
|
qualifiedSupplierNames: [],
|
calibrationRecord: {
|
unitOfMeasure: '', // 计量单位
|
calibrationDate: null, // 校准日期
|
nextCalibrationDate: null, // 下次校准日期
|
calculatingApparatus: '', // 计量器具
|
confirmDate: null, // 确认日期
|
standardRange: '', // 计量标准量程
|
calibrationStandardUncertainty: '', // 计量标准不确定度
|
byDocument: '', // 依据文件
|
certificateSerialNumber: '', // 证书编号
|
status: '', // 状态
|
remark: '', // 备注
|
systemFileName: '', //
|
fileName: '', //
|
},
|
formRules: {
|
unitOfMeasure: [{ required: true, message: '请选择校准服务机构', trigger: 'change' }],
|
calibrationDate: [{ required: true, message: '请选择校准日期', trigger: 'change' }],
|
calculatingApparatus: [{ required: true, message: '请输入计量器具', trigger: 'blur' }],
|
standardRange: [{ required: true, message: '请输入计量标准量程', trigger: 'blur' }],
|
calibrationStandardUncertainty: [{ required: true, message: '请输入计量标准不确定度', trigger: 'blur' }],
|
byDocument: [{ required: true, message: '请输入所依据文件', trigger: 'blur' }],
|
status: [{ required: true, message: '请选择状态', trigger: 'change' }],
|
},
|
}
|
},
|
computed: {
|
// 校准服务机构下拉选项(合格供应商 + 当前值兜底)
|
calibrationServiceOptions() {
|
const list = this.qualifiedSupplierNames.slice();
|
const value = this.calibrationRecord.unitOfMeasure;
|
if (value && list.indexOf(value) === -1) list.push(value);
|
return list;
|
},
|
...mapGetters(["nickName"]),
|
action() {
|
return this.javaApi + '/personBasicInfo/saveCNASFile'
|
}
|
},
|
mounted() {
|
this.obtainQualifiedSupplierList()
|
},
|
methods: {
|
// 打开弹窗:deviceId 设备id;type add新增/view查看;row 查看时的记录行
|
open(deviceId, type, row) {
|
this.deviceId = deviceId
|
this.operationType = type
|
if (type === 'view' && row) {
|
showDeviceMetricsCopy({ id: row.id, type: 'calibrate' }).then(res => {
|
this.calibrateParams = res.data
|
})
|
this.calibrationRecord = { ...row }
|
} else {
|
this.getDeviceCycle()
|
this.getXmsg()
|
}
|
this.visible = true
|
},
|
// 拉取合格供应商列表(校准服务机构下拉选项)
|
obtainQualifiedSupplierList() {
|
selectQualifiedSupplierManagementPage({ current: 1, size: 999 }).then(res => {
|
if (res.code === 200) {
|
const rows = (res.data && res.data.records) || [];
|
this.qualifiedSupplierNames = [...new Set(rows.map(r => r.supplierName).filter(Boolean))];
|
}
|
});
|
},
|
//状态判定
|
checkRadio() {
|
let resultList = this.calibrateParams.map(ele => ele.result)
|
if (resultList && resultList.filter(ele => ele == '1no').length > 0) {
|
this.calibrationRecord.status = '1no'
|
} else if (resultList && resultList.filter(ele => ele == '2other').length == resultList.length) {
|
this.calibrationRecord.status = '2other'
|
} else if (resultList && resultList.filter(ele => ele == '0yes').length == resultList.length) {
|
this.calibrationRecord.status = '0yes'
|
}
|
},
|
// 查询设备校准周期(月),与后端滚动设备档案日期的规则保持一致
|
getDeviceCycle() {
|
if (!this.deviceId) {
|
return
|
}
|
getDeviceById({ deviceId: this.deviceId }).then(res => {
|
const cycle = parseInt(res.data && res.data.calibrationDate)
|
this.calibrationCycle = cycle > 0 ? cycle : 12
|
}).catch(() => {
|
this.calibrationCycle = 12
|
})
|
},
|
// 下次校准日期 = 校准日期 + 校准周期(月)
|
getNextCalibrationDate(val) {
|
if (!val) {
|
this.calibrationRecord.nextCalibrationDate = null
|
return
|
}
|
const cycle = parseInt(this.calibrationCycle)
|
const months = cycle > 0 ? cycle : 12
|
this.calibrationRecord.nextCalibrationDate = dayjs(val).add(months, 'month').format('YYYY-MM-DD')
|
},
|
// 获取设备校准参数(校准条目)
|
async getXmsg() {
|
this.calibrateParamsLoading = true
|
try {
|
await selectDeviceMetric({ deviceId: this.deviceId, type: 'calibrate' }).then(res => {
|
if (res.code == 200) {
|
this.calibrateParams = res.data
|
}
|
this.calibrateParamsLoading = false
|
})
|
} catch (e) {
|
console.log('getXmsg---', e)
|
this.calibrateParamsLoading = false
|
}
|
},
|
addRecord() {
|
this.$refs['calibrationRecord'].validate((valid) => {
|
if (valid) {
|
try {
|
if (this.calibrateParams.some(m => !m.isCalibration)) {
|
this.$message.error('请选择是否校准')
|
return
|
}
|
if (!this.calibrateParams.every(m => m.result)) {
|
this.$message.error('请选择判定结果')
|
return
|
}
|
this.addRecordLoading = true
|
// 只回传明细需要的字段:源行带主键 id/deviceId 会覆盖历史条目,creationTime 格式也与明细表不兼容
|
const deviceMetricsCopyList = this.calibrateParams.map(item => ({
|
measurementParameter: item.measurementParameter,
|
rangeOfMeasurement: item.rangeOfMeasurement,
|
maxPermissibleError: item.maxPermissibleError,
|
judgmentCriteria: item.judgmentCriteria,
|
createdBy: item.createdBy,
|
isCalibration: item.isCalibration,
|
result: item.result,
|
singleResultStatement: item.singleResultStatement,
|
type: item.type
|
}))
|
// 后端日期字段要求 yyyy-MM-dd HH:mm:ss,日期控件只给到 yyyy-MM-dd
|
const payload = {
|
...this.calibrationRecord,
|
deviceId: this.deviceId,
|
createUser: this.nickName,
|
type: 'calibrate',
|
deviceMetricsCopyList
|
}
|
if (payload.calibrationDate && payload.calibrationDate.length === 10) {
|
payload.calibrationDate += ' 00:00:00'
|
}
|
if (payload.nextCalibrationDate && payload.nextCalibrationDate.length === 10) {
|
payload.nextCalibrationDate += ' 00:00:00'
|
}
|
addOrUpdateDeviceMetricRecord(payload).then(res => {
|
if (res.code == 200) {
|
this.$message.success('添加成功')
|
this.visible = false
|
this.$emit('success')
|
}
|
this.addRecordLoading = false
|
}).catch(() => {
|
this.addRecordLoading = false
|
})
|
} catch (e) {
|
console.log('addRecord---', e)
|
this.addRecordLoading = false
|
}
|
} else {
|
this.$message.warning('有必填项未填');
|
}
|
})
|
},
|
resetCalibrationRecord() {
|
this.$refs.calibrationRecord.resetFields()
|
},
|
// 上传附件
|
handleSuccessUp(response, file) {
|
if (response.code == 200) {
|
// 在保存赋值新文件
|
this.calibrationRecord.fileName = file.name
|
this.calibrationRecord.systemFileName = response.data
|
this.upLoading = false;
|
} else {
|
this.upLoading = false;
|
this.$message.error(response.message)
|
}
|
},
|
beforeUpload(file) {
|
if (file.size > 1024 * 1024 * 10) {
|
this.$message.error('上传文件不超过10M');
|
this.$refs.upload.clearFiles()
|
return false;
|
} else {
|
this.upLoading = true;
|
return true;
|
}
|
},
|
onError(err, file, fileList) {
|
this.upLoading = false
|
this.$message.error('上传失败')
|
this.$refs.upload.clearFiles()
|
},
|
deleteFile() {
|
this.$confirm('此操作将永久删除文件, 是否继续?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
deleteCNASFile({ fileName: this.calibrationRecord.systemFileName }).then(res => {
|
if (res.code == 200) {
|
this.calibrationRecord.fileName = ''
|
this.calibrationRecord.systemFileName = ''
|
this.$refs.upload.clearFiles()
|
this.$message.success('删除成功!')
|
}
|
})
|
}).catch((err) => {
|
console.log('err----', err)
|
this.$message({
|
type: 'info',
|
message: '已取消删除'
|
});
|
});
|
},
|
},
|
watch: {
|
visible(newVal) {
|
if (newVal === false) {
|
this.calibrateParams = []
|
this.calibrationRecord = {
|
unitOfMeasure: '', // 计量单位
|
calibrationDate: null, // 校准日期
|
nextCalibrationDate: null, // 下次校准日期
|
calculatingApparatus: '', // 计量器具
|
standardRange: '', // 计量标准量程
|
calibrationStandardUncertainty: '', // 计量标准不确定度
|
byDocument: '', // 依据文件
|
certificateSerialNumber: '', // 证书编号
|
status: '', // 状态
|
remark: '', // 备注
|
}
|
}
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
h4 {
|
font-weight: 400;
|
font-size: 16px;
|
display: flex;
|
justify-content: space-between;
|
margin: 10px 0;
|
}
|
|
h4 .line {
|
display: inline-block;
|
width: 3px;
|
height: 16px;
|
background: var(--el-color-primary);
|
margin-right: 4px;
|
}
|
</style>
|