diff --git a/README.md b/README.md index 86995df85..f3da9a925 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## 🐶 新手必读 -- nodejs > 20.10.0 && pnpm > 10.14.0 (强制使用pnpm) +- nodejs > 20.12.0 && pnpm > 10.14.0 (强制使用pnpm) - 演示地址【Vue3 + element-plus】: - 演示地址【Vue3 + vben5(ant-design-vue)】: - 演示地址【Vue2 + element-ui】: @@ -21,7 +21,7 @@ **芋道**,以开发者为中心,打造中国第一流的快速开发平台,全部开源,个人与企业可 100% 免费使用。 - 采用最新 [vue-vben-admin](https://github.com/vbenjs/vue-vben-admin) v5 实现 -- 支持 [Ant Design Vue](https://www.antdv.com/) | [Element Plus](https://element-plus.org/zh-CN/) | [Naive UI](https://www.naiveui.com/) 多种免费开源的中后台模版,具备如下特性: +- 支持 [Ant Design Vue](https://www.antdv.com/) | [Element Plus](https://element-plus.org/zh-CN/) | [Naive UI](https://www.naiveui.com/) | [TDesign](https://tdesign.tencent.com/) 多种免费开源的中后台模版,具备如下特性: ![首页](.image/demo/vben.png) @@ -46,12 +46,14 @@ | [Ant Design Vue](https://www.antdv.com/) | Ant Design Vue | 4.2.6 | | [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.10.2 | | [Naive UI](https://www.naiveui.com/) | Naive UI | 2.42.0 | +| [TDesign](https://tdesign.tencent.com/) | TDesign | 1.17.1 | | [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 超集 | 5.8.3 | | [pinia](https://pinia.vuejs.org/) | Vue 存储库替代 vuex5 | 3.0.3 | | [vueuse](https://vueuse.org/) | 常用工具集 | 13.4.0 | | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 11.1.7 | | [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.5.1 | | [Tailwind CSS](https://tailwindcss.com/) | 原子 CSS | 3.4.17 | +| [Iconify](https://iconify.design/) | 图标组件 | 5.0.0 | | [Iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.354 | | [TinyMCE](https://www.tiny.cloud/) | 富文本编辑器 | 6.1.0 | | [Echarts](https://echarts.apache.org/) | 图表库 | 5.6.0 | diff --git a/apps/web-antd/package.json b/apps/web-antd/package.json index da86ccc0e..80aa499ef 100644 --- a/apps/web-antd/package.json +++ b/apps/web-antd/package.json @@ -61,10 +61,11 @@ "pinia": "catalog:", "steady-xml": "catalog:", "tinymce": "catalog:", - "video.js": "^7.21.5", + "video.js": "catalog:", "vue": "catalog:", "vue-dompurify-html": "catalog:", "vue-router": "catalog:", + "vue3-print-nb": "catalog:", "vue3-signature": "catalog:", "vuedraggable": "catalog:" } diff --git a/apps/web-antd/src/api/bpm/model/index.ts b/apps/web-antd/src/api/bpm/model/index.ts index cd2afbc84..e16627fa1 100644 --- a/apps/web-antd/src/api/bpm/model/index.ts +++ b/apps/web-antd/src/api/bpm/model/index.ts @@ -20,6 +20,7 @@ export namespace BpmModelApi { suspensionState: number; formType?: number; formCustomViewPath?: string; + formFields?: string[]; } /** 流程模型 */ diff --git a/apps/web-antd/src/api/bpm/processInstance/index.ts b/apps/web-antd/src/api/bpm/processInstance/index.ts index ecbc03855..06fb2fec1 100644 --- a/apps/web-antd/src/api/bpm/processInstance/index.ts +++ b/apps/web-antd/src/api/bpm/processInstance/index.ts @@ -20,6 +20,7 @@ export namespace BpmProcessInstanceApi { export interface User { avatar: string; + deptName?: string; id: number; nickname: string; } @@ -101,6 +102,22 @@ export namespace BpmProcessInstanceApi { }[]; taskId: string; } + + /** 打印数据任务信息 */ + export interface PrintTask { + description: string; + id: number; + name: string; + signPicUrl?: string; + } + + /** 打印数据 */ + export interface PrintData { + printTemplateEnable: boolean; + printTemplateHtml?: string; + processInstance: ProcessInstance; + tasks: PrintTask[]; + } } /** 查询我的流程实例分页 */ @@ -205,3 +222,10 @@ export async function getProcessInstanceBpmnModelView(id: string) { `/bpm/process-instance/get-bpmn-model-view?id=${id}`, ); } + +/** 获取流程实例打印数据 */ +export async function getProcessInstancePrintData(id: string) { + return requestClient.get( + `/bpm/process-instance/get-print-data?processInstanceId=${id}`, + ); +} diff --git a/apps/web-antd/src/api/mp/draft/index.ts b/apps/web-antd/src/api/mp/draft/index.ts index 435f13e0b..9032ffd57 100644 --- a/apps/web-antd/src/api/mp/draft/index.ts +++ b/apps/web-antd/src/api/mp/draft/index.ts @@ -35,9 +35,13 @@ export function getDraftPage(params: PageParam) { /** 创建草稿 */ export function createDraft(accountId: number, articles: MpDraftApi.Article[]) { - return requestClient.post('/mp/draft/create', articles, { - params: { accountId }, - }); + return requestClient.post( + '/mp/draft/create', + { articles }, + { + params: { accountId }, + }, + ); } /** 更新草稿 */ @@ -46,9 +50,13 @@ export function updateDraft( mediaId: string, articles: MpDraftApi.Article[], ) { - return requestClient.put('/mp/draft/update', articles, { - params: { accountId, mediaId }, - }); + return requestClient.put( + '/mp/draft/update', + { articles }, + { + params: { accountId, mediaId }, + }, + ); } /** 删除草稿 */ diff --git a/apps/web-antd/src/assets/imgs/wechat.png b/apps/web-antd/src/assets/imgs/wechat.png new file mode 100644 index 000000000..6afc5e41c Binary files /dev/null and b/apps/web-antd/src/assets/imgs/wechat.png differ diff --git a/apps/web-antd/src/components/form-create/helpers.ts b/apps/web-antd/src/components/form-create/helpers.ts index 902efd665..f92780d75 100644 --- a/apps/web-antd/src/components/form-create/helpers.ts +++ b/apps/web-antd/src/components/form-create/helpers.ts @@ -1,3 +1,5 @@ +import type { Rule } from '@form-create/ant-design-vue'; + import type { Ref } from 'vue'; import type { Menu } from '#/components/form-create/typing'; @@ -34,7 +36,7 @@ export function encodeFields(designerRef: any) { // 解码表单 Fields export function decodeFields(fields: string[]) { - const rule: object[] = []; + const rule: Rule[] = []; fields.forEach((item) => { rule.push(formCreate.parseJson(item)); }); diff --git a/apps/web-antd/src/router/routes/modules/vben.ts b/apps/web-antd/src/router/routes/modules/vben.ts deleted file mode 100644 index 96f980d10..000000000 --- a/apps/web-antd/src/router/routes/modules/vben.ts +++ /dev/null @@ -1,81 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -// import { -// VBEN_DOC_URL, -// VBEN_ELE_PREVIEW_URL, -// VBEN_GITHUB_URL, -// VBEN_LOGO_URL, -// VBEN_NAIVE_PREVIEW_URL, -// } from '@vben/constants'; -// -// import { IFrameView } from '#/layouts'; -// import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - // { - // meta: { - // badgeType: 'dot', - // icon: VBEN_LOGO_URL, - // order: 9998, - // title: $t('demos.vben.title'), - // }, - // name: 'VbenProject', - // path: '/vben-admin', - // children: [ - // { - // name: 'VbenDocument', - // path: '/vben-admin/document', - // component: IFrameView, - // meta: { - // icon: 'lucide:book-open-text', - // link: VBEN_DOC_URL, - // title: $t('demos.vben.document'), - // }, - // }, - // { - // name: 'VbenGithub', - // path: '/vben-admin/github', - // component: IFrameView, - // meta: { - // icon: 'mdi:github', - // link: VBEN_GITHUB_URL, - // title: 'Github', - // }, - // }, - // { - // name: 'VbenNaive', - // path: '/vben-admin/naive', - // component: IFrameView, - // meta: { - // badgeType: 'dot', - // icon: 'logos:naiveui', - // link: VBEN_NAIVE_PREVIEW_URL, - // title: $t('demos.vben.naive-ui'), - // }, - // }, - // { - // name: 'VbenElementPlus', - // path: '/vben-admin/ele', - // component: IFrameView, - // meta: { - // badgeType: 'dot', - // icon: 'logos:element', - // link: VBEN_ELE_PREVIEW_URL, - // title: $t('demos.vben.element-plus'), - // }, - // }, - // ], - // }, - // { - // name: 'VbenAbout', - // path: '/vben-admin/about', - // component: () => import('#/views/_core/about/index.vue'), - // meta: { - // icon: 'lucide:copyright', - // title: $t('demos.vben.about'), - // order: 9999, - // }, - // }, -]; - -export default routes; // update by 芋艿:不展示 diff --git a/apps/web-antd/src/utils/index.ts b/apps/web-antd/src/utils/index.ts index 3a066fd4a..5877010a3 100644 --- a/apps/web-antd/src/utils/index.ts +++ b/apps/web-antd/src/utils/index.ts @@ -1,2 +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-antd/src/utils/routerHelper.ts b/apps/web-antd/src/utils/routerHelper.ts index 6c86773ab..a9e99f54b 100644 --- a/apps/web-antd/src/utils/routerHelper.ts +++ b/apps/web-antd/src/utils/routerHelper.ts @@ -1,4 +1,7 @@ -import type { RouteLocationNormalizedLoaded } from 'vue-router'; +import type { + RouteLocationNormalized, + RouteRecordNormalized, +} from 'vue-router'; import { defineAsyncComponent } from 'vue'; @@ -17,13 +20,19 @@ export function registerComponent(componentPath: string) { } } -export function getRawRoute( - route: RouteLocationNormalizedLoaded, -): RouteLocationNormalizedLoaded { +export const getRawRoute = ( + route: RouteLocationNormalized, +): RouteLocationNormalized => { if (!route) return route; - const { matched, ...others } = route; + const { matched, ...opt } = route; return { - ...others, - matched: matched ? matched.map((m) => ({ ...m })) : [], + ...opt, + matched: (matched + ? matched.map((item) => ({ + meta: item.meta, + name: item.name, + path: item.path, + })) + : undefined) as RouteRecordNormalized[], }; -} +}; diff --git a/apps/web-antd/src/utils/useUpload.ts b/apps/web-antd/src/utils/useUpload.ts new file mode 100644 index 000000000..4c87c04ec --- /dev/null +++ b/apps/web-antd/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 }; diff --git a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue index 4fce9dacf..14fdf8539 100644 --- a/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue +++ b/apps/web-antd/src/views/bpm/components/bpmn-process-designer/package/designer/ProcessDesigner.vue @@ -660,16 +660,15 @@ onBeforeUnmount(() => { -
-
+ diff --git a/apps/web-antd/src/views/bpm/components/simple-process-design/components/nodes-config/modules/condition.vue b/apps/web-antd/src/views/bpm/components/simple-process-design/components/nodes-config/modules/condition.vue index 3c274cf8a..e52eb8ee0 100644 --- a/apps/web-antd/src/views/bpm/components/simple-process-design/components/nodes-config/modules/condition.vue +++ b/apps/web-antd/src/views/bpm/components/simple-process-design/components/nodes-config/modules/condition.vue @@ -42,6 +42,7 @@ const props = defineProps({ modelValue: { type: Object, required: true, + default: () => ({}), }, }); diff --git a/apps/web-antd/src/views/bpm/components/simple-process-design/components/nodes-config/router-node-config.vue b/apps/web-antd/src/views/bpm/components/simple-process-design/components/nodes-config/router-node-config.vue index b23a01a66..a5a3c02a4 100644 --- a/apps/web-antd/src/views/bpm/components/simple-process-design/components/nodes-config/router-node-config.vue +++ b/apps/web-antd/src/views/bpm/components/simple-process-design/components/nodes-config/router-node-config.vue @@ -272,7 +272,7 @@ defineExpose({ openDrawer }); // 暴露方法给父组件 diff --git a/apps/web-antd/src/views/bpm/model/form/modules/basic-info.vue b/apps/web-antd/src/views/bpm/model/form/modules/basic-info.vue index 5da27465e..9ead376ff 100644 --- a/apps/web-antd/src/views/bpm/model/form/modules/basic-info.vue +++ b/apps/web-antd/src/views/bpm/model/form/modules/basic-info.vue @@ -248,9 +248,8 @@ defineExpose({ validate }); :rules="rules" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }" - class="mt-5" > - +
- +
- + - + - + - + - + - + +