From 3d14e2ef3644ab878c91b3252067ab53dfd4f1ad Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 09 四月 2026 15:36:03 +0800
Subject: [PATCH] 中兴实强 1.产品维护产品大类新增时层级不做限制
---
src/views/basicData/product/index.vue | 229 +++++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 166 insertions(+), 63 deletions(-)
diff --git a/src/views/basicData/product/index.vue b/src/views/basicData/product/index.vue
index 3aa263e..3b86b37 100644
--- a/src/views/basicData/product/index.vue
+++ b/src/views/basicData/product/index.vue
@@ -25,18 +25,16 @@
:data="list"
@node-click="handleNodeClick"
:expand-on-click-node="false"
- default-expand-all
+ @node-expand="handleNodeExpand"
+ @node-collapse="handleNodeCollapse"
+ :key="treeKey"
: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 +43,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
@@ -55,7 +53,7 @@
>
缂栬緫
</el-button>
- <el-button type="primary" link @click="openProDia('add', data)" :disabled="node.level >= 3">
+ <el-button type="primary" link @click="openProDia('add', data)">
娣诲姞浜у搧
</el-button>
<el-button
@@ -78,7 +76,7 @@
<el-button type="primary" @click="openModelDia('add')">
鏂板瑙勬牸鍨嬪彿
</el-button>
- <ImportExcel @uploadSuccess="getModelList" />
+ <ImportExcel :product-id="currentId" @uploadSuccess="getModelList" />
<el-button
type="danger"
@click="handleDelete"
@@ -113,6 +111,8 @@
<el-input
v-model="form.productName"
placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
+ maxlength="20"
+ show-word-limit
clearable
@keydown.enter.prevent
/>
@@ -177,7 +177,7 @@
</template>
<script setup>
-import { ref } from "vue";
+import { nextTick, ref } from "vue";
import { ElMessageBox } from "element-plus";
import {
addOrEditProduct,
@@ -192,6 +192,92 @@
const { proxy } = getCurrentInstance();
const tree = ref(null);
const containerRef = ref(null);
+const treeKey = ref(0);
+const expandedKeySet = new Set();
+const EXPANDED_STORAGE_KEY = "basicData_product_tree_expanded_keys_v2";
+
+const loadExpandedKeys = () => {
+ if (typeof window === "undefined") {
+ return [];
+ }
+ try {
+ const saved = localStorage.getItem(EXPANDED_STORAGE_KEY);
+ return saved ? JSON.parse(saved) : [];
+ } catch (error) {
+ console.error(error);
+ return [];
+ }
+};
+
+const saveExpandedKeys = () => {
+ if (typeof window === "undefined") {
+ return;
+ }
+ localStorage.setItem(
+ EXPANDED_STORAGE_KEY,
+ JSON.stringify(Array.from(expandedKeySet))
+ );
+};
+
+loadExpandedKeys().forEach((key) => expandedKeySet.add(key));
+
+const syncExpandedKeysFromTree = () => {
+ const keys = [];
+ const walk = (nodes) => {
+ (nodes || []).forEach((item) => {
+ if (item.expanded && item.data?.id !== undefined) {
+ keys.push(item.data.id);
+ }
+ if (item.childNodes && item.childNodes.length) {
+ walk(item.childNodes);
+ }
+ });
+ };
+
+ walk(tree.value?.root?.childNodes);
+ expandedKeySet.clear();
+ keys.forEach((key) => expandedKeySet.add(key));
+ expandedKeys.value = keys;
+ saveExpandedKeys();
+};
+
+const normalizeExpandedKeys = (treeData) => {
+ const parentMap = new Map();
+ const walk = (nodes, parentId = null) => {
+ (nodes || []).forEach((item) => {
+ parentMap.set(item.id, parentId);
+ if (item.children && item.children.length) {
+ walk(item.children, item.id);
+ }
+ });
+ };
+
+ walk(treeData);
+
+ const normalizedKeys = Array.from(expandedKeySet).filter((key) => {
+ if (!parentMap.has(key)) {
+ return false;
+ }
+ let currentId = key;
+ while (parentMap.has(currentId)) {
+ const parentId = parentMap.get(currentId);
+ if (!parentId) {
+ return true;
+ }
+ if (!expandedKeySet.has(parentId)) {
+ return false;
+ }
+ currentId = parentId;
+ }
+ return true;
+ });
+
+ if (normalizedKeys.length !== expandedKeySet.size) {
+ expandedKeySet.clear();
+ normalizedKeys.forEach((key) => expandedKeySet.add(key));
+ saveExpandedKeys();
+ }
+};
const productDia = ref(false);
const modelDia = ref(false);
@@ -241,7 +327,10 @@
productName: "",
},
rules: {
- productName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ productName: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ { max: 20, message: "浜у搧鍚嶇О涓嶈兘瓒呰繃20涓瓧绗�", trigger: "blur" },
+ ],
},
modelForm: {
model: "",
@@ -258,15 +347,29 @@
treeLoad.value = true;
productTreeList()
.then((res) => {
- list.value = res;
- list.value.forEach((a) => {
- expandedKeys.value.push(a.label);
+ list.value = res || [];
+ normalizeExpandedKeys(list.value);
+ expandedKeys.value = Array.from(expandedKeySet);
+ treeKey.value += 1;
+ nextTick(() => {
+ tree.value?.setDefaultExpandedKeys?.(expandedKeys.value);
});
- treeLoad.value = false;
})
.catch((err) => {
+ console.error(err);
+ })
+ .finally(() => {
treeLoad.value = false;
});
+};
+const handleNodeExpand = (data) => {
+ nextTick(syncExpandedKeysFromTree);
+};
+const handleNodeCollapse = (data, node) => {
+ node?.eachNode?.((item) => {
+ item.collapse();
+ });
+ nextTick(syncExpandedKeysFromTree);
};
// 杩囨护浜у搧鏍�
const searchFilter = () => {
@@ -319,53 +422,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 +508,11 @@
proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
return;
}
- safeConfirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず")
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
.then(() => {
tableLoading.value = true;
delProductModel(ids)
@@ -501,18 +572,21 @@
display: flex;
}
.left {
- width: 380px;
+ width: 450px;
+ min-width: 450px;
padding: 16px;
background: #ffffff;
}
.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 +594,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