| PageParams>(api: RequestApiType,
+ searchFormRef: Ref,
+ searchParams: Ref,
+ isPageTable: boolean = true,
+ dataCallBack?: (data: T[]) => T[],
+ requestError?: (errorMsg: any) => void) => {
+
+ const dataSource = ref([]) as Ref;
+ const loading = ref(false);
+ const pageParams = ref({
+ current: 1,
+ size: 10,
+ total: 0
+ })
+
+ /**
+ * 获取表格数据
+ */
+ const requestGetTableData = async (isInit: boolean = false) => {
+ try {
+ //校验表单
+ !isInit && await searchFormRef.value?.validate();
+ //组装参数
+ let totalSearchParams;
+ if (isPageTable) {
+ totalSearchParams = {
+ params: searchParams.value,
+ page: {
+ current: pageParams.value.current,
+ size: pageParams.value.size
+ }
+ } as PageParams;
+ } else {
+ totalSearchParams = searchParams.value
+ }
+
+ loading.value = true;
+
+ const resp = await api(totalSearchParams as P);
+ let tableData: T[];
+
+ if (isPageTable) {
+ const {current, records, size, total} = resp.data as PageResult;
+ isPageTable && updatePageParams({
+ current: parseInt(current),
+ size: parseInt(size),
+ total: parseInt(total)
+ });
+ tableData = records;
+ } else {
+ tableData = resp.data as T[]
+ }
+ dataCallBack && (tableData = dataCallBack(tableData));
+ dataSource.value = tableData;
+ } catch (error) {
+ requestError && requestError(error);
+ } finally {
+ loading.value = false;
+ }
+ }
+
+ /**
+ * 更新分页信息
+ */
+ const updatePageParams = (ps: Page) => Object.assign(pageParams.value, ps)
+
+ /**
+ * 重置表格状态 包括 dataSource loading pageParams
+ */
+ const resetState = () => {
+ dataSource.value = [];
+ loading.value = false;
+ pageParams.value = {
+ current: 1,
+ size: 10,
+ total: 0
+ }
+ }
+
+ /**
+ * 表格数据查询 与 requestGetTableData 区别是会将页面重置为1
+ * 如果只做刷新数据请用 requestGetTableData
+ */
+ const search = async () => {
+ pageParams.value.current = 1;
+ await requestGetTableData();
+ };
+
+ /**
+ * @description 每页条数改变
+ * @param _
+ * @param {Number} size 页显示数量
+ */
+ const handleSizeChange = async (_: number, size: number) => {
+ pageParams.value.current = 1;
+ pageParams.value.size = size;
+ await requestGetTableData();
+ };
+
+ /**
+ * @description 当前页改变
+ * @param current 当前页
+ */
+ const handleCurrentChange = async (current: number) => {
+ pageParams.value.current = current;
+ await requestGetTableData();
+ };
+
+ return {
+ dataSource,
+ loading,
+ pageParams,
+ requestGetTableData,
+ search,
+ handleSizeChange,
+ handleCurrentChange,
+ resetState
+ };
+
+}
diff --git a/src/types/components/form/index.ts b/src/types/components/form/index.ts
new file mode 100644
index 0000000..f2ad150
--- /dev/null
+++ b/src/types/components/form/index.ts
@@ -0,0 +1,75 @@
+import {
+ FormProps,
+ RangePicker,
+ Input,
+ InputNumber,
+ Textarea,
+ InputPassword,
+ RadioGroup,
+ Select,
+ TreeSelect,
+ Cascader,
+ CheckboxGroup,
+ DatePicker,
+ FormItem, TimeRangePicker, TimePicker,
+} from "ant-design-vue";
+import {Ref, UnwrapRef, VNode} from "vue";
+import {ComponentProps} from "vue-component-type-helpers";
+
+type FormProMaxItemType =
+ | 'custom'
+ | 'input'
+ | 'inputPassword'
+ | 'inputNumber'
+ | 'inputTextArea'
+ | 'radioGroup'
+ | 'select'
+ | 'selectIcon'
+ | 'selectUser'
+ | 'treeSelect'
+ | 'cascader'
+ | 'checkboxGroup'
+ | 'datePicker'
+ | 'rangePicker'
+ | 'timeRangePicker'
+ | 'timePicker'
+ | 'administrativeDivisionsTree';
+
+interface FormProMaxItemCommonProps extends ComponentProps {
+ label?: string,
+ grid?: Grid,
+ placeholder?: string,
+ remarkRender?: () => VNode | string,
+ customRender?: () => VNode;
+ options?: (SelectNodeVo | TreeNodeVo) [] | Ref<(SelectNodeVo | TreeNodeVo)[]>
+}
+
+export interface FormProMaxItemProps extends FormProMaxItemCommonProps {
+ type: T
+ componentsProps?: C
+}
+
+export type FormProMaxItemOptions = {
+ [key in keyof T | string]:
+ FormProMaxItemProps<'custom', ComponentProps>>
+ | FormProMaxItemProps<'input', ComponentProps>
+ | FormProMaxItemProps<'inputPassword', ComponentProps>
+ | FormProMaxItemProps<'inputNumber', ComponentProps>
+ | FormProMaxItemProps<'inputTextArea', ComponentProps>
+ | FormProMaxItemProps<'radioGroup', ComponentProps>
+ | FormProMaxItemProps<'select', ComponentProps>
+ | FormProMaxItemProps<'treeSelect', ComponentProps>
+ | FormProMaxItemProps<'cascader', ComponentProps>
+ | FormProMaxItemProps<'checkboxGroup', ComponentProps>
+ | FormProMaxItemProps<'datePicker', ComponentProps>
+ | FormProMaxItemProps<'rangePicker', ComponentProps>
+ | FormProMaxItemProps<'timeRangePicker', ComponentProps>
+ | FormProMaxItemProps<'timePicker', ComponentProps>
+ | FormProMaxItemProps<'administrativeDivisionsTree', ComponentProps>>
+}
+
+export interface FormProMaxProps extends FormProps {
+ grid?: Grid
+ gutter?: number;
+ formItemOptions?: FormProMaxItemOptions | Ref> | UnwrapRef>
+}
diff --git a/src/types/components/table/index.ts b/src/types/components/table/index.ts
new file mode 100644
index 0000000..9bdf17f
--- /dev/null
+++ b/src/types/components/table/index.ts
@@ -0,0 +1,55 @@
+import {PaginationProps, Table, TableProps} from "ant-design-vue";
+import {TableRowSelection} from "ant-design-vue/lib/table/interface";
+import {Ref, UnwrapRef} from "vue";
+import {ColumnType} from "ant-design-vue/es/table/interface";
+import {ComponentSlots} from "vue-component-type-helpers";
+import {FormProMaxItemOptions, FormProMaxProps} from "@/types/components/form";
+import {PageParams, PageResult} from "@/types/hooks/useTableProMax";
+
+
+export type TableProMaxColumnType = Omit, 'dataIndex'> & {
+ dataIndex: keyof T | string | string[] | number | number[];
+}
+
+
+export type TableProMaxProps<
+ T extends BaseTableRowRecord = {},
+ P extends { [key: string]: any } = {}
+> = Partial, "dataSource" | 'pagination' | 'loading' | 'rowKey' | 'columns'>> & {
+ rowKey?: keyof T,
+ columns?: TableProMaxColumnType[],
+ searchFormProps?: Omit, 'formItems'>
+ searchFormOptions?: FormProMaxItemOptions | Ref> | UnwrapRef>,
+ defaultSearchParams?: { [key in keyof P | string]: any };
+ requestAuto?: boolean,
+ requestApi: RequestApiType,
+ requestError?: (errorMsg: any) => void,
+ dataCallback?: (data: T[]) => T[],
+ isPagination?: boolean,
+ paginationProps?: TableProMaxPaginationProps,
+ isSelection?: boolean,
+ selectionProps?: TableProMaxRowSelect,
+ isPrinter?: boolean,
+ needIndex?: boolean
+}
+
+export type TableProMaxSlots = ComponentSlots & {
+ tableHeader: (scope: { selectKeys: string[], selectRows: T[] }) => any,
+ tableHeaderRight: (scope: { selectKeys: string[], selectRows: T[] }) => any,
+}
+
+export type RequestApiType = (params: P | PageParams) => Promise>>;
+
+export type TableProMaxPaginationProps = Partial>;
+
+export type TableProMaxRowSelect = TableRowSelection;
+
+export interface BaseTableRowRecord {
+ snowFlakeId?: string;
+ createUserName?: string;
+ createTime?: Date | string;
+ updateUserName?: string;
+ updateTime?: Date | string
+}
diff --git a/src/types/hooks/useTableProMax.ts b/src/types/hooks/useTableProMax.ts
new file mode 100644
index 0000000..3989828
--- /dev/null
+++ b/src/types/hooks/useTableProMax.ts
@@ -0,0 +1,26 @@
+/**
+ * 分页对象
+ */
+export interface Page {
+ current: number,
+ size: number,
+ total: number
+}
+
+/**
+ * 分页参数
+ */
+export interface PageParams = {}> {
+ params: T & { [key: string]: any },
+ page: Omit
+}
+
+/**
+ * 分页结果
+ */
+export interface PageResult {
+ current: string,
+ records: T[],
+ size: string,
+ total: string
+}
\ No newline at end of file
diff --git a/src/views/home/index.vue b/src/views/home/index.vue
index a214462..fdf7424 100644
--- a/src/views/home/index.vue
+++ b/src/views/home/index.vue
@@ -63,7 +63,7 @@
+
\ No newline at end of file
+ .foodItem {
+ width: 100%;
+ height: calc(100vh - 100px);
+ overflow: hidden;
+ margin-top: 20px;
+ }
+}
+
diff --git a/src/views/product/food/index.vue b/src/views/product/food/index.vue
index 3dcbc65..ae97792 100644
--- a/src/views/product/food/index.vue
+++ b/src/views/product/food/index.vue
@@ -1,22 +1,174 @@
-
+
- 属性管理
+
+
+
+
+
+
+
+
+ 肉类
+ 蔬菜
+
+
+
+
+ 充足
+ 不足
+ 急需补货
+
+
+
+
+ 全部
+ 3天内过期
+ 7天内过期
+
+
+
+
+ 冷藏
+ 冷冻
+ 常温仓库
+
+
+
+
+
+
+
-
- 我是表格页面
+
+
-
+
+
+
\ No newline at end of file