From b6d6edeeeb03b2d1800adce41d89e4ac184ea73d Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Tue, 11 Nov 2025 13:43:53 +0800 Subject: [PATCH] feat: utils --- apps/web-tdesign/src/utils/index.ts | 29 ++++++++ .../web-tdesign/src/utils/rangePickerProps.ts | 68 +++++++++++++++++++ apps/web-tdesign/src/utils/routerHelper.ts | 38 +++++++++++ apps/web-tdesign/src/utils/useUpload.ts | 63 +++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 apps/web-tdesign/src/utils/index.ts create mode 100644 apps/web-tdesign/src/utils/rangePickerProps.ts create mode 100644 apps/web-tdesign/src/utils/routerHelper.ts create mode 100644 apps/web-tdesign/src/utils/useUpload.ts diff --git a/apps/web-tdesign/src/utils/index.ts b/apps/web-tdesign/src/utils/index.ts new file mode 100644 index 000000000..5877010a3 --- /dev/null +++ b/apps/web-tdesign/src/utils/index.ts @@ -0,0 +1,29 @@ +import type { Recordable } from '@vben/types'; + +export * from './rangePickerProps'; +export * from './routerHelper'; + +/** + * 查找数组对象的某个下标 + * @param {Array} ary 查找的数组 + * @param {Function} fn 判断的方法 + */ +type Fn = (item: T, index: number, array: Array) => boolean; +export const findIndex = >( + ary: Array, + fn: Fn, +): number => { + if (ary.findIndex) { + return ary.findIndex((item, index, array) => fn(item, index, array)); + } + let index = -1; + ary.some((item: T, i: number, ary: Array) => { + const ret: boolean = fn(item, i, ary); + if (ret) { + index = i; + return true; + } + return false; + }); + return index; +}; diff --git a/apps/web-tdesign/src/utils/rangePickerProps.ts b/apps/web-tdesign/src/utils/rangePickerProps.ts new file mode 100644 index 000000000..2ba4be294 --- /dev/null +++ b/apps/web-tdesign/src/utils/rangePickerProps.ts @@ -0,0 +1,68 @@ +import dayjs from 'dayjs'; + +import { $t } from '#/locales'; + +/** 时间段选择器拓展 */ +export function getRangePickerDefaultProps() { + return { + // 设置日期格式,为数组时支持多格式匹配,展示以第一个为准。配置参考 dayjs,支持自定义格式 + format: 'YYYY-MM-DD HH:mm:ss', + // 绑定值的格式,对 value、defaultValue、defaultPickerValue 起作用。不指定则绑定值为 dayjs 对象 + valueFormat: 'YYYY-MM-DD HH:mm:ss', + // 输入框提示文字 + placeholder: [ + $t('utils.rangePicker.beginTime'), + $t('utils.rangePicker.endTime'), + ], + // 快捷时间范围 + presets: [ + { + label: $t('utils.rangePicker.today'), + value: [dayjs().startOf('day'), dayjs().endOf('day')], + }, + { + label: $t('utils.rangePicker.last7Days'), + value: [ + dayjs().subtract(7, 'day').startOf('day'), + dayjs().endOf('day'), + ], + }, + { + label: $t('utils.rangePicker.last30Days'), + value: [ + dayjs().subtract(30, 'day').startOf('day'), + dayjs().endOf('day'), + ], + }, + { + label: $t('utils.rangePicker.yesterday'), + value: [ + dayjs().subtract(1, 'day').startOf('day'), + dayjs().subtract(1, 'day').endOf('day'), + ], + }, + { + label: $t('utils.rangePicker.thisWeek'), + value: [dayjs().startOf('week'), dayjs().endOf('day')], + }, + { + label: $t('utils.rangePicker.thisMonth'), + value: [dayjs().startOf('month'), dayjs().endOf('day')], + }, + { + label: $t('utils.rangePicker.lastWeek'), + value: [ + dayjs().subtract(1, 'week').startOf('day'), + dayjs().endOf('day'), + ], + }, + ], + showTime: { + defaultValue: [ + dayjs('00:00:00', 'HH:mm:ss'), + dayjs('23:59:59', 'HH:mm:ss'), + ], + format: 'HH:mm:ss', + }, + }; +} diff --git a/apps/web-tdesign/src/utils/routerHelper.ts b/apps/web-tdesign/src/utils/routerHelper.ts new file mode 100644 index 000000000..a9e99f54b --- /dev/null +++ b/apps/web-tdesign/src/utils/routerHelper.ts @@ -0,0 +1,38 @@ +import type { + RouteLocationNormalized, + RouteRecordNormalized, +} from 'vue-router'; + +import { defineAsyncComponent } from 'vue'; + +const modules = import.meta.glob('../views/**/*.{vue,tsx}'); + +/** + * 注册一个异步组件 + * @param componentPath 例:/bpm/oa/leave/detail + */ +export function registerComponent(componentPath: string) { + for (const item in modules) { + if (item.includes(componentPath)) { + // 使用异步组件的方式来动态加载组件 + return defineAsyncComponent(modules[item] as any); + } + } +} + +export const getRawRoute = ( + route: RouteLocationNormalized, +): RouteLocationNormalized => { + if (!route) return route; + const { matched, ...opt } = route; + return { + ...opt, + matched: (matched + ? matched.map((item) => ({ + meta: item.meta, + name: item.name, + path: item.path, + })) + : undefined) as RouteRecordNormalized[], + }; +}; diff --git a/apps/web-tdesign/src/utils/useUpload.ts b/apps/web-tdesign/src/utils/useUpload.ts new file mode 100644 index 000000000..4c87c04ec --- /dev/null +++ b/apps/web-tdesign/src/utils/useUpload.ts @@ -0,0 +1,63 @@ +import { message } from 'ant-design-vue'; + +enum UploadType { + Image = 'image', + Video = 'video', + Voice = 'voice', +} + +const useBeforeUpload = (type: UploadType, maxSizeMB: number) => { + const fn = (file: File): boolean => { + let allowTypes: string[] = []; + let name = ''; + + switch (type) { + case UploadType.Image: { + allowTypes = [ + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/bmp', + 'image/jpg', + ]; + maxSizeMB = 2; + name = '图片'; + break; + } + case UploadType.Video: { + allowTypes = ['video/mp4']; + maxSizeMB = 10; + name = '视频'; + break; + } + case UploadType.Voice: { + allowTypes = [ + 'audio/mp3', + 'audio/mpeg', + 'audio/wma', + 'audio/wav', + 'audio/amr', + ]; + maxSizeMB = 2; + name = '语音'; + break; + } + } + // 格式不正确 + if (!allowTypes.includes(file.type)) { + message.error(`上传${name}格式不对!`); + return false; + } + // 大小不正确 + if (file.size / 1024 / 1024 > maxSizeMB) { + message.error(`上传${name}大小不能超过${maxSizeMB}M!`); + return false; + } + + return true; + }; + + return fn; +}; + +export { UploadType, useBeforeUpload };