From 141a3b8aa81efa30d5efc6d6669234f4c726aa47 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 08 五月 2026 13:52:12 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_浪潮' into dev_浪潮
---
src/views/basicData/product/materialIndex.vue | 672 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/views/basicData/product/index.vue | 20 +
2 files changed, 690 insertions(+), 2 deletions(-)
diff --git a/src/views/basicData/product/index.vue b/src/views/basicData/product/index.vue
index 99ab028..99ebc4f 100644
--- a/src/views/basicData/product/index.vue
+++ b/src/views/basicData/product/index.vue
@@ -163,6 +163,17 @@
@keydown.enter.prevent />
</el-form-item>
</el-col>
+ <el-col :span="24">
+ <el-form-item label="搴撳瓨閲忥細"
+ prop="stockInventory">
+ <el-input-number v-model="modelForm.stockInventory"
+ :min="0"
+ style="width: 100%"
+ placeholder="璇疯緭鍏ュ簱瀛橀噺"
+ controls-position="right"
+ @keydown.enter.prevent />
+ </el-form-item>
+ </el-col>
</el-row>
</el-form>
<template #footer>
@@ -303,6 +314,10 @@
prop: "unit",
},
{
+ label: "搴撳瓨閲�",
+ prop: "stockInventory",
+ },
+ {
dataType: "action",
label: "鎿嶄綔",
align: "center",
@@ -340,18 +355,18 @@
model: "",
unit: "",
productCode: "",
+ stockInventory: 0,
},
modelRules: {
model: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- productCode: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
},
});
const { form, rules, modelForm, modelRules } = toRefs(data);
// 鏌ヨ浜у搧鏍�
const getProductTreeList = () => {
treeLoad.value = true;
- productTreeList()
+ productTreeList({ productType: "鎴愬搧" })
.then(res => {
list.value = res || [];
normalizeExpandedKeys(list.value);
@@ -407,6 +422,7 @@
modelForm.value.model = "";
modelForm.value.unit = "";
modelForm.value.productCode = "";
+ modelForm.value.stockInventory = 0;
modelForm.value.id = "";
if (type === "edit") {
modelForm.value = { ...data };
diff --git a/src/views/basicData/product/materialIndex.vue b/src/views/basicData/product/materialIndex.vue
new file mode 100644
index 0000000..66c5cad
--- /dev/null
+++ b/src/views/basicData/product/materialIndex.vue
@@ -0,0 +1,672 @@
+<template>
+ <div class="app-container product-view">
+ <div class="left">
+ <div>
+ <el-input v-model="search"
+ style="width: 210px"
+ placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
+ @change="searchFilter"
+ @clear="searchFilter"
+ clearable
+ prefix-icon="Search" />
+ <el-button v-if="false"
+ type="primary"
+ @click="openProDia('addOne')"
+ style="margin-left: 10px">鏂板浜у搧澶х被</el-button>
+ </div>
+ <div ref="containerRef">
+ <el-tree ref="tree"
+ v-loading="treeLoad"
+ :data="list"
+ @node-click="handleNodeClick"
+ :expand-on-click-node="false"
+ @node-expand="handleNodeExpand"
+ @node-collapse="handleNodeCollapse"
+ :key="treeKey"
+ :default-expanded-keys="expandedKeys"
+ :filter-node-method="filterNode"
+ :props="{ children: 'children', label: 'label' }"
+ highlight-current
+ node-key="id"
+ class="product-tree-scroll"
+ style="height: calc(100vh - 190px); overflow-y: auto">
+ <template #default="{ node, data }">
+ <div class="custom-tree-node">
+ <span class="tree-node-content">
+ <el-icon class="orange-icon">
+ <component :is="data.children && data.children.length > 0
+ ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
+ </el-icon>
+ <span class="tree-node-label">{{ data.label }}</span>
+ </span>
+ <div>
+ <el-button type="primary"
+ link
+ :disabled="isTopLevelNode(data, node)"
+ @click="openProDia('edit', data)">
+ 缂栬緫
+ </el-button>
+ <el-button type="primary"
+ link
+ @click="openProDia('add', data)">
+ 娣诲姞浜у搧
+ </el-button>
+ <el-button v-if="!node.childNodes.length"
+ style="margin-left: 4px"
+ type="danger"
+ link
+ :disabled="isTopLevelNode(data, node)"
+ @click="remove(node, data)">
+ 鍒犻櫎
+ </el-button>
+ </div>
+ </div>
+ </template>
+ </el-tree>
+ </div>
+ </div>
+ <div class="right">
+ <div style="margin-bottom: 10px"
+ v-if="isShowButton">
+ <el-button type="primary"
+ @click="openModelDia('add')">
+ 鏂板瑙勬牸鍨嬪彿
+ </el-button>
+ <ImportExcel :product-id="currentId"
+ @uploadSuccess="getModelList" />
+ <el-button type="danger"
+ @click="handleDelete"
+ style="margin-left: 10px"
+ plain>
+ 鍒犻櫎
+ </el-button>
+ </div>
+ <PIMTable rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :page="page"
+ :isSelection="true"
+ @selection-change="handleSelectionChange"
+ :tableLoading="tableLoading"
+ @pagination="pagination"></PIMTable>
+ </div>
+ <el-dialog v-model="productDia"
+ title="浜у搧"
+ width="400px"
+ @keydown.enter.prevent>
+ <el-form :model="form"
+ label-width="140px"
+ label-position="top"
+ :rules="rules"
+ ref="formRef">
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="浜у搧鍚嶇О锛�"
+ prop="productName">
+ <el-input v-model="form.productName"
+ placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
+ maxlength="20"
+ show-word-limit
+ clearable
+ @keydown.enter.prevent />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary"
+ @click="submitForm">纭</el-button>
+ <el-button @click="closeProDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ <el-dialog v-model="modelDia"
+ title="瑙勬牸鍨嬪彿"
+ width="400px"
+ @close="closeModelDia"
+ @keydown.enter.prevent>
+ <el-form :model="modelForm"
+ label-width="140px"
+ label-position="top"
+ :rules="modelRules"
+ ref="modelFormRef">
+ <el-row>
+ <el-row>
+ <el-col :span="24">
+ <el-form-item label="浜у搧缂栧彿锛�"
+ prop="productCode">
+ <el-input v-model="modelForm.productCode"
+ placeholder="璇疯緭鍏ヤ骇鍝佺紪鍙�"
+ clearable
+ @keydown.enter.prevent />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-col :span="24">
+ <el-form-item label="瑙勬牸鍨嬪彿锛�"
+ prop="model">
+ <el-input v-model="modelForm.model"
+ 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"
+ placeholder="璇疯緭鍏ュ崟浣�"
+ clearable
+ @keydown.enter.prevent />
+ </el-form-item>
+ </el-col>
+ <el-col :span="24">
+ <el-form-item label="搴撳瓨閲忥細"
+ prop="stockInventory">
+ <el-input-number v-model="modelForm.stockInventory"
+ :min="0"
+ style="width: 100%"
+ placeholder="璇疯緭鍏ュ簱瀛橀噺"
+ controls-position="right"
+ @keydown.enter.prevent />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary"
+ @click="submitModelForm">纭</el-button>
+ <el-button @click="closeModelDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+ import { nextTick, ref } from "vue";
+ import { ElMessageBox } from "element-plus";
+ import {
+ addOrEditProduct,
+ addOrEditProductModel,
+ delProduct,
+ delProductModel,
+ modelListPage,
+ productTreeList,
+ } from "@/api/basicData/product.js";
+ import ImportExcel from "./ImportExcel/index.vue";
+
+ 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);
+ const modelOperationType = ref("");
+ const search = ref("");
+ const currentId = ref("");
+ const currentParentId = ref("");
+ const operationType = ref("");
+ const treeLoad = ref(false);
+ const list = ref([]);
+ const expandedKeys = ref([]);
+ const tableColumn = ref([
+ {
+ label: "浜у搧缂栧彿",
+ prop: "productCode",
+ },
+ {
+ label: "瑙勬牸鍨嬪彿",
+ prop: "model",
+ },
+ {
+ label: "鍗曚綅",
+ prop: "unit",
+ },
+ {
+ label: "搴撳瓨閲�",
+ prop: "stockInventory",
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ operation: [
+ {
+ name: "缂栬緫",
+ type: "text",
+ clickFun: row => {
+ openModelDia("edit", row);
+ },
+ },
+ ],
+ },
+ ]);
+ const tableData = ref([]);
+ const tableLoading = ref(false);
+ const isShowButton = ref(false);
+ const selectedRows = ref([]);
+ const page = reactive({
+ current: 1,
+ size: 10,
+ total: 0,
+ });
+ const data = reactive({
+ form: {
+ productName: "",
+ },
+ rules: {
+ productName: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ { max: 20, message: "浜у搧鍚嶇О涓嶈兘瓒呰繃20涓瓧绗�", trigger: "blur" },
+ ],
+ },
+ modelForm: {
+ model: "",
+ unit: "",
+ productCode: "",
+ stockInventory: 0,
+ },
+ modelRules: {
+ model: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ },
+ });
+ const { form, rules, modelForm, modelRules } = toRefs(data);
+ // 鏌ヨ浜у搧鏍�
+ const getProductTreeList = () => {
+ treeLoad.value = true;
+ productTreeList({ productType: "鐗╂枡" })
+ .then(res => {
+ list.value = res || [];
+ normalizeExpandedKeys(list.value);
+ expandedKeys.value = Array.from(expandedKeySet);
+ treeKey.value += 1;
+ nextTick(() => {
+ tree.value?.setDefaultExpandedKeys?.(expandedKeys.value);
+ });
+ })
+ .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 = () => {
+ proxy.$refs.tree.filter(search.value);
+ };
+ const isTopLevelNode = (data, node) => {
+ if (node?.level !== undefined) {
+ return node.level === 1;
+ }
+ return [null, undefined, "", 0, "0"].includes(data?.parentId);
+ };
+ // 鎵撳紑浜у搧寮规
+ const openProDia = (type, data) => {
+ if (data && type === "edit" && isTopLevelNode(data)) {
+ proxy.$modal.msgWarning("涓�绾ц妭鐐逛笉鑳界紪杈戞垨鍒犻櫎");
+ return;
+ }
+ operationType.value = type;
+ productDia.value = true;
+ form.value.productName = "";
+ if (type === "edit") {
+ form.value.productName = data.productName;
+ }
+ };
+ // 鎵撳紑瑙勬牸鍨嬪彿寮规
+ const openModelDia = (type, data) => {
+ modelOperationType.value = type;
+ modelDia.value = true;
+ modelForm.value.model = "";
+ modelForm.value.unit = "";
+ modelForm.value.productCode = "";
+ modelForm.value.stockInventory = 0;
+ modelForm.value.id = "";
+ if (type === "edit") {
+ modelForm.value = { ...data };
+ }
+ };
+ // 鎻愪氦浜у搧鍚嶇О淇敼
+ const submitForm = () => {
+ proxy.$refs.formRef.validate(valid => {
+ if (valid) {
+ if (operationType.value === "add") {
+ form.value.parentId = currentId.value;
+ form.value.id = "";
+ } else if (operationType.value === "addOne") {
+ form.value.id = "";
+ form.value.parentId = "";
+ } else {
+ form.value.id = currentId.value;
+ form.value.parentId = "";
+ }
+ addOrEditProduct(form.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeProDia();
+ getProductTreeList();
+ });
+ }
+ });
+ };
+ // 鍏抽棴浜у搧寮规
+ const closeProDia = () => {
+ proxy.$refs.formRef.resetFields();
+ productDia.value = false;
+ };
+
+ // 鍒犻櫎浜у搧
+ const remove = (node, data) => {
+ if (isTopLevelNode(data, node)) {
+ proxy.$modal.msgWarning("涓�绾ц妭鐐逛笉鑳界紪杈戞垨鍒犻櫎");
+ return;
+ }
+ let ids = [];
+ ids.push(data.id);
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ tableLoading.value = true;
+ delProduct(ids)
+ .then(res => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getProductTreeList();
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+ };
+ // 閫夋嫨浜у搧
+ const handleNodeClick = (val, node, el) => {
+ // 鍒ゆ柇鏄惁涓哄彾瀛愯妭鐐�
+ isShowButton.value = !(val.children && val.children.length > 0);
+ // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
+ currentId.value = val.id;
+ currentParentId.value = val.parentId;
+ getModelList();
+ };
+
+ // 鎻愪氦瑙勬牸鍨嬪彿淇敼
+ const submitModelForm = () => {
+ proxy.$refs.modelFormRef.validate(valid => {
+ if (valid) {
+ modelForm.value.productId = currentId.value;
+ addOrEditProductModel(modelForm.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeModelDia();
+ getModelList();
+ });
+ }
+ });
+ };
+ // 鍏抽棴鍨嬪彿寮规
+ const closeModelDia = () => {
+ proxy.$refs.modelFormRef.resetFields();
+ modelDia.value = false;
+ };
+ // 琛ㄦ牸閫夋嫨鏁版嵁
+ const handleSelectionChange = selection => {
+ selectedRows.value = selection;
+ };
+
+ // 鏌ヨ瑙勬牸鍨嬪彿
+ const pagination = obj => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getModelList();
+ };
+ const getModelList = () => {
+ tableLoading.value = true;
+ modelListPage({
+ id: currentId.value,
+ current: page.current,
+ size: page.size,
+ }).then(res => {
+ console.log("res", res);
+ tableData.value = res.records;
+ page.total = res.total;
+ tableLoading.value = false;
+ });
+ };
+ // 鍒犻櫎瑙勬牸鍨嬪彿
+ const handleDelete = () => {
+ let ids = [];
+ if (selectedRows.value.length > 0) {
+ ids = selectedRows.value.map(item => item.id);
+ } else {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ tableLoading.value = true;
+ delProductModel(ids)
+ .then(res => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getModelList();
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+ };
+ // 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
+ const filterNode = (value, data, node) => {
+ if (!value) {
+ //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
+ return true;
+ }
+ // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
+ let val = value.toLowerCase();
+ return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
+ };
+ // 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
+ const chooseNode = (value, data, node) => {
+ if (data.label.indexOf(value) !== -1) {
+ return true;
+ }
+ const level = node.level;
+ // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
+ if (level === 1) {
+ return false;
+ }
+ // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
+ let parentData = node.parent;
+ // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
+ let index = 0;
+ while (index < level - 1) {
+ // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
+ if (parentData.data.label.indexOf(value) !== -1) {
+ return true;
+ }
+ // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
+ parentData = parentData.parent;
+ index++;
+ }
+ // 娌″尮閰嶅埌杩斿洖false
+ return false;
+ };
+ getProductTreeList();
+</script>
+
+<style scoped>
+ .product-view {
+ display: flex;
+ }
+ .left {
+ width: 450px;
+ min-width: 450px;
+ padding: 16px;
+ background: #ffffff;
+ }
+ .right {
+ 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;
+ font-size: 14px;
+ padding-right: 8px;
+ }
+ .tree-node-content {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ 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