| src/api/cnas/resourceDemand/device.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/api/cnas/resourceDemand/standardMaterial/standardMaterial.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/CNAS/resourceDemand/device/component/deviceOverview.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/CNAS/resourceDemand/device/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/CNAS/resourceDemand/standardMaterial/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/business/productOrder/components/addOrder.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/business/productOrder/components/addView.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/api/cnas/resourceDemand/device.js
@@ -38,6 +38,15 @@ }); } // 下载设备导入模板 export function downloadDeviceImportTemplate() { return request({ url: "/deviceScope/importTemplate", method: "get", responseType: "blob", }); } //设备里面选择检验项目(树形结构) export function getInsProduction(query) { return request({ src/api/cnas/resourceDemand/standardMaterial/standardMaterial.js
@@ -37,6 +37,15 @@ }); } // 下载标准物质导入模板 export function downloadStandardSubstanceImportTemplate() { return request({ url: '/feStandardSubstance/importTemplate', method: 'get', responseType: 'blob' }) } //标准物质清单借用 export function borrowSubstance(query) { return request({ src/views/CNAS/resourceDemand/device/component/deviceOverview.vue
@@ -20,6 +20,7 @@ <div style="line-height: 30px;"> <el-button size="mini" type="primary" @click="currentPage = 1, keyMap = {}, list = [], finishLoding = false, refreshTable()">查询</el-button> <el-button size="mini" @click="refresh()">重置</el-button> <el-button size="mini" type="primary" @click="importVisible = true">导入</el-button> </div> </div> </div> @@ -73,6 +74,22 @@ 暂无数据 </div> </div> <el-dialog title="设备导入" :visible.sync="importVisible" width="500px" @closed="resetImport"> <div style="margin-bottom: 12px;"> 请使用设备导入模板填写数据,单个文件不超过10MB。 <el-button type="text" @click="downloadTemplate">下载导入模板</el-button> </div> <el-upload ref="deviceUpload" drag name="file" accept=".xlsx" :action="importAction" :headers="uploadHeader" :auto-upload="false" :limit="1" :file-list="importFiles" :before-upload="beforeImport" :on-success="importSuccess" :on-error="importError"> <i class="el-icon-upload"></i> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> </el-upload> <span slot="footer" class="dialog-footer"> <el-button @click="importVisible = false">取消</el-button> <el-button type="primary" :loading="importing" @click="submitImport">导入</el-button> </span> </el-dialog> </div> </template> @@ -80,6 +97,7 @@ import ScrollPagination from '@/components/index/scroll-paging.vue' import { selectDeviceParameter, downloadDeviceImportTemplate, } from '@/api/cnas/resourceDemand/device.js' export default { props: { @@ -108,6 +126,14 @@ finishLoding: false, // 加载完成,显示已经没有更多了 keyMap: {}, laboratoryNameIsNull: false, importVisible: false, importing: false, importFiles: [], } }, computed: { importAction() { return this.javaApi + '/deviceScope/importDevice' } }, created() { @@ -118,6 +144,52 @@ this.clickSidebar(this.clickNodeVal) }, methods: { downloadTemplate() { downloadDeviceImportTemplate().then(res => { this.$download.saveAs(new Blob([res]), '设备导入模板.xlsx') }) }, submitImport() { if (!this.$refs.deviceUpload.uploadFiles.length) { this.$message.warning('请选择需要导入的Excel文件') return } this.$refs.deviceUpload.submit() }, beforeImport(file) { if (!file.name.toLowerCase().endsWith('.xlsx')) { this.$message.error('仅支持.xlsx格式文件') return false } if (file.size > 10 * 1024 * 1024) { this.$message.error('导入文件不能超过10MB') return false } this.importing = true return true }, importSuccess(response) { this.importing = false if (response.code !== 200) { this.$message.error(response.message || response.msg || '导入失败') return } this.$message.success(`成功导入${response.data}条设备`) this.importVisible = false this.refresh() this.$emit('refresh-tree') }, importError() { this.importing = false this.$message.error('导入失败') }, resetImport() { this.importing = false this.importFiles = [] if (this.$refs.deviceUpload) { this.$refs.deviceUpload.clearFiles() } }, refreshTable() { const key = `_${this.currentPage}` const value = this.keyMap[key] src/views/CNAS/resourceDemand/device/index.vue
@@ -38,7 +38,7 @@ <div v-if="isShowAll" style="height: 100%;"> <el-tabs v-model="menuListActiveName" class="main_right" type="border-card"> <el-tab-pane label="设备总览" name="设备总览"> <overview v-if="menuListActiveName == '设备总览'" :clickNodeVal="clickNodeVal" /> <overview v-if="menuListActiveName == '设备总览'" :clickNodeVal="clickNodeVal" @refresh-tree="geList" /> </el-tab-pane> <el-tab-pane label="设备工具明细" name="设备工具明细"> <management v-if="menuListActiveName == '设备工具明细'" :clickNodeVal="clickNodeVal" /> src/views/CNAS/resourceDemand/standardMaterial/index.vue
@@ -19,6 +19,7 @@ </div> <div> <el-button size="small" @click="exportFun">导 出</el-button> <el-button size="small" type="primary" @click="importVisible = true">导 入</el-button> <el-button size="small" type="primary" @click="openFormDia('add')">新 增</el-button> </div> </div> @@ -29,6 +30,22 @@ <form-dia v-if="formDia" ref="formDia" @closeYearDia="closeYearDia"></form-dia> <borrow-dia v-if="borrowDia" ref="borrowDia" @closeYearDia="closeBorrowDia"></borrow-dia> <return-dia v-if="returnDia" ref="returnDia" @closeYearDia="closeReturnDia"></return-dia> <el-dialog title="标准物质导入" :visible.sync="importVisible" width="500px" @closed="resetImport"> <div style="margin-bottom: 12px;"> 请使用标准物质导入模板填写数据,单个文件不超过10MB。 <el-button type="text" @click="downloadTemplate">下载导入模板</el-button> </div> <el-upload ref="standardSubstanceUpload" drag name="file" accept=".xlsx" :action="importAction" :headers="uploadHeader" :auto-upload="false" :limit="1" :file-list="importFiles" :before-upload="beforeImport" :on-success="importSuccess" :on-error="importError"> <i class="el-icon-upload"></i> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> </el-upload> <span slot="footer" class="dialog-footer"> <el-button @click="importVisible = false">取消</el-button> <el-button type="primary" :loading="importing" @click="submitImport">导入</el-button> </span> </el-dialog> </div> </template> @@ -39,7 +56,8 @@ import { getPageStandardSubstance, removeStandardSubstance, exportOfStandardSubstanceList exportOfStandardSubstanceList, downloadStandardSubstanceImportTemplate } from '@/api/cnas/resourceDemand/standardMaterial/standardMaterial' import FormDia from '../standardMaterial/component/formDia.vue'; import BorrowDia from '../standardMaterial/component/borrowDia.vue'; @@ -173,12 +191,65 @@ formDia: false, borrowDia: false, returnDia: false, importVisible: false, importing: false, importFiles: [], } }, computed: { importAction() { return this.javaApi + '/feStandardSubstance/importStandardSubstance' } }, mounted() { this.searchList() }, methods: { downloadTemplate() { downloadStandardSubstanceImportTemplate().then(res => { this.$download.saveAs(new Blob([res]), '标准物质导入模板.xlsx') }) }, submitImport() { if (!this.$refs.standardSubstanceUpload.uploadFiles.length) { this.$message.warning('请选择需要导入的Excel文件') return } this.$refs.standardSubstanceUpload.submit() }, beforeImport(file) { if (!file.name.toLowerCase().endsWith('.xlsx')) { this.$message.error('仅支持.xlsx格式文件') return false } if (file.size > 10 * 1024 * 1024) { this.$message.error('导入文件不能超过10MB') return false } this.importing = true return true }, importSuccess(response) { this.importing = false if (response.code !== 200) { this.$message.error(response.message || response.msg || '导入失败') return } this.$message.success(`成功导入${response.data}条标准物质`) this.importVisible = false this.searchList() }, importError() { this.importing = false this.$message.error('导入失败') }, resetImport() { this.importing = false this.importFiles = [] if (this.$refs.standardSubstanceUpload) { this.$refs.standardSubstanceUpload.clearFiles() } }, exportFun() { this.outLoading = true exportOfStandardSubstanceList(this.searchForm).then(res => { src/views/business/productOrder/components/addOrder.vue
@@ -300,19 +300,27 @@ </template> </el-table-column> </el-table> <div v-if="canSelectProduct" style="display: flex; align-items: center; gap: 12px; padding: 10px 0;"> <span>检测范围:</span> <el-radio-group v-model="inspectionScope" size="small" @change="changeInspectionScope"> <el-radio-button label="all">全部检验</el-radio-button> <el-radio-button label="specified">指定检验项</el-radio-button> </el-radio-group> <span>已选 {{ selectedProductCount }} / 共 {{ productList.length }} 项</span> </div> <el-table ref="productTable" v-loading="getProductLoad" :data="productList" :row-class-name="tableRowClassName" border class="el-table" :header-cell-style="{ background: '#f8f8f9', color: '#515a6e' }" max-height="400px" style="margin-bottom: 10px;" tooltip-effect="dark" @select="selectOne" @selection-change="selectProduct" @select-all="handleAll"> <el-table-column v-if="active==1" :selectable="selectable0" type="selection" width="65"></el-table-column> <el-table-column v-if="canSelectProduct" :selectable="selectable0" type="selection" width="65"></el-table-column> <el-table-column label="检验项分类" min-width="140" prop="inspectionItemClass" show-overflow-tooltip></el-table-column> <el-table-column label="检验项" min-width="140" prop="inspectionItem" show-overflow-tooltip> <template slot="header" slot-scope="scope"> <div style="display: flex;align-items: center;flex-direction: column;font-size: 14px"> <span>检验项</span> <el-input v-if="active==1" v-if="canSelectProduct" v-model="inspectionItem" placeholder="请输入" size="mini" @@ -326,7 +334,7 @@ <div style="display: flex;align-items: center;flex-direction: column;font-size: 14px"> <span>检验项子项</span> <el-input v-if="active==1" v-if="canSelectProduct" v-model="inspectionItemSubclass" placeholder="请输入" size="mini" @@ -368,7 +376,7 @@ <div style="display: flex;align-items: center;flex-direction: column;font-size: 14px"> <span>试验方法</span> <el-input v-if="active==1" v-if="canSelectProduct" v-model="methodS" placeholder="请输入" size="mini" @@ -614,6 +622,12 @@ }, computed:{ ...mapGetters(["nickName", 'nameEn', 'userName']), canSelectProduct() { return this.active == 1 || (this.tabIndex == 4 && this.active == 2) }, selectedProductCount() { return this.productList.filter(item => item.state == 1).length }, newJuLaboratoryList() { return (this.dict.type.sys_sub_lab || []).filter(item => item.label === '新聚') }, @@ -691,9 +705,6 @@ ], testQuantity: [ { required: true, message: '请填写抽检数量', trigger: 'blur' } ], production: [ { required: true, message: '请填写生产单位', trigger: 'blur' } ], }, sample: { @@ -796,6 +807,7 @@ quarterItemOptions: [], // 查询季度信息 specialStandardMethod: '', isSpecial: false, inspectionScope: 'all', } }, watch: { @@ -906,7 +918,12 @@ ...res.data.insOrder }; this.addObj.type = String(this.addObj.type) this.sampleList = this.HaveJson(res.data.sampleProduct); const samples = this.HaveJson(res.data.sampleProduct) const loadSamples = this.canSelectProduct ? Promise.all(samples.map(sample => this.loadSelectableProducts(sample))) : Promise.resolve(samples) loadSamples.then(sampleList => { this.sampleList = sampleList this.specialStandardMethod = this.sampleList[0].specialStandardMethod this.getProNum() this.addObj.sampleNum = this.sampleList.length @@ -916,6 +933,7 @@ this.$refs.sampleTable.setCurrentRow(this.sampleList[0], true) this.rowClick(this.sampleList[0]) } }) }) }) } @@ -1166,22 +1184,23 @@ if (this.tabIndex != 4) { delete c.id } if (c.isNew) { c.id = null delete c.isNew } }) } if (a.endModels) { a.model = a.endModels } if (!this.canSelectProduct || this.active == 1) { a.insProduct = a.insProduct.filter(b=>b.state === 1) } }) let projectNum = this.totalArr.filter(a => a.state == 1).length if(projectNum==0){ this.$confirm('检验项目为空,是否确认提交?', "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }).then(() => { this.saveMethod(sampleList) }).catch(() => {}) this.$message.warning('请至少选择一个检验项') return }else{ let isRTS = this.totalArr.find(a => a.ask != null && this.symbolList.find(b=>a.ask.includes(b)) && a.state == 1) if (isRTS) { @@ -1206,12 +1225,18 @@ if (this.tabIndex != 4) { delete c.id } if (c.isNew) { c.id = null delete c.isNew } }) } if (a.endModels) { a.model = a.endModels } if (!this.canSelectProduct || this.active == 1) { a.insProduct = a.insProduct.filter(b=>b.state === 1) } }) this.saveMethod(sampleList) }else{ @@ -1625,6 +1650,9 @@ } this.productList = row.insProduct this.productList0 = JSON.parse(JSON.stringify(this.productList)) this.inspectionScope = this.productList.length === 0 ? (this.active == 1 ? 'all' : 'specified') : (this.productList.every(item => item.state == 1) ? 'all' : 'specified') setTimeout(() => { this.productList.forEach(a => { if (a.state == 1) { @@ -1694,6 +1722,9 @@ }) this.changeProductList0() this.currentMethod.insProduct = this.productList0 this.inspectionScope = this.productList.length > 0 && this.productList.every(item => item.state == 1) ? 'all' : 'specified' this.getProNum() }, permute(nums) { @@ -1814,7 +1845,7 @@ conductorType: row.conductorType, }).then(res => { res.data.forEach(a => { a.state = 0 a.state = this.inspectionScope === 'all' ? 1 : 0 }) row.insProduct = this.HaveJson(res.data) this.getProductLoad = false @@ -1829,6 +1860,9 @@ this.productList.forEach(a => { if (a.state == 1) this.toggleSelection(a) }) if (this.inspectionScope === 'all') { this.handleAll(this.productList.filter(item => this.selectable0(item))) } }, 200) }) }, @@ -1876,7 +1910,7 @@ factory: selectTreeList.join(" - "), }).then(res => { res.data.forEach(a => { a.state = 0 a.state = this.inspectionScope === 'all' ? 1 : 0 }) row.insProduct = this.HaveJson(res.data) this.getProductLoad = false @@ -1887,6 +1921,9 @@ this.productList.forEach(a => { if (a.state == 1) this.toggleSelection(a) }) if (this.inspectionScope === 'all') { this.handleAll(this.productList.filter(item => this.selectable0(item))) } }, 200) }) }, @@ -1955,7 +1992,7 @@ } }, selectable0(row,index) { if (this.active > 1||row.repetitionTag) { if (!this.canSelectProduct||row.repetitionTag) { return false } else { return true @@ -2026,18 +2063,58 @@ return item }) } this.productList.forEach(item => { if (item.id == row.id) { item.state = row.state; } }) this.changeProductList0() this.currentMethod.insProduct = this.productList0 this.inspectionScope = e.length > 0 ? 'all' : 'specified' this.getProNum() this.$nextTick(() => { this.$refs.productTable.doLayout() }) }, changeInspectionScope(scope) { if (scope !== 'all' || this.productList.length === 0) return this.$refs.productTable.clearSelection() this.productList.forEach(item => { if (this.selectable0(item)) this.$refs.productTable.toggleRowSelection(item, true) }) this.handleAll(this.productList.filter(item => this.selectable0(item))) }, inspectionProductKey(product) { return [ product.structureItemParameterId, product.inspectionItemClass, product.inspectionItem, product.inspectionItemSubclass ].join('|') }, loadSelectableProducts(sample) { const selectedProducts = sample.insProduct || [] if (!sample.standardMethodListId) return Promise.resolve(sample) const product = selectedProducts[0] || {} const factory = [ product.factory || this.addObj.factory, product.laboratory || this.addObj.laboratory, product.sampleType || this.addObj.sampleType, product.sample || sample.sample, product.model || sample.model ].join(' - ') return selectStandardProductList({ model: sample.model, modelNum: sample.modelNum, standardMethodListId: sample.standardMethodListId, factory, cores: sample.cores, conductorMaterial: sample.conductorMaterial, conductorType: sample.conductorType }).then(res => { const selectedKeys = new Set(selectedProducts.map(item => this.inspectionProductKey(item))) const availableProducts = (res.data || []) .filter(item => !selectedKeys.has(this.inspectionProductKey(item))) .map((item, index) => ({...item, id: `new-${sample.id}-${index}`, state: 0, isNew: true})) sample.insProduct = selectedProducts.concat(availableProducts) return sample }).catch(() => sample) }, submitTell() { if (!this.tell) { this.$message.error('请输入不通过原因') src/views/business/productOrder/components/addView.vue
@@ -686,9 +686,6 @@ testQuantity: [ { required: true, message: '请填写抽检数量', trigger: 'blur' } ], production: [ { required: true, message: '请填写生产单位', trigger: 'blur' } ], }, sample: { sampleCode: null,