gaoluyang
11 小时以前 0fca4eca794dba7ac8a6f89d4ce2636de00fd413
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
@@ -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"
@@ -97,10 +95,9 @@
        @selection-change="handleSelectionChange"
        :tableLoading="tableLoading"
        @pagination="pagination"
        :total="total"
      ></PIMTable>
    </div>
    <el-dialog v-model="productDia" title="产品" width="400px">
    <el-dialog v-model="productDia" title="产品" width="400px" @keydown.enter.prevent>
      <el-form
        :model="form"
        label-width="140px"
@@ -114,7 +111,10 @@
              <el-input
                v-model="form.productName"
                placeholder="请输入产品名称"
                maxlength="20"
                show-word-limit
                clearable
                @keydown.enter.prevent
              />
            </el-form-item>
          </el-col>
@@ -132,6 +132,7 @@
      title="规格型号"
      width="400px"
      @close="closeModelDia"
      @keydown.enter.prevent
    >
      <el-form
        :model="modelForm"
@@ -147,6 +148,7 @@
                v-model="modelForm.model"
                placeholder="请输入规格型号"
                clearable
                @keydown.enter.prevent
              />
            </el-form-item>
          </el-col>
@@ -158,6 +160,7 @@
                v-model="modelForm.unit"
                placeholder="请输入单位"
                clearable
                @keydown.enter.prevent
              />
            </el-form-item>
          </el-col>
@@ -189,6 +192,34 @@
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";
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 productDia = ref(false);
const modelDia = ref(false);
@@ -227,18 +258,21 @@
const tableData = ref([]);
const tableLoading = ref(false);
const isShowButton = ref(false);
const total = ref(0);
const selectedRows = ref([]);
const page = reactive({
  current: 1,
  size: 10,
  total: 0,
});
const data = reactive({
  form: {
    productName: "",
  },
  rules: {
    productName: [{ required: true, message: "请输入", trigger: "blur" }],
    productName: [
      { required: true, message: "请输入", trigger: "blur" },
      { max: 20, message: "产品名称不能超过20个字符", trigger: "blur" },
    ],
  },
  modelForm: {
    model: "",
@@ -255,15 +289,26 @@
  treeLoad.value = true;
  productTreeList()
    .then((res) => {
      list.value = res;
      list.value.forEach((a) => {
        expandedKeys.value.push(a.label);
      });
      treeLoad.value = false;
      list.value = res || [];
      expandedKeys.value = Array.from(expandedKeySet);
      treeKey.value += 1;
    })
    .catch((err) => {
      console.error(err);
    })
    .finally(() => {
      treeLoad.value = false;
    });
};
const handleNodeExpand = (data) => {
  expandedKeySet.add(data.id);
  expandedKeys.value = Array.from(expandedKeySet);
  saveExpandedKeys();
};
const handleNodeCollapse = (data) => {
  expandedKeySet.delete(data.id);
  expandedKeys.value = Array.from(expandedKeySet);
  saveExpandedKeys();
};
// 过滤产品树
const searchFilter = () => {
@@ -316,6 +361,7 @@
  proxy.$refs.formRef.resetFields();
  productDia.value = false;
};
// 删除产品
const remove = (node, data) => {
  let ids = [];
@@ -388,7 +434,7 @@
  }).then((res) => {
    console.log("res", res);
    tableData.value = res.records;
    total.value = res.total;
    page.total = res.total;
    tableLoading.value = false;
  });
};
@@ -465,18 +511,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;
@@ -484,13 +533,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>