diff --git a/.gitignore b/.gitignore index 095c630..da8e129 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ yarn.lock src/typings/elegant-router.d.ts src/typings/components.d.ts +src/router/elegant/transform.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0c2bf2d..e6d6a37 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,9 @@ importers: '@sa/utils': specifier: workspace:* version: link:packages/utils + '@sa/workflow': + specifier: workspace:* + version: link:packages/work-flow '@vueuse/core': specifier: 10.9.0 version: 10.9.0(vue@3.4.27(typescript@5.4.5)) @@ -291,6 +294,8 @@ importers: specifier: 4.2.2 version: 4.2.2 + packages/work-flow: {} + packages: '@ampproject/remapping@2.3.0': @@ -4746,6 +4751,17 @@ packages: '@vue/composition-api': optional: true + vue-demi@0.14.8: + resolution: {integrity: sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue-draggable-plus@0.4.1: resolution: {integrity: sha512-KNi+c482OQUZTZ2kXIGc41fEwknkNF+LlngjBr5TVtBLNvpX2dmwRJJ3J7dy5dGcijXb7V1j+mhqce4iHOoi6Q==} peerDependencies: @@ -9963,7 +9979,7 @@ snapshots: dependencies: codemirror: 6.0.1(@lezer/common@1.2.1) vue: 3.4.27(typescript@5.4.5) - vue-demi: 0.14.7(vue@3.4.27(typescript@5.4.5)) + vue-demi: 0.14.8(vue@3.4.27(typescript@5.4.5)) transitivePeerDependencies: - '@lezer/common' - '@vue/composition-api' @@ -9976,6 +9992,10 @@ snapshots: dependencies: vue: 3.4.27(typescript@5.4.5) + vue-demi@0.14.8(vue@3.4.27(typescript@5.4.5)): + dependencies: + vue: 3.4.27(typescript@5.4.5) + vue-draggable-plus@0.4.1(@types/sortablejs@1.15.8): dependencies: '@types/sortablejs': 1.15.8 diff --git a/public/iconify/cbi.json b/public/iconify/cbi.json new file mode 100644 index 0000000..54d4521 --- /dev/null +++ b/public/iconify/cbi.json @@ -0,0 +1,14 @@ +{ + "prefix": "cbi", + "lastModified": 1715922185, + "aliases": {}, + "width": 24, + "height": 24, + "icons": { + "scene-dynamic": { + "body": "", + "width": 32, + "height": 32 + } + } +} diff --git a/public/iconify/fluent.json b/public/iconify/fluent.json new file mode 100644 index 0000000..ac1b6e4 --- /dev/null +++ b/public/iconify/fluent.json @@ -0,0 +1,12 @@ +{ + "prefix": "fluent", + "lastModified": 1716181326, + "aliases": {}, + "width": 20, + "height": 20, + "icons": { + "people-call-20-filled": { + "body": "" + } + } +} diff --git a/public/iconify/oui.json b/public/iconify/oui.json new file mode 100644 index 0000000..f0f1e7e --- /dev/null +++ b/public/iconify/oui.json @@ -0,0 +1,12 @@ +{ + "prefix": "oui", + "lastModified": 1714628006, + "aliases": {}, + "icons": { + "app-spaces": { + "body": "", + "width": 32, + "height": 32 + } + } +} diff --git a/public/iconify/streamline.json b/public/iconify/streamline.json new file mode 100644 index 0000000..0aeb1c0 --- /dev/null +++ b/public/iconify/streamline.json @@ -0,0 +1,17 @@ +{ + "prefix": "streamline", + "lastModified": 1702314084, + "aliases": {}, + "width": 14, + "height": 14, + "icons": { + "interface-arrows-synchronize-warning-arrow-fail-notification-sync-warning-failure-synchronize-error": { + "body": "", + "hidden": true + }, + "interface-user-multiple-close-geometric-human-multiple-person-up-user": { + "body": "", + "hidden": true + } + } +} diff --git a/public/iconify/tabler.json b/public/iconify/tabler.json new file mode 100644 index 0000000..5a4f022 --- /dev/null +++ b/public/iconify/tabler.json @@ -0,0 +1,12 @@ +{ + "prefix": "tabler", + "lastModified": 1716442914, + "aliases": {}, + "width": 24, + "height": 24, + "icons": { + "logs": { + "body": "" + } + } +} diff --git a/src/components/common/file-upload.vue b/src/components/common/file-upload.vue index 853dd63..0b40d64 100644 --- a/src/components/common/file-upload.vue +++ b/src/components/common/file-upload.vue @@ -7,6 +7,12 @@ defineOptions({ name: 'FileUpload' }); +const emit = defineEmits(); + +interface Emits { + (e: 'refresh'): void; +} + interface Props { accept?: string; action?: string; @@ -51,6 +57,7 @@ const handleImport = ({ }) .then(() => { onFinish(); + emit('refresh'); }) .catch(() => onError()); }; diff --git a/src/router/elegant/transform.ts b/src/router/elegant/transform.ts deleted file mode 100644 index f6cb0ee..0000000 --- a/src/router/elegant/transform.ts +++ /dev/null @@ -1,250 +0,0 @@ -/* eslint-disable */ -/* prettier-ignore */ -// Generated by elegant-router -// Read more: https://github.com/soybeanjs/elegant-router - -import type { RouteRecordRaw, RouteComponent } from 'vue-router'; -import type { ElegantConstRoute } from '@elegant-router/vue'; -import type { RouteMap, RouteKey, RoutePath } from '@elegant-router/types'; - -/** - * transform elegant const routes to vue routes - * @param routes elegant const routes - * @param layouts layout components - * @param views view components - */ -export function transformElegantRoutesToVueRoutes( - routes: ElegantConstRoute[], - layouts: Record Promise)>, - views: Record Promise)> -) { - return routes.flatMap(route => transformElegantRouteToVueRoute(route, layouts, views)); -} - -/** - * transform elegant route to vue route - * @param route elegant const route - * @param layouts layout components - * @param views view components - */ -function transformElegantRouteToVueRoute( - route: ElegantConstRoute, - layouts: Record Promise)>, - views: Record Promise)> -) { - const LAYOUT_PREFIX = 'layout.'; - const VIEW_PREFIX = 'view.'; - const ROUTE_DEGREE_SPLITTER = '_'; - const FIRST_LEVEL_ROUTE_COMPONENT_SPLIT = '$'; - - function isLayout(component: string) { - return component.startsWith(LAYOUT_PREFIX); - } - - function getLayoutName(component: string) { - const layout = component.replace(LAYOUT_PREFIX, ''); - - if(!layouts[layout]) { - throw new Error(`Layout component "${layout}" not found`); - } - - return layout; - } - - function isView(component: string) { - return component.startsWith(VIEW_PREFIX); - } - - function getViewName(component: string) { - const view = component.replace(VIEW_PREFIX, ''); - - if(!views[view]) { - throw new Error(`View component "${view}" not found`); - } - - return view; - } - - function isFirstLevelRoute(item: ElegantConstRoute) { - return !item.name.includes(ROUTE_DEGREE_SPLITTER); - } - - function isSingleLevelRoute(item: ElegantConstRoute) { - return isFirstLevelRoute(item) && !item.children?.length; - } - - function getSingleLevelRouteComponent(component: string) { - const [layout, view] = component.split(FIRST_LEVEL_ROUTE_COMPONENT_SPLIT); - - return { - layout: getLayoutName(layout), - view: getViewName(view) - }; - } - - const vueRoutes: RouteRecordRaw[] = []; - - // add props: true to route - if (route.path.includes(':') && !route.props) { - route.props = true; - } - - const { name, path, component, children, ...rest } = route; - - const vueRoute = { name, path, ...rest } as RouteRecordRaw; - - try { - if (component) { - if (isSingleLevelRoute(route)) { - const { layout, view } = getSingleLevelRouteComponent(component); - - const singleLevelRoute: RouteRecordRaw = { - path, - component: layouts[layout], - children: [ - { - name, - path: '', - component: views[view], - ...rest - } as RouteRecordRaw - ] - }; - - return [singleLevelRoute]; - } - - if (isLayout(component)) { - const layoutName = getLayoutName(component); - - vueRoute.component = layouts[layoutName]; - } - - if (isView(component)) { - const viewName = getViewName(component); - - vueRoute.component = views[viewName]; - } - - } - } catch (error: any) { - console.error(`Error transforming route "${route.name}": ${error.toString()}`); - return []; - } - - - // add redirect to child - if (children?.length && !vueRoute.redirect) { - vueRoute.redirect = { - name: children[0].name - }; - } - - if (children?.length) { - const childRoutes = children.flatMap(child => transformElegantRouteToVueRoute(child, layouts, views)); - - if(isFirstLevelRoute(route)) { - vueRoute.children = childRoutes; - } else { - vueRoutes.push(...childRoutes); - } - } - - vueRoutes.unshift(vueRoute); - - return vueRoutes; -} - -/** - * map of route name and route path - */ -const routeMap: RouteMap = { - "root": "/", - "not-found": "/:pathMatch(.*)*", - "exception": "/exception", - "exception_403": "/exception/403", - "exception_404": "/exception/404", - "exception_500": "/exception/500", - "document": "/document", - "document_project": "/document/project", - "document_project-link": "/document/project-link", - "document_vue": "/document/vue", - "document_vite": "/document/vite", - "document_unocss": "/document/unocss", - "document_naive": "/document/naive", - "document_antd": "/document/antd", - "403": "/403", - "404": "/404", - "500": "/500", - "about": "/about", - "function": "/function", - "function_hide-child": "/function/hide-child", - "function_hide-child_one": "/function/hide-child/one", - "function_hide-child_three": "/function/hide-child/three", - "function_hide-child_two": "/function/hide-child/two", - "function_multi-tab": "/function/multi-tab", - "function_request": "/function/request", - "function_super-page": "/function/super-page", - "function_tab": "/function/tab", - "function_toggle-auth": "/function/toggle-auth", - "group": "/group", - "home": "/home", - "iframe-page": "/iframe-page/:url", - "job": "/job", - "job_batch": "/job/batch", - "job_task": "/job/task", - "login": "/login/:module(pwd-login)?", - "manage": "/manage", - "manage_menu": "/manage/menu", - "manage_role": "/manage/role", - "manage_user": "/manage/user", - "manage_user-detail": "/manage/user-detail/:id", - "multi-menu": "/multi-menu", - "multi-menu_first": "/multi-menu/first", - "multi-menu_first_child": "/multi-menu/first/child", - "multi-menu_second": "/multi-menu/second", - "multi-menu_second_child": "/multi-menu/second/child", - "multi-menu_second_child_home": "/multi-menu/second/child/home", - "namespace": "/namespace", - "notify": "/notify", - "notify_recipient": "/notify/recipient", - "notify_scene": "/notify/scene", - "pods": "/pods", - "retry": "/retry", - "retry_dead-letter": "/retry/dead-letter", - "retry_log": "/retry/log", - "retry_scene": "/retry/scene", - "retry_task": "/retry/task", - "user": "/user", - "user_manager": "/user/manager", - "user-center": "/user-center", - "workflow": "/workflow", - "workflow_batch": "/workflow/batch", - "workflow_form": "/workflow/form", - "workflow_form_add": "/workflow/form/add", - "workflow_form_batch": "/workflow/form/batch", - "workflow_form_copy": "/workflow/form/copy", - "workflow_form_detail": "/workflow/form/detail", - "workflow_form_edit": "/workflow/form/edit", - "workflow_task": "/workflow/task" -}; - -/** - * get route path by route name - * @param name route name - */ -export function getRoutePath(name: T) { - return routeMap[name]; -} - -/** - * get route name by route path - * @param path route path - */ -export function getRouteName(path: RoutePath) { - const routeEntries = Object.entries(routeMap) as [RouteKey, RoutePath][]; - - const routeName: RouteKey | null = routeEntries.find(([, routePath]) => routePath === path)?.[0] || null; - - return routeName; -} diff --git a/src/typings/api.d.ts b/src/typings/api.d.ts index b81cfc4..b65346a 100644 --- a/src/typings/api.d.ts +++ b/src/typings/api.d.ts @@ -212,7 +212,7 @@ declare namespace Api { type DashboardLineJob = { createDt: string; total: number; - failNum: number; + fail: number; stop: number; cancel: number; success: number; @@ -649,8 +649,7 @@ declare namespace Api { /** notifyRecipient search params */ type NotifyRecipientParams = CommonType.RecordNullable< - Pick & - CommonSearchParams + Pick & CommonSearchParams >; /** notifyRecipient list */ @@ -659,6 +658,11 @@ declare namespace Api { /** 1: 钉钉通知 2: 邮件通知 3: 企业通知 4: 飞书 5: Webhook */ type AlarmType = 1 | 2 | 3 | 4 | 5; + type ExportNotifyRecipient = Common.CommonRecord<{ + notifyRecipientIds: string[]; + }> & + NotifyRecipientParams; + /* 1: application/json 2:application/x-www-form-urlencoded */ type AlarmTypeWebhook = 1 | 2; } @@ -894,6 +898,11 @@ declare namespace Api { Pick & CommonSearchParams >; + type ExportWorkflow = Common.CommonRecord<{ + workflowIds: String[]; + }> & + WorkflowSearchParams; + /** workflow list */ type WorkflowList = Common.PaginatingQueryRecord; } @@ -982,6 +991,11 @@ declare namespace Api { /** JobTask list */ type JobList = Common.PaginatingQueryRecord; + type ExportJob = Common.CommonRecord<{ + jobIds: string[]; + }> & + JobSearchParams; + /** 2、固定时间 3、CRON表达式 99、工作流 */ type TriggerType = 2 | 3 | 99; diff --git a/src/views/group/index.vue b/src/views/group/index.vue index d4c3142..b59a7dc 100644 --- a/src/views/group/index.vue +++ b/src/views/group/index.vue @@ -195,7 +195,7 @@ function handleExport() { @refresh="getData" >