diff --git a/apps/web-antd/package.json b/apps/web-antd/package.json index c608b554d..164d7449a 100644 --- a/apps/web-antd/package.json +++ b/apps/web-antd/package.json @@ -45,6 +45,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 68d19ee1a..c90d9f269 100644 --- a/apps/web-antd/src/bootstrap.ts +++ b/apps/web-antd/src/bootstrap.ts @@ -7,6 +7,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 000000000..026d7d23f --- /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 000000000..d4f95fddb --- /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 000000000..411333778 --- /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 000000000..a707c4865 --- /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 000000000..98e3a52d1 --- /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 000000000..8cf44ccfa --- /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 c2c15b755..968974b6c 100644 --- a/apps/web-antd/src/utils/dict.ts +++ b/apps/web-antd/src/utils/dict.ts @@ -64,7 +64,7 @@ function getDictObj(dictType: string, value: any) { function getDictOptions( dictType: string, valueType: 'boolean' | 'number' | 'string' = 'string', -) { +): any[] { const dictStore = useDictStore(); const dictOpts = dictStore.getDictOptions(dictType); const dictOptions: DefaultOptionType = []; 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 000000000..01a8b5fab --- /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 000000000..8f95c8044 --- /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 cdad97dae..2c5275c35 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 2a5de70bd..21ac04e2e 100644 --- a/packages/@core/base/icons/src/lucide.ts +++ b/packages/@core/base/icons/src/lucide.ts @@ -69,4 +69,5 @@ export { Upload, UserRoundPen, X, + RefreshCw, } from 'lucide-vue-next';