| | |
| | | <template> |
| | | <el-dialog |
| | | title="新增检测数据" |
| | | :title="isEdit ? '编辑检测数据' : '新增检测数据'" |
| | | :visible.sync="dialogVisible" |
| | | width="60%" |
| | | :close-on-click-modal="false" |
| | |
| | | > |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="检测样编号" prop="sampleCode"> |
| | | <el-form-item label="数据编号" prop="dataCode"> |
| | | <el-input |
| | | v-model="form.sampleCode" |
| | | placeholder="请输入检测样编号" |
| | | v-model="form.dataCode" |
| | | placeholder="请输入数据编号" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="检测数据" prop="testData"> |
| | | <el-form-item label="检测数据" prop="dataTitle"> |
| | | <el-input |
| | | v-model="form.testData" |
| | | v-model="form.dataTitle" |
| | | placeholder="请输入检测数据" |
| | | /> |
| | | </el-form-item> |
| | |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="检测类型" prop="testTypes"> |
| | | <el-checkbox-group v-model="form.testTypes"> |
| | | <el-checkbox label="photo">拍照</el-checkbox> |
| | | <el-checkbox label="spectrum">图谱</el-checkbox> |
| | | <el-form-item label="检测类型" prop="dataType"> |
| | | <el-checkbox-group v-model="form.dataType"> |
| | | <el-checkbox label="1">拍照</el-checkbox> |
| | | <el-checkbox label="2">图谱</el-checkbox> |
| | | </el-checkbox-group> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | :on-change="handlePhotoChange" |
| | | > |
| | | <i class="el-icon-plus"></i> |
| | | <!-- <div class="el-upload__tip" slot="tip">支持 jpg、png 格式文件</div> --> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | visible: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | isEdit: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | isIPad: /iPad/i.test(navigator.userAgent), |
| | | form: { |
| | | sampleCode: "", |
| | | testData: "", |
| | | testTypes: ["photo"], // 默认选中拍照 |
| | | dataCode: "", |
| | | dataTitle: "", |
| | | dataType: ["1"], |
| | | dataFiles: "", |
| | | dataPictures: "", |
| | | photos: [], |
| | | spectrums: [] |
| | | }, |
| | | rules: { |
| | | sampleCode: [ |
| | | { required: true, message: "请输入检测样编号", trigger: "blur" } |
| | | dataCode: [ |
| | | { required: true, message: "请输入数据编号", trigger: "blur" } |
| | | ], |
| | | testData: [ |
| | | dataTitle: [ |
| | | { required: true, message: "请输入检测数据", trigger: "blur" } |
| | | ], |
| | | testTypes: [ |
| | | dataType: [ |
| | | { |
| | | type: 'array', |
| | | required: true, |
| | |
| | | message: "请上传检测照片", |
| | | trigger: "change", |
| | | validator: (rule, value, callback) => { |
| | | if (this.form.testTypes.includes('photo') && (!this.photoList || !this.photoList.length)) { |
| | | if (this.form.dataType.includes('1') && (!this.photoList || !this.photoList.length)) { |
| | | callback(new Error('请上传检测照片')); |
| | | } else { |
| | | callback(); |
| | |
| | | message: "请上传检测图谱", |
| | | trigger: "change", |
| | | validator: (rule, value, callback) => { |
| | | if (this.form.testTypes.includes('spectrum') && (!this.spectrumList || !this.spectrumList.length)) { |
| | | if (this.form.dataType.includes('2') && (!this.spectrumList || !this.spectrumList.length)) { |
| | | callback(new Error('请上传检测图谱')); |
| | | } else { |
| | | callback(); |
| | |
| | | } |
| | | }, |
| | | showPhotoUpload() { |
| | | return this.form.testTypes.includes('photo'); |
| | | return this.form.dataType.includes('1'); |
| | | }, |
| | | showSpectrumUpload() { |
| | | return this.form.testTypes.includes('spectrum'); |
| | | return this.form.dataType.includes('2'); |
| | | } |
| | | }, |
| | | methods: { |
| | | setFormData(data) { |
| | | console.log('data',data) |
| | | |
| | | // 设置基础表单数据 |
| | | this.form.sampleCode = data.sampleCode; |
| | | this.form.testData = data.testData; |
| | | this.form.testTypes = data.testTypes; |
| | | this.form.dataCode = data.dataCode; |
| | | this.form.dataTitle = data.dataTitle; |
| | | // 处理 dataType,确保它是数组格式 |
| | | this.form.dataType = Array.isArray(data.dataType) ? data.dataType : (data.dataType ? data.dataType.split(',') : []); |
| | | |
| | | // 设置照片列表 |
| | | if (data.photos && data.photos.length) { |
| | | this.photoList = data.photos.map(photo => ({ |
| | | name: photo.name, |
| | | url: photo.url, |
| | | status: 'success' |
| | | })); |
| | | if (data.dataPictures) { |
| | | try { |
| | | const pictures = typeof data.dataPictures === 'string' ? JSON.parse(data.dataPictures) : data.dataPictures; |
| | | this.photoList = pictures.map(photo => ({ |
| | | name: photo.name, |
| | | url: photo.url, |
| | | status: 'success' |
| | | })); |
| | | } catch (e) { |
| | | console.error('解析照片数据失败:', e); |
| | | this.photoList = []; |
| | | } |
| | | } else { |
| | | this.photoList = []; |
| | | } |
| | | |
| | | // 设置图谱列表 |
| | | if (data.spectrums && data.spectrums.length) { |
| | | this.spectrumList = data.spectrums.map(spectrum => ({ |
| | | name: spectrum.name, |
| | | url: spectrum.url, |
| | | status: 'success' |
| | | })); |
| | | if (data.dataFiles) { |
| | | try { |
| | | const files = typeof data.dataFiles === 'string' ? JSON.parse(data.dataFiles) : data.dataFiles; |
| | | this.spectrumList = files.map(file => ({ |
| | | name: file.name, |
| | | url: file.url, |
| | | status: 'success' |
| | | })); |
| | | } catch (e) { |
| | | console.error('解析图谱数据失败:', e); |
| | | this.spectrumList = []; |
| | | } |
| | | } else { |
| | | this.spectrumList = []; |
| | | } |
| | |
| | | this.photoList = []; |
| | | this.spectrumList = []; |
| | | this.form = { |
| | | sampleCode: "", |
| | | testData: "", |
| | | testTypes: ["photo"], |
| | | dataCode: "", |
| | | dataTitle: "", |
| | | dataType: ["1"], |
| | | dataFiles: "", |
| | | dataPictures: "", |
| | | photos: [], |
| | | spectrums: [] |
| | | }; |
| | |
| | | if (valid) { |
| | | const submitData = { |
| | | ...this.form, |
| | | photos: this.photoList, |
| | | spectrums: this.spectrumList |
| | | // 确保 dataType 在提交时转换为字符串 |
| | | dataType: Array.isArray(this.form.dataType) ? this.form.dataType.join(',') : this.form.dataType, |
| | | dataFiles: JSON.stringify(this.spectrumList), |
| | | dataPictures: JSON.stringify(this.photoList) |
| | | }; |
| | | this.$emit("success", submitData); |
| | | } |
| | | }); |
| | | }, |
| | | handlePhotoChange(file, fileList) { |
| | | this.photoList = fileList; |
| | | // 模拟上传成功 |
| | | const mockFile = { |
| | | name: file.name || '测试图片.jpg', |
| | | url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg', |
| | | status: 'success' |
| | | }; |
| | | this.photoList = [...this.photoList, mockFile]; |
| | | this.$refs.form.validateField('photos'); |
| | | }, |
| | | handleSpectrumChange(file, fileList) { |
| | | this.spectrumList = fileList; |
| | | // 模拟上传成功 |
| | | const mockFile = { |
| | | name: file.name || '测试图谱.pdf', |
| | | url: 'https://example.com/test.pdf', |
| | | status: 'success' |
| | | }; |
| | | this.spectrumList = [...this.spectrumList, mockFile]; |
| | | this.$refs.form.validateField('spectrums'); |
| | | }, |
| | | handleSpectrumRemove(file) { |
| | |
| | | }, |
| | | // iPad 相关方法 |
| | | handleIPadPhoto() { |
| | | // TODO: 调用 iPad 拍照功能 |
| | | console.log('调用 iPad 拍照功能'); |
| | | // 模拟 iPad 拍照功能 |
| | | const mockFile = { |
| | | name: 'iPad拍照.jpg', |
| | | url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg', |
| | | status: 'success' |
| | | }; |
| | | this.photoList = [...this.photoList, mockFile]; |
| | | this.$refs.form.validateField('photos'); |
| | | }, |
| | | handleIPadUpload() { |
| | | // TODO: 调用 iPad 上传功能 |
| | | console.log('调用 iPad 上传功能'); |
| | | // 模拟 iPad 上传功能 |
| | | const mockFile = { |
| | | name: 'iPad上传图片.jpg', |
| | | url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg', |
| | | status: 'success' |
| | | }; |
| | | this.photoList = [...this.photoList, mockFile]; |
| | | this.$refs.form.validateField('photos'); |
| | | }, |
| | | handleIPadSpectrum() { |
| | | // TODO: 调用 iPad 选择图谱功能 |
| | | console.log('调用 iPad 选择图谱功能'); |
| | | // 模拟 iPad 选择图谱功能 |
| | | const mockFile = { |
| | | name: 'iPad图谱.pdf', |
| | | url: 'https://example.com/test.pdf', |
| | | status: 'success' |
| | | }; |
| | | this.spectrumList = [...this.spectrumList, mockFile]; |
| | | this.$refs.form.validateField('spectrums'); |
| | | } |
| | | } |
| | | }; |
| | |
| | | label-position="top" |
| | | > |
| | | <div style="padding-left: 25px"> |
| | | <el-form-item prop="recordNo" label="原始检验记录编号"> |
| | | <el-input v-model="form.recordNo" placeholder="请输入" /> |
| | | <el-form-item prop="originalCode" label="原始检验记录编号"> |
| | | <el-input v-model="form.originalCode" placeholder="请输入" disabled /> |
| | | </el-form-item> |
| | | |
| | | </div> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | |
| | | </div> |
| | | </div> |
| | | <div style="padding-left: 25px"> |
| | | <el-form-item prop="testItemName" label="检测项名字"> |
| | | <el-input v-model="form.testItemName" placeholder="请输入" /> |
| | | <el-form-item prop="termName" label="检测项名字"> |
| | | <el-input v-model="form.termName" placeholder="请输入" disabled /> |
| | | </el-form-item> |
| | | <el-form-item prop="testItemNo" label="检测项编号"> |
| | | <el-input v-model="form.testItemNo" placeholder="请输入" /> |
| | | <el-form-item prop="termCode" label="检测项编号"> |
| | | <el-input v-model="form.termCode" placeholder="请输入" disabled /> |
| | | </el-form-item> |
| | | <el-form-item prop="testMethodName" label="检测方法名字"> |
| | | <el-input v-model="form.testMethodName" placeholder="请输入" /> |
| | | <el-form-item prop="termMethod" label="检测方法名字"> |
| | | <el-input v-model="form.termMethod" placeholder="请输入" disabled /> |
| | | </el-form-item> |
| | | <el-form-item prop="testMethodNo" label="检测方法编号"> |
| | | <el-input v-model="form.testMethodNo" placeholder="请输入" /> |
| | | <el-form-item prop="termMethodCode" label="检测方法编号"> |
| | | <el-input v-model="form.termMethodCode" placeholder="请输入" disabled /> |
| | | </el-form-item> |
| | | </div> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>一 、检测标准</span> |
| | | <div>一 、检测标准</div> |
| | | </div> |
| | | </div> |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>二 、检测仪器</span> |
| | | </div> |
| | | </div> |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>三 、检测试剂</span> |
| | | </div> |
| | | </div> |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>四 、检测步骤</span> |
| | | </div> |
| | | </div> |
| | | <AiEditor |
| | | ref="standardEditor" |
| | | :value="editorContents.termStandard" |
| | | height="200px" |
| | | style="margin: 20px 0;" |
| | | placeholder="请输入检测标准..." |
| | | :readOnly="isDetail" |
| | | /> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>五 、检测数据及参照</span> |
| | | <div>二 、检测仪器</div> |
| | | </div> |
| | | <el-button type="primary" class="el-icon-plus" @click="handleAddTask">添加检测数据</el-button> |
| | | </div> |
| | | <AiEditor |
| | | ref="instrumentEditor" |
| | | :value="editorContents.termInstrument" |
| | | height="200px" |
| | | style="margin: 20px 0;" |
| | | placeholder="请输入检测仪器..." |
| | | :readOnly="isDetail" |
| | | /> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>三 、检测试剂</div> |
| | | </div> |
| | | </div> |
| | | <AiEditor |
| | | ref="reagentEditor" |
| | | :value="editorContents.termReagent" |
| | | height="200px" |
| | | style="margin: 20px 0;" |
| | | placeholder="请输入检测试剂..." |
| | | :readOnly="isDetail" |
| | | /> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>四 、检测步骤</div> |
| | | </div> |
| | | </div> |
| | | <AiEditor |
| | | ref="stepsEditor" |
| | | :value="editorContents.termStep" |
| | | height="200px" |
| | | style="margin: 20px 0;" |
| | | placeholder="请输入检测步骤..." |
| | | :readOnly="isDetail" |
| | | /> |
| | | |
| | | <div class="header-title" style="margin-bottom: 38px"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <div>五 、检测数据及参照</div> |
| | | </div> |
| | | <el-button v-if="!isDetail" type="primary" class="el-icon-plus" @click="handleAddTask">添加检测数据</el-button> |
| | | </div> |
| | | |
| | | <Table :data="taskTableData" :total="0" :height="null" class="rwuTable"> |
| | | <el-table-column type="index" label="序号" width="80"></el-table-column> |
| | | <el-table-column prop="sampleCode" label="检测样编号"></el-table-column> |
| | | <el-table-column prop="testData" label="检测数据"></el-table-column> |
| | | <el-table-column prop="createTime" label="检测时间" width="180"></el-table-column> |
| | | <el-table-column label="检测图片" width="200"> |
| | | <template slot-scope="scope"> |
| | | <div class="image-preview" v-if="scope.row.photos && scope.row.photos.length"> |
| | |
| | | <span v-else>无图谱</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="添加时间" width="180"></el-table-column> |
| | | <el-table-column label="操作" width="150"> |
| | | |
| | | <el-table-column v-if="!isDetail" label="操作" width="150"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" @click="handleEditTask(scope.row)">编辑</el-button> |
| | | <el-button type="text" @click="handleDeleteTask(scope.row)">删除</el-button> |
| | |
| | | <div class="header-title"> |
| | | <div class="header-title-left"> |
| | | <img src="@/assets/public/headercard.png" /> |
| | | <span>六 、检测结果预算</span> |
| | | <div>六 、检测结果运算</div> |
| | | </div> |
| | | </div> |
| | | <AiEditor |
| | | ref="resultCalculationEditor" |
| | | :value="editorContents.termResult" |
| | | height="200px" |
| | | style="margin: 20px 0;" |
| | | placeholder="请输入检测结果运算..." |
| | | :readOnly="isDetail" |
| | | /> |
| | | <Table :data="taskTableData" :total="0" :height="null" class="rwuTable"> |
| | | <el-table-column type="index" label="序号" width="80"></el-table-column> |
| | | <el-table-column prop="sampleCode" label="检测样编号"></el-table-column> |
| | | <el-table-column prop="testData" label="检测数据"></el-table-column> |
| | | <el-table-column label="检测结果" > |
| | | <template slot-scope="scope"> |
| | | <el-input v-model="scope.row.testResult" placeholder="请输入检测结果"></el-input> |
| | | <el-input v-model="scope.row.resultText" placeholder="请输入检测结果" :disabled="isDetail"></el-input> |
| | | </template> |
| | | </el-table-column> |
| | | </Table> |
| | | |
| | | <div class="add-project-footer"> |
| | | <el-button type="primary" class="save-btn">发送</el-button> |
| | | <el-button>存草稿</el-button> |
| | | <div class="add-project-footer" v-if="!isDetail"> |
| | | <el-button type="primary" class="save-btn" @click="handleSubmit(false)">填写完毕</el-button> |
| | | <el-button @click="handleSaveDraft">存草稿</el-button> |
| | | </div> |
| | | </el-form> |
| | | <!-- 添加检测数据弹窗 --> |
| | | <add-dialog |
| | | ref="addDialog" |
| | | :visible.sync="dialogVisible" |
| | | :is-edit="isEdit" |
| | | @success="handleTaskSubmit" |
| | | /> |
| | | </Card> |
| | |
| | | |
| | | <script> |
| | | import AddDialog from './components/addDialog.vue' |
| | | import AiEditor from '@/components/AiEditor' |
| | | import moment from 'moment' |
| | | import { getDetail, update } from './service' |
| | | |
| | | export default { |
| | | name: "AddProject", |
| | | components: { |
| | | AddDialog |
| | | AddDialog, |
| | | AiEditor |
| | | }, |
| | | data() { |
| | | return { |
| | | dialogVisible: false, |
| | | isEdit: false, |
| | | currentEditIndex: -1, |
| | | isDetail: this.$route.query.type === 'detail', |
| | | form: { |
| | | recordNo: '', |
| | | testItemName: '', |
| | | testItemNo: '', |
| | | testMethodName: '', |
| | | testMethodNo: '' |
| | | id: '', |
| | | originalCode: '', |
| | | termName: '', |
| | | termCode: '', |
| | | termMethod: '', |
| | | termMethodCode: '', |
| | | status: 1, |
| | | termStandard: '', |
| | | termInstrument: '', |
| | | termReagent: '', |
| | | termStep: '', |
| | | termResult: '' |
| | | }, |
| | | editorContents: { |
| | | termStandard: '', |
| | | termInstrument: '', |
| | | termReagent: '', |
| | | termStep: '', |
| | | termResult: '' |
| | | }, |
| | | rules: { |
| | | recordNo: [{ required: true, message: "请输入原始检验记录编号", trigger: "blur" }], |
| | | testItemName: [{ required: true, message: "请输入检测项名字", trigger: "blur" }], |
| | | testItemNo: [{ required: true, message: "请输入检测项编号", trigger: "blur" }], |
| | | testMethodName: [{ required: true, message: "请输入检测方法名字", trigger: "blur" }], |
| | | testMethodNo: [{ required: true, message: "请输入检测方法编号", trigger: "blur" }] |
| | | termName: [{ required: true, message: "请输入检测项名字", trigger: "blur" }], |
| | | termCode: [{ required: true, message: "请输入检测项编号", trigger: "blur" }], |
| | | experimentName: [{ required: true, message: "请输入检测方法名字", trigger: "blur" }], |
| | | experimentCode: [{ required: true, message: "请输入检测方法编号", trigger: "blur" }] |
| | | }, |
| | | taskTableData: [] |
| | | }; |
| | | }, |
| | | methods: { |
| | | // 获取详情 |
| | | getDetail() { |
| | | const id = this.$route.query.id; |
| | | if (id) { |
| | | getDetail({ id }).then(res => { |
| | | if (res) { |
| | | const data = res; |
| | | // 设置表单数据 |
| | | this.form = { |
| | | ...data, |
| | | termCode: data.testMethodConfirmSheetTerm.termCode || '', |
| | | termName: data.testMethodConfirmSheetTerm.termName || '', |
| | | termMethod: data.testMethodConfirmSheetTerm.termMethod || '', |
| | | termMethodCode: data.testMethodConfirmSheetTerm.termMethodCode || '', |
| | | |
| | | termStandard: data.termStandard || '', |
| | | termInstrument: data.termInstrument || '', |
| | | termReagent: data.termReagent || '', |
| | | termStep: data.termStep || '', |
| | | termResult: data.termResult || '' |
| | | }; |
| | | // 设置编辑器内容 |
| | | this.editorContents = { |
| | | termStandard: data.termStandard || '', |
| | | termInstrument: data.termInstrument || '', |
| | | termReagent: data.termReagent || '', |
| | | termStep: data.termStep || '', |
| | | termResult: data.termResult || '' |
| | | }; |
| | | // 设置检测数据表格 |
| | | if (data.testMethodConfirmSheetOriginalDataList && data.testMethodConfirmSheetOriginalDataList.length > 0) { |
| | | this.taskTableData = data.testMethodConfirmSheetOriginalDataList.map(item => ({ |
| | | sampleCode: item.dataCode || '', |
| | | testData: item.dataTitle || '', |
| | | resultText: item.resultText || '', |
| | | photos: item.dataPictures ? item.dataPictures.split(',').map(url => ({ url })) : [], |
| | | spectrums: item.dataFiles ? JSON.parse(item.dataFiles) : [], |
| | | createTime: item.createTime || moment().format('YYYY-MM-DD HH:mm:ss') |
| | | })); |
| | | } |
| | | } |
| | | }).catch(err => { |
| | | console.error('获取详情失败:', err); |
| | | this.$message.error('获取详情失败'); |
| | | }); |
| | | } |
| | | }, |
| | | handleAddTask() { |
| | | this.isEdit = false; |
| | | this.currentEditIndex = -1; |
| | |
| | | this.currentEditIndex = this.taskTableData.findIndex(item => item === row); |
| | | |
| | | const editData = { |
| | | sampleCode: row.sampleCode, |
| | | testData: row.testData, |
| | | testTypes: [], |
| | | dataCode: row.sampleCode, |
| | | dataTitle: row.testData, |
| | | dataType: [], |
| | | dataFiles: '', |
| | | dataPictures: '', |
| | | photos: [], |
| | | spectrums: [] |
| | | }; |
| | | |
| | | if (row.photos && row.photos.length > 0) { |
| | | editData.testTypes.push('photo'); |
| | | editData.photos = row.photos.map(photo => ({ |
| | | name: photo.name, |
| | | url: photo.url, |
| | | raw: null |
| | | })); |
| | | editData.dataType.push('1'); |
| | | editData.dataPictures = row.photos; |
| | | } |
| | | if (row.spectrums && row.spectrums.length > 0) { |
| | | editData.testTypes.push('spectrum'); |
| | | editData.spectrums = row.spectrums.map(spectrum => ({ |
| | | name: spectrum.name, |
| | | url: spectrum.url, |
| | | raw: null |
| | | })); |
| | | editData.dataType.push('2'); |
| | | editData.dataFiles = row.spectrums; |
| | | } |
| | | |
| | | this.$nextTick(() => { |
| | |
| | | .catch(() => {}); |
| | | }, |
| | | handleTaskSubmit(formData) { |
| | | const photos = formData.photos.map(file => ({ |
| | | name: file.name, |
| | | url: file.url || URL.createObjectURL(file.raw) |
| | | })); |
| | | |
| | | const spectrums = formData.spectrums.map(file => ({ |
| | | name: file.name, |
| | | url: file.url || URL.createObjectURL(file.raw) |
| | | })); |
| | | |
| | | const newData = { |
| | | sampleCode: formData.sampleCode, |
| | | testData: formData.testData, |
| | | testResult: '', |
| | | photos, |
| | | spectrums, |
| | | sampleCode: formData.dataCode, |
| | | testData: formData.dataTitle, |
| | | resultText: this.isEdit && this.currentEditIndex > -1 ? this.taskTableData[this.currentEditIndex].resultText : '', |
| | | photos: formData.dataPictures ? JSON.parse(formData.dataPictures) : [], |
| | | spectrums: formData.dataFiles ? JSON.parse(formData.dataFiles) : [], |
| | | createTime: this.isEdit ? this.taskTableData[this.currentEditIndex].createTime : moment().format('YYYY-MM-DD HH:mm:ss') |
| | | }; |
| | | |
| | | if (this.isEdit && this.currentEditIndex > -1) { |
| | | const oldData = this.taskTableData[this.currentEditIndex]; |
| | | if (oldData.photos) { |
| | | oldData.photos.forEach(photo => { |
| | | if (photo.url.startsWith('blob:') && !photos.find(p => p.url === photo.url)) { |
| | | URL.revokeObjectURL(photo.url); |
| | | } |
| | | }); |
| | | } |
| | | if (oldData.spectrums) { |
| | | oldData.spectrums.forEach(spectrum => { |
| | | if (spectrum.url.startsWith('blob:') && !spectrums.find(s => s.url === spectrum.url)) { |
| | | URL.revokeObjectURL(spectrum.url); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | this.taskTableData.splice(this.currentEditIndex, 1, newData); |
| | | this.$message.success('更新成功'); |
| | | } else { |
| | |
| | | }, |
| | | getPhotoUrls(photos) { |
| | | return photos.map(photo => photo.url); |
| | | }, |
| | | // 获取所有编辑器的内容 |
| | | getAllEditorContent() { |
| | | return { |
| | | termStandard: this.$refs.standardEditor.getContent(), |
| | | termInstrument: this.$refs.instrumentEditor.getContent(), |
| | | termReagent: this.$refs.reagentEditor.getContent(), |
| | | termStep: this.$refs.stepsEditor.getContent(), |
| | | termResult: this.$refs.resultCalculationEditor.getContent() |
| | | } |
| | | }, |
| | | // 验证所有编辑器内容 |
| | | validateEditors() { |
| | | const editors = { |
| | | termStandard: this.$refs.standardEditor.getContent(), |
| | | termInstrument: this.$refs.instrumentEditor.getContent(), |
| | | termReagent: this.$refs.reagentEditor.getContent(), |
| | | termStep: this.$refs.stepsEditor.getContent(), |
| | | termResult: this.$refs.resultCalculationEditor.getContent() |
| | | }; |
| | | |
| | | // 判断内容是否为空(排除<p></p>) |
| | | const isEmptyContent = (content) => { |
| | | return !content || content === '<p></p>' || content.trim() === '<p></p>'; |
| | | }; |
| | | |
| | | const emptyFields = []; |
| | | if (isEmptyContent(editors.termStandard)) emptyFields.push('检测标准'); |
| | | if (isEmptyContent(editors.termInstrument)) emptyFields.push('检测仪器'); |
| | | if (isEmptyContent(editors.termReagent)) emptyFields.push('检测试剂'); |
| | | if (isEmptyContent(editors.termStep)) emptyFields.push('检测步骤'); |
| | | if (isEmptyContent(editors.termResult)) emptyFields.push('检测结果运算'); |
| | | |
| | | if (emptyFields.length > 0) { |
| | | this.$message.warning(`请填写${emptyFields.join('、')}`); |
| | | return false; |
| | | } |
| | | return true; |
| | | }, |
| | | |
| | | // 获取编辑器对应的标签名 |
| | | getEditorLabel(key) { |
| | | const labels = { |
| | | termStandard: '检测标准', |
| | | termInstrument: '检测仪器', |
| | | termReagent: '检测试剂', |
| | | termStep: '检测步骤', |
| | | termResult: '检测结果运算' |
| | | }; |
| | | return labels[key] || ''; |
| | | }, |
| | | |
| | | // 验证表格数据 |
| | | validateTableData() { |
| | | if (!this.taskTableData || this.taskTableData.length === 0) { |
| | | this.$message.error('请至少添加一条检测数据'); |
| | | return false; |
| | | } |
| | | return true; |
| | | }, |
| | | |
| | | // 提交表单 |
| | | async handleSubmit(isDraft) { |
| | | try { |
| | | // 如果不是草稿,需要验证所有必填项 |
| | | if (!isDraft) { |
| | | // 验证编辑器内容 |
| | | if (!this.validateEditors()) { |
| | | return; |
| | | } |
| | | |
| | | // 验证表格数据 |
| | | if (!this.validateTableData()) { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | // 获取所有编辑器内容 |
| | | const editorContents = { |
| | | termStandard: this.$refs.standardEditor.getContent(), |
| | | termInstrument: this.$refs.instrumentEditor.getContent(), |
| | | termReagent: this.$refs.reagentEditor.getContent(), |
| | | termStep: this.$refs.stepsEditor.getContent(), |
| | | termResult: this.$refs.resultCalculationEditor.getContent() |
| | | }; |
| | | |
| | | // 构建提交数据 |
| | | const submitData = { |
| | | id: this.form.id, |
| | | status: isDraft ? -1 : 2, |
| | | ...editorContents, |
| | | testMethodConfirmSheetOriginalDataList: this.taskTableData.map(item => ({ |
| | | dataCode: item.sampleCode, |
| | | dataTitle: item.testData, |
| | | dataType: item.photos && item.spectrums ? '1,2' : |
| | | item.photos ? '1' : |
| | | item.spectrums ? '2' : '', |
| | | dataFiles: JSON.stringify(item.spectrums || []), |
| | | dataPictures: (item.photos || []).map(photo => photo.url).join(','), |
| | | originalId: this.form.id, |
| | | resultText: item.resultText || '' |
| | | })) |
| | | }; |
| | | |
| | | console.log('提交数据:', submitData); |
| | | |
| | | // 调用更新接口 |
| | | const res = await update(submitData); |
| | | if (res.code === 200) { |
| | | // 根据 isDraft 显示不同的成功提示 |
| | | if (isDraft) { |
| | | this.$message.success('保存草稿成功'); |
| | | } else { |
| | | this.$message.success('填写完毕'); |
| | | } |
| | | // 返回上一页 |
| | | this.$router.back(); |
| | | } else { |
| | | this.$message.error(res.msg || '提交失败'); |
| | | } |
| | | } catch (error) { |
| | | console.error('提交失败:', error); |
| | | this.$message.error('提交失败'); |
| | | } |
| | | }, |
| | | |
| | | // 存草稿 |
| | | handleSaveDraft() { |
| | | this.handleSubmit(true); |
| | | } |
| | | }, |
| | | created() { |
| | | this.getDetail(); |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .ai-editor-container{ |
| | | margin-left: 40px; |
| | | width: 85%; |
| | | } |
| | | .el-form--inline .el-form-item { |
| | | margin-right: 83px; |
| | | } |
| | |
| | | flex-wrap: wrap; |
| | | gap: 13px; |
| | | margin-top: 38px; |
| | | margin-bottom: 38px; |
| | | |
| | | .header-title-left { |
| | | display: flex; |
| | |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | } |
| | | div { |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | | font-size: 18px; |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | &:before { |
| | | content: "*"; |
| | | color: #f56c6c; |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | <template> |
| | | <div class="list"> |
| | | <TableCustom :queryForm="form" :tableData="tableData" :total="total" :height="null"> |
| | | <TableCustom :queryForm="form" :tableData="tableData" :total="total" :height="null" @handlePageChange="handlePageChange" @handleSizeChange="handleSizeChange"> |
| | | <template #search> |
| | | <el-form :model="form" labelWidth="auto" inline> |
| | | <el-form-item label="项目课题方案名称:"> |
| | | <el-input v-model="form.projectName" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="所属实验编号:"> |
| | | <el-input v-model="form.planCode" placeholder="请输入"></el-input> |
| | | <el-input v-model="form.experimentCode" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="创建人:"> |
| | | <el-input v-model="form.creator" placeholder="请输入"></el-input> |
| | | <el-input v-model="form.createBy" placeholder="请输入"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="创建时间:"> |
| | | <el-date-picker |
| | |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | value-format="yyyy-MM-dd" |
| | | :default-time="['00:00:00', '23:59:59']" |
| | | @change="handleDateChange" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item label="审批人:"> |
| | | <!-- <el-form-item label="审批人:"> |
| | | <el-input v-model="form.approver" placeholder="请输入"></el-input> |
| | | </el-form-item> --> |
| | | <el-form-item label="状态:"> |
| | | <el-select v-model="form.status" placeholder="请选择"> |
| | | <el-option label="全部" value=""></el-option> |
| | | <el-option label="未填写" value="1"></el-option> |
| | | <el-option label="已填写" value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label=""> |
| | | <el-button type="default" @click="resetForm">重置</el-button> |
| | | <el-button type="primary" @click="handleSearch">查询</el-button> |
| | | <el-button type="primary" @click="handleSearch" style="margin-left: 10px;">查询</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <template #setting> |
| | | <div class="tableTitle"> |
| | | <div class="flex a-center"> |
| | |
| | | </div> |
| | | </template> |
| | | <template #table> |
| | | <el-table-column prop="projectPlan" label="所属项目课题方案"></el-table-column> |
| | | <el-table-column prop="experimentNo" label="实验编号"></el-table-column> |
| | | <el-table-column prop="projectName" label="所属项目课题方案"></el-table-column> |
| | | <el-table-column prop="originalCode" label="原始检验记录编号"></el-table-column> |
| | | |
| | | <el-table-column prop="experimentCode" label="所属实验编号"></el-table-column> |
| | | <el-table-column prop="experimentName" label="实验名称"></el-table-column> |
| | | <el-table-column prop="creator" label="创建人"></el-table-column> |
| | | <el-table-column prop="termCode" label="检测项编号"></el-table-column> |
| | | <el-table-column prop="termName" label="检测项名称"></el-table-column> |
| | | <el-table-column prop="createTime" label="创建时间"></el-table-column> |
| | | <el-table-column prop="createBy" label="创建人"></el-table-column> |
| | | |
| | | <!-- <el-table-column prop="termInstrument" label="检测仪器"></el-table-column> --> |
| | | <!-- <el-table-column prop="termReagent" label="检测试剂"></el-table-column> --> |
| | | <!-- <el-table-column prop="termStandard" label="检测标准"></el-table-column> --> |
| | | <!-- <el-table-column prop="termStep" label="检测步骤"></el-table-column> --> |
| | | <!-- <el-table-column prop="termResult" label="检测结果"></el-table-column> --> |
| | | <el-table-column prop="status" label="状态"> |
| | | <template slot-scope="scope"> |
| | | <el-tag :type="scope.row.status === '已填写' ? 'success' : 'warning'"> |
| | | {{ scope.row.status }} |
| | | <el-tag :type="getStatusType(scope.row.status)"> |
| | | {{ getStatusText(scope.row.status) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="150"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" @click="handleEdit(scope.row)">编辑</el-button> |
| | | <el-button type="text" @click="handleDetail(scope.row.id)">详情</el-button> |
| | | <template v-if="isLabTechnician"> |
| | | <el-button |
| | | type="text" |
| | | @click="handleEdit(scope.row)" |
| | | |
| | | >编辑</el-button> |
| | | |
| | | </template> |
| | | <template v-else> |
| | | <el-button type="text" @click="handleDetail(scope.row.id)">详情</el-button> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | </template> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { getList } from './service'; |
| | | |
| | | export default { |
| | | name: "OriginalRecordTest", |
| | | computed: { |
| | | /** |
| | | * 判断当前用户是否为化验师 |
| | | * @returns {boolean} 是否为化验师 |
| | | */ |
| | | isLabTechnician() { |
| | | const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}'); |
| | | return userInfo.roleType == 4; // 4是化验师 |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | // 查询表单数据 |
| | | form: { |
| | | planCode: "", |
| | | creator: "", |
| | | createTime: [], |
| | | approver: "" |
| | | projectName: "", // 项目课题方案名称 |
| | | experimentCode: "", // 所属实验编号 |
| | | createBy: "", // 创建人 |
| | | createTime: [], // 创建时间范围 |
| | | startTime: "", // 开始时间 |
| | | endTime: "", // 结束时间 |
| | | status: "", // 状态 |
| | | pageNum: 1, // 当前页码 |
| | | pageSize: 10 // 每页条数 |
| | | }, |
| | | tableData: [ |
| | | { |
| | | id: '1', |
| | | projectPlan: 'DD250218-JL01', |
| | | experimentNo: '31423764', |
| | | experimentName: '化学成分分析实验', |
| | | creator: '张三', |
| | | createTime: '2025-1-8 17:56:11', |
| | | status: '未填写' |
| | | }, |
| | | { |
| | | id: '2', |
| | | projectPlan: 'DD250218-JL02', |
| | | experimentNo: '31423765', |
| | | experimentName: '物理性能测试实验', |
| | | creator: '李四', |
| | | createTime: '2025-1-8 18:00:00', |
| | | status: '未填写' |
| | | }, |
| | | { |
| | | id: '3', |
| | | projectPlan: 'DD250218-JL03', |
| | | experimentNo: '31423766', |
| | | experimentName: '材料强度测试', |
| | | creator: '王五', |
| | | createTime: '2025-1-8 18:30:00', |
| | | status: '已填写' |
| | | }, |
| | | { |
| | | id: '4', |
| | | projectPlan: 'DD250218-JL04', |
| | | experimentNo: '31423767', |
| | | experimentName: '耐久性测试实验', |
| | | creator: '赵六', |
| | | createTime: '2025-1-8 19:00:00', |
| | | status: '已填写' |
| | | }, |
| | | { |
| | | id: '5', |
| | | projectPlan: 'DD250218-JL05', |
| | | experimentNo: '31423768', |
| | | experimentName: '环境适应性测试', |
| | | creator: '孙七', |
| | | createTime: '2025-1-8 19:30:00', |
| | | status: '未填写' |
| | | } |
| | | ], |
| | | total: 5 |
| | | tableData: [], // 表格数据 |
| | | total: 0 // 总条数 |
| | | }; |
| | | }, |
| | | created() { |
| | |
| | | methods: { |
| | | resetForm() { |
| | | this.form = { |
| | | planCode: "", |
| | | creator: "", |
| | | projectName: "", |
| | | experimentCode: "", |
| | | createBy: "", |
| | | createTime: [], |
| | | approver: "" |
| | | startTime: "", |
| | | endTime: "", |
| | | status: "", |
| | | pageNum: 1, |
| | | pageSize: 10 |
| | | }; |
| | | }, |
| | | handleSearch() { |
| | | this.form.pageNum = 1; |
| | | this.getTableData(); |
| | | }, |
| | | handleEdit(row) { |
| | | console.log("编辑数据:", row); |
| | | this.$router.push({ |
| | | path: "/dataManagement/originalRecordTest/detail", |
| | | query: { |
| | | id: row.id, |
| | | type: 'edit' |
| | | } |
| | | }); |
| | | }, |
| | | handleDetail(id) { |
| | | this.$router.push({ |
| | | path: "/dataManagement/originalRecordTest/detail", |
| | | query: { id } |
| | | query: { |
| | | id, |
| | | type: 'detail' |
| | | } |
| | | }); |
| | | }, |
| | | handlePageChange(page) { |
| | | this.form.pageNum = page; |
| | | this.getTableData(); |
| | | }, |
| | | handleSizeChange(size) { |
| | | this.form.pageSize = size; |
| | | this.form.pageNum = 1; |
| | | this.getTableData(); |
| | | }, |
| | | handleDateChange(val) { |
| | | if (val) { |
| | | this.form.startTime = val[0]; |
| | | this.form.endTime = val[1]; |
| | | } else { |
| | | this.form.startTime = ""; |
| | | this.form.endTime = ""; |
| | | } |
| | | }, |
| | | getTableData() { |
| | | // TODO: 调用接口获取数据 |
| | | // this.tableData = []; |
| | | // this.total = 0; |
| | | const params = { |
| | | pageNum: this.form.pageNum, |
| | | pageSize: this.form.pageSize, |
| | | createBy: this.form.createBy, |
| | | projectName: this.form.projectName, |
| | | experimentCode: this.form.experimentCode, |
| | | status: this.form.status, |
| | | startTime: this.form.startTime, |
| | | endTime: this.form.endTime |
| | | }; |
| | | console.log('params',params) |
| | | |
| | | getList(params).then(res => { |
| | | if (res.code == 200) { |
| | | this.tableData = res.data.records || []; |
| | | this.total = res.data.total || 0; |
| | | } |
| | | }); |
| | | }, |
| | | getStatusType(status) { |
| | | const statusMap = { |
| | | '-1': 'info', |
| | | '1': 'warning', |
| | | '2': 'success' |
| | | }; |
| | | return statusMap[status] || 'info'; |
| | | }, |
| | | getStatusText(status) { |
| | | const statusMap = { |
| | | '-1': '草稿箱', |
| | | '1': '未填写', |
| | | '2': '已填写' |
| | | }; |
| | | return statusMap[status] || '未知'; |
| | | } |
| | | } |
| | | }; |
New file |
| | |
| | | import axios from '@/utils/request'; |
| | | |
| | | // 列表 |
| | | export const getList = (data) => { |
| | | return axios.post('/api/t-test-method-confirm-sheet-original/pageList', { ...data }) |
| | | } |
| | | // 详情 |
| | | export const getDetail = (data) => { |
| | | return axios.get('/open/t-test-method-confirm-sheet-original/getDetailById', { params:data }) |
| | | } |
| | | |
| | | //修改 |
| | | export const update = (data) => { |
| | | return axios.post('/api/t-test-method-confirm-sheet-original/update', { ...data }) |
| | | } |