diff --git a/.env.development b/.env.development index 3c5fcd5..e118379 100644 --- a/.env.development +++ b/.env.development @@ -41,6 +41,9 @@ VITE_GLOB_API_URL_PREFIX = #租户开关 # VITE_GLOB_TENANT_ENABLED = true +#登录时是否需要输入租户码 +# VITE_GLOB_TENANT_INPUT_REQUIRED = true + # 屏蔽通知消息的轮询 VITE_GLOB_DISABLE_NEWS=false # 禁用关闭页面提示 diff --git a/.env.development.example b/.env.development.example index 40cc05c..5f1c007 100644 --- a/.env.development.example +++ b/.env.development.example @@ -36,3 +36,9 @@ VITE_GLOB_API_URL_PREFIX = # 屏蔽通知消息的轮询 VITE_GLOB_DISABLE_NEWS = true + +#租户开关 +# VITE_GLOB_TENANT_ENABLED = true +#登录时是否需要输入租户码 +# VITE_GLOB_TENANT_INPUT_REQUIRED = true + diff --git a/.env.production b/.env.production index 2867d21..5b4625c 100644 --- a/.env.production +++ b/.env.production @@ -38,6 +38,9 @@ VITE_GLOB_API_URL_PREFIX = VITE_USE_PWA = false #租户开关 VITE_GLOB_TENANT_ENABLED = true +#登录时是否需要输入租户码 +# VITE_GLOB_TENANT_INPUT_REQUIRED = true + # 屏蔽通知消息的轮询 VITE_GLOB_DISABLE_NEWS=false # 禁用关闭页面提示 diff --git a/.env.production.example b/.env.production.example index 9f5ddda..3a6f021 100644 --- a/.env.production.example +++ b/.env.production.example @@ -36,3 +36,9 @@ VITE_GLOB_API_URL_PREFIX = # 打包是否开启pwa功能 VITE_USE_PWA = false + +#租户开关 +# VITE_GLOB_TENANT_ENABLED = true +#登录时是否需要输入租户码 +# VITE_GLOB_TENANT_INPUT_REQUIRED = true + diff --git a/src/api/form/design/index.ts b/src/api/form/design/index.ts index 387277d..a6e1d0f 100644 --- a/src/api/form/design/index.ts +++ b/src/api/form/design/index.ts @@ -112,6 +112,21 @@ export async function getFormTemplate(id: string, mode: ErrorMessageMode = 'moda ); } +/** + * @description: 获取模板详情信息-优先从缓存获取 + */ +export async function getFormTemplateUsingCache(id: string, mode: ErrorMessageMode = 'modal') { + return defHttp.get( + { + url: Api.Info, + params: {id,useCache:1}, + }, + { + errorMessageMode: mode, + }, + ); +} + /** * @description: 更新模板状态 */ diff --git a/src/api/system/dataMigration/index.ts b/src/api/system/dataMigration/index.ts new file mode 100644 index 0000000..af38afb --- /dev/null +++ b/src/api/system/dataMigration/index.ts @@ -0,0 +1,79 @@ +import { defHttp } from '/@/utils/http/axios'; +import { ErrorMessageMode } from '/#/axios'; + +enum Api { + ExportDatas= '/system/dataMigration/exportDatas', + DownloadDatas='/system/dataMigration/downloadDatas', + LogList='/system/dataMigration/logList', + LogDetails='/system/dataMigration/logDetails', +} + +/** + * @description: 系统配置迁移-导出资源 + */ +export async function exportDatas(params, mode: ErrorMessageMode = 'modal') { + return defHttp.post( + { + url: Api.ExportDatas, + data:params, + }, + { + errorMessageMode: mode, + }, + ); +} + + +/** + * @description: 根据uuid(目录名称)下载数据 + */ +export async function downloadDatas(params?: object, mode: ErrorMessageMode = 'modal') { + return defHttp.download( + { + url: Api.DownloadDatas+"/"+params.uuid, + method: 'GET', + responseType: 'blob', + }, + { + errorMessageMode: mode, + }, + ); +} + + +/** + * @description: 获取日志列表 + */ +export async function getLogList(mode: ErrorMessageMode = 'modal') { + return defHttp.get<[]>( + { + url: Api.LogList + }, + { + errorMessageMode: mode, + }, + ); +} + +/** + * @description: 获取日志详情 + */ +export async function getLogDetails(fileName:String,mode: ErrorMessageMode = 'modal') { + return defHttp.get<[]>( + { + url: Api.LogDetails, + params:{ + fileName + } + }, + { + errorMessageMode: mode, + }, + ); +} + + + + + + diff --git a/src/api/system/menu/index.ts b/src/api/system/menu/index.ts index 7e620e6..1dd879a 100644 --- a/src/api/system/menu/index.ts +++ b/src/api/system/menu/index.ts @@ -11,6 +11,7 @@ enum Api { SimpleTree = '/system/menu/simple-tree', TenantSimpleTree = '/system/menu/tenant-auth-tree', Menu = '/system/menu', + MenuInfoByComponentPath = '/system/menu/info-by-component-path', Button = '/system/menu/button', Column = '/system/menu-colum/list', Form = '/system/menu-form/list', @@ -197,3 +198,21 @@ export async function getMenuFormById(params, mode: ErrorMessageMode = 'modal') }, ); } + +/** + * @description: 根据组件路径查询菜单 + */ +export async function getMenuByIdComponentPath(componentPath:String, mode: ErrorMessageMode = 'modal') { + return defHttp.get( + { + url: Api.MenuInfoByComponentPath, + params:{componentPath} + }, + { + errorMessageMode: mode, + }, + ); +} + + + diff --git a/src/components/Application/src/UserTenantChange.vue b/src/components/Application/src/UserTenantChange.vue index 057c45f..c6f9748 100644 --- a/src/components/Application/src/UserTenantChange.vue +++ b/src/components/Application/src/UserTenantChange.vue @@ -27,31 +27,20 @@ import { storeToRefs } from 'pinia'; import { Tooltip } from 'ant-design-vue'; import { useUserStore } from '/@/store/modules/user'; - import { changeTenant } from '/@/api/system/tenant'; import { useI18n } from '/@/hooks/web/useI18n'; import {useMessage} from "/@/hooks/web/useMessage"; - import {useTabs} from "/@/hooks/web/useTabs"; - import {router} from "/@/router"; - import {setupRouterGuard} from "/@/router/guard"; - import {usePermissionStore} from "/@/store/modules/permission"; - import {useMenuSetting} from "/@/hooks/setting/useMenuSetting"; - import {useAppInject} from "/@/hooks/web/useAppInject"; - import {useAppStore} from "/@/store/modules/app"; + import {useTenantManager} from "/@/utils/tenantManager"; const userStore = useUserStore(); const { t } = useI18n(); const { userInfo } = storeToRefs(userStore); - const { closeAll } = useTabs(router); - const permissionStore = usePermissionStore(); - const { getShowTopMenu } = useMenuSetting(); - const { getIsMobile } = useAppInject(); - const appStore = useAppStore(); const formInfo: any = ref({ tenants: [], tenantId: '', tenantCode: '', tenantName: '', }); + const {toggleLocal}=useTenantManager(); getDropMenuList(); watch( () => userInfo.value, @@ -73,20 +62,9 @@ }); } } - async function toggleLocale(lang: string) { - appStore.setPageLoadingAction(true); - let res = await changeTenant(lang); - await userStore.afterLoginAction(true); - closeAll(); - await setupRouterGuard(router); - await permissionStore.changeSubsystem(getShowTopMenu.value, getIsMobile.value); - if(permissionStore.getSubSysList.length>0){ - permissionStore.setSubSystem(permissionStore.getSubSysList[0].id); - }else{ - permissionStore.setSubSystem(""); - } - //appStore.setPageLoadingAction(false); - //location.reload(); + + async function switchTenant(tenantCode: string) { + await toggleLocal({tenantCode:tenantCode, goHome:true,tabCloseAction:"closeAll"}); } function handleMenuEvent(menu: DropMenu) { @@ -99,7 +77,7 @@ title: () => h('span', t('温馨提醒')), content: () => h('span', t('是否确认切换租户?未保存的数据可能会丢失!')), onOk: async () => { - toggleLocale(menu.event as string); + switchTenant(menu.event as string); }, okText: () => t('确认'), cancelText: () => t('取消'), diff --git a/src/components/CreateCodeStep/index.ts b/src/components/CreateCodeStep/index.ts index 4d6fe5c..dd0d606 100644 --- a/src/components/CreateCodeStep/index.ts +++ b/src/components/CreateCodeStep/index.ts @@ -1,5 +1,6 @@ export { default as MenuConfigStep } from './src/MenuConfigStep.vue'; export { default as StructureConfigStep } from './src/StructureConfigStep.vue'; +export { default as EntireConfigStep } from './src/EntireConfigStep.vue'; export { default as ViewDesignStep } from './src/ViewDesignStep.vue'; diff --git a/src/components/CreateCodeStep/src/EntireConfigStep.vue b/src/components/CreateCodeStep/src/EntireConfigStep.vue new file mode 100644 index 0000000..08a001c --- /dev/null +++ b/src/components/CreateCodeStep/src/EntireConfigStep.vue @@ -0,0 +1,150 @@ + + + diff --git a/src/enums/workflowEnum.ts b/src/enums/workflowEnum.ts index 3ad650d..4afae2d 100644 --- a/src/enums/workflowEnum.ts +++ b/src/enums/workflowEnum.ts @@ -185,6 +185,7 @@ export enum TaskTypeUrl { // 工作流分类id export enum FlowCategory { ID = '1419276800524425555', + CODE = 'WF10000', } // 审批类型 0 同意 1 拒绝 2 驳回 3 结束 4 其他(用户自定义按钮) diff --git a/src/hooks/web/useFormConfig.ts b/src/hooks/web/useFormConfig.ts new file mode 100644 index 0000000..f0d5c65 --- /dev/null +++ b/src/hooks/web/useFormConfig.ts @@ -0,0 +1,149 @@ + +import { FormSchema } from '/@/components/Form'; +import { BasicColumn } from "/@/components/Table"; +import { getFormTemplateUsingCache } from '/@/api/form/design'; +import { getMenuByIdComponentPath } from '/@/api/system/menu'; +import { deepMerge } from '/@/utils'; +import { useI18n } from '/@/hooks/web/useI18n'; +import { useMessage } from '/@/hooks/web/useMessage'; + +const { t } = useI18n(); +const { notification } = useMessage(); + +export function useFormConfig() { + async function mergeFormSchemas(obj:{formSchema: FormSchema[],formId:String,formPath:String}){ + try{ + let formProps; + if(obj.formId){ + formProps=await queryConfig(obj.formId,'formProps'); + }else{ + formProps=await queryConfigByFormPath(obj.formPath,'formProps'); + } + + let fschemas=formProps?.schemas; + if(fschemas&&fschemas.length>0){ + return deepMerge(obj.formSchema,fschemas); + }else{ + return formSchema; + } + }catch(e){ + return []; + } + } + + async function mergeFormEventConfigs(obj:{formEventConfigs,formId:String,formPath:String}){ + try{ + let fEConfigs; + if(obj.formId){ + fEConfigs=await queryConfig(obj.formId,'formEventConfigs'); + }else{ + fEConfigs=await queryConfigByFormPath(obj.formPath,'formEventConfigs'); + } + + return deepMerge(obj.formEventConfigs,fEConfigs); + }catch(e){ + return {}; + } + } + + + async function mergeColumns(columns: BasicColumn[],formId:String){ + try{ + const cols=await queryConfig(formId,'columns'); + if(cols&&cols.length>0){ + const filteredCol = cols.filter(colItem => + columns.some(column => column.dataIndex === colItem.dataIndex) + ); + return filteredCol; + }else{ + return columns; + } + }catch(e){ + return []; + } + } + + async function mergeSearchFormSchema(searchFormSchema: FormSchema[],formId:String){ + try{ + const sFormSchema=await queryConfig(formId,'searchFormSchema'); + if(sFormSchema&&sFormSchema.length>0){ + const filteredsFormSchema = sFormSchema.filter(sItem => + searchFormSchema.some( searchItem => searchItem.field === sItem.field) + ); + return filteredsFormSchema; + }else{ + return searchFormSchema; + } + }catch(e){ + return []; + } + } + + async function mergeButtons(buttons,formId:String){ + try{ + const btns=await queryConfig(formId,'buttons'); + if(btns&&btns.length>0){ + return btns; + }else{ + return buttons; + } + }catch(e){ + return[]; + } + } + + async function queryConfigByFormPath(componentPath:String,configName:String){ + if(componentPath==null){ + notification.error({ + message: t('提示'), + description: `发生异常,组件路径不能为空!`, + }); + throw new Error('发生异常,组件路径不能为空!'); + } + const menu=await getMenuByIdComponentPath("/"+componentPath+"/index"); + if(menu==null){ + notification.error({ + message: t('提示'), + description: `发生异常,根据组件路径找不到菜单!`, + }); + throw new Error('发生异常,根据组件路径找不到菜单!'); + } + const formId=menu.formId; + + return await queryConfig(formId,configName); + + } + + async function queryConfig(formId:String,configName:String){ + const formTemplate = await getFormTemplateUsingCache(formId); + const renderConfig=formTemplate.renderConfig; + const exportMatches = renderConfig.matchAll(/export\s+const\s+(\w+)\s*(?::\s*\w+(?:\[\])?)?\s*=\s*([\s\S]*?)(?=\n\s*export\s+const|\n\s*const|\n\s*export\s+function|\n\s*function|$)/g); + for (const match of exportMatches) { + const varName = match[1]; + const valueCode = match[2].trim(); + const cleanCode = valueCode.endsWith(';') ? valueCode.slice(0, -1) : valueCode; + if(varName==configName) { + try { + const value = new Function(`return ${cleanCode}`)(); + return value; + } catch (e) { + console.error(`Failed to parse ${varName}:`, e); + notification.error({ + message: t('提示'), + description: `解析表单渲染覆盖配置出错[解析${configName}发生异常]`, + }); + throw new Error('解析表单渲染覆盖配置出错,请联系管理员处理'); + } + } + } + return null; + } + + return { + mergeFormSchemas, + mergeColumns, + mergeSearchFormSchema, + mergeButtons, + mergeFormEventConfigs + }; +} diff --git a/src/utils/env.ts b/src/utils/env.ts index e6a512f..c67b0dd 100644 --- a/src/utils/env.ts +++ b/src/utils/env.ts @@ -22,7 +22,7 @@ export function getAppEnvConfig() { (import.meta.env as unknown as GlobEnvConfig) : window[ENV_NAME as any]) as unknown as GlobEnvConfig; - const { VITE_GLOB_APP_TITLE, VITE_GLOB_API_URL, VITE_GLOB_APP_SHORT_NAME, VITE_GLOB_API_URL_PREFIX, VITE_GLOB_REQUEST_TIMEOUT, VITE_GLOB_UPLOAD_URL, VITE_GLOB_UPLOAD_PREVIEW, VITE_GLOB_OUT_LINK_URL, VITE_GLOB_REPORT_URL, VITE_GLOB_PRINT_BASE_URL, VITE_GLOB_TENANT_ENABLED } = ENV; + const { VITE_GLOB_APP_TITLE, VITE_GLOB_API_URL, VITE_GLOB_APP_SHORT_NAME, VITE_GLOB_API_URL_PREFIX, VITE_GLOB_REQUEST_TIMEOUT, VITE_GLOB_UPLOAD_URL, VITE_GLOB_UPLOAD_PREVIEW, VITE_GLOB_OUT_LINK_URL, VITE_GLOB_REPORT_URL, VITE_GLOB_PRINT_BASE_URL, VITE_GLOB_TENANT_ENABLED,VITE_GLOB_TENANT_INPUT_REQUIRED } = ENV; if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) { warn(`VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.`); @@ -39,7 +39,8 @@ export function getAppEnvConfig() { VITE_GLOB_OUT_LINK_URL, VITE_GLOB_REPORT_URL, VITE_GLOB_PRINT_BASE_URL, - VITE_GLOB_TENANT_ENABLED + VITE_GLOB_TENANT_ENABLED, + VITE_GLOB_TENANT_INPUT_REQUIRED }; } diff --git a/src/utils/helper/generatorHelper.ts b/src/utils/helper/generatorHelper.ts index f9f5d1c..78635fa 100644 --- a/src/utils/helper/generatorHelper.ts +++ b/src/utils/helper/generatorHelper.ts @@ -643,6 +643,7 @@ ${hasTemplatePrint ? ' reactive ' : ''} import { useMessage } from '/@/hooks/web/useMessage'; import { useI18n } from '/@/hooks/web/useI18n'; import { usePermission } from '/@/hooks/web/usePermission'; + import { useFormConfig } from '/@/hooks/web/useFormConfig'; import { useRouter } from 'vue-router'; import { get${pascalMainTableName} } from '/@/api/${ model.outputConfig.outputValue @@ -710,7 +711,7 @@ ${hasTemplatePrint ? ' reactive ' : ''} : '' } ${componentArray.includes('money-chinese') ? `import nzhcn from 'nzh/cn';` : ''} - import { searchFormSchema, columns } from './components/config'; + import {formConfig, searchFormSchema, columns } from './components/config'; ${ model.listConfig.buttonConfigs.filter((x) => x.isUse).length > 0 || model.listConfig.leftMenuConfig?.childIcon || @@ -746,15 +747,20 @@ ${hasTemplatePrint ? ' reactive ' : ''} } import useEventBus from '/@/hooks/event/useEventBus'; - + import { cloneDeep } from 'lodash-es'; + const { bus, CREATE_FLOW, FLOW_PROCESSED, FORM_LIST_MODIFIED } = useEventBus(); const { notification } = useMessage(); const { t } = useI18n(); defineEmits(['register']); const { filterColumnAuth, filterButtonAuth } = usePermission(); + const { mergeColumns,mergeSearchFormSchema,mergeButtons } = useFormConfig(); - const filterColumns = filterColumnAuth(columns); + const filterColumns = cloneDeep(filterColumnAuth(columns)); + const customConfigColums =ref(filterColumns); + const customSearchFormSchema =ref(searchFormSchema); + const tableRef = ref(); ${ hasFilterButton @@ -766,11 +772,13 @@ ${hasTemplatePrint ? ' reactive ' : ''} }` : '' } + + //所有按钮 + const buttons = ref(${JSON.stringify(model.listConfig.buttonConfigs.filter((x) => x.isUse))}); //展示在列表内的按钮 const actionButtons = ref(['view', 'edit', 'copyData', 'delete', 'startwork','flowRecord']); const buttonConfigs = computed(()=>{ - const list = ${JSON.stringify(model.listConfig.buttonConfigs.filter((x) => x.isUse))} - return filterButtonAuth(list); + return filterButtonAuth(buttons.value); }) const tableButtonConfig = computed(() => { @@ -868,12 +876,12 @@ ${hasTemplatePrint ? ' reactive ' : ''} title: '${model.listConfig?.listTitle||''}' || (formName + '列表'), api: get${pascalMainTableName}Page, rowKey: '${camelCaseString(mainTable.pkField)}', - columns: filterColumns, + columns: customConfigColums, formConfig: { rowProps: { gutter: 16, }, - schemas: searchFormSchema, + schemas: customSearchFormSchema, fieldMapToTime: [${ model.listConfig.queryConfigs .filter((item) => { @@ -961,7 +969,8 @@ ${hasTemplatePrint ? ' reactive ' : ''} path: '/flow/' + schemaId + '/' + (processId || '') + '/approveFlow', query: { taskId: taskIds[0], - formName: formName + formName: formName, + formId:currentRoute.value.meta.formId } }); } else if (schemaId && !taskIds && processId) { @@ -970,7 +979,8 @@ ${hasTemplatePrint ? ' reactive ' : ''} query: { readonly: 1, taskId: '', - formName: formName + formName: formName, + formId:currentRoute.value.meta.formId } }); } else { @@ -978,7 +988,8 @@ ${hasTemplatePrint ? ' reactive ' : ''} path: '/form/${lowerClassName}/' + record.id + '/viewForm', query: { formPath: '${model.outputConfig.outputValue}/${lowerClassName}', - formName: formName + formName: formName, + formId:currentRoute.value.meta.formId } }); } @@ -1007,7 +1018,8 @@ ${hasTemplatePrint ? ' reactive ' : ''} path: '/form/${lowerClassName}/0/createForm', query: { formPath: '${model.outputConfig.outputValue}/${lowerClassName}', - formName: formName + formName: formName, + formId:currentRoute.value.meta.formId } }); } @@ -1025,7 +1037,8 @@ ${hasTemplatePrint ? ' reactive ' : ''} path: '/form/${lowerClassName}/' + record.id + '/updateForm', query: { formPath: '${model.outputConfig.outputValue}/${lowerClassName}', - formName: formName + formName: formName, + formId:currentRoute.value.meta.formId } });` : ` @@ -1440,6 +1453,9 @@ ${hasTemplatePrint ? ' reactive ' : ''} } else { bus.on(FORM_LIST_MODIFIED, handleRefresh); } + + // 合并渲染覆盖配置中的列表配置,包括展示字段配置、搜索字段配置、按钮配置 + mergeCustomListRenderConfig(); }); onUnmounted(() => { if (schemaIdComputedRef.value) { @@ -1587,6 +1603,21 @@ ${hasTemplatePrint ? ' reactive ' : ''} ` : '' } + + async function mergeCustomListRenderConfig(){ + if (formConfig.useCustomConfig) { + let formId=currentRoute.value.meta.formId; + //1.合并展示字段配置 + let cols= await mergeColumns(customConfigColums.value,formId); + customConfigColums.value=cols; + //2.合并搜索字段配置 + let sFormSchema= await mergeSearchFormSchema(customSearchFormSchema.value,formId); + customSearchFormSchema.value=sFormSchema; + //3.合并按钮配置 + let btns= await mergeButtons(buttons.value,formId); + buttons.value=btns; + } + }; `; - return code; + return code.replace(/(\n\s*\n\s*\n)+/g, '\n'); } /** * 构建SimpleForm页面 @@ -1640,8 +1671,8 @@ export function buildSimpleFormCode(model: GeneratorConfig, _tableInfo: TableInf /> diff --git a/src/views/form/design/tabpanes/ZeroCodeTypeTabPane.vue b/src/views/form/design/tabpanes/ZeroCodeTypeTabPane.vue new file mode 100644 index 0000000..85543b0 --- /dev/null +++ b/src/views/form/design/tabpanes/ZeroCodeTypeTabPane.vue @@ -0,0 +1,356 @@ + + + + + diff --git a/src/views/secondDev/LoginForm.vue b/src/views/secondDev/LoginForm.vue index b5d1af0..67ecfc7 100644 --- a/src/views/secondDev/LoginForm.vue +++ b/src/views/secondDev/LoginForm.vue @@ -34,7 +34,7 @@ - + +
+
导出所选项目{{configType}}
+
+ + + + +
+
+ + + + + diff --git a/src/views/system/dataMigration/components/import/ImportSystemConfig.vue b/src/views/system/dataMigration/components/import/ImportSystemConfig.vue new file mode 100644 index 0000000..6509b0a --- /dev/null +++ b/src/views/system/dataMigration/components/import/ImportSystemConfig.vue @@ -0,0 +1,184 @@ + + + + diff --git a/src/views/system/dataMigration/components/import/index.vue b/src/views/system/dataMigration/components/import/index.vue new file mode 100644 index 0000000..b6b195b --- /dev/null +++ b/src/views/system/dataMigration/components/import/index.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/src/views/system/dataMigration/index.vue b/src/views/system/dataMigration/index.vue new file mode 100644 index 0000000..96a1e5d --- /dev/null +++ b/src/views/system/dataMigration/index.vue @@ -0,0 +1,91 @@ + + + + diff --git a/src/views/workflow/design/bpmn/panel/process/basic/Index.vue b/src/views/workflow/design/bpmn/panel/process/basic/Index.vue index f7b23c0..7d534de 100644 --- a/src/views/workflow/design/bpmn/panel/process/basic/Index.vue +++ b/src/views/workflow/design/bpmn/panel/process/basic/Index.vue @@ -70,7 +70,7 @@ getCategoryList(); async function getCategoryList() { categoryOptions.value = (await getDicDetailList({ - itemId: FlowCategory.ID, + itemCode: FlowCategory.CODE, })) as unknown as TreeItem[]; } diff --git a/src/views/workflow/design/index.vue b/src/views/workflow/design/index.vue index f9d8ab7..3bc11ee 100644 --- a/src/views/workflow/design/index.vue +++ b/src/views/workflow/design/index.vue @@ -296,7 +296,7 @@ async function getCategoryTree() { let res = (await getDicDetailList({ - itemId: FlowCategory.ID, + itemCode: FlowCategory.CODE, })) as unknown as TreeItem[]; data.treeData = res.map((ele) => { ele.icon = 'ant-design:tags-outlined'; diff --git a/src/views/workflow/task/components/processTasks/ToDoTasksV2.vue b/src/views/workflow/task/components/processTasks/ToDoTasksV2.vue index fa51d09..95b90ed 100644 --- a/src/views/workflow/task/components/processTasks/ToDoTasksV2.vue +++ b/src/views/workflow/task/components/processTasks/ToDoTasksV2.vue @@ -30,11 +30,22 @@ import { getSchemaTask } from '/@/api/workflow/process'; import { TaskTypeUrl } from '/@/enums/workflowEnum'; import { useI18n } from '/@/hooks/web/useI18n'; - import { unref, watch, onMounted, onUnmounted } from 'vue'; + import { unref, watch, onMounted, onUnmounted ,h} from 'vue'; import { useRouter } from 'vue-router'; import useEventBus from '/@/hooks/event/useEventBus'; + import { getAppEnvConfig } from '/@/utils/env'; + import { storeToRefs } from 'pinia'; + import { useUserStore } from '/@/store/modules/user'; + import {useMessage} from "/@/hooks/web/useMessage"; + import {useTenantManager} from "/@/utils/tenantManager"; + const router = useRouter(); + const { currentRoute } = router; const { t } = useI18n(); + const userStore = useUserStore(); + const { userInfo } = storeToRefs(userStore); + + const configColumns: BasicColumn[] = [ { title: t('流水号'), @@ -112,9 +123,8 @@ setting: false } }); - const router = useRouter(); - const { currentRoute } = router; - + + const {toggleLocal}=useTenantManager(); onMounted(() => { bus.on(FLOW_PROCESSED, onFlowProcessed); @@ -131,18 +141,66 @@ { deep: true } ); const onRowDblClick = (record, index) => { - const { processId, taskId, schemaId } = record; + const {tenantId,tenantCode,tenantName} = record; + let tenantEnabled=getAppEnvConfig().VITE_GLOB_TENANT_ENABLED; + if(tenantEnabled =='true'&&tenantId){ + let currentTenantId=userInfo.value.tenantId; + if(tenantId!=currentTenantId){ + const { createConfirm} = useMessage(); + createConfirm({ + iconType: 'warning', + title: () => h('span', t('温馨提醒')), + content: () => h('div', [ + h('span', t(`当前流程的发起租户是"${tenantName}",需要切换到该租户才能对该流程进行审批`)), + h('br'), + h('span', t('是否确认切换租户?未保存的数据可能会丢失!')) + ]), + width:'600px', + onOk: async () => { + switchTenant(tenantCode).then(()=>{ + openDetailPage(record,true); + }) + + }, + okText: () => t('确认'), + cancelText: () => t('取消'), + }); + + }else{ + openDetailPage(record); + }; + }else{ + openDetailPage(record); + } + }; + + function openDetailPage(record,isTenantSwitch){ + const { processId, taskId, schemaId} = record; router.push({ path: `/flow/${schemaId}/${processId}/approveFlow`, query: { taskId } + }).then(()=> { + if (isTenantSwitch) { + const {notification} = useMessage(); + const {tenantName} = record; + notification.success({ + message: 'Tip', + description: t('已切换到租户“' + tenantName + '"'), + }); + } }); - }; + } function onFlowProcessed() { reload(); } + + async function switchTenant(tenantCode: string) { + await toggleLocal({tenantCode:tenantCode, goHome:false,tabCloseAction:"closeOther"}); + } +