From a6667d3351aea21abc363c35285e066ee37f40b2 Mon Sep 17 00:00:00 2001
From: zhang_nuo <zhang_12370@163.com>
Date: 星期二, 15 九月 2026 19:45:07 +0800
Subject: [PATCH] feat(qualityManagement): add batch selection for product binding tree
---
src/views/qualityManagement/metricBinding/index.vue | 102 ++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 93 insertions(+), 9 deletions(-)
diff --git a/src/views/qualityManagement/metricBinding/index.vue b/src/views/qualityManagement/metricBinding/index.vue
index ba989ea..d353bac 100644
--- a/src/views/qualityManagement/metricBinding/index.vue
+++ b/src/views/qualityManagement/metricBinding/index.vue
@@ -124,13 +124,19 @@
@close="closeBindingDialog"
>
<div class="binding-dialog">
- <el-input
- v-model="productSearchKeyword"
- placeholder="鎼滅储浜у搧"
- clearable
- prefix-icon="Search"
- class="binding-search"
- />
+ <div class="tree-toolbar">
+ <el-input
+ v-model="productSearchKeyword"
+ placeholder="鎼滅储浜у搧"
+ clearable
+ prefix-icon="Search"
+ class="binding-search"
+ />
+ <div class="tree-actions">
+ <el-button size="small" @click="handleCheckAll">鍏ㄩ��</el-button>
+ <el-button size="small" @click="handleCheckNone">娓呯┖</el-button>
+ </div>
+ </div>
<el-tree
ref="productTreeRef"
:key="productTreeKey"
@@ -143,7 +149,18 @@
:filter-node-method="filterProductNode"
class="product-binding-tree"
@check="handleProductTreeCheck"
- />
+ >
+ <template #default="{ node, data }">
+ <span class="custom-tree-node">
+ <span class="node-label">{{ node.label }}</span>
+ <span v-if="data.children?.length" class="node-action">
+ <el-button link type="primary" size="small" @click.stop="handleCheckNodeChildren(data)">
+ 鍏ㄩ��
+ </el-button>
+ </span>
+ </span>
+ </template>
+ </el-tree>
<div v-if="selectedProductLabels.length" class="selected-products">
<div class="selected-title">宸查�夋嫨锛坽{ selectedProductLabels.length }}锛�</div>
<div class="selected-tags">
@@ -343,6 +360,45 @@
const handleProductTreeCheck = () => {
selectedProductIds.value = productTreeRef.value?.getCheckedKeys(true) || []
+}
+
+// 鏀堕泦鎵�鏈夊彾瀛愯妭鐐� id
+const collectLeafNodeIds = (nodes) => {
+ const ids = []
+ const walk = (list) => {
+ ;(list || []).forEach((node) => {
+ if (node.children?.length) {
+ walk(node.children)
+ } else if (!node.disabled && node.id != null) {
+ ids.push(node.id)
+ }
+ })
+ }
+ walk(nodes)
+ return ids
+}
+
+// 鍏ㄩ�夛細閫変腑鎵�鏈夊彾瀛愯妭鐐�
+const handleCheckAll = () => {
+ const leafIds = collectLeafNodeIds(productTreeData.value)
+ productTreeRef.value?.setCheckedKeys(leafIds, false)
+ selectedProductIds.value = leafIds
+}
+
+// 娓呯┖锛氬彇娑堟墍鏈夐�変腑
+const handleCheckNone = () => {
+ productTreeRef.value?.setCheckedKeys([], false)
+ selectedProductIds.value = []
+}
+
+// 閫変腑褰撳墠鑺傜偣涓嬬殑鎵�鏈夊彾瀛愯妭鐐�
+const handleCheckNodeChildren = (data) => {
+ const leafIds = collectLeafNodeIds(data.children || [])
+ // 鍚堝苟褰撳墠宸查�変腑鐨� id
+ const currentChecked = productTreeRef.value?.getCheckedKeys(true) || []
+ const merged = Array.from(new Set([...currentChecked, ...leafIds]))
+ productTreeRef.value?.setCheckedKeys(merged, false)
+ selectedProductIds.value = merged
}
const removeSelectedProduct = (id) => {
@@ -614,8 +670,20 @@
gap: 12px;
}
+.tree-toolbar {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
.binding-search {
- width: 100%;
+ flex: 1;
+}
+
+.tree-actions {
+ display: flex;
+ gap: 6px;
+ flex-shrink: 0;
}
.product-binding-tree {
@@ -626,6 +694,22 @@
padding: 8px;
}
+.custom-tree-node {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ padding-right: 8px;
+}
+
+.node-label {
+ flex: 1;
+}
+
+.node-action {
+ flex-shrink: 0;
+}
+
.selected-products {
border-top: 1px solid #ebeef5;
padding-top: 12px;
--
Gitblit v1.9.3