浏览代码

产品分类-页面重新开发

jingbb 4 月之前
父节点
当前提交
795fdf1031

+ 3 - 1
src/views/BasicData/api/productCassification.api.ts

@@ -4,13 +4,15 @@ import { useMessage } from "/@/hooks/web/useMessage";
 const { createConfirm } = useMessage();
 enum Api {
   list = '/baseCode/baseProductClass/list',
+  treeList = '/baseCode/baseProductClass/queryByTree',
   save = '/baseCode/baseProductClass/add',
   edit = '/baseCode/baseProductClass/edit',
   deleteDict = '/baseCode/baseProductClass/delete',
   deleteBatch = 'baseCode/baseProductClass/deleteBatch',
 }
 
-export const list = (params) => defHttp.get({ url: Api.list, params });
+export const list = (params) => defHttp.get({ url: Api.list, params })
+export const listTree= (params) => defHttp.get({ url: Api.treeList, params });
 /**
  * 列表
  * @param params

+ 40 - 165
src/views/BasicData/productCassification.vue

@@ -1,173 +1,48 @@
 <template>
-  <!--定义表格-->
-  <BasicTable @register="registerTable" :rowSelection="rowSelection">
-    <template #tableTitle>
-      <a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate" v-auth="'baseCode:base_product_class:add'">
-        新增(add)</a-button
-      >
-      <a-dropdown v-if="selectedRowKeys.length > 0">
-        <template #overlay>
-          <a-menu>
-            <a-menu-item key="1" @click="batchHandleDelete">
-              <Icon icon="ant-design:delete-outlined" />
-              删除(delete)
-            </a-menu-item>
-          </a-menu>
-        </template>
-        <a-button v-auth="'baseCode:base_product_class:deleteBatch'"
-          >批量操作
-          <Icon icon="mdi:chevron-down" />
-        </a-button>
-      </a-dropdown>
-      <!-- <div style="margin-left: 10px;margin-top: 5px">当前登录租户: <span class="tenant-name">{{loginTenantName}}</span> </div> -->
-    </template>
-    <!--操作栏-->
-    <template #action="{ record }">
-      <TableAction :actions="getTableAction(record)" />
-    </template>
-  </BasicTable>
-  <productCassificationModel @register="registerModal" @success="handleSuccess" />
+  <a-row :class="['p-4', `${prefixCls}--box`]" :gutter="10">
+    <a-col :xl="6" :lg="8" :md="10" :sm="24" style="flex: 1">
+      <a-card :bordered="false" style="height: 100%">
+        <a-tabs defaultActiveKey="user-info">
+          <a-tab-pane tab="产品分类(Product Classification)" key="base-info" forceRender>
+              <productCassificationTree @select="selectId" ref="treeListRef"/>
+          </a-tab-pane>
+        </a-tabs>
+      </a-card>
+    </a-col>
+    <a-col :xl="18" :lg="16" :md="14" :sm="24" style="flex: 1">
+      <a-card :bordered="false" style="height: 100%">
+        <a-tabs defaultActiveKey="user-info">
+          <a-tab-pane tab="分类列表(Classification List)" key="base-info" forceRender>
+            <productCassification2 ref="classListRef" @success="addListSuccess"/>
+          </a-tab-pane>
+        </a-tabs>
+      </a-card>
+    </a-col>
+  </a-row>
 </template>
 
-<script lang="ts" name="basic-table-demo" setup>
-  import { onMounted, ref } from 'vue';
-  import { useModal } from '/@/components/Modal';
-  import { ActionItem, BasicColumn, BasicTable, TableAction, FormSchema } from '/@/components/Table';
-  import productCassificationModel from './components/productCassificationModel.vue';
-  import { useListPage } from '/@/hooks/system/useListPage';
-  import { list, deleteDict, batchDelete } from './api/productCassification.api';
-  const showFooter = ref(true);
-  const [registerModal, { openModal }] = useModal();
-  //定义表格列字段
-  const columns: BasicColumn[] = [
-    {
-      title: '编码(code)',
-      dataIndex: 'code',
-      key: 'code',
-    },
-    {
-      title: '名称(name)',
-      dataIndex: 'name',
-      key: 'name',
-    },
-    {
-      title: '上级分类(parent)',
-      dataIndex: 'parentId_dictText',
-      key: 'parentId',
-    },
-    {
-      title: '毛利率(gross margin)',
-      dataIndex: 'grossMargin',
-      key: 'grossMargin',
-      customRender: function (t, r, index) {
-        if (t.text && t.text !== '') {
-          return t.text + '%';
-        } else {
-          return '';
-        }
-      },
-    },
-    {
-      title: '税率(tax rate)',
-      dataIndex: 'taxRate',
-      key: 'taxRate',
-      customRender: function (t, r, index) {
-        if (t.text && t.text !== '') {
-          return t.text + '%';
-        } else {
-          return '';
-        }
-      },
-    },
-  ];
-  //表单搜索字段
-  const searchFormSchema: FormSchema[] = [
-    {
-      label: '编码(code)', //显示label
-      field: 'code', //查询字段
-      component: 'JInput', //渲染的组件
-      defaultValue: '', //设置默认值
-    },
-    {
-      label: '名称(name)', //显示label
-      field: 'name', //查询字段
-      component: 'JInput', //渲染的组件
-      defaultValue: '', //设置默认值、
-      componentProps: {
-        AutoComplete: 'off',
-      },
-    },
-  ];
-  /** useListPage 是整个框架的核心用于表格渲染,里边封装了很多公共方法;
-   * 平台通过此封装,简化了代码,支持自定义扩展*/
-  // 通过hook useListPage渲染表格(设置dataSource、columns、actionColumn等参数)
-  const { tableContext } = useListPage({
-    designScope: 'basic-table-demo',
-    tableProps: {
-      title: '',
-      api: list,
-      columns: columns,
-      size: 'small',
-      rowkey: 'id',
-      actionColumn: {
-        width: 120,
-      },
-      formConfig: {
-        schemas: searchFormSchema,
-      },
-    },
-  });
-  const [registerTable, { reload, updateTableDataRecord }, { rowSelection, selectedRows, selectedRowKeys }] = tableContext;
-  /**
-   * 操作栏
-   */
-  function getTableAction(record): ActionItem[] {
-    return [
-      {
-        label: '编辑',
-        onClick: handleEdit.bind(null, record),
-        auth: 'baseCode:base_product_class:edit',
-      },
-      {
-        label: '删除',
-        popConfirm: {
-          title: '确定删除吗?',
-          confirm: handleDelete.bind(null, record),
-        },
-        auth: 'baseCode:base_product_class:delete',
-      },
-    ];
-  }
+<script lang="ts" setup name="system-depart-user">
+  import { provide, ref } from 'vue';
+  import { useDesign } from '/@/hooks/web/useDesign';
 
-  function handleEdit(record) {
-    openModal(true, {
-      record,
-      isUpdate: true,
-    });
-  }
+  import productCassificationTree from './productCassificationTree.vue';
+  import productCassification2 from './productCassification1.vue';
+  // import DepartUserInfoTab from './components/DepartUserInfoTab.vue';
+  // import DepartRoleInfoTab from './components/DepartRoleInfoTab.vue';
 
-  async function handleDelete(record) {
-    await deleteDict({ id: record.id }, reload);
-  }
-  function handleCreate() {
-    openModal(true, {
-      isUpdate: false,
-    });
+  const { prefixCls } = useDesign('depart-user');
+  provide('prefixCls', prefixCls);
+  const classListRef = ref();
+  const treeListRef = ref();
+  // 左侧树选择后触发
+  async function selectId(data) {
+      await classListRef.value.getAppointRow(data)    
   }
-  /**
-   * 成功回调
-   */
-  function handleSuccess({ isUpdate, values }) {
-    if (isUpdate) {
-      updateTableDataRecord(values.id, values);
-    } else {
-      reload();
-    }
-  }
-  /**
-   * 批量删除事件
-   */
-  async function batchHandleDelete() {
-    await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
+  function addListSuccess(){
+    treeListRef.value.loadDepartTreeData()    
   }
 </script>
+
+<style lang="less">
+  // @import './index.less';
+</style>

+ 29 - 45
src/views/BasicData/productCassification1.vue

@@ -1,6 +1,6 @@
 <template>
   <!--定义表格-->
-  <BasicTable @register="registerTable" :rowSelection="rowSelection" @expand="handleExpand" :expandedRowKeys="expandedRowKeys" @fetch-success="onFetchSuccess">
+  <BasicTable @register="registerTable" :rowSelection="rowSelection" :afterFetch="afterFetch">
     <template #tableTitle>
       <a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate" v-auth="'baseCode:base_product_class:add'">
         新增(add)</a-button
@@ -37,8 +37,8 @@
   import { useListPage } from '/@/hooks/system/useListPage';
   import { list, deleteDict, batchDelete } from './api/productCassification.api';
   const showFooter = ref(true);
-  const expandedRowKeys = ref([]);
   const [registerModal, { openModal }] = useModal();
+  const emit = defineEmits(['success']);
   //定义表格列字段
   const columns: BasicColumn[] = [
     {
@@ -88,12 +88,14 @@
       field: 'code', //查询字段
       component: 'JInput', //渲染的组件
       defaultValue: '', //设置默认值
+      labelWidth: 100,
     },
     {
       label: '名称(name)', //显示label
       field: 'name', //查询字段
       component: 'JInput', //渲染的组件
       defaultValue: '', //设置默认值、
+      labelWidth: 100,
       componentProps: {
         AutoComplete: 'off',
       },
@@ -103,7 +105,7 @@
    * 平台通过此封装,简化了代码,支持自定义扩展*/
   // 通过hook useListPage渲染表格(设置dataSource、columns、actionColumn等参数)
   const { tableContext } = useListPage({
-    designScope: 'category-template',
+    designScope: 'basic-table-demo',
     tableProps: {
       title: '',
       api: list,
@@ -116,10 +118,9 @@
       formConfig: {
         schemas: searchFormSchema,
       },
-      isTreeTable: true,
     },
   });
-  const [registerTable, { reload, updateTableDataRecord,findTableDataRecord, getDataSource }, { rowSelection, selectedRows, selectedRowKeys }] = tableContext;
+  const [registerTable, { reload, updateTableDataRecord ,setTableData}, { rowSelection, selectedRows, selectedRowKeys }] = tableContext;
   /**
    * 操作栏
    */
@@ -150,6 +151,7 @@
 
   async function handleDelete(record) {
     await deleteDict({ id: record.id }, reload);
+    emit('success')
   }
   function handleCreate() {
     openModal(true, {
@@ -159,11 +161,13 @@
   /**
    * 成功回调
    */
-  function handleSuccess({ isUpdate, values }) {
+  async function handleSuccess({ isUpdate, values }) {
     if (isUpdate) {
-      updateTableDataRecord(values.id, values);
+      await updateTableDataRecord(values.id, values);
+      emit('success')
     } else {
-      reload();
+      await reload();
+      emit('success')
     }
   }
   /**
@@ -172,44 +176,24 @@
   async function batchHandleDelete() {
     await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
   }
-  function onFetchSuccess(result) {
-    debugger
-    getDataByResult(result.items)
-  }
-  async function handleExpand(expanded, record) {
-    debugger
-    // 判断是否是展开状态,展开状态(expanded)并且存在子集(children)并且未加载过(isLoading)的就去查询子节点数据
-    if (expanded) {
-      expandedRowKeys.value.push(record.id);
-      if (record.children.length > 0 && !!record.children[0].isLoading) {
-        debugger
-        // let result = await getChildList({ pid: record.id });
-        // if (result && result.length > 0) {
-        //   record.children = getDataByResult(result);
-        // } else {
-        //   record.children = null;
-        //   record.hasChild = '0';
-        // }
-      }
-    } else {
-      let keyIndex = expandedRowKeys.value.indexOf(record.id);
-      if (keyIndex >= 0) {
-        expandedRowKeys.value.splice(keyIndex, 1);
-      }
+  async function getAppointRow(id){
+    if(id=='0'){
+      reload()
+    }else{
+      var obj = await list({id:id})
+      obj.records.map(item=>{
+        delete item.children
+      })
+      setTableData(obj.records);
     }
+    
   }
-  function getDataByResult(result) {
-    debugger
-    if (result && result.length > 0) {
-      return result.map((item) => {
-        item.hasChild='1'
-        //判断是否标记了带有子节点
-        if (item['hasChild'] == '1') {
-          let loadChild = { id: item.id + '_loadChild', name: 'loading...', isLoading: true };
-          item.children = [loadChild];
-        }
-        return item;
-      });
-    }
+  function afterFetch(data) {
+    data.map(item=>{
+      delete item.children
+    })
   }
+  defineExpose({
+    getAppointRow
+  });
 </script>

+ 113 - 0
src/views/BasicData/productCassificationTree.vue

@@ -0,0 +1,113 @@
+<template>
+  <div class="bg-white m-4 mr-0 overflow-hidden">
+    <a-spin :spinning="loading">
+        <!--组织机构树-->
+        <a-tree
+          v-if="!treeReloading"
+          title="分类列表"
+          toolbar
+          search
+          :checkStrictly="true"
+          :clickRowToExpand="false"
+          :treeData="treeData"
+          :replaceFields="{ key: 'id', title: 'name' }"
+          :selectedKeys="selectedKeys"
+          :expandedKeys="expandedKeys"
+          :autoExpandParent="autoExpandParent"
+          @select="onSelect"
+          @expand="onExpand"
+        >
+      </a-tree>
+    </a-spin>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { inject, nextTick, ref ,onMounted} from 'vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { listTree} from './api/productCassification.api';
+
+  const prefixCls = inject('prefixCls');
+  const emit = defineEmits(['select']);
+  const { createMessage } = useMessage();
+
+  let loading = ref<boolean>(false);
+  // 部门树列表数据
+  let treeData = ref<any[]>([]);
+  // 当前展开的项
+  let expandedKeys = ref<any[]>([]);
+  // 当前选中的项
+  let selectedKeys = ref<any[]>([]);
+  // 是否自动展开父级
+  let autoExpandParent = ref<boolean>(true);
+  // 用户身份
+  let userIdentity = ref<string>('2');
+  // 树组件重新加载
+  let treeReloading = ref<boolean>(false);
+  onMounted(() => {
+      loadDepartTreeData();   
+  });
+  // 加载信息
+  async function loadDepartTreeData() {
+    loading.value = true;
+    treeData.value = [];
+    listTree({pageSize:-1})
+      .then((res) => {
+          if (Array.isArray(res)) {
+            treeData.value[0] = {id:'0',name:'基本分类(Basic Classification)',children:[]};
+            treeData.value[0].children = res;
+            expandedKeys.value=['0']
+            // autoExpandParentNode();
+          }
+      })
+      .finally(() => (loading.value = false));
+  }
+
+  
+
+  // 自动展开父节点,只展开一级
+  function autoExpandParentNode() {
+    expandedKeys.value=['0']
+    // let keys: Array<any> = [];
+    // treeData.value.forEach((item, index) => {
+    //   if (item.children && item.children.length > 0) {
+    //     keys.push(item.id);
+    //   }
+    // });
+    // if (keys.length > 0) {
+    //   reloadTree();
+    //   expandedKeys.value = keys;
+    // }
+  }
+
+  // 重新加载树组件,防止无法默认展开数据
+  async function reloadTree() {
+    debugger
+    await nextTick();
+    treeReloading.value = true;
+    await nextTick();
+    treeReloading.value = false;
+  }
+
+  // 树选择事件
+  function onSelect(selKeys, event) {
+    if (selKeys.length > 0 && selectedKeys.value[0] !== selKeys[0]) {
+      emit('select', selKeys[0]);
+    }
+  }
+
+  // 树展开事件
+  async function onExpand(keys,event) {
+        expandedKeys.value = keys;
+        autoExpandParent.value = false;
+  }
+  defineExpose({
+    loadDepartTreeData
+  });
+</script>
+<style lang="less" scoped>
+  /*升级antd3后,查询框与树贴的太近,样式优化*/
+  :deep(.jeecg-tree-header) {
+    margin-bottom: 6px;
+  }
+</style>