Преглед на файлове

feat(组件-SmartPullownTable): 添加下拉表格组件 SmartPullownTable

shizhongming преди 2 години
родител
ревизия
203ea35a55

+ 1 - 0
src/components/Form/index.ts

@@ -16,5 +16,6 @@ export { default as ApiTransfer } from './src/components/ApiTransfer.vue';
 export { default as SmartTableSelect } from './src/smart-boot/components/base/SmartTableSelect';
 export { default as SmartUserSelectModal } from './src/smart-boot/components/SmartUserSelectModal.vue';
 export { default as SmartApiSelectTable } from './src/smart-boot/components/SmartApiSelectTable.vue';
+export { default as SmartPulldownTable } from './src/smart-boot/components/SmartPulldownTable';
 
 export { BasicForm };

+ 2 - 0
src/components/Form/src/componentMap.ts

@@ -37,6 +37,7 @@ import { CropperAvatar } from '@/components/Cropper';
 import SmartApiSelectDict from './smart-boot/components/SmartApiSelectDict.vue';
 import SmartUserTableSelect from './smart-boot/components/user/SmartUserTableSelect.vue';
 import SmartApiSelectTable from './smart-boot/components/SmartApiSelectTable.vue';
+import SmartPulldownTable from './smart-boot/components/SmartPulldownTable';
 
 const componentMap = new Map<ComponentType | string, Component>();
 
@@ -85,6 +86,7 @@ componentMap.set('BasicTitle', BasicTitle);
 componentMap.set('SmartApiSelectDict', SmartApiSelectDict);
 componentMap.set('SmartUserTableSelect', SmartUserTableSelect);
 componentMap.set('SmartApiSelectTable', SmartApiSelectTable);
+componentMap.set('SmartPulldownTable', SmartPulldownTable);
 
 export function add<T extends string, R extends Component>(
   compName: ComponentType | T,

+ 129 - 0
src/components/Form/src/smart-boot/components/SmartPulldownTable.tsx

@@ -0,0 +1,129 @@
+import { computed, defineComponent, ref, toRefs, unref, watch } from 'vue';
+import { SmartTableProps, SmartTable } from '@/components/SmartTable';
+import { propTypes } from '@/utils/propTypes';
+import { type VxePulldownInstance, VxeGridInstance } from 'vxe-table';
+import { Icon } from '@/components/Icon';
+
+import './style/SmartPullownTable.less';
+
+/**
+ * 下拉表格
+ */
+export default defineComponent({
+  name: 'SmartPullownTable',
+  props: {
+    tableProps: {
+      type: Object as PropType<SmartTableProps>,
+    },
+    showField: propTypes.string,
+    showFunction: propTypes.func,
+    dropdownWidth: propTypes.number.def(600),
+    value: propTypes.oneOfType([propTypes.string, propTypes.number]),
+    valueField: propTypes.string.isRequired,
+    // 是否每次都加载
+    alwaysLoad: propTypes.bool.def(false),
+  },
+  emits: ['select', 'change'],
+  setup(props, { emit, slots, attrs }) {
+    const { showField, dropdownWidth, value: valueRef } = toRefs(props);
+    const pulldownRef = ref<VxePulldownInstance>();
+    const tableRef = ref();
+    // 选中的行
+    const selectRowRef = ref<Recordable | null>(null);
+    const computedSelectRowValue = computed(() => {
+      const showFieldValue = unref(showField);
+      if (!props.showFunction && !showFieldValue) {
+        throw new Error('未设置showField或showFunction');
+      }
+      const selectRow = unref(selectRowRef);
+      if (!selectRow) {
+        return null;
+      }
+      if (props.showFunction) {
+        return props.showFunction(selectRow);
+      }
+      return selectRow[showFieldValue];
+    });
+
+    /**
+     * 下拉容器样式
+     */
+    const computedDropdownContainerStyle = computed(() => {
+      return {
+        width: unref(dropdownWidth) + 'px',
+      };
+    });
+
+    watch(valueRef, (value) => {
+      const tableInstance: VxeGridInstance = unref(tableRef)?.tableAction.getTableInstance();
+      let row = null;
+      if (!tableInstance) {
+        return false;
+      }
+      if (!value) {
+        tableInstance.clearCurrentRow();
+      }
+      const fullData = tableInstance.getTableData().fullData;
+      const selectRows = fullData.filter((item) => item[props.valueField] === value);
+      if (selectRows.length === 0) {
+        tableInstance.clearCurrentRow();
+      } else {
+        row = selectRows[0];
+        tableInstance.setCurrentRow(selectRows[0]);
+      }
+      selectRowRef.value = row;
+    });
+
+    /**
+     * 显示弹窗
+     */
+    const handleShow = () => {
+      unref(pulldownRef)?.showPanel();
+      if (props.alwaysLoad) {
+        unref(tableRef)?.tableAction.query();
+      }
+    };
+
+    const dropdownTableProps = {
+      size: 'mini',
+      ...props.tableProps,
+      rowConfig: {
+        ...(props.tableProps?.rowConfig || {}),
+        isCurrent: true,
+      },
+      onCellClick: ({ row }) => {
+        emit('select', row);
+        emit('change', row[props.valueField]);
+        unref(pulldownRef)?.hidePanel();
+      },
+    };
+
+    const inputIconSlots = {
+      addonAfter: () => <Icon onClick={handleShow} icon="ant-design:table-outlined" />,
+    };
+
+    const pulldownSlots = {
+      default: () => (
+        <a-input onFocus={handleShow} value={unref(computedSelectRowValue)} {...attrs}>
+          {inputIconSlots}
+        </a-input>
+      ),
+      dropdown: () => (
+        <div style={unref(computedDropdownContainerStyle)}>
+          <SmartTable ref={tableRef} {...dropdownTableProps} />
+        </div>
+      ),
+      ...slots,
+    };
+    return () => (
+      <vxe-pulldown
+        ref={pulldownRef}
+        {...attrs}
+        popup-class-name="smart-pullown-table"
+        class-name="smart-pullown-input"
+      >
+        {pulldownSlots}
+      </vxe-pulldown>
+    );
+  },
+});

+ 20 - 0
src/components/Form/src/smart-boot/components/style/SmartPullownTable.less

@@ -0,0 +1,20 @@
+.smart-pullown-table {
+  .smart-table-container {
+    padding: 0;
+  }
+
+  .vxe-pulldown--panel-wrapper {
+    box-shadow:
+      0 6px 16px 0 rgb(0 0 0 / 8%),
+      0 3px 6px -4px rgb(0 0 0 / 12%),
+      0 9px 28px 8px rgb(0 0 0 / 5%);
+  }
+
+  .ant-input-group-addon {
+    cursor: pointer;
+  }
+}
+
+.smart-pullown-input {
+  width: 100%;
+}

+ 5 - 0
src/components/Form/src/types/index.ts

@@ -133,6 +133,9 @@ interface _CustomComponents {
   SmartApiSelectTable: ExtractPropTypes<
     (typeof import('@/components/Form/src/smart-boot/components/SmartApiSelectTable.vue'))['default']
   >;
+  SmartPulldownTable: ExtractPropTypes<
+    (typeof import('@/components/Form/src/smart-boot/components/SmartPulldownTable'))['default']
+  >;
 }
 
 type CustomComponents<T = _CustomComponents> = {
@@ -185,4 +188,6 @@ export interface ComponentProps {
   SmartApiSelectDict: CustomComponents['SmartApiSelectDict'] & ComponentProps['ApiSelect'];
   SmartUserTableSelect: CustomComponents['SmartUserTableSelect'];
   SmartApiSelectTable: CustomComponents['SmartApiSelectTable'] & ComponentProps['ApiSelect'];
+  SmartPulldownTable: CustomComponents['SmartPulldownTable'] &
+    ExtractPropTypes<(typeof import('vxe-table/es/pulldown'))['default']>;
 }