From fa652918dd80558deafeb55790228adf9240eae1 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 13 三月 2026 16:54:48 +0800
Subject: [PATCH] 军泰伟业 1.产品数据添加导入功能,规格型号添加产品类型字段
---
src/views/basicData/product/index.vue | 288 ++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 222 insertions(+), 66 deletions(-)
diff --git a/src/views/basicData/product/index.vue b/src/views/basicData/product/index.vue
index 3aa263e..e613f09 100644
--- a/src/views/basicData/product/index.vue
+++ b/src/views/basicData/product/index.vue
@@ -1,7 +1,7 @@
<template>
<div class="app-container product-view">
<div class="left">
- <div>
+ <div class="left-header">
<el-input
v-model="search"
style="width: 210px"
@@ -11,12 +11,17 @@
clearable
prefix-icon="Search"
/>
- <el-button
- type="primary"
- @click="openProDia('addOne')"
- style="margin-left: 10px"
- >鏂板浜у搧澶х被</el-button
- >
+ <div class="button-group">
+ <el-button
+ type="primary"
+ @click="openProDia('addOne')"
+ >鏂板浜у搧澶х被</el-button>
+ <el-button
+ type="success"
+ @click="handleImport"
+ icon="Upload"
+ >瀵煎叆</el-button>
+ </div>
</div>
<div ref="containerRef">
<el-tree
@@ -25,18 +30,13 @@
:data="list"
@node-click="handleNodeClick"
:expand-on-click-node="false"
- default-expand-all
:default-expanded-keys="expandedKeys"
- :draggable="true"
:filter-node-method="filterNode"
:props="{ children: 'children', label: 'label' }"
highlight-current
node-key="id"
- style="
- height: calc(100vh - 190px);
- overflow-y: scroll;
- scrollbar-width: none;
- "
+ class="product-tree-scroll"
+ style="height: calc(100vh - 190px); overflow-y: auto"
>
<template #default="{ node, data }">
<div class="custom-tree-node">
@@ -45,7 +45,7 @@
<component :is="data.children && data.children.length > 0
? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
</el-icon>
- {{ data.label }}
+ <span class="tree-node-label">{{ data.label }}</span>
</span>
<div>
<el-button
@@ -113,6 +113,8 @@
<el-input
v-model="form.productName"
placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
+ maxlength="20"
+ show-word-limit
clearable
@keydown.enter.prevent
/>
@@ -127,8 +129,7 @@
</div>
</template>
</el-dialog>
- <el-dialog
- v-model="modelDia"
+ <el-dialog v-model="modelDia"
title="瑙勬牸鍨嬪彿"
width="400px"
@close="closeModelDia"
@@ -155,6 +156,18 @@
</el-row>
<el-row>
<el-col :span="24">
+ <el-form-item label="鍥剧焊缂栧彿锛�" prop="drawingNumber">
+ <el-input
+ v-model="modelForm.drawingNumber"
+ placeholder="璇疯緭鍏ュ浘绾哥紪鍙�"
+ clearable
+ @keydown.enter.prevent
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="24">
<el-form-item label="鍗曚綅锛�" prop="unit">
<el-input
v-model="modelForm.unit"
@@ -162,6 +175,21 @@
clearable
@keydown.enter.prevent
/>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="24">
+ <el-form-item label="浜у搧绫诲瀷锛�" prop="productType">
+ <el-select
+ v-model="modelForm.productType"
+ placeholder="璇烽�夋嫨浜у搧绫诲瀷"
+ clearable
+ style="width: 100%"
+ >
+ <el-option label="鐗╂枡" :value="1" />
+ <el-option label="浜у搧" :value="2" />
+ </el-select>
</el-form-item>
</el-col>
</el-row>
@@ -173,12 +201,47 @@
</div>
</template>
</el-dialog>
+ <el-dialog v-model="importDia" title="浜у搧瀵煎叆" width="600px">
+ <el-upload
+ ref="importUploadRef"
+ :limit="1"
+ accept=".xlsx,.xls"
+ :action="importUpload.url"
+ :headers="importUpload.headers"
+ :before-upload="importUpload.beforeUpload"
+ :on-success="importUpload.onSuccess"
+ :on-error="importUpload.onError"
+ :on-progress="importUpload.onProgress"
+ :on-change="importUpload.onChange"
+ :auto-upload="false"
+ drag
+ >
+ <i class="el-icon-upload"></i>
+ <div class="el-upload__text">
+ 灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em>
+ </div>
+ <template #tip>
+ <div class="el-upload__tip">
+ 浠呮敮鎸� xls/xlsx锛屽ぇ灏忎笉瓒呰繃 10MB銆�
+ <el-button link type="primary" @click="importTemplate">涓嬭浇瀵煎叆妯℃澘</el-button>
+ </div>
+ </template>
+ </el-upload>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitImport">纭瀵煎叆</el-button>
+ <el-button @click="importDia = false">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
</div>
</template>
<script setup>
import { ref } from "vue";
import { ElMessageBox } from "element-plus";
+import { getToken } from "@/utils/auth.js";
+import { FileUpload } from "@/components/Upload";
import {
addOrEditProduct,
addOrEditProductModel,
@@ -186,15 +249,18 @@
delProductModel,
modelListPage,
productTreeList,
+ downloadTemplate,
} from "@/api/basicData/product.js";
import ImportExcel from "./ImportExcel/index.vue";
const { proxy } = getCurrentInstance();
const tree = ref(null);
const containerRef = ref(null);
+const importUploadRef = ref(null);
const productDia = ref(false);
const modelDia = ref(false);
+const importDia = ref(false);
const modelOperationType = ref("");
const search = ref("");
const currentId = ref("");
@@ -209,8 +275,18 @@
prop: "model",
},
{
+ label: "鍥剧焊缂栧彿",
+ prop: "drawingNumber",
+ },
+ {
label: "鍗曚綅",
prop: "unit",
+ },
+ {
+ label: "浜у搧绫诲瀷",
+ prop: "productType",
+ width: 100,
+ formatData: (v) => ({ "1": "鐗╂枡", "2": "浜у搧" }[String(v)] ?? v),
},
{
dataType: "action",
@@ -241,18 +317,72 @@
productName: "",
},
rules: {
- productName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ productName: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ { max: 20, message: "浜у搧鍚嶇О涓嶈兘瓒呰繃20涓瓧绗�", trigger: "blur" },
+ ],
},
modelForm: {
model: "",
unit: "",
+ drawingNumber: "",
+ productType: "",
},
modelRules: {
model: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ drawingNumber: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ productType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
},
});
const { form, rules, modelForm, modelRules } = toRefs(data);
+
+const importUpload = reactive({
+ title: "浜у搧瀵煎叆",
+ open: false,
+ url: import.meta.env.VITE_APP_BASE_API + "/basic/product/import",
+ headers: { Authorization: "Bearer " + getToken() },
+ isUploading: false,
+ beforeUpload: (file) => {
+ const isExcel = file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
+ const isLt10M = file.size / 1024 / 1024 < 10;
+ if (!isExcel) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
+ return false;
+ }
+ if (!isLt10M) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
+ return false;
+ }
+ return true;
+ },
+ onChange: (file, fileList) => {
+ console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
+ },
+ onProgress: (event, file, fileList) => {
+ console.log('涓婁紶涓�...', event.percent);
+ },
+ onSuccess: (response, file, fileList) => {
+ console.log('涓婁紶鎴愬姛', response, file, fileList);
+ importUpload.isUploading = false;
+ if (response.code === 200) {
+ proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
+ importDia.value = false;
+ if (importUploadRef.value) {
+ importUploadRef.value.clearFiles();
+ }
+ getProductTreeList();
+ } else {
+ proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
+ }
+ },
+ onError: (error, file, fileList) => {
+ console.log('涓婁紶澶辫触', error, file, fileList);
+ importUpload.isUploading = false;
+ proxy.$modal.msgError("瀵煎叆澶辫触");
+ }
+});
+
// 鏌ヨ浜у搧鏍�
const getProductTreeList = () => {
treeLoad.value = true;
@@ -286,8 +416,8 @@
modelOperationType.value = type;
modelDia.value = true;
modelForm.value.model = "";
- modelForm.value.model = "";
modelForm.value.id = "";
+ modelForm.value.productType = "";
if (type === "edit") {
modelForm.value = { ...data };
}
@@ -319,53 +449,17 @@
proxy.$refs.formRef.resetFields();
productDia.value = false;
};
-// 灏佽涓�涓畨鍏ㄧ殑纭妗嗭紝褰诲簳闃绘Enter閿Е鍙�
-const safeConfirm = (message, title) => {
- // 鏍囪鏄惁鏄紶鏍囩偣鍑伙紙鐐瑰嚮鎸夐挳浼氳Е鍙慺ocus浜嬩欢锛�
- let isMouseClick = false;
- return new Promise((resolve, reject) => {
- const box = ElMessageBox.confirm(message, title, {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- beforeClose: (action, instance, done) => {
- if (action === "confirm") {
- // 鍙湁榧犳爣鐐瑰嚮鏃舵墠鍏佽纭
- if (isMouseClick) {
- done();
- resolve();
- } else {
- // Enter閿Е鍙戞椂闃绘
- done(false);
- }
- } else {
- // 鍙栨秷鎿嶄綔鐩存帴鍏佽
- done();
- reject();
- }
- }
- });
-
- // 鐩戝惉纭鎸夐挳鐨刦ocus浜嬩欢锛堥紶鏍囩偣鍑讳細瑙﹀彂锛孍nter閿笉浼氾級
- setTimeout(() => {
- const confirmBtn = document.querySelector('.el-message-box__btns .el-button--primary');
- if (confirmBtn) {
- confirmBtn.addEventListener('focus', () => {
- isMouseClick = true;
- });
- }
- }, 0); // 寤惰繜鑾峰彇锛岀‘淇滵OM宸叉覆鏌�
- });
-};
-// 鍒犻櫎浜у搧
// 鍒犻櫎浜у搧
const remove = (node, data) => {
- let ids = [data.id];
- // 浣跨敤灏佽鐨剆afeConfirm
- safeConfirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず")
+ let ids = [];
+ ids.push(data.id);
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
.then(() => {
- // 纭鍒犻櫎閫昏緫
tableLoading.value = true;
delProduct(ids)
.then((res) => {
@@ -441,7 +535,11 @@
proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
return;
}
- safeConfirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず")
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
.then(() => {
tableLoading.value = true;
delProductModel(ids)
@@ -493,6 +591,22 @@
// 娌″尮閰嶅埌杩斿洖false
return false;
};
+
+const handleImport = () => {
+ importDia.value = true;
+ if (importUploadRef.value) {
+ importUploadRef.value.clearFiles();
+ }
+};
+
+const submitImport = () => {
+ importUploadRef.value.submit();
+};
+
+const importTemplate = () => {
+ proxy.download("/basic/product/downloadTemplate", {}, "浜у搧瀵煎叆妯℃澘.xlsx");
+};
+
getProductTreeList();
</script>
@@ -501,18 +615,31 @@
display: flex;
}
.left {
- width: 380px;
+ width: 450px;
+ min-width: 450px;
padding: 16px;
background: #ffffff;
}
+.left-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 16px;
+}
+.button-group {
+ display: flex;
+ gap: 10px;
+}
.right {
- width: calc(100% - 380px);
+ flex: 1;
+ min-width: 0;
padding: 16px;
margin-left: 20px;
background: #ffffff;
}
.custom-tree-node {
flex: 1;
+ min-width: 0;
display: flex;
align-items: center;
justify-content: space-between;
@@ -520,13 +647,42 @@
padding-right: 8px;
}
.tree-node-content {
+ flex: 1;
+ min-width: 0;
display: flex;
- align-items: center; /* 鍨傜洿灞呬腑 */
+ align-items: center;
height: 100%;
+ overflow: hidden;
+}
+.tree-node-content .orange-icon {
+ flex-shrink: 0;
+}
+.tree-node-label {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
.orange-icon {
color: orange;
font-size: 18px;
margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
}
+.product-tree-scroll {
+ scrollbar-width: thin;
+ scrollbar-color: #c0c4cc #f5f7fa;
+}
+.product-tree-scroll::-webkit-scrollbar {
+ width: 8px;
+}
+.product-tree-scroll::-webkit-scrollbar-track {
+ background: #f5f7fa;
+ border-radius: 4px;
+}
+.product-tree-scroll::-webkit-scrollbar-thumb {
+ background: #c0c4cc;
+ border-radius: 4px;
+}
+.product-tree-scroll::-webkit-scrollbar-thumb:hover {
+ background: #909399;
+}
</style>
--
Gitblit v1.9.3