fix: 修复多个页面样式、交互及路由问题
- 修复表格样式,调整滚动条尺寸和圆角,统一操作列宽度
- 修复路由跳转逻辑,为详情页添加独立路由,避免参数传递错误
- 修复图片/文件上传组件,支持多种图片格式,优化错误处理和上传队列
- 修复评估组件数据解析逻辑,确保类型变化时正确重置
- 修复原始记录详情页文件路径处理,统一URL前缀
- 修复选择项目组件单选逻辑,优化高亮样式
- 修复多个页面标题和按钮文字,统一为“实验方案列表”等
- 修复审批撤销提示文字,明确影响范围
| | |
| | | .table-container { |
| | | ::-webkit-scrollbar { |
| | | display: block !important; |
| | | width: 6px; |
| | | height: 6px; |
| | | width: 10px; |
| | | height: 10px; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-track { |
| | | background: #f1f1f1; |
| | | border-radius: 3px; |
| | | border-radius: 5px; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-thumb { |
| | | background: #009688; |
| | | border-radius: 3px; |
| | | border-radius: 5px; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-thumb:hover { |
| | |
| | | (res, file, fileList) => |
| | | handleImageSuccess(res, file, fileList, header.name) |
| | | " |
| | | :on-error=" |
| | | (err, file, fileList) => |
| | | handleImageError(err, file, fileList, header.name) |
| | | " |
| | | :on-preview="handlePreview" |
| | | :disabled="!checkEditPermission(header)" |
| | | accept="image/*" |
| | | multiple |
| | | > |
| | | <div |
| | |
| | | > |
| | | <i class="el-icon-plus"></i> |
| | | </div> |
| | | <div slot="tip" class="el-upload__tip">只支持.jpg格式</div> |
| | | <div slot="tip" class="el-upload__tip">支持任意图片格式上传</div> |
| | | </el-upload> |
| | | </el-form-item> |
| | | <el-form-item |
| | |
| | | }, |
| | | }, |
| | | methods: { |
| | | removeUploadItem(fileList, file) { |
| | | const list = Array.isArray(fileList) ? fileList : []; |
| | | const nextList = list.filter((item) => item.uid !== file.uid); |
| | | const removeIndex = list.findIndex((item) => item.uid === file.uid); |
| | | |
| | | if (removeIndex > -1) { |
| | | list.splice(removeIndex, 1); |
| | | } |
| | | |
| | | return nextList; |
| | | }, |
| | | getUserOptions() { |
| | | listByRole() |
| | | .then((res) => { |
| | |
| | | }); |
| | | }, |
| | | beforeImageUpload(file) { |
| | | const isJPG = file.type === "image/jpeg"; |
| | | // const isLt2M = file.size / 1024 / 1024 < 2; |
| | | const isImage = |
| | | (file.type && file.type.startsWith("image/")) || |
| | | /\.(png|jpe?g|gif|bmp|webp|svg|ico|tiff?)$/i.test(file.name || ""); |
| | | |
| | | if (!isJPG) { |
| | | this.$message.error("上传图片只能是 JPG 格式!"); |
| | | if (!isImage) { |
| | | this.$message.error("只能上传图片类型文件"); |
| | | return false; |
| | | } |
| | | return true; |
| | |
| | | this.$refs.form && this.$refs.form.validateField(fieldName); |
| | | }, |
| | | handleImageSuccess(res, file, fileList, fieldName) { |
| | | if (!res || (res.code !== 200 && res.code !== "200") || !res.msg) { |
| | | const errorMessage = |
| | | (res && (res.msg || res.message)) || "图片上传失败"; |
| | | this.$message.error(errorMessage); |
| | | file.status = "fail"; |
| | | file.url = ""; |
| | | const successFileList = this.removeUploadItem(fileList, file); |
| | | this.$set(this.imageListMap, fieldName, successFileList); |
| | | this.$set( |
| | | this.form, |
| | | fieldName, |
| | | successFileList.map((f) => |
| | | f.url ? (f.url.startsWith("http") ? f.url : getFullUrl(f.url)) : "" |
| | | ) |
| | | ); |
| | | this.$refs.form && this.$refs.form.validateField(fieldName); |
| | | return; |
| | | } |
| | | |
| | | const url = res.msg; |
| | | file.url = getFullUrl(url); |
| | | if (!Array.isArray(this.form[fieldName])) { |
| | |
| | | this.$set(this.imageListMap, fieldName, fileList); |
| | | this.$refs.form && this.$refs.form.validateField(fieldName); |
| | | }, |
| | | handleImageError(err, file, fileList, fieldName) { |
| | | let errorMessage = "图片上传失败"; |
| | | const rawMessage = |
| | | (err && |
| | | (err.message || |
| | | err.response || |
| | | err.responseText || |
| | | (err.target && err.target.response))) || |
| | | ""; |
| | | |
| | | if (typeof rawMessage === "string" && rawMessage) { |
| | | try { |
| | | const parsedMessage = JSON.parse(rawMessage); |
| | | errorMessage = |
| | | parsedMessage.msg || parsedMessage.message || errorMessage; |
| | | } catch (e) { |
| | | errorMessage = rawMessage; |
| | | } |
| | | } |
| | | |
| | | this.$message.error(errorMessage); |
| | | file.status = "fail"; |
| | | file.url = ""; |
| | | const validFileList = this.removeUploadItem( |
| | | (fileList || []).filter((item) => item.status !== "fail"), |
| | | file |
| | | ); |
| | | this.$set(this.imageListMap, fieldName, validFileList); |
| | | this.$set( |
| | | this.form, |
| | | fieldName, |
| | | validFileList.map((f) => |
| | | f.url ? (f.url.startsWith("http") ? f.url : getFullUrl(f.url)) : "" |
| | | ) |
| | | ); |
| | | this.$refs.form && this.$refs.form.validateField(fieldName); |
| | | }, |
| | | handleImageRemove(file, fileList, fieldName) { |
| | | this.$set( |
| | | this.form, |
| | |
| | | (res, file, fileList) => |
| | | handleFileSuccess(res, file, fileList, idx) |
| | | " |
| | | :on-error=" |
| | | (err, file, fileList) => |
| | | handleFileError(err, file, fileList, idx) |
| | | " |
| | | list-type="text" |
| | | > |
| | | <el-button size="small" icon="el-icon-upload2">点击上传</el-button> |
| | |
| | | (res, file, fileList) => |
| | | handleImageSuccess(res, file, fileList, idx) |
| | | " |
| | | :on-error=" |
| | | (err, file, fileList) => |
| | | handleImageError(err, file, fileList, idx) |
| | | " |
| | | :auto-upload="true" |
| | | :before-upload="beforeImageUpload" |
| | | list-type="picture-card" |
| | | :on-preview="(file) => handlePreview(file, idx)" |
| | | class="image-uploader" |
| | | accept="image/*" |
| | | > |
| | | <i class="el-icon-plus"></i> |
| | | <div class="upload-text">上传图片</div> |
| | |
| | | class="preview-image" |
| | | /> |
| | | </div> |
| | | <div class="uploaf-notice">支持.jpg .png格式</div> |
| | | <div class="uploaf-notice">支持任意图片格式上传</div> |
| | | </div> |
| | | </div> |
| | | <img |
| | |
| | | methods: { |
| | | getFullUrl, |
| | | downloadFileByUrl, |
| | | removeUploadItem(fileList, file) { |
| | | const list = Array.isArray(fileList) ? fileList : []; |
| | | const nextList = list.filter((item) => item.uid !== file.uid); |
| | | const removeIndex = list.findIndex((item) => item.uid === file.uid); |
| | | |
| | | if (removeIndex > -1) { |
| | | list.splice(removeIndex, 1); |
| | | } |
| | | |
| | | return nextList; |
| | | }, |
| | | getUserDisplayText(fieldName, rowData) { |
| | | // 检查是否有对应的userInfo数据 |
| | | const userInfoKey = `${fieldName}_userInfo`; |
| | |
| | | this.emitUpdate(); |
| | | }, |
| | | handleFileSuccess(res, file, fileList, idx) { |
| | | if (!res || (res.code !== 200 && res.code !== "200") || !res.msg) { |
| | | const errorMessage = |
| | | (res && (res.msg || res.message)) || "文件上传失败"; |
| | | this.$message.error(errorMessage); |
| | | file.status = "fail"; |
| | | file.url = ""; |
| | | this.components[idx].data.fileList = this.removeUploadItem( |
| | | fileList, |
| | | file |
| | | ); |
| | | this.emitUpdate(); |
| | | return; |
| | | } |
| | | |
| | | // 上传成功后设置真实 url |
| | | file.url = this.getFullUrl(res.msg); |
| | | this.components[idx].data.fileList = fileList; |
| | | this.emitUpdate(); |
| | | }, |
| | | handleFileError(err, file, fileList, idx) { |
| | | let errorMessage = "文件上传失败"; |
| | | const rawMessage = |
| | | (err && |
| | | (err.message || |
| | | err.response || |
| | | err.responseText || |
| | | (err.target && err.target.response))) || |
| | | ""; |
| | | |
| | | if (typeof rawMessage === "string" && rawMessage) { |
| | | try { |
| | | const parsedMessage = JSON.parse(rawMessage); |
| | | errorMessage = |
| | | parsedMessage.msg || parsedMessage.message || errorMessage; |
| | | } catch (e) { |
| | | errorMessage = rawMessage; |
| | | } |
| | | } |
| | | |
| | | this.$message.error(errorMessage); |
| | | file.status = "fail"; |
| | | file.url = ""; |
| | | this.components[idx].data.fileList = this.removeUploadItem( |
| | | (fileList || []).filter((item) => item.status !== "fail"), |
| | | file |
| | | ); |
| | | this.emitUpdate(); |
| | | }, |
| | | handleImageChange(idx, fileList) { |
| | |
| | | this.emitUpdate(); |
| | | }, |
| | | handleImageSuccess(res, file, fileList, idx) { |
| | | if (!res || (res.code !== 200 && res.code !== "200") || !res.msg) { |
| | | const errorMessage = |
| | | (res && (res.msg || res.message)) || "图片上传失败"; |
| | | this.$message.error(errorMessage); |
| | | file.status = "fail"; |
| | | file.url = ""; |
| | | this.components[idx].data.imageList = this.removeUploadItem( |
| | | fileList, |
| | | file |
| | | ); |
| | | this.emitUpdate(); |
| | | return; |
| | | } |
| | | |
| | | // 上传成功后设置真实 url |
| | | file.url = this.getFullUrl(res.msg); |
| | | this.components[idx].data.imageList = fileList; |
| | | this.emitUpdate(); |
| | | }, |
| | | beforeImageUpload(file) { |
| | | const isJPG = file.type === "image/jpeg"; |
| | | const isPNG = file.type === "image/png"; |
| | | // const isLt2M = file.size / 1024 / 1024 < 2; |
| | | handleImageError(err, file, fileList, idx) { |
| | | let errorMessage = "图片上传失败"; |
| | | const rawMessage = |
| | | (err && |
| | | (err.message || |
| | | err.response || |
| | | err.responseText || |
| | | (err.target && err.target.response))) || |
| | | ""; |
| | | |
| | | if (!isJPG && !isPNG) { |
| | | this.$message.error("上传图片只能是 JPG 或 PNG 格式!"); |
| | | if (typeof rawMessage === "string" && rawMessage) { |
| | | try { |
| | | const parsedMessage = JSON.parse(rawMessage); |
| | | errorMessage = |
| | | parsedMessage.msg || parsedMessage.message || errorMessage; |
| | | } catch (e) { |
| | | errorMessage = rawMessage; |
| | | } |
| | | } |
| | | |
| | | this.$message.error(errorMessage); |
| | | file.status = "fail"; |
| | | file.url = ""; |
| | | this.components[idx].data.imageList = this.removeUploadItem( |
| | | (fileList || []).filter((item) => item.status !== "fail"), |
| | | file |
| | | ); |
| | | this.emitUpdate(); |
| | | }, |
| | | beforeImageUpload(file) { |
| | | const isImage = |
| | | (file.type && file.type.startsWith("image/")) || |
| | | /\.(png|jpe?g|gif|bmp|webp|svg|ico|tiff?)$/i.test(file.name || ""); |
| | | |
| | | if (!isImage) { |
| | | this.$message.error("只能上传图片类型文件"); |
| | | return false; |
| | | } |
| | | // if (!isLt2M) { |
| | |
| | | if (newVal) { |
| | | try { |
| | | const parsedData = JSON.parse(newVal) |
| | | this.activeIndex = parsedData |
| | | this.activeIndex = parsedData.map(item => ({ |
| | | num: item.num, |
| | | score: item.score |
| | | })) |
| | | } catch (e) { |
| | | this.resetData() |
| | | } |
| | | } else { |
| | | this.resetData() |
| | | } |
| | | }, |
| | | immediate: true |
| | | }, |
| | | type: { |
| | | handler() { |
| | | if (!this.viewJson) { |
| | | this.resetData() |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | data() { |
| | |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | |
| | | <template #tableCustom> |
| | | <Table ref="memberTable" :height="null" :row-key="row => row.id" :data="tableData" :total="0" |
| | | highlight-current-row @current-change="handleCurrentChange"> |
| | | <!-- <el-table-column type="selection" width="55" /> --> |
| | | highlight-current-row @row-click="handleRowClick" @select="handleSelect" |
| | | @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" /> |
| | | <el-table-column prop="teamName" label="项目组名称"></el-table-column> |
| | | <el-table-column prop="personCharge" label="项目负责人"></el-table-column> |
| | | <el-table-column prop="staffName" label="项目组成员"></el-table-column> |
| | |
| | | endTime: '', |
| | | teamName: '', |
| | | }, |
| | | selectData: [], |
| | | selectData: null, |
| | | tableData: [], |
| | | total: 0 |
| | | } |
| | | }, |
| | | methods: { |
| | | setSingleSelection(row) { |
| | | if (!row || !this.$refs.memberTable) { |
| | | return; |
| | | } |
| | | this.$refs.memberTable.clearSelection(); |
| | | this.$refs.memberTable.toggleRowSelection(row, true); |
| | | this.selectData = row; |
| | | }, |
| | | open() { |
| | | if(this.form.date && this.form.date.length === 2){ |
| | | this.form.startTime=this.form.date[0] |
| | |
| | | this.$nextTick(() => { |
| | | const row = this.tableData.find(item => item.id === this.selectedData.id) |
| | | if (row) { |
| | | this.$refs.memberTable.toggleRowSelection(row, true) |
| | | this.setSingleSelection(row) |
| | | } |
| | | }) |
| | | } else { |
| | | this.selectData = null |
| | | } |
| | | }) |
| | | }, |
| | |
| | | submitData(){ |
| | | this.$emit('submit',this.selectData) |
| | | }, |
| | | handleCurrentChange(val) { |
| | | this.selectData = val; |
| | | handleSelectionChange(selection) { |
| | | if (!selection || selection.length === 0) { |
| | | this.selectData = null; |
| | | } |
| | | }, |
| | | handleSelect(selection, row) { |
| | | if (!row) { |
| | | return; |
| | | } |
| | | const selectedRow = selection.find((item) => item.id === row.id); |
| | | if (selectedRow) { |
| | | this.setSingleSelection(row); |
| | | } else { |
| | | this.selectData = null; |
| | | } |
| | | }, |
| | | handleRowClick(row) { |
| | | if (!row) { |
| | | return; |
| | | } |
| | | if (this.selectData && this.selectData.id === row.id) { |
| | | this.$refs.memberTable.clearSelection(); |
| | | this.selectData = null; |
| | | return; |
| | | } |
| | | this.setSingleSelection(row); |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped></style> |
| | | <style lang="less" scoped> |
| | | ::v-deep .el-table__row.current-row > td, |
| | | ::v-deep .el-table__row.selection-row > td { |
| | | background: #ebffff !important; |
| | | } |
| | | </style> |
| | |
| | | keepAlive: true, |
| | | }, |
| | | component: () => import("../views/dataManagement/sampleManage/addSample"), |
| | | }, |
| | | { |
| | | path: "detailSample", |
| | | name: "detailSample", |
| | | meta: { |
| | | title: "样品详情", |
| | | hide: true, |
| | | keepAlive: true, |
| | | }, |
| | | component: () => import("../views/dataManagement/sampleManage/addSample"), |
| | | }, { |
| | | path: "record", |
| | | meta: { |
| | |
| | | component: () => import("../views/chemistQa/projectTesting/add.vue"), |
| | | }, |
| | | { |
| | | path: "detail", |
| | | name: "DetailProjectTesting", |
| | | meta: { |
| | | title: "检测项详情", |
| | | hide: true, |
| | | keepAlive: true, |
| | | }, |
| | | component: () => import("../views/chemistQa/projectTesting/add.vue"), |
| | | }, |
| | | { |
| | | path: "addDetectionReport", |
| | | meta: { |
| | | title: "新增报告", |
| | |
| | | }, |
| | | { |
| | | // 工艺工程师 |
| | | path: "detailTesterWorkerEvaluate", |
| | | name: 'DetailTesterWorkerEvaluate', |
| | | meta: { |
| | | title: "实验员工作评定详情", |
| | | hide: true, |
| | | keepAlive: true, |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/testerWorkerEvaluate/add"), |
| | | }, |
| | | { |
| | | // 工艺工程师 |
| | | path: "chemistEvaluate", |
| | | meta: { |
| | | title: "化验师工作评定", |
| | |
| | | |
| | | ::selection { |
| | | background: fade(@theme-color, 20%); |
| | | } |
| | | } |
| | | .el-table__cell { |
| | | .cell{ |
| | | display: flex; |
| | | justify-content: space-around; |
| | | } |
| | | } |
| | |
| | | <div class="table-setting"> |
| | | <div class="flex a-center"> |
| | | <div class="table-title" :class="{ active: currentType == 'list' }" @click="handleTypeChange('list')"> |
| | | 中试、生产验证试验检验分析报告 |
| | | 实验、中试、生产验证试验检验分析报告 |
| | | </div> |
| | | <div v-if="isChemist" class="table-tit" :class="{ active: currentType == 'draft' }" @click="handleTypeChange('draft')"> |
| | | 草稿箱 |
| | |
| | | import chooseProject from '@/components/chooseProject' |
| | | import ShowDelConfirm from "@/components/showDelConfirm/index.vue"; |
| | | import { addData, editData, getDetail,revokedReport,deleteDetail } from './service' |
| | | import { mapState } from "vuex"; |
| | | |
| | | export default { |
| | | name: "AddProjectTesting", |
| | |
| | | isDetail: false, |
| | | currentType: 'list', // 当前显示类型:list-列表,draft-草稿箱 |
| | | expandRowKeys: [], |
| | | allReportTableData: [], |
| | | reportTableData: [], |
| | | reportTotal: 0, |
| | | form: { |
| | |
| | | } |
| | | }, |
| | | mounted() { |
| | | const routeName = this.$route.name; |
| | | if (routeName === "EditProjectTesting" && this.$route.query.id) { |
| | | if (this.$route.query.type === 'detail') { |
| | | this.isDetail = true |
| | | } else if (this.$route.query.type === 'edit') { |
| | | this.isEdit = true |
| | | } |
| | | this.getDetail() |
| | | } |
| | | if (this.$route.query.itemId) { |
| | | this.itemId = this.$route.query.itemId |
| | | } |
| | | }, |
| | | activated() { |
| | | const routeId = this.$route.query.id; |
| | | const routeName = this.$route.name; |
| | | |
| | | // 如果是编辑路由,且id发生变化,重新加载数据 |
| | | if (routeName === "EditProjectTesting" && routeId && routeId !== this.form.id) { |
| | | if (this.$route.query.type === 'detail') { |
| | | this.isDetail = true |
| | | } else if (this.$route.query.type === 'edit') { |
| | | this.isEdit = true |
| | | } |
| | | this.getDetail() |
| | | } |
| | | // 如果是新增路由,不重置表单,保留用户填写的数据 |
| | | }, |
| | | this.initPageMode(); |
| | | this.initRouteData(); |
| | | }, |
| | | activated() { |
| | | this.initPageMode(); |
| | | this.itemId = this.$route.query.itemId || null; |
| | | |
| | | const routeId = this.$route.query.id; |
| | | if ((this.isEdit || this.isDetail) && routeId && routeId !== this.form.id) { |
| | | this.getDetail(); |
| | | } |
| | | }, |
| | | computed: { |
| | | ...mapState(["tagList"]) |
| | | }, |
| | | methods: { |
| | | initPageMode() { |
| | | const routeName = this.$route.name; |
| | | this.isEdit = routeName === 'EditProjectTesting'; |
| | | this.isDetail = routeName === 'DetailProjectTesting'; |
| | | }, |
| | | initRouteData() { |
| | | this.itemId = this.$route.query.itemId || null; |
| | | if ((this.isEdit || this.isDetail) && this.$route.query.id) { |
| | | this.getDetail(); |
| | | } |
| | | }, |
| | | getDetail() { |
| | | getDetail(this.$route.query.id).then(res => { |
| | | if (res) { |
| | |
| | | this.$forceUpdate() |
| | | this.showChoose = false |
| | | }, |
| | | backToListAndCloseTag() { |
| | | const currentPath = this.$route.path; |
| | | this.$router.push('/chemistQa/projectTesting'); |
| | | this.$store.commit( |
| | | "SET_TAGLIST", |
| | | this.tagList.filter((item) => item.path !== currentPath) |
| | | ); |
| | | }, |
| | | submit() { |
| | | if (this.tableData.length === 0) { |
| | | this.$message.error('请选择项目组') |
| | |
| | | request.then(res => { |
| | | if (res.code === 200) { |
| | | this.$message.success(this.isEdit ? '修改成功' : '提交成功') |
| | | this.$router.push('/chemistQa/projectTesting') |
| | | this.backToListAndCloseTag() |
| | | } else { |
| | | this.$message.error(res.msg || (this.isEdit ? '修改失败' : '提交失败')) |
| | | } |
| | |
| | | request.then(res => { |
| | | if (res.code === 200) { |
| | | this.$message.success(this.isEdit ? '修改成功' : '保存成功') |
| | | this.$router.push('/chemistQa/projectTesting') |
| | | this.backToListAndCloseTag() |
| | | } else { |
| | | this.$message.error(res.msg || (this.isEdit ? '修改失败' : '保存失败')) |
| | | } |
| | |
| | | path: '/chemistQa/addDetectionReport', |
| | | query: { |
| | | id: row.id, |
| | | itemId: this.$route.query.id, |
| | | itemId: this.form.id || this.$route.query.id, |
| | | type: 'detail' |
| | | } |
| | | }) |
| | |
| | | path: '/chemistQa/addDetectionReport', |
| | | query: { |
| | | id: row.id, |
| | | itemId: this.$route.query.id, |
| | | itemId: this.form.id || this.$route.query.id, |
| | | type: 'edit' |
| | | } |
| | | }) |
| | |
| | | margin-bottom: 20px; |
| | | } |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | this.$router.push({ |
| | | path: '/chemistQa/edit', |
| | | query: { |
| | | id: row.id, |
| | | type: 'edit' |
| | | id: row.id |
| | | } |
| | | }) |
| | | }, |
| | |
| | | }, |
| | | handleDetail(row) { |
| | | if (this.isChemist) { |
| | | // 化验师角色使用原有逻辑 |
| | | // 化验师角色进入独立详情路由 |
| | | this.$router.push({ |
| | | path: '/chemistQa/add', |
| | | path: '/chemistQa/detail', |
| | | query: { |
| | | id: row.id, |
| | | // itemId: row.itemId, |
| | | type: 'detail' |
| | | id: row.id |
| | | } |
| | | }) |
| | | } else { |
| | |
| | | this.currentAction = 'revoke'; |
| | | this.confirmType = 'revoke'; |
| | | this.confirmTitle = '确认要撤销这条审批吗?'; |
| | | this.confirmTip = '撤销后工艺工程师将无法收到此条审批信息'; |
| | | this.confirmTip = '撤销后,审批人将无法收到此条审批信息'; |
| | | this.showDelConfirm = true; |
| | | }, |
| | | handleWithdraw(row) { |
| | |
| | | margin-bottom: 20px; |
| | | } |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | <TableCustom :queryForm="form" |
| | | :tableData="tableData" |
| | | :total="total" |
| | | :height="null" |
| | | @handleCurrentChange="handleCurrentChange" |
| | | @handleSizeChange="handleSizeChange"> |
| | | <template #search> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { customUploadRequest, getFullUrl } from "@/utils/utils"; |
| | | import apiConfig from "@/utils/baseurl"; |
| | | import { |
| | | customUploadRequest, |
| | | getAllocateIp, |
| | | getFullUrl, |
| | | } from "@/utils/utils"; |
| | | export default { |
| | | name: "AddDialog", |
| | | props: { |
| | |
| | | }, |
| | | photoList: [], |
| | | spectrumList: [], |
| | | photoUploadQueue: [], |
| | | isPhotoUploading: false, |
| | | spectrumUploadQueue: [], |
| | | isSpectrumUploading: false, |
| | | }; |
| | | }, |
| | | computed: { |
| | |
| | | }, |
| | | }, |
| | | methods: { |
| | | normalizeRelativeUrl(url) { |
| | | if (!url) return ""; |
| | | const prefixes = [getAllocateIp(), apiConfig.showImgUrl].filter(Boolean); |
| | | const matchedPrefix = prefixes.find((prefix) => url.startsWith(prefix)); |
| | | return matchedPrefix ? url.slice(matchedPrefix.length) : url; |
| | | }, |
| | | buildUploadItem(file) { |
| | | const rawUrl = this.normalizeRelativeUrl(file.rawUrl || file.url || ""); |
| | | return { |
| | | name: file.name || "", |
| | | rawUrl, |
| | | url: getFullUrl(rawUrl), |
| | | status: "success", |
| | | }; |
| | | }, |
| | | buildSubmitFileList(fileList) { |
| | | return (fileList || []).map((file) => ({ |
| | | name: file.name || "", |
| | | url: this.normalizeRelativeUrl(file.rawUrl || file.url || ""), |
| | | })); |
| | | }, |
| | | setFormData(data) { |
| | | // 设置基础表单数据 |
| | | this.form.dataCode = data.dataCode; |
| | |
| | | typeof data.dataPictures === "string" |
| | | ? JSON.parse(data.dataPictures) |
| | | : data.dataPictures; |
| | | this.photoList = pictures.map((photo) => ({ |
| | | name: photo.name, |
| | | url: photo.url, |
| | | status: "success", |
| | | })); |
| | | this.photoList = pictures.map((photo) => this.buildUploadItem(photo)); |
| | | } catch (e) { |
| | | console.error("解析照片数据失败:", e); |
| | | this.photoList = []; |
| | |
| | | typeof data.dataFiles === "string" |
| | | ? JSON.parse(data.dataFiles) |
| | | : data.dataFiles; |
| | | this.spectrumList = files.map((file) => ({ |
| | | name: file.name, |
| | | url: file.url, |
| | | status: "success", |
| | | })); |
| | | this.spectrumList = files.map((file) => this.buildUploadItem(file)); |
| | | } catch (e) { |
| | | console.error("解析图谱数据失败:", e); |
| | | this.spectrumList = []; |
| | |
| | | this.$refs.form?.resetFields(); |
| | | this.photoList = []; |
| | | this.spectrumList = []; |
| | | this.photoUploadQueue = []; |
| | | this.isPhotoUploading = false; |
| | | this.spectrumUploadQueue = []; |
| | | this.isSpectrumUploading = false; |
| | | this.form = { |
| | | dataCode: "", |
| | | dataTitle: "", |
| | |
| | | dataType: Array.isArray(this.form.dataType) |
| | | ? this.form.dataType.join(",") |
| | | : this.form.dataType, |
| | | dataFiles: JSON.stringify(this.spectrumList), |
| | | dataPictures: JSON.stringify(this.photoList), |
| | | dataFiles: JSON.stringify(this.buildSubmitFileList(this.spectrumList)), |
| | | dataPictures: JSON.stringify( |
| | | this.buildSubmitFileList(this.photoList) |
| | | ), |
| | | }; |
| | | this.$emit("success", submitData); |
| | | } |
| | | }); |
| | | }, |
| | | // 真实图片上传 |
| | | handlePhotoUpload(options) { |
| | | const { file, onSuccess, onError } = options; |
| | | customUploadRequest({ |
| | | file, |
| | | onSuccess: (res) => { |
| | | console.log('res',res) |
| | | if (res.code == 200) { |
| | | const fileObj = { |
| | | name: file.name, |
| | | url: getFullUrl(res.msg || res.data || ""), |
| | | status: "success", |
| | | }; |
| | | this.photoList.push(fileObj); |
| | | // this.$refs.form.validateField("photos"); |
| | | this.$message.success("图片上传成功"); |
| | | onSuccess(res); |
| | | } else { |
| | | this.$message.error(res.message || "图片上传失败"); |
| | | onError(); |
| | | } |
| | | }, |
| | | onError: (err) => { |
| | | this.$message.error("图片上传失败"); |
| | | onError(err); |
| | | }, |
| | | uploadSingleFile(file) { |
| | | return new Promise((resolve, reject) => { |
| | | customUploadRequest({ |
| | | file, |
| | | onSuccess: resolve, |
| | | onError: reject, |
| | | }); |
| | | }); |
| | | }, |
| | | getUploadErrorMessage(err, defaultMessage) { |
| | | if ( |
| | | err && |
| | | err.response && |
| | | err.response.data && |
| | | (err.response.data.msg || err.response.data.message) |
| | | ) { |
| | | return err.response.data.msg || err.response.data.message; |
| | | } |
| | | return (err && err.message) || defaultMessage; |
| | | }, |
| | | // 真实图片上传,按选择顺序串行上传 |
| | | handlePhotoUpload(options) { |
| | | this.photoUploadQueue.push(options); |
| | | this.processPhotoUploadQueue(); |
| | | }, |
| | | async processPhotoUploadQueue() { |
| | | if (this.isPhotoUploading || !this.photoUploadQueue.length) { |
| | | return; |
| | | } |
| | | |
| | | this.isPhotoUploading = true; |
| | | const { file, onSuccess, onError } = this.photoUploadQueue.shift(); |
| | | |
| | | try { |
| | | const res = await this.uploadSingleFile(file); |
| | | if (res.code == 200) { |
| | | const fileObj = { |
| | | name: file.name, |
| | | rawUrl: this.normalizeRelativeUrl(res.msg || res.data || ""), |
| | | url: getFullUrl(res.msg || res.data || ""), |
| | | status: "success", |
| | | }; |
| | | this.photoList.push(fileObj); |
| | | this.$message.success("图片上传成功"); |
| | | onSuccess && onSuccess(res); |
| | | } else { |
| | | const errorMessage = res.msg || res.message || "图片上传失败"; |
| | | this.$message.error(errorMessage); |
| | | onError && onError(new Error(errorMessage)); |
| | | } |
| | | } catch (err) { |
| | | const errorMessage = this.getUploadErrorMessage(err, "图片上传失败"); |
| | | this.$message.error(errorMessage); |
| | | onError && onError(err); |
| | | } finally { |
| | | this.isPhotoUploading = false; |
| | | this.processPhotoUploadQueue(); |
| | | } |
| | | }, |
| | | handlePhotoRemove(file) { |
| | | const index = this.photoList.findIndex((item) => item.name === file.name); |
| | |
| | | // this.$refs.form.validateField("photos"); |
| | | } |
| | | }, |
| | | // 真实图谱上传 |
| | | // 真实图谱上传,按选择顺序串行上传 |
| | | handleSpectrumUpload(options) { |
| | | const { file, onSuccess, onError } = options; |
| | | customUploadRequest({ |
| | | file, |
| | | onSuccess: (res) => { |
| | | if (res.code === 200) { |
| | | const fileObj = { |
| | | name: file.name, |
| | | url: getFullUrl(res.msg || res.data || ""), |
| | | status: "success", |
| | | }; |
| | | this.spectrumList.push(fileObj); |
| | | // this.$refs.form.validateField('spectrums'); |
| | | this.$message.success("文件上传成功"); |
| | | onSuccess(res); |
| | | } else { |
| | | this.$message.error(res.message || "文件上传失败"); |
| | | onError(); |
| | | } |
| | | }, |
| | | onError: (err) => { |
| | | this.$message.error("文件上传失败"); |
| | | onError(err); |
| | | }, |
| | | }); |
| | | this.spectrumUploadQueue.push(options); |
| | | this.processSpectrumUploadQueue(); |
| | | }, |
| | | async processSpectrumUploadQueue() { |
| | | if (this.isSpectrumUploading || !this.spectrumUploadQueue.length) { |
| | | return; |
| | | } |
| | | |
| | | this.isSpectrumUploading = true; |
| | | const { file, onSuccess, onError } = this.spectrumUploadQueue.shift(); |
| | | |
| | | try { |
| | | const res = await this.uploadSingleFile(file); |
| | | if (res.code === 200) { |
| | | const fileObj = { |
| | | name: file.name, |
| | | rawUrl: this.normalizeRelativeUrl(res.msg || res.data || ""), |
| | | url: getFullUrl(res.msg || res.data || ""), |
| | | status: "success", |
| | | }; |
| | | this.spectrumList.push(fileObj); |
| | | this.$message.success("文件上传成功"); |
| | | onSuccess && onSuccess(res); |
| | | } else { |
| | | const errorMessage = res.msg || res.message || "文件上传失败"; |
| | | this.$message.error(errorMessage); |
| | | onError && onError(new Error(errorMessage)); |
| | | } |
| | | } catch (err) { |
| | | const errorMessage = this.getUploadErrorMessage(err, "文件上传失败"); |
| | | this.$message.error(errorMessage); |
| | | onError && onError(err); |
| | | } finally { |
| | | this.isSpectrumUploading = false; |
| | | this.processSpectrumUploadQueue(); |
| | | } |
| | | }, |
| | | handleSpectrumRemove(file) { |
| | | const index = this.spectrumList.findIndex( |
| | |
| | | import AiEditor from '@/components/AiEditor' |
| | | import moment from 'moment' |
| | | import { getDetail, update } from './service' |
| | | import apiConfig from '@/utils/baseurl' |
| | | import { getAllocateIp, getFullUrl } from '@/utils/utils' |
| | | import { mapState } from "vuex"; |
| | | |
| | | export default { |
| | |
| | | ...mapState(["tagList", "isFold"]), |
| | | }, |
| | | methods: { |
| | | normalizeRelativeUrl(url) { |
| | | if (!url) return ''; |
| | | const prefixes = [getAllocateIp(), apiConfig.showImgUrl].filter(Boolean); |
| | | const matchedPrefix = prefixes.find((prefix) => url.startsWith(prefix)); |
| | | return matchedPrefix ? url.slice(matchedPrefix.length) : url; |
| | | }, |
| | | buildDisplayFile(file) { |
| | | const rawUrl = this.normalizeRelativeUrl(file.rawUrl || file.url || ''); |
| | | return { |
| | | ...file, |
| | | rawUrl, |
| | | url: getFullUrl(rawUrl) |
| | | }; |
| | | }, |
| | | // 获取详情 |
| | | getDetail() { |
| | | const id = this.$route.query.id; |
| | |
| | | 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) : [], |
| | | photos: item.dataPictures ? item.dataPictures.split(',').map(url => this.buildDisplayFile({ url })) : [], |
| | | spectrums: item.dataFiles ? JSON.parse(item.dataFiles).map(file => this.buildDisplayFile(file)) : [], |
| | | createTime: item.createTime || moment().format('YYYY-MM-DD HH:mm:ss') |
| | | })); |
| | | } else { |
| | |
| | | .catch(() => { }); |
| | | }, |
| | | handleTaskSubmit(formData) { |
| | | const photos = formData.dataPictures |
| | | ? JSON.parse(formData.dataPictures).map((photo) => |
| | | this.buildDisplayFile(photo) |
| | | ) |
| | | : []; |
| | | const spectrums = formData.dataFiles |
| | | ? JSON.parse(formData.dataFiles).map((file) => this.buildDisplayFile(file)) |
| | | : []; |
| | | |
| | | const newData = { |
| | | 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) : [], |
| | | photos, |
| | | spectrums, |
| | | createTime: this.isEdit ? this.taskTableData[this.currentEditIndex].createTime : moment().format('YYYY-MM-DD HH:mm:ss') |
| | | }; |
| | | if (this.isEdit && this.currentEditIndex > -1) { |
| | |
| | | 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(','), |
| | | dataFiles: JSON.stringify( |
| | | (item.spectrums || []).map(file => ({ |
| | | name: file.name || '', |
| | | url: this.normalizeRelativeUrl(file.rawUrl || file.url || '') |
| | | })) |
| | | ), |
| | | dataPictures: (item.photos || []) |
| | | .map(photo => this.normalizeRelativeUrl(photo.rawUrl || photo.url || '')) |
| | | .join(','), |
| | | originalId: this.form.id, |
| | | resultText: item.resultText || '' |
| | | })) |
| | |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | created() { |
| | | const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}'); |
| | | this.userRole = userInfo.roleType || ''; |
| | | |
| | | // 获取路由参数 |
| | | const { id, type } = this.$route.query; |
| | | if (id) { |
| | | this.pageType = type || 'detail'; |
| | | this.getDetailData(id); |
| | | } |
| | | this.initPageMode(); |
| | | this.initRouteData(); |
| | | }, |
| | | activated() { |
| | | const routeId = this.$route.query.id; |
| | | const routeName = this.$route.name; |
| | | console.log('routeName routeName',routeName) |
| | | |
| | | // 如果是编辑路由,且id发生变化,重新加载数据 |
| | | if (routeName === "EditSample" && routeId && routeId !== this.sampleId) { |
| | | |
| | | this.initPageMode(); |
| | | |
| | | // 如果是编辑/详情路由,且id发生变化,重新加载数据 |
| | | if ( |
| | | (routeName === "editSample" || routeName === "detailSample") && |
| | | routeId && |
| | | routeId !== this.sampleId |
| | | ) { |
| | | this.sampleId = routeId; |
| | | const { type } = this.$route.query; |
| | | this.pageType = type || 'detail'; |
| | | this.getDetailData(routeId); |
| | | } |
| | | // 如果是新增路由,不重置表单,保留用户填写的数据 |
| | |
| | | }, |
| | | methods: { |
| | | getFullUrl, |
| | | initPageMode() { |
| | | const routeName = this.$route.name; |
| | | if (routeName === 'editSample') { |
| | | this.pageType = 'edit'; |
| | | } else if (routeName === 'detailSample') { |
| | | this.pageType = 'detail'; |
| | | } else { |
| | | this.pageType = 'add'; |
| | | } |
| | | }, |
| | | initRouteData() { |
| | | const routeId = this.$route.query.id; |
| | | if ((this.pageType === 'edit' || this.pageType === 'detail') && routeId) { |
| | | this.sampleId = routeId; |
| | | this.getDetailData(routeId); |
| | | } |
| | | }, |
| | | // 获取详情数据 |
| | | async getDetailData(id) { |
| | | this.sampleId = id; |
| | |
| | | }); |
| | | }, |
| | | back() { |
| | | this.$router.back(); |
| | | const currentPath = this.$route.path; |
| | | this.$router.push('/sampleManage/manage'); |
| | | this.$store.commit( |
| | | "SET_TAGLIST", |
| | | this.tagList.filter((item) => item.path !== this.$route.path) |
| | | this.tagList.filter((item) => item.path !== currentPath) |
| | | ); |
| | | }, |
| | | // 添加存草稿方法 |
| | |
| | | // margin-top: 20px; |
| | | } |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | {{ getSampleStatus(scope.row) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="200"> |
| | | <el-table-column label="操作" width="200" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <el-button v-if="currentType == 'list'" type="text" @click="handleDetail(scope.row.id)">详情</el-button> |
| | | <template v-if="currentType == 'draft'"> |
| | |
| | | this.$router.push({ |
| | | path: "/sampleManage/editSample", |
| | | query: { |
| | | id: row.id, |
| | | type: 'edit' |
| | | id: row.id |
| | | } |
| | | }); |
| | | }, |
| | |
| | | }, |
| | | handleDetail(id) { |
| | | this.$router.push({ |
| | | path: "/sampleManage/addSample", |
| | | path: "/sampleManage/detailSample", |
| | | query: { |
| | | id: id, |
| | | type: 'detail' |
| | | id: id |
| | | } |
| | | }); |
| | | }, |
| | |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | <template #setting> |
| | | <div class="tableTitle"> |
| | | <div class="flex a-center flex-wrap"> |
| | | <div class="title" :class="{ active: currentType === 'list' }" @click="handleTypeChange('list')">项目课题方案列表 |
| | | <div class="title" :class="{ active: currentType === 'list' }" @click="handleTypeChange('list')">实验方案列表 |
| | | </div> |
| | | <div v-if="userRole == '3' || userRole == '5'" class="drafts" :class="{ active: currentType === 'draft' }" |
| | | @click="handleTypeChange('draft')">草稿箱</div> |
| | |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" fixed="right"> |
| | | <el-table-column label="操作" fixed="right" width="250"> |
| | | <template slot-scope="scope"> |
| | | <!-- 草稿箱模式下,只显示编辑和详情 --> |
| | | <template v-if="currentType === 'draft'"> |
| | |
| | | <template> |
| | | <el-dialog :visible.sync="dialogVisible" :title="dialogTitle" width="79.17%" @close="handleClose"> |
| | | <EvaluateTable ref="evaluateTable" :viewJson="viewJson" :type="type == 'labTechnician' ? 1 : type == 'experimenter' ? 2 : 3" /> |
| | | <EvaluateTable :key="`${type}-${targetId || 'empty'}-${viewJson || 'empty'}`" ref="evaluateTable" :viewJson="viewJson" |
| | | :type="type == 'labTechnician' ? 1 : type == 'experimenter' ? 2 : 3" /> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit" class="submit-btn">确认评定结果</el-button> |
| | | </div> |
| | |
| | | viewJson: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | targetId: { |
| | | type: [String, Number], |
| | | default: '' |
| | | } |
| | | }, |
| | | data() { |
| | |
| | | modelValue: { |
| | | handler(val) { |
| | | this.dialogVisible = val; |
| | | if (val) { |
| | | this.$nextTick(() => { |
| | | if (this.$refs.evaluateTable && !this.viewJson) { |
| | | this.$refs.evaluateTable.resetData(); |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | immediate: true, |
| | | }, |
| | |
| | | min-width: 80px; |
| | | } |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | <div class="evaluate-card-cotent"> |
| | | <template v-if="selectedProcessEngineer"> |
| | | <template v-if="selectedProcessEngineer.data"> |
| | | <div class="evaluate-table-wrapper" @click="handleEvaluate('processEngineer')"> |
| | | <div class="evaluate-table-wrapper" @click="handleProcessEngineerEvaluate"> |
| | | <EvaluateTable class="evaluate-table" :isReadonly="true" :type="1" |
| | | :viewJson="selectedProcessEngineer.data.resultEvaluateJson" /> |
| | | </div> |
| | | </template> |
| | | <template v-else> |
| | | <div class="no-data">暂未评定</div> |
| | | <div v-if=" |
| | | <!-- 原逻辑保留:详情态下审批人和管理员可直接进入工艺工程师评定 --> |
| | | <!-- <div v-if=" |
| | | isView && form.status == 2 && (userRole == 1 || userRole == 2) |
| | | " class="to-evaluate" @click="handleEvaluate('processEngineer')"> |
| | | " class="to-evaluate" @click="handleEvaluate('processEngineer')"> --> |
| | | <div v-if=" |
| | | !isApproverDetailView && |
| | | isView && |
| | | form.status == 2 && |
| | | (userRole == 1 || userRole == 2) |
| | | " class="to-evaluate" @click="handleProcessEngineerEvaluate"> |
| | | 去评价 |
| | | </div> |
| | | </template> |
| | |
| | | <el-button type="primary" class="save-btn" @click="handleSubmit(1)">提交</el-button> |
| | | <el-button @click="handleSubmit(-1)">存草稿</el-button> |
| | | </div> |
| | | <div class="add-project-footer" v-if="isView && form.status == 2 && (userRole == 1 || userRole == 2)"> |
| | | <el-button type="primary" class="save-btn" @click="handleEvaluate('processEngineer')">工艺工程师评定</el-button> |
| | | <!-- 原逻辑保留:详情态下审批人和管理员显示工艺工程师评定按钮 --> |
| | | <!-- <div class="add-project-footer" v-if="isView && form.status == 2 && (userRole == 1 || userRole == 2)"> --> |
| | | <div class="add-project-footer" v-if=" |
| | | !isApproverDetailView && |
| | | isView && |
| | | form.status == 2 && |
| | | (userRole == 1 || userRole == 2) |
| | | "> |
| | | <el-button type="primary" class="save-btn" @click="handleProcessEngineerEvaluate">工艺工程师评定</el-button> |
| | | <!-- <el-button @click="handleSubmit(-1)">存草稿</el-button> --> |
| | | </div> |
| | | </el-form> |
| | |
| | | @submit="handleSchedulingSelect" /> |
| | | <!-- 评价弹窗 --> |
| | | <evaluation-dialog :modelValue="evaluationDialogVisible" :type="currentEvaluationType" |
| | | :target-id="currentEvaluationTargetId" |
| | | :viewJson="currentEvaluationData ? currentEvaluationData : ''" @update:modelValue="updateEvaluationDialogVisible" |
| | | @submit="handleEvaluationSubmit" /> |
| | | <!-- 检验结果详情弹窗 --> |
| | |
| | | 3: "已封存", |
| | | }, |
| | | currentEvaluationData: null, // 添加当前评价数据 |
| | | currentEvaluationTargetId: null, |
| | | userRole: "", |
| | | // 原始检测项列表--新增 |
| | | formMore: { |
| | |
| | | handleSelectProcessEngineer(engineer) { |
| | | this.selectedProcessEngineer = engineer; |
| | | }, |
| | | handleProcessEngineerEvaluate() { |
| | | if (this.isApproverDetailView) { |
| | | // 原逻辑保留:审批人详情态下点击后会继续执行工艺工程师评定 |
| | | // this.handleEvaluate("processEngineer"); |
| | | return; |
| | | } |
| | | this.handleEvaluate("processEngineer"); |
| | | }, |
| | | // 去评价 |
| | | handleEvaluate(type) { |
| | | if (this.isApproverDetailView && type == "processEngineer") { |
| | | // 原逻辑保留:详情态审批人此前允许打开工艺工程师评定弹窗 |
| | | // this.evaluationDialogVisible = true; |
| | | return; |
| | | } |
| | | if ( |
| | | this.$route.query.type == "view" && |
| | | type != "processEngineer" && |
| | |
| | | return; |
| | | } |
| | | this.currentEvaluationType = type; |
| | | this.currentEvaluationData = null; |
| | | this.currentEvaluationTargetId = null; |
| | | // 根据类型获取当前选中人员的评定数据 |
| | | if (type == "labTechnician" && this.selectedLabTechnician) { |
| | | this.currentEvaluationTargetId = this.selectedLabTechnician.id; |
| | | this.currentEvaluationData = |
| | | this.selectedLabTechnician.data?.resultEvaluateJson; |
| | | } else if (type == "experimenter" && this.selectedExperimenter) { |
| | | this.currentEvaluationTargetId = this.selectedExperimenter.id; |
| | | this.currentEvaluationData = |
| | | this.selectedExperimenter.data?.resultEvaluateJson; |
| | | } else if (type == "processEngineer" && this.selectedProcessEngineer) { |
| | | this.currentEvaluationTargetId = this.selectedProcessEngineer.id; |
| | | this.currentEvaluationData = |
| | | this.selectedProcessEngineer.data?.resultEvaluateJson; |
| | | } |
| | |
| | | } |
| | | this.evaluationDialogVisible = false; |
| | | this.currentEvaluationData = null; |
| | | this.currentEvaluationTargetId = null; |
| | | }, |
| | | // 将分数转换为评定值 |
| | | getEvaluateValue(score) { |
| | |
| | | this.evaluationDialogVisible = value; |
| | | if (!value) { |
| | | this.currentEvaluationData = null; // 关闭弹窗时清空数据 |
| | | this.currentEvaluationTargetId = null; |
| | | } |
| | | }, |
| | | handleSchedulingClose() { |
| | |
| | | }, |
| | | }, |
| | | computed: { |
| | | ...mapState(["tagList", "isFold"]), |
| | | isView() { |
| | | return this.$route.query.type == "view"; |
| | | }, |
| | | isApproverDetailView() { |
| | | return this.isView && this.userRole == 2; |
| | | }, |
| | | }, |
| | | }; |
| | |
| | | gap: 16px; |
| | | |
| | | .evaluate-card-people-item { |
| | | width: 125px; |
| | | min-width: 125px; |
| | | background: #ffffff; |
| | | border-radius: 6px; |
| | | padding: 10px 5px; |
| | |
| | | opacity: 0.8; |
| | | } |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="180"> |
| | | <el-table-column fixed="right" label="操作" width="250"> |
| | | <template slot-scope="scope"> |
| | | <template v-if="currentType === 'list'"> |
| | | <template v-if="isProcessEngineer"> |
| | |
| | | import ExperimentalScheduling from "@/views/dataManagement/schemeManagement/components/experimental-scheduling"; |
| | | import { getEvaluateChemist, add ,getEvaluateDetailById,update} from "./service.js"; |
| | | import moment from "moment"; |
| | | import { mapState } from "vuex"; |
| | | |
| | | export default { |
| | | name: "AddTesterWorkerEvaluate", |
| | |
| | | data() { |
| | | return { |
| | | evaluateId: "", |
| | | editId: "", |
| | | showScheduling: false, |
| | | participantsData: [], |
| | | selectedParticipants: [], |
| | |
| | | activated() { |
| | | const routeId = this.$route.query.id; |
| | | const routeName = this.$route.name; |
| | | |
| | | // 如果是编辑路由,且id发生变化,重新加载数据 |
| | | if (routeName === "EditTesterWorkerEvaluate" && routeId && routeId !== this.evaluateId) { |
| | | |
| | | this.initPageMode(); |
| | | |
| | | // 如果是编辑/详情路由,且id发生变化,重新加载数据 |
| | | if ( |
| | | (routeName === "EditTesterWorkerEvaluate" || |
| | | routeName === "DetailTesterWorkerEvaluate") && |
| | | routeId && |
| | | routeId !== this.evaluateId |
| | | ) { |
| | | this.evaluateId = routeId; |
| | | this.isEdit = this.$route.query.type == "view" ? false : true; |
| | | this.editId = routeId; |
| | | this.loadEditData(); |
| | | } |
| | |
| | | mounted() { |
| | | const routeId = this.$route.query.id; |
| | | const routeName = this.$route.name; |
| | | |
| | | // 如果是编辑路由,加载数据 |
| | | if (routeName === "EditTesterWorkerEvaluate" && routeId) { |
| | | |
| | | this.initPageMode(); |
| | | |
| | | // 如果是编辑/详情路由,加载数据 |
| | | if ( |
| | | (routeName === "EditTesterWorkerEvaluate" || |
| | | routeName === "DetailTesterWorkerEvaluate") && |
| | | routeId |
| | | ) { |
| | | this.evaluateId = routeId; |
| | | this.isEdit = this.$route.query.type == "view" ? false : true; |
| | | this.editId = routeId; |
| | | this.loadEditData(); |
| | | } |
| | | }, |
| | | computed: { |
| | | ...mapState(["tagList"]), |
| | | }, |
| | | methods: { |
| | | initPageMode() { |
| | | const routeName = this.$route.name; |
| | | this.isEdit = routeName !== "DetailTesterWorkerEvaluate"; |
| | | }, |
| | | loadEditData(){ |
| | | getEvaluateDetailById({ id: this.editId }).then((res) => { |
| | | if(res.experimentDispatch){ |
| | |
| | | }; |
| | | return scoreMap[score] || 0; // 默认返回失误 |
| | | }, |
| | | backToListAndCloseTag() { |
| | | const currentPath = this.$route.path; |
| | | this.$router.push("/deliveryAssessment/testerWorkerEvaluate"); |
| | | this.$store.commit( |
| | | "SET_TAGLIST", |
| | | this.tagList.filter((item) => item.path !== currentPath) |
| | | ); |
| | | }, |
| | | submitForm() { |
| | | const evaluateTable = this.$refs.evaluateTable; |
| | | if (!evaluateTable) { |
| | |
| | | update({...evaluateData,id:this.editId}).then((res) => { |
| | | if (res.code == 200) { |
| | | this.$message.success("编辑成功"); |
| | | this.$router.back(); |
| | | this.backToListAndCloseTag(); |
| | | } else { |
| | | this.$message.error(res.msg || "编辑失败"); |
| | | } |
| | |
| | | add(evaluateData).then((res) => { |
| | | if (res.code == 200) { |
| | | this.$message.success("保存成功"); |
| | | this.$router.back(); |
| | | this.backToListAndCloseTag(); |
| | | } else { |
| | | this.$message.error(res.msg || "保存失败"); |
| | | } |
| | |
| | | width: 220px; |
| | | } |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | }); |
| | | }, |
| | | handleDetail(row) { |
| | | // 详情逻辑后续补充 |
| | | this.$router.push({ |
| | | path: "/deliveryAssessment/addTesterWorkerEvaluate", |
| | | query: { id: row.id, type: 'view' }, |
| | | path: "/deliveryAssessment/detailTesterWorkerEvaluate", |
| | | query: { id: row.id }, |
| | | }); |
| | | }, |
| | | handleEdit(row) { |
| | | // 编辑逻辑后续补充 |
| | | this.$router.push({ |
| | | path: "/deliveryAssessment/editTesterWorkerEvaluate", |
| | | query: { id: row.id, type: 'edit' }, |
| | | query: { id: row.id }, |
| | | }); |
| | | }, |
| | | handleDelete(row) { |