diff --git a/apps/web-antd/package.json b/apps/web-antd/package.json index d7e71449a125ca0643dfd9c7ab237888a67464b6..db404c46646bf408b2c65da2607a51d118c0f564 100644 --- a/apps/web-antd/package.json +++ b/apps/web-antd/package.json @@ -43,6 +43,7 @@ "@vben/utils": "workspace:*", "@vueuse/core": "catalog:", "ant-design-vue": "catalog:", + "vxe-table": "catalog:", "cropperjs": "catalog:", "crypto-js": "catalog:", "dayjs": "catalog:", diff --git a/apps/web-antd/src/bootstrap.ts b/apps/web-antd/src/bootstrap.ts index e4aaf40571dc27e81b4c8897114798993a3aba56..3cb24a1add17ee8f4b923d738eced572a5eaee2c 100644 --- a/apps/web-antd/src/bootstrap.ts +++ b/apps/web-antd/src/bootstrap.ts @@ -6,6 +6,7 @@ import { preferences } from '@vben/preferences'; import { initStores } from '@vben/stores'; import '@vben/styles'; import '@vben/styles/antd'; +import 'vxe-table/styles/cssvar.scss'; import { useTitle } from '@vueuse/core'; diff --git a/apps/web-antd/src/components/content-wrap/content-wrap.vue b/apps/web-antd/src/components/content-wrap/content-wrap.vue new file mode 100644 index 0000000000000000000000000000000000000000..026d7d23ff542036b3d3828d4d95cbe976a7811d --- /dev/null +++ b/apps/web-antd/src/components/content-wrap/content-wrap.vue @@ -0,0 +1,24 @@ + + + diff --git a/apps/web-antd/src/components/content-wrap/index.ts b/apps/web-antd/src/components/content-wrap/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..d4f95fddb0838fc99e81a84f30f70a4a1bb97765 --- /dev/null +++ b/apps/web-antd/src/components/content-wrap/index.ts @@ -0,0 +1 @@ +export { default as ContentWrap } from './content-wrap.vue'; diff --git a/apps/web-antd/src/components/description/description.vue b/apps/web-antd/src/components/description/description.vue new file mode 100644 index 0000000000000000000000000000000000000000..41133377832304ba03a915f33b8fcdd594606f63 --- /dev/null +++ b/apps/web-antd/src/components/description/description.vue @@ -0,0 +1,71 @@ + diff --git a/apps/web-antd/src/components/description/index.ts b/apps/web-antd/src/components/description/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..a707c486557880c088e1b4a4b0557f224c5ef039 --- /dev/null +++ b/apps/web-antd/src/components/description/index.ts @@ -0,0 +1,3 @@ +export { default as Description } from './description.vue'; +export * from './typing'; +export { useDescription } from './use-description'; diff --git a/apps/web-antd/src/components/description/typing.ts b/apps/web-antd/src/components/description/typing.ts new file mode 100644 index 0000000000000000000000000000000000000000..98e3a52d1d10e22fb23d42555c3e0216a0241fc2 --- /dev/null +++ b/apps/web-antd/src/components/description/typing.ts @@ -0,0 +1,18 @@ +import type { DescriptionsProps } from 'ant-design-vue'; +import type { CSSProperties, VNode } from 'vue'; + +export interface DescriptionItemSchema { + label: string | VNode; // 内容的描述 + field?: string; // 对应 data 中的字段名 + content?: ((data: any) => string | VNode) | string | VNode; // 自定义需要展示的内容,比如说 dict-tag + span?: number; // 包含列的数量 + labelStyle?: CSSProperties; // 自定义标签样式 + contentStyle?: CSSProperties; // 自定义内容样式 + hidden?: ((data: any) => boolean) | boolean; // 是否显示 +} + +export interface DescriptionsOptions { + data?: Record; // 数据 + schema?: DescriptionItemSchema[]; // 描述项配置 + componentProps?: DescriptionsProps; // antd Descriptions 组件参数 +} diff --git a/apps/web-antd/src/components/description/use-description.ts b/apps/web-antd/src/components/description/use-description.ts new file mode 100644 index 0000000000000000000000000000000000000000..8cf44ccfaa1b1022c416793772b0e67cb86bc121 --- /dev/null +++ b/apps/web-antd/src/components/description/use-description.ts @@ -0,0 +1,70 @@ +import type { DescriptionsOptions } from './typing'; + +import { defineComponent, h, isReactive, reactive, watch } from 'vue'; + +import { Description } from './index'; + +/** 描述列表 api 定义 */ +class DescriptionApi { + private state = reactive>({}); + + constructor(options: DescriptionsOptions) { + this.state = { ...options }; + } + + getState(): DescriptionsOptions { + return this.state as DescriptionsOptions; + } + + setState(newState: Partial) { + this.state = { ...this.state, ...newState }; + } +} + +export type ExtendedDescriptionApi = DescriptionApi; + +export function useDescription(options: DescriptionsOptions) { + const IS_REACTIVE = isReactive(options); + const api = new DescriptionApi(options); + // 扩展API + const extendedApi: ExtendedDescriptionApi = api as never; + const Desc = defineComponent({ + name: 'UseDescription', + inheritAttrs: false, + setup(_, { attrs, slots }) { + // 合并props和attrs到state + api.setState({ ...attrs }); + + return () => + h( + Description, + { + ...api.getState(), + ...attrs, + }, + slots, + ); + }, + }); + + // 响应式支持 + if (IS_REACTIVE) { + watch( + () => options.schema, + (newSchema) => { + api.setState({ schema: newSchema }); + }, + { immediate: true, deep: true }, + ); + + watch( + () => options.data, + (newData) => { + api.setState({ data: newData }); + }, + { immediate: true, deep: true }, + ); + } + + return [Desc, extendedApi] as const; +} diff --git a/apps/web-antd/src/utils/dict.ts b/apps/web-antd/src/utils/dict.ts index adef41445fbbcee80490b47515c9b46449ee6400..59326210ea6b23763f7c1151dc63d581fdeeb363 100644 --- a/apps/web-antd/src/utils/dict.ts +++ b/apps/web-antd/src/utils/dict.ts @@ -38,10 +38,7 @@ function getDictObj(dictType: string, value: any) { * @param dictType 字典类型 * @returns 字典数组 */ -function getDictOptions( - dictType: string, - valueType: 'boolean' | 'number' | 'string' = 'string', -) { +function getDictOptions(dictType: string, valueType: 'boolean' | 'number' | 'string' = 'string'): any[] { const dictOpts = dictStore.getDictOptions(dictType); const dictOptions: DefaultOptionType = []; if (dictOpts.length > 0) { diff --git a/apps/web-antd/src/views/infra/demo/general/demo01/index.vue b/apps/web-antd/src/views/infra/demo/general/demo01/index.vue new file mode 100644 index 0000000000000000000000000000000000000000..01a8b5fab53c0ca82f1459dbce3de17572c905de --- /dev/null +++ b/apps/web-antd/src/views/infra/demo/general/demo01/index.vue @@ -0,0 +1,223 @@ + + + diff --git a/apps/web-antd/src/views/infra/demo/general/demo01/modules/form.vue b/apps/web-antd/src/views/infra/demo/general/demo01/modules/form.vue new file mode 100644 index 0000000000000000000000000000000000000000..8f95c804494a8d9ff9f77e5e90a6154a6f4e19d6 --- /dev/null +++ b/apps/web-antd/src/views/infra/demo/general/demo01/modules/form.vue @@ -0,0 +1,121 @@ + + + diff --git a/apps/web-antd/src/views/system/notify/my/modules/detail.vue b/apps/web-antd/src/views/system/notify/my/modules/detail.vue index cdad97daea27c8329a4e7789fb461d1b7e6a3627..2c5275c35ccecca5f0819d99831b49f4a928ebaf 100644 --- a/apps/web-antd/src/views/system/notify/my/modules/detail.vue +++ b/apps/web-antd/src/views/system/notify/my/modules/detail.vue @@ -1,18 +1,56 @@ diff --git a/packages/@core/base/icons/src/lucide.ts b/packages/@core/base/icons/src/lucide.ts index d6747133b9e89fc298f7abbfd914d030be39fab5..c00f4d9a7adc73cbbbc9ffb004948efb57d37902 100644 --- a/packages/@core/base/icons/src/lucide.ts +++ b/packages/@core/base/icons/src/lucide.ts @@ -69,4 +69,5 @@ export { Upload, CloudUpload, History, + RefreshCw, } from 'lucide-vue-next';