diff --git a/resources/admin/components/catchTable/components/ellipsis/index.vue b/resources/admin/components/catchTable/components/ellipsis/index.vue new file mode 100644 index 0000000..bf358be --- /dev/null +++ b/resources/admin/components/catchTable/components/ellipsis/index.vue @@ -0,0 +1,34 @@ + + + {{ content }} + + + + {{ ellipsis(length) }} + + + + + diff --git a/resources/admin/components/catchTable/components/switchColumn/index.vue b/resources/admin/components/catchTable/components/switchColumn/index.vue new file mode 100644 index 0000000..3ba1aab --- /dev/null +++ b/resources/admin/components/catchTable/components/switchColumn/index.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/resources/admin/components/catchTable/csearch.vue b/resources/admin/components/catchTable/csearch.vue new file mode 100644 index 0000000..49d2787 --- /dev/null +++ b/resources/admin/components/catchTable/csearch.vue @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ t('system.search') }} + {{ t('system.reset') }} + + + + + + + + diff --git a/resources/admin/components/catchTable/ctable.ts b/resources/admin/components/catchTable/ctable.ts new file mode 100644 index 0000000..892acbd --- /dev/null +++ b/resources/admin/components/catchTable/ctable.ts @@ -0,0 +1,63 @@ +export type columnType = 'expand' | 'selection' | 'index' | 'operate' +export type fixed = 'fiexed' | 'right' | 'left' +export interface Column { + type?: columnType // 类型 expand select index + label?: string + prop?: string + 'min-width'?: string | number + width?: number | string + slot?: 'string' + header: 'string' // 表头插槽名称 + align?: string + fixed?: fixed + sortable?: boolean | string + 'sort-method'?: Function + 'sort-by'?: Function + resizable?: boolean + formatter?: Function // function(row, column, cellValue, index) + 'header-align'?: string + 'class-name'?: string + selectable?: Function // function(row, index) + show: boolean + index?: number | Function // 如果设置了 type=index,可以通过传递 index 属性来自定义索引 + children?: Array // 多级表头 + filter?:Function, + ellipsis?:boolean|number, // 当文字太多时,可以使用省略文字 + switch?: boolean, // swith 字段状态切换 + switchRefresh?: Function, // switch refresh 刷新 + // 图片预览 + image?: boolean, + preview: boolean, // 默认不预览 + // 标签 + tags?: boolean|Array, + // 链接🔗 + link?:boolean, + link_text?: string, + // 操作 + update?: boolean, // 编辑操作 + destroy?: boolean // 删除操作 +} + +// 分页 +export interface paginate { + layout:string, + limit: number, + page: number, + limits: Array, + total: number, + changePage: Function, + changeLimit: Function +} + +// option +export interface Option { + label: string, + value: string|number +} +// 搜索 item +export interface SItem { + type: string, + name: string, + default: any, + options: Array +} diff --git a/resources/admin/components/catchTable/ctcolumns.tsx b/resources/admin/components/catchTable/ctcolumns.tsx new file mode 100644 index 0000000..0d8db28 --- /dev/null +++ b/resources/admin/components/catchTable/ctcolumns.tsx @@ -0,0 +1,48 @@ +import { defineComponent } from 'vue' +import { ElTableColumn } from 'element-plus' +import { Column } from './ctable' + +export default defineComponent({ + name: 'DynamicTable', + props: { + columns: { + type: Array, + default: [] + }, + api: { + type: String, + default: '' + } + }, + setup(props, { slots }) { + const renderColumns = (columns: Array) => { + return columns.map(column => { + if (column.children) { + return ( + + {renderColumns(column.children)} + + ) + } else { + return ( + + {{ + default: (row: any) => { + // 使用默认插槽 + return row[column.prop as string] + }, + customSlot: (row: any) => { + // 使用具名插槽 customSlot + return slots.customSlot ? slots.customSlot({ column, row }) : null + } + }} + + ) + } + }) + } + + return renderColumns(props.columns) + // return () => {renderColumns(props.columns)} + } +}) diff --git a/resources/admin/components/catchTable/index.vue b/resources/admin/components/catchTable/index.vue new file mode 100644 index 0000000..02954d0 --- /dev/null +++ b/resources/admin/components/catchTable/index.vue @@ -0,0 +1,475 @@ + + + + + + + + + + + + + 已选 {{ multiSelectIds.length }} 条数据 + + + + 删除 + + + + + + + 导出 + + + + + + + + + + + + + + + + 宽松 + 宽松 + 默认 + 紧凑 + + + + + + + + + + + + + + {{ column.label }} + + + + + + + + + + + + + + + + {{ emptyText }} + + + + + + + + + + + + + + + + + + + "> + + + + + + + + + + + + + + + + + + + diff --git a/resources/admin/components/catchTable/tcolumns.vue b/resources/admin/components/catchTable/tcolumns.vue new file mode 100644 index 0000000..34f9b52 --- /dev/null +++ b/resources/admin/components/catchTable/tcolumns.vue @@ -0,0 +1,151 @@ + + + + "> + + + + + + + + {{ column.width }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ column.link_text ? column.link_text : '链接' }} + + + + + {{ column.filter ? column.filter(scope.row[column.prop]) : scope.row[column.prop] }} + + + + {{ column.filter ? column.filter(scope.row[column.prop]) : scope.row[column.prop] }} + + + + + + + diff --git a/resources/admin/components/catchTable/types.ts b/resources/admin/components/catchTable/types.ts new file mode 100644 index 0000000..acec6df --- /dev/null +++ b/resources/admin/components/catchTable/types.ts @@ -0,0 +1,19 @@ +export type itemType = 'input' | 'select' | 'input-number' | 'date' | 'datetime' | 'range' + +export interface Option { + label: string + value: string | number +} + +export interface Field { + type: itemType + label: string + name: string + api?: string + placeholder?: string + default?: any + options?: Array + children?: Array + show?: boolean + props?: Object // 树形 props +} diff --git a/resources/admin/components/catchTable/useSearch.ts b/resources/admin/components/catchTable/useSearch.ts new file mode 100644 index 0000000..6db6896 --- /dev/null +++ b/resources/admin/components/catchTable/useSearch.ts @@ -0,0 +1,93 @@ +import { ref } from 'vue' +import http from '/admin/support/http' + +interface response { + code: number + data: Array | Object + message: string + total?: number + page?: number + limit?: number +} + +export default function useSearch(api: string | Function, isPagination: boolean, pageLimit: number, currentPage: number, defaultParams: Object = {}) { + // 默认设置分页参数 + const limit = ref(pageLimit) + const page = ref(currentPage) + const total = ref(0) + const loading = ref(false) + // 搜索参数 + const searchParams = ref({}) + const data = ref() + + if (isPagination) { + searchParams.value = Object.assign(searchParams.value, { page: currentPage, limit: pageLimit }) + } + + // 分页切换 + const changePage = (p: number) => { + page.value = p + setPaginateParams(p) + } + + // limit 切换 + const changeLimit = (l: number) => { + limit.value = l + page.value = 1 + setPaginateParams(0, l) + } + + // 设置分页查询参数 + const setPaginateParams = (page: number = 0, limit: number = 0) => { + if (page) { + // @ts-ignore + searchParams.value.page = page + } + if (limit) { + // @ts-ignore + searchParams.value.limit = limit + } + + getTableData() + } + + // 执行 search + const doSearch = (params: Object | null = null, append: boolean = true) => { + if (params && !append) { + searchParams.value = params + } else { + searchParams.value = Object.assign(searchParams.value, params) + } + getTableData() + } + + // 重置 || 刷新 + const reset = () => { + searchParams.value = Object.assign({}) + if (isPagination) { + // 这里会调用 getTableData 方法 + setPaginateParams(currentPage, pageLimit) + } else { + getTableData() + } + } + + const getTableData = () => { + loading.value = true + setDefaultParams() + http.get(api as string, searchParams.value).then(r => { + loading.value = false + data.value = r.data + if (isPagination) { + total.value = r.data.total + } + }) + } + + // 设置搜索默认参数 + const setDefaultParams = () => { + searchParams.value = Object.assign(searchParams.value, defaultParams) + } + + return { limit, page, total, changeLimit, setPaginateParams, searchParams, changePage, doSearch, reset, loading, data, getTableData } +}