| | |
| | | <template> |
| | | <div class="table-container" style="width: 100%;"> |
| | | <el-table ref="elTable" border v-bind="$attrs" v-on="$listeners" :height="height"> |
| | | <el-table ref="elTable" border v-bind="$attrs" v-on="$listeners" :height="height"> |
| | | <slot></slot> |
| | | </el-table> |
| | | <div v-if="total > 0"> |
| | |
| | | |
| | | } |
| | | |
| | | ::v-deep .el-checkbox__input.is-disabled .el-checkbox__inner { |
| | | background-color: #049C9A !important; |
| | | border-color: #049C9A !important; |
| | | |
| | | } |
| | | |
| | | ::v-deep .el-table__expanded-cell { |
| | | padding: 0; |
| | | } |
| | |
| | | /* 当复选框禁用时覆盖默认样式 */ |
| | | |
| | | ::v-deep .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner { |
| | | background-color: #409eff; |
| | | border-color: #409eff; |
| | | background-color: #049C9A !important; |
| | | border-color: #049C9A !important; |
| | | } |
| | | |
| | | ::v-deep .el-checkbox.is-disabled .el-checkbox__inner::after { |
| | |
| | | <!-- <div v-if="!item.meta.hide && menus.includes(item.meta.privilege)"> --> |
| | | <div v-if="item.meta && item.meta.title && !item.meta.hide"> |
| | | <!-- 根菜单 --> |
| | | <MenuLink :to="resolvePath()" v-if="!item.children"> |
| | | <MenuLink :to="resolvePath()" v-if="!filteredChildren || filteredChildren.length === 0"> |
| | | <el-menu-item :index="resolvePath()"> |
| | | <i :class="(item.meta && item.meta.icon) || ''"></i> |
| | | <span slot="title">{{ (item.meta && item.meta.title) || '' }}</span> |
| | |
| | | <i :class="(item.meta && item.meta.icon) || ''"></i> |
| | | <span slot="title">{{ (item.meta && item.meta.title) || '' }}</span> |
| | | </template> |
| | | <!-- 这里递归去展示多级菜单 --> |
| | | <menu-item v-for="(route, index) in item.children" :key="index" :item="route" |
| | | <!-- 递归展示多级菜单,已过滤无权限的children --> |
| | | <menu-item v-for="(route, index) in filteredChildren" :key="index" :item="route" |
| | | :fatherPath="resolvePath(route.path)"> |
| | | </menu-item> |
| | | </el-submenu> |
| | |
| | | import { mapState } from "vuex"; |
| | | import path from "path"; |
| | | import MenuLink from "./MenuLink.vue"; |
| | | |
| | | function filterMenusByPrivilege(menus, flatMenus) { |
| | | if (!menus) return []; |
| | | return menus |
| | | .filter(menu => { |
| | | if (menu.meta && menu.meta.privilege) { |
| | | return flatMenus.includes(menu.meta.privilege); |
| | | } |
| | | return true; |
| | | }) |
| | | .map(menu => { |
| | | if (menu.children && menu.children.length > 0) { |
| | | return { |
| | | ...menu, |
| | | children: filterMenusByPrivilege(menu.children, flatMenus) |
| | | }; |
| | | } |
| | | return menu; |
| | | }) |
| | | .filter(menu => { |
| | | if (menu.children && menu.children.length === 0) { |
| | | return false; |
| | | } |
| | | return true; |
| | | }); |
| | | } |
| | | |
| | | export default { |
| | | // 做组件递归时必须定义一个name。然后递归时的组件名就是这里的name值 |
| | |
| | | }, |
| | | |
| | | computed: { |
| | | ...mapState(["menus"]), |
| | | ...mapState(["flatMenus"]), |
| | | filteredChildren() { |
| | | // 只对children做权限过滤 |
| | | return filterMenusByPrivilege(this.item.children, this.flatMenus); |
| | | } |
| | | }, |
| | | data() { |
| | | return {}; |
| | |
| | | <script> |
| | | import routers from "../../../router"; |
| | | import MenuItem from "./MenuItem.vue"; |
| | | import { mapState } from "vuex"; |
| | | |
| | | // 递归过滤菜单 |
| | | function filterMenusByPrivilege(menus, flatMenus) { |
| | | return menus |
| | | .filter(menu => { |
| | | // 没有 privilege 字段的菜单默认显示,有 privilege 字段的要判断权限 |
| | | if (menu.meta && menu.meta.privilege) { |
| | | return flatMenus.includes(menu.meta.privilege); |
| | | } |
| | | return true; |
| | | }) |
| | | .map(menu => { |
| | | // 递归处理 children |
| | | if (menu.children && menu.children.length > 0) { |
| | | return { |
| | | ...menu, |
| | | children: filterMenusByPrivilege(menu.children, flatMenus) |
| | | }; |
| | | } |
| | | return menu; |
| | | }) |
| | | .filter(menu => { |
| | | // 过滤掉 children 为空的父级菜单 |
| | | if (menu.children && menu.children.length === 0) { |
| | | return false; |
| | | } |
| | | return true; |
| | | }); |
| | | } |
| | | |
| | | export default { |
| | | components: { |
| | | MenuItem, |
| | | }, |
| | | computed: { |
| | | ...mapState(["flatMenus"]), |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | mounted() { |
| | | // 获取所有定义的一级菜单和多级菜单 |
| | | // 过滤掉登录路由和重定向路由,只获取主布局下的路由 |
| | | this.routersList = routers.options.routes.filter(route => |
| | | const allMenus = routers.options.routes.filter(route => |
| | | route.path !== '/login' && |
| | | route.path !== '/' && |
| | | !route.meta?.hide |
| | | ); |
| | | // 权限过滤 |
| | | this.routersList = filterMenusByPrivilege(allMenus, this.flatMenus); |
| | | }, |
| | | }; |
| | | </script> |
| | |
| | | meta: { |
| | | title: "中台", |
| | | middleground: true, |
| | | privilege:'middleground' |
| | | // hide: true, |
| | | }, |
| | | component: () => import("../views/middleground"), |
| | |
| | | path: "/system", |
| | | meta: { |
| | | title: "系统管理", |
| | | privilege:'system' |
| | | |
| | | }, |
| | | component: Layouts, |
| | | children: [{ |
| | |
| | | name: "User", |
| | | meta: { |
| | | title: "人员管理", |
| | | privilege:'system_user' |
| | | }, |
| | | component: () => import("../views/system/user"), |
| | | }, |
| | |
| | | name: "Role", |
| | | meta: { |
| | | title: "角色管理", |
| | | privilege:'system_role' |
| | | }, |
| | | component: () => import("../views/system/role"), |
| | | }, |
| | |
| | | path: "operation-log", |
| | | meta: { |
| | | title: "操作日志", |
| | | privilege:'system_operation-log' |
| | | }, |
| | | component: () => import("../views/system/operation-log"), |
| | | }, |
| | |
| | | path: "/projectList", |
| | | meta: { |
| | | title: "项目组管理", |
| | | privilege:'projectList' |
| | | }, |
| | | component: Layouts, |
| | | children: [{ |
| | |
| | | name: "ProjectList", |
| | | meta: { |
| | | title: "项目组管理", |
| | | privilege:'projectList_list' |
| | | }, |
| | | component: () => import("../views/projectList"), |
| | | }, |
| | |
| | | component: Layouts, |
| | | meta: { |
| | | title: "实验室数据管理", |
| | | privilege:'dataManagement' |
| | | }, |
| | | children: [{ |
| | | path: "approvalPlan", |
| | | meta: { |
| | | title: "项目课题方案审批", |
| | | keepAlive: true, |
| | | privilege:'dataManagement_approvalPlan' |
| | | }, |
| | | component: () => import("../views/dataManagement/approvalPlan/list.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "实验调度管理", |
| | | keepAlive: true, |
| | | privilege:'dataManagement_dispatching' |
| | | }, |
| | | component: () => import("../views/dataManagement/dispatching/list.vue"), |
| | | }, |
| | |
| | | name: "ConfirmationSheet", |
| | | meta: { |
| | | title: "检验方法确认单", |
| | | privilege:'dataManagement_confirmation-sheet' |
| | | }, |
| | | component: () => import("../views/dataManagement/confirmation-sheet"), |
| | | }, |
| | |
| | | name: "schemeManagement", |
| | | meta: { |
| | | title: "实验方案管理", |
| | | privilege:'dataManagement_scheme-management' |
| | | }, |
| | | component: () => import("../views/dataManagement/schemeManagement/list.vue"), |
| | | }, |
| | |
| | | path: "/sampleManage", |
| | | meta: { |
| | | title: "样品管理", |
| | | privilege:'sampleManage' |
| | | // keepAlive: true, |
| | | }, |
| | | component: Parent, |
| | |
| | | meta: { |
| | | title: "样品管理", |
| | | keepAlive: true, |
| | | privilege:'sampleManage_manage' |
| | | }, |
| | | component: () => import("../views/dataManagement/sampleManage/list.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "取样操作记录列表", |
| | | keepAlive: true, |
| | | privilege:'sampleManage_record' |
| | | }, |
| | | component: () => import("../views/dataManagement/sampleRecordList/list.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "送样单列表", |
| | | keepAlive: true, |
| | | privilege:'sampleManage_submissionList' |
| | | }, |
| | | component: () => import("../views/dataManagement/sampleSubmissionList/list.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "取样送样记录", |
| | | keepAlive: true, |
| | | privilege:'dataManagement_deliveryRecord' |
| | | }, |
| | | component: () => import("../views/dataManagement/SampleDeliveryRecord/list.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "原始检验记录", |
| | | keepAlive: true, |
| | | privilege:'dataManagement_originalRecordTest' |
| | | }, |
| | | component: () => import("../views/dataManagement/originalRecordTest/list.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "检验报告管理", |
| | | keepAlive: true, |
| | | privilege:'dataManagement_inspectionReport' |
| | | }, |
| | | component: () => import("../views/dataManagement/inspectionReport/list.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "实验结果汇报", |
| | | keepAlive: true, |
| | | privilege:'dataManagement_testResultReport' |
| | | }, |
| | | component: () => import("../views/dataManagement/testResultReport/list.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "实验中止审批", |
| | | keepAlive: true, |
| | | privilege:'dataManagement_suspendExperiment' |
| | | }, |
| | | component: () => import("../views/dataManagement/suspendExperiment/list.vue"), |
| | | }, |
| | |
| | | component: Layouts, |
| | | meta: { |
| | | title: "专业报告库审批", |
| | | privilege:'reportLibrary' |
| | | }, |
| | | children: [{ |
| | | path: "feasibilityStudy", |
| | | meta: { |
| | | title: "可研报告库", |
| | | keepAlive: true, |
| | | privilege:'reportLibrary_feasibilityStudy' |
| | | }, |
| | | component: () => import("../views/reportLibrary/feasibilityStudy/index.vue"), |
| | | }, |
| | |
| | | }, |
| | | component: () => import("../views/reportLibrary/feasibilityStudy/add.vue"), |
| | | }, |
| | | |
| | | { |
| | | path: "feasibilityReport", |
| | | meta: { |
| | | title: "可行报告库", |
| | | keepAlive: true, |
| | | privilege:'reportLibrary_feasibilityReport' |
| | | }, |
| | | component: () => import("../views/reportLibrary/feasibilityReport/index.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "工艺开发工具", |
| | | keepAlive: true, |
| | | privilege:'reportLibrary_processDevelopment' |
| | | }, |
| | | component: () => import("../views/reportLibrary/processDevelopment/index.vue"), |
| | | }, |
| | |
| | | }, |
| | | component: () => import("../views/reportLibrary/processDevelopment/add.vue"), |
| | | }, |
| | | |
| | | |
| | | |
| | | { |
| | | path: "verificationRelease", |
| | | meta: { |
| | | title: "验证与发布", |
| | | keepAlive: true, |
| | | privilege:'reportLibrary_verificationRelease' |
| | | }, |
| | | component: () => import("../views/reportLibrary/verificationRelease/index.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "立项报告库", |
| | | keepAlive: true, |
| | | privilege:'reportLibrary_projectProposalLibrary' |
| | | }, |
| | | component: () => import("../views/reportLibrary/projectProposalLibrary/index.vue"), |
| | | }, |
| | |
| | | component: Layouts, |
| | | meta: { |
| | | title: "化验师QA专题报告", |
| | | privilege:'chemistQa' |
| | | }, |
| | | children: [{ |
| | | path: "projectTesting", |
| | | meta: { |
| | | title: "项目检测项、检验包列表", |
| | | keepAlive: true, |
| | | privilege:'chemistQa_projectTesting' |
| | | }, |
| | | component: () => import("../views/chemistQa/projectTesting/index.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "中试、生产验证试验检验分析报告", |
| | | keepAlive: true, |
| | | privilege:'chemistQa_pilotAndProduction' |
| | | }, |
| | | component: () => import("../views/chemistQa/pilotAndProduction/index.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "原辅料、包材、竞品检验分析报告", |
| | | keepAlive: true, |
| | | privilege:'chemistQa_rawMaterials' |
| | | }, |
| | | component: () => import("../views/chemistQa/rawMaterials/index.vue"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "产品报批及项目工作总计报告", |
| | | keepAlive: true, |
| | | privilege:'chemistQa_productApproval' |
| | | }, |
| | | component: () => import("../views/chemistQa/productApproval/index.vue"), |
| | | }, |
| | |
| | | component: Layouts, |
| | | meta: { |
| | | title: "工作交付评定", |
| | | privilege:'deliveryAssessment' |
| | | }, |
| | | children: [{ |
| | | path: "projectTeamIntegral", |
| | | meta: { |
| | | title: "项目组总积分", |
| | | privilege:'deliveryAssessment_projectTeamIntegral' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/projectTeamIntegral"), |
| | | }, |
| | |
| | | path: "taskList", |
| | | meta: { |
| | | title: "课题列表", |
| | | privilege:'deliveryAssessment_taskList' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/taskList"), |
| | | }, |
| | |
| | | path: "restsTask", |
| | | meta: { |
| | | title: "实验员其他任务", |
| | | privilege:'deliveryAssessment_restsTask' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/restsTask"), |
| | | }, |
| | |
| | | path: "clinicalTrial", |
| | | meta: { |
| | | title: "临床试验积分列表", |
| | | privilege:'deliveryAssessment_clinicalTrial' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/clinicalTrial"), |
| | | }, |
| | |
| | | path: "testingAndEvaluation", |
| | | meta: { |
| | | title: "检测项评定列表", |
| | | privilege:'deliveryAssessment_testingAndEvaluation' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/testingAndEvaluation"), |
| | | }, |
| | |
| | | path: "experimentResults", |
| | | meta: { |
| | | title: "实验结果评定", |
| | | privilege:'deliveryAssessment_experimentResults' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/experimentResults"), |
| | | }, |
| | |
| | | path: "assayTaskList", |
| | | meta: { |
| | | title: "课题评定列表", |
| | | privilege:'deliveryAssessment_assayTaskList' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/assayTaskList"), |
| | | }, |
| | |
| | | path: "processEngineerEvaluate", |
| | | meta: { |
| | | title: "工艺工程师工作评定详情", |
| | | privilege:'deliveryAssessment_processEngineerEvaluate' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/processEngineerEvaluate"), |
| | | }, |
| | |
| | | path: "testerWorkerEvaluate", |
| | | meta: { |
| | | title: "实验员工作评定", |
| | | privilege:'deliveryAssessment_testerWorkerEvaluate' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/testerWorkerEvaluate"), |
| | | }, |
| | |
| | | path: "chemistEvaluate", |
| | | meta: { |
| | | title: "化验师工作评定", |
| | | privilege:'deliveryAssessment_chemistEvaluate' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/chemistEvaluate"), |
| | | }, |
| | |
| | | name: 'QAList', |
| | | meta: { |
| | | title: "化验师QA专题报告评定", |
| | | privilege:'deliveryAssessment_QAList', |
| | | keepAlive: true, |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/QA"), |
| | |
| | | name: 'ExperimenterJobEvaluation', |
| | | meta: { |
| | | title: "实验员工作评定详情", |
| | | privilege:'deliveryAssessment_experimenterJobEvaluation', |
| | | keepAlive: true, |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/experimenterJobEvaluation"), |
| | |
| | | meta: { |
| | | title: "化验师工作评定详情", |
| | | keepAlive: true, |
| | | privilege:'deliveryAssessment_technicianJobEvaluation' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/technicianJobEvaluation"), |
| | | }, |
| | |
| | | meta: { |
| | | title: "专业报告库评定", |
| | | keepAlive: true, |
| | | privilege:'deliveryAssessment_reportEvaluation' |
| | | }, |
| | | component: () => import("../views/deliveryAssessment/reportEvaluation"), |
| | | }, |
| | |
| | | return; |
| | | } |
| | | |
| | | // 判断是否拥有要跳转菜单权限 |
| | | let menus = store.state.menus |
| | | if (to.meta.hasOwnProperty('privilege') && !menus.includes(to.meta.privilege)) { |
| | | return |
| | | // 权限判断(使用flatMenus) |
| | | let flatMenus = store.state.flatMenus |
| | | if (!flatMenus || flatMenus.length === 0) { |
| | | // 刷新后从sessionStorage恢复 |
| | | const menus = JSON.parse(sessionStorage.getItem('menus') || '[]') |
| | | const flat = JSON.parse(sessionStorage.getItem('flatMenus') || '[]') |
| | | store.commit('SET_MENUS', menus) |
| | | store.commit('SET_FLAT_MENUS', flat) |
| | | flatMenus = flat |
| | | } |
| | | if (to.meta && to.meta.privilege) { |
| | | if (!flatMenus.includes(to.meta.privilege)) { |
| | | next('/403') // 无权限跳转403 |
| | | return |
| | | } |
| | | } |
| | | |
| | | // 设置标签列表 |
| | |
| | | const store = new Vuex.Store({ |
| | | state: { |
| | | menus: sessionStorage.getItem('menuList') ? JSON.parse(sessionStorage.getItem('menuList')) : [], |
| | | flatMenus: sessionStorage.getItem('flatMenus') ? JSON.parse(sessionStorage.getItem('flatMenus')) : [], // 新增,拍平后的path数组 |
| | | keepAliveList: sessionStorage.getItem('keepAliveList') ? JSON.parse(sessionStorage.getItem('keepAliveList')) : [],//缓存页面 |
| | | tagList: sessionStorage.getItem('tagList') ? JSON.parse(sessionStorage.getItem('tagList')) : [],//标签列表 |
| | | isFold: false,//是否折叠 |
| | |
| | | SET_MENUS(state, data) { |
| | | state.menus = data; |
| | | }, |
| | | SET_FLAT_MENUS(state, data) { |
| | | state.flatMenus = data; |
| | | }, |
| | | SET_KEEPALIVELIST(state, data) { |
| | | state.keepAliveList = data; |
| | | sessionStorage.setItem('keepAliveList', JSON.stringify(data)); |
| | |
| | | setMenus({ commit }, data) { |
| | | commit('SET_MENUS', data); |
| | | }, |
| | | setFlatMenus({ commit }, data) { |
| | | commit('SET_FLAT_MENUS', data); |
| | | }, |
| | | setKeepAliveList({ commit }, data) { |
| | | commit('SET_KEEPALIVELIST', data); |
| | | }, |
| | |
| | | planName: '', // 项目课题方案名称 |
| | | testCode: '', // 实验编号 |
| | | testName: '', // 实验名称 |
| | | sampleCode: '' // 取样单编号 |
| | | }, |
| | | selectedScheduling: null, // 添加选中的实验调度数据 |
| | | currentTestItem: null, // 当前编辑的检测项 |
| | |
| | | planName: selectedData.projectName || '', |
| | | testCode: selectedData.experimentCode || '', |
| | | testName: selectedData.experimentName || '', |
| | | sampleCode: selectedData.experimentCode || '' // 使用实验编号作为取样单编号 |
| | | }; |
| | | }, |
| | | |
| | |
| | | planName: this.selectedScheduling.projectName || '', // 所属项目课题方案 |
| | | testCode: this.selectedScheduling.experimentCode || '', // 实验编号 |
| | | testName: this.selectedScheduling.experimentName || '', // 实验名称 |
| | | sampleCode: this.selectedScheduling.experimentCode || '' // 取样单编号 |
| | | } |
| | | this.confirmDialogVisible = true |
| | | }, |
| | |
| | | // 设置实验调度数据 |
| | | this.selectedScheduling = { |
| | | id: res.dispatchId, |
| | | ...res |
| | | } |
| | | this.tableData = [{ |
| | | // planCode: res.projectName, |
| | |
| | | status: this.getStatusText(res.status) // 状态 |
| | | |
| | | }] |
| | | // this.confirmFormData = { |
| | | // planName: res.projectName || '', |
| | | // testCode: res.experimentCode || '', |
| | | // testName: res.experimentName || '', |
| | | // }; |
| | | console.log('confirmFormData confirmFormData ',this.confirmFormData) |
| | | |
| | | // 设置检测项数据 |
| | | this.testItems = res.testMethodConfirmSheetTerms.map(item => ({ |
| | |
| | | confirmSign: res.confirmSign, |
| | | signTime: res.signTime |
| | | } |
| | | |
| | | } |
| | | } catch (error) { |
| | | this.$message.error('获取详情失败:' + (error.message || '未知错误')) |
| | |
| | | } |
| | | // 获取实验调度列表 |
| | | export const getDispatchList = (data) => { |
| | | return axios.get('/open/t-experiment-dispatch/chemistSignList', { ...data }) |
| | | return axios.get('/open/t-experiment-dispatch/chemistSignList', { params:data }) |
| | | } |
| | | // 撤销 |
| | | export const revokedSheet = (data) => { |
| | | return axios.get('/open/t-test-method-confirm-sheet/revokedSheet', { params:data }) |
| | | return axios.put(`/open/t-test-method-confirm-sheet/revokedSheet?id=${data.id}`, {params:data }) |
| | | } |
| | |
| | | const index = this.allTaskTableData.findIndex(item => item === row) |
| | | if (index > -1) { |
| | | this.allTaskTableData.splice(index, 1) |
| | | // 删除后判断是否需要跳页 |
| | | const maxPage = Math.ceil(this.allTaskTableData.length / this.taskPageSize) || 1; |
| | | if (this.taskPageNum > maxPage) { |
| | | this.taskPageNum = maxPage; |
| | | } |
| | | this.updateTaskTableData(); |
| | | this.$message.success('删除成功') |
| | | } |
| | |
| | | this.allTaskTableData.splice(index, 1, taskData); |
| | | } else { |
| | | this.allTaskTableData.push(taskData); |
| | | this.taskPageNum = 1; // 新增后回到第一页 |
| | | } |
| | | this.updateTaskTableData(); |
| | | // 更新表单数据 |
| | |
| | | <template> |
| | | <Card> |
| | | <el-form |
| | | ref="form" |
| | | :model="form" |
| | | :rules="rules" |
| | | inline |
| | | label-position="top" |
| | | > |
| | | <el-form ref="form" :model="form" :rules="rules" inline label-position="top"> |
| | | <div style="padding-left: 25px"> |
| | | <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> |
| | | </div> |
| | | <AiEditor |
| | | ref="standardEditor" |
| | | :value="editorContents.termStandard" |
| | | height="200px" |
| | | style="margin: 20px 0;" |
| | | placeholder="请输入检测标准..." |
| | | :readOnly="isDetail" |
| | | /> |
| | | <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"> |
| | |
| | | <div>二 、检测仪器</div> |
| | | </div> |
| | | </div> |
| | | <AiEditor |
| | | ref="instrumentEditor" |
| | | :value="editorContents.termInstrument" |
| | | height="200px" |
| | | style="margin: 20px 0;" |
| | | placeholder="请输入检测仪器..." |
| | | :readOnly="isDetail" |
| | | /> |
| | | <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"> |
| | |
| | | <div>三 、检测试剂</div> |
| | | </div> |
| | | </div> |
| | | <AiEditor |
| | | ref="reagentEditor" |
| | | :value="editorContents.termReagent" |
| | | height="200px" |
| | | style="margin: 20px 0;" |
| | | placeholder="请输入检测试剂..." |
| | | :readOnly="isDetail" |
| | | /> |
| | | <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"> |
| | |
| | | <div>四 、检测步骤</div> |
| | | </div> |
| | | </div> |
| | | <AiEditor |
| | | ref="stepsEditor" |
| | | :value="editorContents.termStep" |
| | | height="200px" |
| | | style="margin: 20px 0;" |
| | | placeholder="请输入检测步骤..." |
| | | :readOnly="isDetail" |
| | | /> |
| | | <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"> |
| | |
| | | <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"> |
| | | <Table :data="taskTableData" :total="allTaskTableData.length" :height="null" |
| | | :queryForm="{ pageNum: currentPage, pageSize: pageSize }" :disAblePagination="true" |
| | | @handleCurrentChange="handleCurrentChange" 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="检测图片" width="200"> |
| | | <template slot-scope="scope"> |
| | | <div class="image-preview" v-if="scope.row.photos && scope.row.photos.length"> |
| | | <el-image |
| | | v-for="(photo, index) in scope.row.photos" |
| | | :key="index" |
| | | :src="photo.url" |
| | | :preview-src-list="getPhotoUrls(scope.row.photos)" |
| | | fit="cover" |
| | | class="preview-image" |
| | | > |
| | | <el-image v-for="(photo, index) in scope.row.photos" :key="index" :src="photo.url" |
| | | :preview-src-list="getPhotoUrls(scope.row.photos)" fit="cover" class="preview-image"> |
| | | <div slot="error" class="image-slot"> |
| | | <i class="el-icon-picture-outline"></i> |
| | | </div> |
| | |
| | | <el-table-column label="检测图谱" width="200"> |
| | | <template slot-scope="scope"> |
| | | <div v-if="scope.row.spectrums && scope.row.spectrums.length"> |
| | | <el-link |
| | | v-for="(spectrum, index) in scope.row.spectrums" |
| | | :key="index" |
| | | type="primary" |
| | | :href="spectrum.url" |
| | | target="_blank" |
| | | class="spectrum-link" |
| | | > |
| | | <el-link v-for="(spectrum, index) in scope.row.spectrums" :key="index" type="primary" :href="spectrum.url" |
| | | target="_blank" class="spectrum-link"> |
| | | {{ spectrum.name }} |
| | | </el-link> |
| | | </div> |
| | | <span v-else>无图谱</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | |
| | | <el-table-column v-if="!isDetail" label="操作" width="150"> |
| | | <template slot-scope="scope"> |
| | | <el-button type="text" @click="handleEditTask(scope.row)">编辑</el-button> |
| | |
| | | <div>六 、检测结果运算</div> |
| | | </div> |
| | | </div> |
| | | <AiEditor |
| | | ref="resultCalculationEditor" |
| | | :value="editorContents.termResult" |
| | | height="200px" |
| | | style="margin: 20px 0;" |
| | | placeholder="请输入检测结果运算..." |
| | | :readOnly="isDetail" |
| | | /> |
| | | <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="检测结果" > |
| | | <el-table-column label="检测结果"> |
| | | <template slot-scope="scope"> |
| | | <el-input v-model="scope.row.resultText" placeholder="请输入检测结果" :disabled="isDetail"></el-input> |
| | | </template> |
| | |
| | | |
| | | <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> |
| | | <!-- <el-button @click="handleSaveDraft">存草稿</el-button> --> |
| | | </div> |
| | | </el-form> |
| | | <!-- 添加检测数据弹窗 --> |
| | | <add-dialog |
| | | ref="addDialog" |
| | | :visible.sync="dialogVisible" |
| | | :is-edit="isEdit" |
| | | @success="handleTaskSubmit" |
| | | /> |
| | | <add-dialog ref="addDialog" :visible.sync="dialogVisible" :is-edit="isEdit" @success="handleTaskSubmit" /> |
| | | </Card> |
| | | </template> |
| | | |
| | | |
| | | <script> |
| | | import AddDialog from './components/addDialog.vue' |
| | | import AiEditor from '@/components/AiEditor' |
| | |
| | | experimentName: [{ required: true, message: "请输入检测方法名字", trigger: "blur" }], |
| | | experimentCode: [{ required: true, message: "请输入检测方法编号", trigger: "blur" }] |
| | | }, |
| | | taskTableData: [] |
| | | currentPage: 1, |
| | | pageSize: 15, |
| | | allTaskTableData: [], |
| | | taskTableData: [], |
| | | }; |
| | | }, |
| | | methods: { |
| | |
| | | termName: data.testMethodConfirmSheetTerm.termName || '', |
| | | termMethod: data.testMethodConfirmSheetTerm.termMethod || '', |
| | | termMethodCode: data.testMethodConfirmSheetTerm.termMethodCode || '', |
| | | |
| | | termStandard: data.termStandard || '', |
| | | termInstrument: data.termInstrument || '', |
| | | termReagent: data.termReagent || '', |
| | |
| | | }; |
| | | // 设置检测数据表格 |
| | | if (data.testMethodConfirmSheetOriginalDataList && data.testMethodConfirmSheetOriginalDataList.length > 0) { |
| | | this.taskTableData = data.testMethodConfirmSheetOriginalDataList.map(item => ({ |
| | | this.allTaskTableData = data.testMethodConfirmSheetOriginalDataList.map(item => ({ |
| | | sampleCode: item.dataCode || '', |
| | | testData: item.dataTitle || '', |
| | | resultText: item.resultText || '', |
| | |
| | | spectrums: item.dataFiles ? JSON.parse(item.dataFiles) : [], |
| | | createTime: item.createTime || moment().format('YYYY-MM-DD HH:mm:ss') |
| | | })); |
| | | } else { |
| | | this.allTaskTableData = []; |
| | | } |
| | | this.currentPage = 1; |
| | | this.updateTableData(); |
| | | } |
| | | }).catch(err => { |
| | | console.error('获取详情失败:', err); |
| | |
| | | handleEditTask(row) { |
| | | this.isEdit = true; |
| | | this.currentEditIndex = this.taskTableData.findIndex(item => item === row); |
| | | |
| | | |
| | | const editData = { |
| | | dataCode: row.sampleCode, |
| | | dataTitle: row.testData, |
| | |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | const index = this.taskTableData.findIndex((item) => item === row); |
| | | const index = this.allTaskTableData.findIndex((item) => item === row); |
| | | if (index > -1) { |
| | | const item = this.taskTableData[index]; |
| | | const item = this.allTaskTableData[index]; |
| | | if (item.photos) { |
| | | item.photos.forEach(photo => { |
| | | if (photo.url.startsWith('blob:')) { |
| | |
| | | } |
| | | }); |
| | | } |
| | | |
| | | this.taskTableData.splice(index, 1); |
| | | this.allTaskTableData.splice(index, 1); |
| | | // 删除后判断是否需要跳页 |
| | | const maxPage = Math.ceil(this.allTaskTableData.length / this.pageSize) || 1; |
| | | if (this.currentPage > maxPage) { |
| | | this.currentPage = maxPage; |
| | | } |
| | | this.updateTableData(); |
| | | this.$message.success("删除成功"); |
| | | } |
| | | }) |
| | | .catch(() => {}); |
| | | .catch(() => { }); |
| | | }, |
| | | handleTaskSubmit(formData) { |
| | | const newData = { |
| | |
| | | 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) { |
| | | this.taskTableData.splice(this.currentEditIndex, 1, newData); |
| | | this.$message.success('更新成功'); |
| | | this.allTaskTableData.splice(this.currentEditIndex, 1, newData); |
| | | } else { |
| | | this.taskTableData.push(newData); |
| | | this.$message.success('添加成功'); |
| | | this.allTaskTableData.push(newData); |
| | | this.currentPage = 1; // 新增后回到第一页 |
| | | } |
| | | |
| | | this.updateTableData(); |
| | | this.dialogVisible = false; |
| | | this.isEdit = false; |
| | | this.currentEditIndex = -1; |
| | | this.$message.success(this.isEdit ? '更新成功' : '添加成功'); |
| | | }, |
| | | getPhotoUrls(photos) { |
| | | return photos.map(photo => photo.url); |
| | |
| | | testMethodConfirmSheetOriginalDataList: this.taskTableData.map(item => ({ |
| | | dataCode: item.sampleCode, |
| | | dataTitle: item.testData, |
| | | dataType: item.photos && item.spectrums ? '1,2' : |
| | | item.photos ? '1' : |
| | | item.spectrums ? '2' : '', |
| | | 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, |
| | |
| | | }; |
| | | |
| | | console.log('提交数据:', submitData); |
| | | |
| | | |
| | | // 调用更新接口 |
| | | const res = await update(submitData); |
| | | if (res.code === 200) { |
| | |
| | | // 存草稿 |
| | | handleSaveDraft() { |
| | | this.handleSubmit(true); |
| | | }, |
| | | updateTableData() { |
| | | const start = (this.currentPage - 1) * this.pageSize; |
| | | const end = this.currentPage * this.pageSize; |
| | | this.taskTableData = this.allTaskTableData.slice(start, end); |
| | | }, |
| | | handleCurrentChange(page) { |
| | | this.currentPage = page; |
| | | this.updateTableData(); |
| | | } |
| | | }, |
| | | created() { |
| | |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | |
| | | <style scoped lang="less"> |
| | | .ai-editor-container{ |
| | | .ai-editor-container { |
| | | margin-left: 40px; |
| | | width: 85%; |
| | | } |
| | | |
| | | .el-form--inline .el-form-item { |
| | | margin-right: 83px; |
| | | } |
| | |
| | | gap: 13px; |
| | | margin-top: 38px; |
| | | margin-bottom: 38px; |
| | | |
| | | |
| | | .header-title-left { |
| | | display: flex; |
| | | align-items: center; |
| | |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | } |
| | | |
| | | div { |
| | | flex-shrink: 0; |
| | | font-weight: bold; |
| | |
| | | color: #222222; |
| | | line-height: 27px; |
| | | font-family: "Source Han Sans CN Bold Bold"; |
| | | |
| | | &:before { |
| | | content: "*"; |
| | | color: #f56c6c; |
| | |
| | | .spectrum-link { |
| | | display: block; |
| | | margin-bottom: 5px; |
| | | |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | |
| | | <el-table-column prop="addAuxiliaryTen" label="加辅10" width="150"></el-table-column> |
| | | </template> |
| | | <el-table-column prop="sampleAmount" label="取样量" width="150"></el-table-column> |
| | | <el-table-column prop="pictures" label="拍照" width="150"> |
| | | <!-- <el-table-column prop="pictures" label="拍照" width="150"> |
| | | <template slot-scope="scope"> |
| | | <template v-if="scope.row.pictures"> |
| | | <el-image |
| | |
| | | </template> |
| | | <span v-else>-</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="handlePersonName" label="操作人员" width="150"></el-table-column> |
| | | </el-table-column> --> |
| | | <el-table-column prop="sendTime" label="送样时间" width="150"></el-table-column> |
| | | <el-table-column prop="sendPersonName" label="送样人" width="150"></el-table-column> |
| | | <el-table-column label="状态" prop="status" width="100" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.row.status == '2' ? '待接收' : '已接收' }}</span> |
| | |
| | | <span v-else>-</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="handlePersonName" label="操作人员" width="150"></el-table-column> |
| | | <el-table-column prop="receiveTime" label="收样时间" width="150"></el-table-column> |
| | | <el-table-column prop="receiver" label="收样人" width="150"></el-table-column> |
| | | <el-table-column prop="sendTime" label="送样时间" width="150"></el-table-column> |
| | | <el-table-column prop="sendPersonName" label="送样人" width="150"></el-table-column> |
| | | <el-table-column prop="receiptsTime" label="收样时间" width="150"></el-table-column> |
| | | <el-table-column prop="receiptsPersonName" label="收样人" width="150"></el-table-column> |
| | | <el-table-column label="状态" prop="status" width="100" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.row.status == '3' ? '已接收' : '待接收' }}</span> |
| | |
| | | /> |
| | | |
| | | <div class="add-project-footer" v-if="isEngineer && pageType !== 'detail'"> |
| | | <el-button type="primary" class="save-btn" @click="handleSave">保存</el-button> |
| | | <el-button type="primary" class="save-btn" @click="handleSave">{{'发送'}}</el-button> |
| | | <el-button @click="handleSaveDraft">存草稿</el-button> |
| | | </div> |
| | | </div> |
| | |
| | | }, |
| | | // 去评价 |
| | | handleEvaluate(type) { |
| | | if(this.$route.query.type == 'view' && type !='processEngineer'){ |
| | | if(this.$route.query.type == 'view' || type !='processEngineer'){ |
| | | this.$message.warning('当前为查看模式,无法进行评价'); |
| | | return; |
| | | } |
| | |
| | | this.$message.warning('请输入密码') |
| | | return |
| | | } |
| | | // 工具函数:拍平menus,获取所有path |
| | | function flattenMenus(menus) { |
| | | let result = [] |
| | | menus.forEach(menu => { |
| | | if (menu.path) result.push(menu.path) |
| | | if (menu.children && menu.children.length) { |
| | | result = result.concat(flattenMenus(menu.children)) |
| | | } |
| | | }) |
| | | return result |
| | | } |
| | | loginReq(this.loginForm).then(res => { |
| | | sessionStorage.setItem('token', res.token) |
| | | sessionStorage.setItem('userInfo', JSON.stringify(res.userInfo.user)) |
| | | this.$router.push('/system') |
| | | sessionStorage.setItem('menus', JSON.stringify(res.menus)) |
| | | // 拍平path数组 |
| | | const flatMenus = flattenMenus(res.menus) |
| | | sessionStorage.setItem('flatMenus', JSON.stringify(flatMenus)) |
| | | // 存到vuex |
| | | this.$store.commit('SET_MENUS', res.menus) |
| | | this.$store.commit('SET_FLAT_MENUS', flatMenus) |
| | | this.$router.push('/middleground') |
| | | }) |
| | | } |
| | | } |
| | |
| | | </div> |
| | | <div class="sconed"> |
| | | <div class="subpage" |
| | | v-if="(item.children.length > 0 && item.children[0].children.length > 0) || item.children[0].children.menuType != 'F'"> |
| | | v-if="item.children && item.children.length > 0 && ((item.children[0].children && item.children[0].children.length > 0) || item.children[0].menuType != 'F')"> |
| | | <div v-for="item1 in item.children" :key="item1.menuId" class="two"> |
| | | <div class="left"> |
| | | <el-checkbox disabled :checked="item1.selected"> |
| | |
| | | border-right: none; |
| | | |
| | | .left { |
| | | width: 200px; |
| | | width: 300px; |
| | | padding: 13px 20px; |
| | | border-right: 1px solid #e8e8e8; |
| | | } |
| | |
| | | } |
| | | |
| | | .title { |
| | | width: 200px; |
| | | width: 300px; |
| | | padding: 8px 20px; |
| | | } |
| | | } |
| | |
| | | div:nth-child(2) { |
| | | margin-right: 8px; |
| | | } |
| | | } |
| | | ::v-deep .checkbox__inner{ |
| | | background-color: #009688 !important; |
| | | border-color: #009688 !important; |
| | | } |
| | | |
| | | .no-data { |
| | |
| | | /* 当复选框禁用时覆盖默认样式 */ |
| | | |
| | | ::v-deep .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner { |
| | | background-color: #409eff; |
| | | border-color: #409eff; |
| | | background-color: #049C9A !important; |
| | | border-color: #049C9A !important; |
| | | } |
| | | |
| | | ::v-deep .el-checkbox.is-disabled .el-checkbox__inner::after { |