diff --git a/apps/web-antd/src/api/infra/file/index.ts b/apps/web-antd/src/api/infra/file/index.ts index 5f352432f..aac65cf99 100644 --- a/apps/web-antd/src/api/infra/file/index.ts +++ b/apps/web-antd/src/api/infra/file/index.ts @@ -46,12 +46,9 @@ export function deleteFile(id: number) { /** 获取文件预签名地址 */ export function getFilePresignedUrl(path: string) { - return requestClient.get( - '/infra/file/presigned-url', - { - params: { path }, - }, - ); + return requestClient.get('/infra/file/presigned-url', { + params: { path }, + }); } /** 创建文件 */ @@ -60,9 +57,6 @@ export function createFile(data: InfraFileApi.File) { } /** 上传文件 */ -export function uploadFile( - data: InfraFileApi.FileUploadReqVO, - onUploadProgress?: AxiosProgressEvent, -) { +export function uploadFile(data: InfraFileApi.FileUploadReqVO, onUploadProgress?: AxiosProgressEvent) { return requestClient.upload('/infra/file/upload', data, { onUploadProgress }); } 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..54be93730 --- /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..76ae9cb99 --- /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 DescriptionProps { + data?: Record; // 数据 + schema?: DescriptionItemSchema[]; // 描述项配置 + descriptionsProps?: DescriptionsProps; // 原生 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..fbef6616b --- /dev/null +++ b/apps/web-antd/src/components/description/use-description.ts @@ -0,0 +1,70 @@ +import type { DescriptionProps } from './typing'; + +import { defineComponent, h, isReactive, reactive, watch } from 'vue'; + +import { Description } from './index'; + +/** 描述列表 api 定义 */ +class DescriptionApi { + private state = reactive>({}); + + constructor(options: DescriptionProps) { + this.state = { ...options }; + } + + getState(): DescriptionProps { + return this.state as DescriptionProps; + } + + setState(newState: Partial) { + this.state = { ...this.state, ...newState }; + } +} + +export type ExtendedDescriptionApi = DescriptionApi; + +export function useDescription(options: DescriptionProps) { + 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/components/upload/use-upload.ts b/apps/web-antd/src/components/upload/use-upload.ts index 94e238d1c..81aa22076 100644 --- a/apps/web-antd/src/components/upload/use-upload.ts +++ b/apps/web-antd/src/components/upload/use-upload.ts @@ -1,17 +1,14 @@ +import type { AxiosProgressEvent, InfraFileApi } from '#/api/infra/file'; import type { Ref } from 'vue'; -import type { AxiosProgressEvent, InfraFileApi } from '#/api/infra/file'; - +import { createFile, getFilePresignedUrl, uploadFile } from '#/api/infra/file'; +import { baseRequestClient } from '#/api/request'; import { computed, unref } from 'vue'; import { useAppConfig } from '@vben/hooks'; import { $t } from '@vben/locales'; - import CryptoJS from 'crypto-js'; -import { createFile, getFilePresignedUrl, uploadFile } from '#/api/infra/file'; -import { baseRequestClient } from '#/api/request'; - const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD); /** @@ -46,9 +43,7 @@ export function useUploadType({ const getStringAccept = computed(() => { return unref(getAccept) .map((item) => { - return item.indexOf('/') > 0 || item.startsWith('.') - ? item - : `.${item}`; + return item.indexOf('/') > 0 || item.startsWith('.') ? item : `.${item}`; }) .join(','); }); @@ -85,13 +80,9 @@ export const useUpload = () => { // 后端上传地址 const uploadUrl = getUploadUrl(); // 是否使用前端直连上传 - const isClientUpload = - UPLOAD_TYPE.CLIENT === import.meta.env.VITE_UPLOAD_TYPE; + const isClientUpload = UPLOAD_TYPE.CLIENT === import.meta.env.VITE_UPLOAD_TYPE; // 重写ElUpload上传方法 - const httpRequest = async ( - file: File, - onUploadProgress?: AxiosProgressEvent, - ) => { + const httpRequest = async (file: File, onUploadProgress?: AxiosProgressEvent) => { // 模式一:前端上传 if (isClientUpload) { // 1.1 生成文件名称 @@ -137,11 +128,7 @@ export const getUploadUrl = (): string => { * @param name 文件名称 * @param file 文件 */ -function createFile0( - vo: InfraFileApi.FilePresignedUrlRespVO, - name: string, - file: File, -) { +function createFile0(vo: InfraFileApi.FilePresignedUrlRespVO, name: string, file: File) { const fileVO = { configId: vo.configId, url: vo.url, diff --git a/apps/web-antd/src/router/access.ts b/apps/web-antd/src/router/access.ts index c4b161a5d..ecb000a4e 100644 --- a/apps/web-antd/src/router/access.ts +++ b/apps/web-antd/src/router/access.ts @@ -1,8 +1,4 @@ -import type { - AppRouteRecordRaw, - ComponentRecordType, - GenerateMenuAndRoutesOptions, -} from '@vben/types'; +import type { AppRouteRecordRaw, ComponentRecordType, GenerateMenuAndRoutesOptions } from '@vben/types'; import { generateAccessible } from '@vben/access'; import { preferences } from '@vben/preferences'; diff --git a/apps/web-antd/src/views/_core/profile/modules/profile-user.vue b/apps/web-antd/src/views/_core/profile/modules/profile-user.vue index b205991c9..bf0f444cc 100644 --- a/apps/web-antd/src/views/_core/profile/modules/profile-user.vue +++ b/apps/web-antd/src/views/_core/profile/modules/profile-user.vue @@ -1,17 +1,16 @@ diff --git a/apps/web-antd/src/views/bpm/processInstance/create/index.vue b/apps/web-antd/src/views/bpm/processInstance/create/index.vue index 3a439c08e..278a8387d 100644 --- a/apps/web-antd/src/views/bpm/processInstance/create/index.vue +++ b/apps/web-antd/src/views/bpm/processInstance/create/index.vue @@ -1,17 +1,11 @@