From 3c6566a26c6bb6f68deed9f2c8e7b6eab1209134 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期五, 28 八月 2026 15:42:42 +0800
Subject: [PATCH] feat(order): 添加产品检验项选择功能并增加导入导出功能 - 实现产品检验项的选择状态管理和计数显示功能 - 添加标准物质和设备管理模块的导入导出功能 - 新增导入模板下载和上传验证机制 - 调整表单验证规则,移除生产单位必填限制
---
src/views/CNAS/resourceDemand/device/component/deviceOverview.vue | 377 ++++++++++++++++++++++++++++++-----------------------
1 files changed, 211 insertions(+), 166 deletions(-)
diff --git a/src/views/CNAS/resourceDemand/device/component/deviceOverview.vue b/src/views/CNAS/resourceDemand/device/component/deviceOverview.vue
index 48dcb89..b64653b 100644
--- a/src/views/CNAS/resourceDemand/device/component/deviceOverview.vue
+++ b/src/views/CNAS/resourceDemand/device/component/deviceOverview.vue
@@ -1,175 +1,28 @@
<!-- 璁惧鎬昏 -->
-<style scoped>
-.title {
- height: 60px;
- line-height: 60px;
-}
-
-.search {
- background-color: #fff;
- height: 50px;
- display: flex;
- align-items: center;
-}
-
-.search_thing {
- width: 350px;
- display: flex;
- align-items: center;
-}
-
-.search_label {
- width: 110px;
- font-size: 14px;
- text-align: left;
-}
-
-.search_input {
- width: calc(100% - 110px);
-}
-
-.table {
- background-color: #fff;
- height: calc(100vh - 17em);
- /* padding: 10px; */
- overflow-y: auto;
-}
-
-.card {
- list-style-type: none;
- display: grid;
- grid-template-columns: repeat(auto-fit, 330px);
- justify-content: start;
- grid-gap: 16px;
- min-height: 300px;
- padding-left: 0;
-}
-
-.card li {
- width: 330px;
- height: 165px;
- border-radius: 8px 8px 8px 8px;
- border: 1px solid #EEEEEE;
- margin: 0 !important;
- display: flex;
- align-items: center;
- box-sizing: border-box;
- padding: 16px;
- font-size: 14px;
- color: #666666;
- position: relative;
- overflow: hidden;
-}
-
-.card li .img {
- width: 90px;
- height: 90px;
- border-radius: 16px;
- margin-right: 10px;
-}
-
-.list-left .list-left-info {
- line-height: 36px;
- display: flex;
-}
-
-.text-truncate {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap
-}
-
-.circles {
- position: absolute;
- width: 70px;
- height: 70px;
- right: 0;
- top: 0;
- z-index: 0;
-}
-
-.circles .circle {
- border-radius: 50%;
- opacity: 0.2;
-}
-
-.circle0,
-.circle1,
-.circle2 {
- width: 60px;
- height: 60px;
- position: absolute;
-}
-
-.circle3 {
- width: 16px;
- height: 16px;
- position: absolute;
-}
-
-.circle0 {
- bottom: 6px;
- left: 0;
-}
-
-.circle1 {
- bottom: 0;
- right: -30px;
-}
-
-.circle2 {
- left: 0;
- top: -30px;
-}
-
-.circle3 {
- top: 0;
- right: 0;
-}
-
-.success .circle {
- background: #34BD66;
-}
-
-.danger .circle {
- background: #FF3838;
-}
-
-.warning .circle {
- background: #FBB247;
-}
-
-.info .circle {
- background: #909399;
-}
-
-.el-form-item {
- margin-top: 11px;
- margin-bottom: 11px;
-}
-</style>
-
<template>
<div class="role_manage">
- <div>
- <el-form :model="entity" inline label-position="right" label-width="80px">
- <el-form-item label="鐘舵��:">
- <el-select v-model="entity.deviceStatus" placeholder="鍏ㄩ儴" size="small" clearable>
+ <div style="display: flex;justify-content: space-between;margin-top: 10px;">
+ <div style="display: flex;">
+ <div style="margin-bottom: 18px;margin-right: 10px;display: flex;align-items: center;line-height: 32px;">
+ <span style="width: 48px;font-size: 14px;font-weight: 700;color: #606266;">鐘舵��</span>
+ <el-select v-model="entity.deviceStatus" placeholder="鍏ㄩ儴"
+ @change="currentPage = 1, keyMap = {}, list = [], finishLoding = false, refreshTable()"
+ size="small" clearable>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
- </el-form-item>
- <el-form-item label="璁惧鍚嶇О:">
- <el-input size="small" placeholder="璇疯緭鍏�" clearable v-model="entity.deviceName"></el-input>
- </el-form-item>
- <el-form-item>
- <el-button size="small" @click="refresh()">閲� 缃�</el-button>
- </el-form-item>
- <el-form-item>
- <el-button size="small" type="primary"
- @click="currentPage = 1, keyMap = {}, list = [], finishLoding = false, refreshTable()">鏌� 璇�</el-button>
- </el-form-item>
- </el-form>
+ </div>
+ <div style="margin-bottom: 18px;margin-right: 10px;display: flex;align-items: center;line-height: 32px;">
+ <span style="width: 88px;font-size: 14px;font-weight: 700;color: #606266;">璁惧鍚嶇О</span>
+ <el-input size="small" placeholder="璇疯緭鍏�" clearable v-model="entity.deviceName"
+ @keyup.enter.native="currentPage = 1, keyMap = {}, list = [], finishLoding = false, refreshTable()"></el-input>
+ </div>
+ <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>
<div class="table" v-loading="loading">
<scroll-pagination @load="refreshTable()" :finishLoding="finishLoding" :list="list"
@@ -221,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>
@@ -228,6 +97,7 @@
import ScrollPagination from '@/components/index/scroll-paging.vue'
import {
selectDeviceParameter,
+ downloadDeviceImportTemplate,
} from '@/api/cnas/resourceDemand/device.js'
export default {
props: {
@@ -256,6 +126,14 @@
finishLoding: false, // 鍔犺浇瀹屾垚锛屾樉绀哄凡缁忔病鏈夋洿澶氫簡
keyMap: {},
laboratoryNameIsNull: false,
+ importVisible: false,
+ importing: false,
+ importFiles: [],
+ }
+ },
+ computed: {
+ importAction() {
+ return this.javaApi + '/deviceScope/importDevice'
}
},
created() {
@@ -266,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]
@@ -390,3 +314,124 @@
}
}
</script>
+<style scoped>
+.table {
+ background-color: #fff;
+ height: calc(100vh - 17em);
+ /* padding: 10px; */
+ overflow-y: auto;
+}
+
+.card {
+ list-style-type: none;
+ display: grid;
+ grid-template-columns: repeat(auto-fit, 330px);
+ justify-content: start;
+ grid-gap: 16px;
+ min-height: 300px;
+ padding-left: 0;
+}
+
+.card li {
+ width: 330px;
+ height: 165px;
+ border-radius: 8px 8px 8px 8px;
+ border: 1px solid #EEEEEE;
+ margin: 0 !important;
+ display: flex;
+ align-items: center;
+ box-sizing: border-box;
+ padding: 16px;
+ font-size: 14px;
+ color: #666666;
+ position: relative;
+ overflow: hidden;
+}
+
+.card li .img {
+ width: 90px;
+ height: 90px;
+ border-radius: 16px;
+ margin-right: 10px;
+}
+
+.list-left .list-left-info {
+ line-height: 36px;
+ display: flex;
+}
+
+.text-truncate {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap
+}
+
+.circles {
+ position: absolute;
+ width: 70px;
+ height: 70px;
+ right: 0;
+ top: 0;
+ z-index: 0;
+}
+
+.circles .circle {
+ border-radius: 50%;
+ opacity: 0.2;
+}
+
+.circle0,
+.circle1,
+.circle2 {
+ width: 60px;
+ height: 60px;
+ position: absolute;
+}
+
+.circle3 {
+ width: 16px;
+ height: 16px;
+ position: absolute;
+}
+
+.circle0 {
+ bottom: 6px;
+ left: 0;
+}
+
+.circle1 {
+ bottom: 0;
+ right: -30px;
+}
+
+.circle2 {
+ left: 0;
+ top: -30px;
+}
+
+.circle3 {
+ top: 0;
+ right: 0;
+}
+
+.success .circle {
+ background: #34BD66;
+}
+
+.danger .circle {
+ background: #FF3838;
+}
+
+.warning .circle {
+ background: #FBB247;
+}
+
+.info .circle {
+ background: #909399;
+}
+
+.el-form-item {
+ margin-top: 11px;
+ margin-bottom: 11px;
+}
+</style>
--
Gitblit v1.9.3