linwenxin 1 سال پیش
والد
کامیت
035f08a8fc

+ 3 - 3
package-lock.json

@@ -4716,9 +4716,9 @@
       "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
     },
     "@zjlib/element-plugins": {
-      "version": "2.13.18",
-      "resolved": "http://121.41.110.30:4873/@zjlib%2felement-plugins/-/element-plugins-2.13.18.tgz",
-      "integrity": "sha512-P9gMVRm/wlzlR+uAJvARH8jkf7wOCk9XWx6NcN5mZqM04li079GNpaHp9Qb0s9f9j0G4fMCBVuZGtm2BBpEo3A==",
+      "version": "2.13.20",
+      "resolved": "http://121.41.110.30:4873/@zjlib%2felement-plugins/-/element-plugins-2.13.20.tgz",
+      "integrity": "sha512-qHa59hdy7sIvmv3oMl7J0tzQPOR6B3e1HNZWHdo2alcyVqwnoT9xawYqabNhQJwH+Hfy22slJmjM00hlqIMQtw==",
       "requires": {
         "@turf/turf": "^6.5.0",
         "@vuemap/vue-amap": "^0.1.12",

+ 1 - 1
package.json

@@ -18,7 +18,7 @@
     "@turf/turf": "^6.5.0",
     "@vue-office/excel": "^1.3.0",
     "@vue/composition-api": "^1.7.1",
-    "@zjlib/element-plugins": "^2.13.18",
+    "@zjlib/element-plugins": "^2.13.20",
     "@zjlib/element-ui2": "^1.0.3",
     "axios": "0.18.1",
     "chatgpt": "^4.1.2",

+ 106 - 0
src/api/tradeInConfig.js

@@ -0,0 +1,106 @@
+import request, { postBlob, getBlob, handleImport } from '@/utils/request'
+
+export function tradeListPage(data) {
+  return request({
+    url: `/trade/list/page?moduleId=${data.moduleId}`,
+    method: 'post',
+    data
+  })
+}
+
+export function tradePageExport(data, name) {
+  return postBlob({
+    url: '/trade/pageExport',
+    data,
+    name
+  })
+}
+
+
+export function tradeListOtherPage(data) {
+  return request({
+    url: `/trade/listOther/page?moduleId=${data.moduleId}`,
+    method: 'post',
+    data
+  })
+}
+
+export function tradePageOtherExport(data, name) {
+  return postBlob({
+    url: '/trade/pageOtherExport',
+    data,
+    name
+  })
+}
+
+export function tradeList(params) {
+  return request({
+    url: '/trade/list',
+    method: 'get',
+    params: params
+  })
+}
+
+export function serviceCategoryAdd(data) {
+  return request({
+    url: '/trade/add',
+    method: 'post',
+    data: data
+  })
+}
+
+export function serviceCategoryUpdate(data) {
+  return request({
+    url: '/trade/update',
+    method: 'post',
+    data: data
+  })
+}
+
+export function serviceCategoryDel(params) {
+  return request({
+    url: '/trade/delete',
+    method: 'post',
+    params: params
+  })
+}
+
+export function serviceCategoryDetail(params) {
+  return request({
+    url: '/trade/detail',
+    method: 'get',
+    params: params
+  })
+}
+
+export function serviceCategoryItemAdd(data) {
+  return request({
+    url: '/trade/addItem',
+    method: 'post',
+    data: data
+  })
+}
+
+export function serviceCategoryItemUpdate(data) {
+  return request({
+    url: '/trade/updateItem',
+    method: 'post',
+    data: data
+  })
+}
+
+export function serviceCategoryItemDel(params) {
+  return request({
+    url: '/trade/deleteItem',
+    method: 'post',
+    params: params
+  })
+}
+
+export function serviceCategoryItemDetail(params) {
+  return request({
+    url: '/trade/detailItem',
+    method: 'get',
+    params: params
+  })
+}

+ 7 - 0
src/components/template/template-page-1.vue

@@ -141,6 +141,10 @@ export default {
       type: String,
       default: 'exp'
     },
+    // 数据钩子
+    recordsHook: {
+      type: Function
+    },
   },
   data() {
     return {
@@ -390,6 +394,9 @@ export default {
         var res = await this.getList(this.parameter)
         // alert('接收到数据断点')
         if (res.code == 200) {
+          if (this.recordsHook) {
+            res.data.records = this.recordsHook([...(res?.data?.records || [])]) || res?.data?.records || []
+          }
           if (this.fieldBeansHook) {
             res.fieldBeans = this.fieldBeansHook(res.fieldBeans) || res.fieldBeans
           }

+ 18 - 4
src/utils/util.js

@@ -2,6 +2,20 @@ import axios from 'axios'
 import FileSaver from 'file-saver'
 import { getToken } from '@/utils/auth'
 
+// 定义一个函数将树形数据转换为列表
+export function treeToList(tree, key = "children", list = []) {
+  // 将当前节点添加到列表中
+  list.push(...tree);
+  // 遍历当前节点的子节点
+  tree?.forEach(item => {
+    if (item?.[key]?.length) {
+      // 递归调用,将子节点及其后代节点添加到列表中
+      treeToList(item?.[key], key, list);
+    }
+  });
+  return list;
+}
+
 /**
  * 删除对象中的空值
  * @param {object} obj
@@ -9,8 +23,8 @@ import { getToken } from '@/utils/auth'
  */
 export function deleteEmptyObj(obj) {
   let newObj = obj;
-  for(var key in newObj) {
-    if(newObj[key] === '' || newObj[key] === null || newObj[key] === undefined) {
+  for (var key in newObj) {
+    if (newObj[key] === '' || newObj[key] === null || newObj[key] === undefined) {
       delete newObj[key]
     }
   }
@@ -25,12 +39,12 @@ export function deleteEmptyObj(obj) {
  * @returns 
  */
 export function findElem(array, attr, val) {
-  if(!array || !array.length){
+  if (!array || !array.length) {
     return -1
   }
   for (var i = 0; i < array.length; i++) {
     if (array[i][attr] == val) {
-        return i; //返回当前索引值
+      return i; //返回当前索引值
     }
   }
   return -1;

+ 20 - 0
src/views/setting/tradeInConfig/index.vue

@@ -0,0 +1,20 @@
+<template>
+  <categoryAllocation/>
+</template>
+
+<script>
+import categoryAllocation from './pages/categoryAllocation.vue'
+export default {
+  components: { categoryAllocation },
+  data() {
+    return {
+    }
+  },
+  methods: {
+    
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 208 - 0
src/views/setting/tradeInConfig/mixins/formItems.js

@@ -0,0 +1,208 @@
+import {
+  serviceCategoryAdd,
+  serviceCategoryUpdate,
+  serviceCategoryDel,
+  serviceCategoryDetail
+} from '@/api/tradeInConfig.js'
+import ImageUpload from '@/components/file-upload'
+import { required } from '@/components/template/rules_verify.js'
+export default {
+  components: { ImageUpload },
+  data() {
+    return {
+      formDialog: false,
+      formData: {
+        level: 0,
+        name: '',
+        parentId: 0,
+        sortNum: 0,
+        status: true,
+        typeAttribute: '',
+        typeOption: '',
+        // type: '',
+        // indexSort: 0,
+        // imgUrl: []
+      }
+    }
+  },
+  computed: {
+    formItems() {
+      return [
+        {
+          isShow: !!~[2, 3].indexOf(this.formData.level),
+          name: 'el-select',
+          md: 24,
+          formItemAttributes: {
+            label: '上级名称',
+            prop: 'parentId',
+            rules: [...required]
+          },
+          options: this.list.map(item => ({ label: item.name, value: item.categoryId })),
+          attributes: { disabled: true, clearable: true, filterable: true, placeholder: '请选择' }
+        },
+        {
+          name: 'el-input',
+          md: 24,
+          attributes: { disabled: false, placeholder: '请输入', maxlength: 11 },
+          formItemAttributes: {
+            label: "类型名称",
+            prop: 'name',
+            rules: [...required]
+          }
+        },
+        // {
+        //   md: 24,
+        //   isShow: !!~[2].indexOf(this.formData.level),
+        //   name: 'slot-component',
+        //   formItemAttributes: {
+        //     prop: 'imgUrl',
+        //     label: '分类图片',
+        //     rules: [...required]
+        //   },
+        //   render: (h, { props, onInput }) => {
+        //     var { value } = props
+        //     return <ImageUpload fileList={this.formData.imgUrl} limit={1} isEdit={true} />
+        //   }
+        // },
+        {
+          isShow: !!~[3].indexOf(this.formData.level),
+          md: 24,
+          name: 'el-radio',
+          options: [
+            { label: '单选', value: 'SIGIN' },
+            { label: '多选', value: 'MANY' }
+          ],
+          attributes: { disabled: this.formData.id ? true : false },
+          formItemAttributes: {
+            label: '选项属性',
+            prop: 'typeOption',
+            rules: [...required]
+          }
+        },
+        {
+          isShow: !!~[3].indexOf(this.formData.level),
+          md: 24,
+          name: 'el-radio',
+          options: [
+            { label: '规格', value: 'SPEC' },
+            // { label: '增减参考金额', value: 'DED' },
+            { label: '其他', value: 'OTHER' }
+          ],
+          attributes: { disabled: this.formData.id ? true : false },
+          formItemAttributes: {
+            label: '属性类型',
+            prop: 'typeAttribute',
+            rules: [...required]
+          }
+        },
+        {
+          md: 24,
+          name: 'el-radio',
+          options: [
+            { label: '有效', value: true },
+            { label: '无效', value: false }
+          ],
+          attributes: {},
+          formItemAttributes: {
+            label: '状态',
+            prop: 'status',
+            rules: [...required]
+          }
+        },
+        {
+          name: 'el-input',
+          md: 12,
+          attributes: { disabled: false, placeholder: '请输入', maxlength: 11 },
+          formItemAttributes: {
+            label: '排序',
+            prop: 'sortNum',
+            rules: []
+          }
+        },
+        // {
+        //   isShow: !!~[2].indexOf(this.formData.level),
+        //   name: 'el-input',
+        //   md: 12,
+        //   attributes: { disabled: false, placeholder: '请输入', maxlength: 11 },
+        //   formItemAttributes: {
+        //     label: '首页顺序',
+        //     prop: 'indexSort',
+        //     rules: []
+        //   }
+        // }
+      ]
+    }
+  },
+  methods: {
+    // 添加一级
+    addL1Class() {
+      this.formData.level = 1
+      this.formDialog = true
+    },
+    // 添加二三级
+    addChClass(row) {
+      this.formData.level = row.level + 1
+      this.formData.parentId = row.categoryId
+      this.formDialog = true
+    },
+    // 编辑
+    editClass(row) {
+      serviceCategoryDetail({ categoryId: row.categoryId }).then(res => {
+        Object.assign(
+          this.formData,
+          { ...res.data },
+          // {
+          //   imgUrl: res.data.imgUrl ? res.data.imgUrl.split(',').map(u => ({ imgUrl: u })) : [],
+          //   children: undefined
+          // }
+        )
+        this.formDialog = true
+      })
+    },
+    // 删除
+    handleDelete(row) {
+      serviceCategoryDel({ categoryId: row.categoryId }).then(res => {
+        this.$message({
+          type: 'success',
+          message: `删除成功!`
+        })
+        this.getList()
+      })
+    },
+    // 关闭窗口
+    formCancel() {
+      this.$refs?.formRef?.$refs?.inlineForm?.clearValidate()
+      this.$data.formData = this.$options.data().formData
+      this.formDialog = false
+    },
+    // 确定保存
+    formConfirm() {
+      this.$refs.formRef.validate((valid, invalidFields, errLabels) => {
+        if (valid) {
+          ;[serviceCategoryAdd, serviceCategoryUpdate]
+          [this.formData.id ? 1 : 0]({
+            ...this.formData,
+            // imgUrl: this.formData.imgUrl.map(item => item.imgUrl).join(','),
+            // ...(() => {
+            //   if (this.formData.level == 3) {
+            //     return {
+            //       categoryType: 'A'
+            //     }
+            //   } else {
+            //     return {}
+            //   }
+            // })()
+          })
+            .then(res => {
+              this.$message({
+                type: 'success',
+                message: `保存成功!`
+              })
+              this.formCancel()
+              this.getList()
+            })
+        }
+      })
+    }
+  }
+}

+ 403 - 0
src/views/setting/tradeInConfig/pages/categoryAllocation.vue

@@ -0,0 +1,403 @@
+<template>
+  <div style="width: 100%; height: 100%; box-sizing: border-box; padding: 20px">
+    <zj-page-container direction="row">
+      <div class="catalogue" style="padding-right: 0px">
+        <zj-page-container>
+          <div style="padding: 0 10px 10px; display: flex">
+            <el-button icon="el-icon-refresh-right" size="small" @click="refreshDepartment"
+              style="padding: 9px 10px; margin-right: 6px"></el-button>
+            <el-input placeholder="输入关键字进行过滤" size="small" clearable v-model="filterText"> </el-input>
+          </div>
+          <zj-page-fill>
+            <el-tree :data="listTree" :props="defaultProps" default-expand-all highlight-current
+              :expand-on-click-node="false" :filter-node-method="filterNode" @node-click="handleNodeClick"
+              node-key="categoryId" ref="listTree">
+              <div class="custom-tree-node" slot-scope="{ node, data }">
+                <span>
+                  <i :class="data.children && data.children.length > 0 ? 'el-icon-folder-opened' : 'el-icon-document-remove'
+              "></i>
+                  <span>{{ node.label }}</span>
+                </span>
+                <span v-if="data.level == 2 || data.level == 3">
+                  <el-button v-if="data.level == 2" type="text" size="mini" @click="addChClass(data)"> 添加 </el-button>
+                  <el-button v-if="data.level == 3" type="text" size="mini" @click="editClass(data)"> 编辑 </el-button>
+                  <el-popconfirm v-if="data.level == 3" style="margin-left: 10px" title="确定删除吗?"
+                    @confirm="handleDelete(data)">
+                    <el-button v-if="data.level == 3" slot="reference" size="mini" type="text"> 删除 </el-button>
+                  </el-popconfirm>
+                </span>
+              </div>
+            </el-tree>
+          </zj-page-fill>
+        </zj-page-container>
+      </div>
+      <zj-page-fill v-loading="!showList">
+        <template-page v-if="showList && item && item.typeAttribute" ref="pageRef" :getList="getListRight"
+          :exportList="exportList" :columnParsing="columnParsing" :optionsEvensGroup="optionsEvensGroup"
+          :tableAttributes="tableAttributes" :tableEvents="tableEvents" :operationColumnWidth="200"
+          :operation="operation()" :recordsHook="recordsHook" :replaceOrNotMap="true" :customModuleName="`${$route.meta.title}_${item ? ['规格', '其他'][typeAttribute[item.typeAttribute]] : ''
+              }`" :setModuleId="`${$route.meta.moduleId}_${item ? item.typeAttribute : ''}`">
+        </template-page>
+      </zj-page-fill>
+    </zj-page-container>
+    <el-dialog :title="formData.categoryId ? '编辑' : '新建'" :modal="true" width="600px" :visible.sync="formDialog"
+      :before-close="formCancel" :close-on-click-modal="false">
+      <zj-form-container v-if="formDialog" ref="formRef" :form-data="formData" :styleSwitch="false">
+        <zj-form-module label-width="120px" :showPackUp="false" :form-data="formData" :form-items="formItems">
+        </zj-form-module>
+      </zj-form-container>
+      <div slot="footer" class="dialog-footer">
+        <el-button size="mini" @click="formCancel">取 消</el-button>
+        <el-button size="mini" @click="formConfirm" type="primary">确定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import import_mixin from '@/components/template/import_mixin.js'
+import TemplatePage from '@/components/template/template-page-1.vue'
+import { treeToList } from '@/utils/util'
+import {
+  tradeList,
+  tradeListPage,
+  tradePageExport,
+  tradeListOtherPage,
+  tradePageOtherExport,
+  serviceCategoryDetail,
+  serviceCategoryItemAdd,
+  serviceCategoryItemUpdate,
+  serviceCategoryItemDel
+} from '@/api/tradeInConfig.js'
+import formItems from '../mixins/formItems.js'
+export default {
+  mixins: [import_mixin, formItems],
+  components: {
+    TemplatePage
+  },
+  data() {
+    return {
+      // 事件组合
+      optionsEvensGroup: [],
+      // 表格属性
+      tableAttributes: {},
+      // 表格事件
+      tableEvents: {},
+      // 重新加载列表
+      showList: true,
+      //**部门树 */
+      filterText: '',
+      list: [],
+      listTree: [],
+      defaultProps: {
+        children: 'children',
+        label: 'name'
+      },
+      item: null,
+      typeAttribute: {
+        SPEC: 0,
+        OTHER: 1
+      }
+    }
+  },
+  watch: {
+    filterText(val) {
+      this.$refs.listTree.filter(val)
+    },
+    item(val) {
+      this.showList = false
+      if (val) {
+        this.$nextTick(() => {
+          this.showList = true
+        })
+      }
+    }
+  },
+  mounted() {
+    this.getList()
+  },
+  methods: {
+    getList() {
+      tradeList().then(res => {
+        this.list = treeToList(res.data)
+        this.listTree = res.data
+        this.listTree.map(item => {
+          ; (item.children || []).map(item2 => {
+            ; (item2.children || []).map(item3 => {
+              if (!this.item) {
+                this.item = item3
+                serviceCategoryDetail({ categoryId: item3.categoryId }).then(res => {
+                  this.item = res.data
+                  this.$nextTick(() => {
+                    this.$refs.listTree.setCurrentKey(this.item?.categoryId || '')
+                  })
+                })
+              }
+            })
+          })
+        })
+      })
+    },
+    refreshDepartment() {
+      this.getList()
+    },
+    filterNode(value, data) {
+      if (!value) return true
+      return data.name.indexOf(value) !== -1
+    },
+    // 选择部门
+    handleNodeClick(data) {
+      if (data.level === 3) {
+        serviceCategoryDetail({ categoryId: data.categoryId }).then(res => {
+          this.item = res.data
+        })
+      } else {
+        this.$refs.listTree.setCurrentKey(this.item?.categoryId || '')
+      }
+    },
+    exportList(...p) {
+      return [tradePageExport, tradePageOtherExport][
+        this.typeAttribute[this.item.typeAttribute]
+      ](...p)
+    },
+    // 列表请求函数
+    getListRight(p, cb) {
+      p.params.push({ param: 'service_category_id', compare: '=', value: this.item.categoryId })
+      cb && cb(p)
+      return [tradeListPage, tradeListOtherPage][
+        this.typeAttribute[this.item.typeAttribute]
+      ](p)
+    },
+    recordsHook(list) {
+      return [
+        {
+          "dictName": "",
+          "price": 0,
+          "companyName": JSON.parse(localStorage.getItem('greemall_user')).companyName,
+          "categoryName": this.item?.name || '',
+          "serviceCategoryId": this.item?.categoryId || '',
+          "status": 'ON',
+          "typeAttribute": this.item?.typeAttribute,
+          "remark": "",
+          isRowEdit: true
+        },
+        ...list.map(item => ({ ...item, isRowEdit: false }))
+      ]
+    },
+    // 表格列解析渲染数据更改
+    columnParsing(item, defaultData) {
+      if (item.jname === 'dictName') {
+        defaultData.render = (h, { row, index, column }) => {
+          if (row.isRowEdit) {
+            return (
+              <div class="redbordererr">
+                <el-input
+                  value={row[column.columnAttributes.prop]}
+                  onInput={val => {
+                    row[column.columnAttributes.prop] = val
+                  }}
+                  placeholder="请输入内容"
+                ></el-input>
+              </div>
+            )
+          } else {
+            return <div style="padding:0 6px;">{row[column.columnAttributes.prop]}</div>
+          }
+        }
+      }
+      if (item.jname === 'remark') {
+        defaultData.render = (h, { row, index, column }) => {
+          if (row.isRowEdit) {
+            return (
+              <div class="redbordererr">
+                <el-input
+                  value={row[column.columnAttributes.prop]}
+                  onInput={val => {
+                    row[column.columnAttributes.prop] = val
+                  }}
+                  placeholder="请输入内容"
+                ></el-input>
+              </div>
+            )
+          } else {
+            return <div style="padding:0 6px;">{row[column.columnAttributes.prop]}</div>
+          }
+        }
+      }
+      if (item.jname === 'status') {
+        defaultData.render = (h, { row, index, column }) => {
+          if (row.isRowEdit) {
+            return (
+              <div class="redbordererr">
+                <el-select
+                  value={row[column.columnAttributes.prop]}
+                  onInput={val => {
+                    row[column.columnAttributes.prop] = val
+                  }}
+                  placeholder="请选择"
+                >
+                  {[
+                    { label: '有效', value: 'ON' },
+                    { label: '无效', value: 'OFF' }
+                  ].map((item, index_) => (
+                    <el-option key={index_} label={item.label} value={item.value}></el-option>
+                  ))}
+                </el-select>
+              </div>
+            )
+          } else {
+            return <div style="padding:0 6px;">{row[column.columnAttributes.prop]}</div>
+          }
+        }
+      }
+      if (item.jname === 'price') {
+        defaultData.render = (h, { row, index, column }) => {
+          if (row.isRowEdit) {
+            return (
+              <div class="redbordererr">
+                <el-input
+                  value={row[column.columnAttributes.prop]}
+                  onInput={val => {
+                    row[column.columnAttributes.prop] = val
+                  }}
+                  placeholder="请输入内容"
+                  type="number"
+                ></el-input>
+              </div>
+            )
+          } else {
+            return (
+              <div style="padding:0 6px;">{row[column.columnAttributes.prop]}</div>
+            )
+          }
+        }
+      }
+      return defaultData
+    },
+    operation() {
+      return (h, { row, index, column }) => {
+        return (
+          <div class="operation-btns">
+            {index === 0 || row.isRowEdit ? (
+              <zj-button
+                useLoading={false}
+                parameter={[row]}
+                buttonAttributes={{
+                  size: 'mini',
+                  type: 'primary'
+                }}
+                buttonEvents={{
+                  click: row => {
+                    if (this.jiaoyan(row)) {
+                      ;[serviceCategoryItemAdd, serviceCategoryItemUpdate]
+                      [row.id ? 1 : 0]({
+                        ...row,
+                        status: row.status == '有效' ? 'ON' : row.status == '无效' ? 'OFF' : row.status
+                      })
+                        .then(res => {
+                          this.$message({
+                            type: 'success',
+                            message: `保存成功!`
+                          })
+                          this.$refs.pageRef.refreshList()
+                        })
+                    }
+                  }
+                }}
+              >
+                保存
+              </zj-button>
+            ) : null}
+            {!row.isRowEdit ? (
+              <zj-button
+                useLoading={false}
+                parameter={[row]}
+                buttonAttributes={{
+                  size: 'mini',
+                  type: 'primary'
+                }}
+                buttonEvents={{
+                  click: row => {
+                    row.isRowEdit = true
+                  }
+                }}
+              >
+                编辑
+              </zj-button>
+            ) : null}
+            {index !== 0 ? (
+              <el-popconfirm
+                icon="el-icon-info"
+                icon-color="red"
+                title="这是一段内容确定删除吗?"
+                onConfirm={() => {
+                  serviceCategoryItemDel({
+                    categoryId: row.id
+                  }).then(res => {
+                    this.$message({
+                      type: 'success',
+                      message: `删除成功!`
+                    })
+                    this.$refs.pageRef.refreshList()
+                  })
+                }}
+              >
+                <zj-button
+                  slot="reference"
+                  buttonAttributes={{
+                    size: 'mini',
+                    type: 'danger'
+                  }}
+                >
+                  删除
+                </zj-button>
+              </el-popconfirm>
+            ) : null}
+          </div>
+        )
+      }
+    },
+    jiaoyan(row) {
+      try {
+        ;['dictName', 'price'].map(key => {
+          if (row[key] === undefined || row[key] === null || row[key] === '') {
+            throw new Error(
+              {
+                dictName: '字典值',
+                price: ["回收价格(元/台)", "增减费用(元/台)"][this.typeAttribute[this.item.typeAttribute]],
+              }[key]
+            )
+          }
+        })
+        return true
+      } catch (err) {
+        this.$message({
+          type: 'error',
+          message: `缺少参数【${err.message}】!`
+        })
+        return false
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.catalogue {
+  width: 300px;
+  height: 100%;
+  box-sizing: border-box;
+  padding: 20px;
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+.custom-tree-node {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 14px;
+  padding-right: 8px;
+}
+</style>