ludc
2023-06-15 55517e16da5e7205770bf61fc27c3d06b7d189b5
bug修改
已修改79个文件
已添加60个文件
27455 ■■■■■ 文件已修改
Source/UBCS-WEB/package-lock.json 16956 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/api/GetItem.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/api/omd/OmdAttribute.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/api/system/dept.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/api/system/passwords.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/api/template/setPersonnel.js 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/Crud/Crud.vue 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/FormTemplate/index.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/Master/MasterTree.vue 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/Tree/TemplatePro.vue 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/Tree/attrCrud.vue 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/Tree/classifyTrees.vue 108 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/components/ContextMenu.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/components/ContextMenuItem.vue 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/components/CustomCommand.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/components/DetailForm.vue 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/components/DetailPanel.vue 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/components/EditorMinimap.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/components/Icon.vue 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/components/ItemPanel.vue 485 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/components/Toolbar.vue 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/components/ToolbarButton.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/flowchartEditor.vue 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/flow-cycle/iconfont.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/refer/vciWebReferDefalut.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/refer/vciWebReferTable.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/refer/vciWebReferTree.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/template/FlowPath.vue 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/template/SetPersonnel.vue 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/template/Stage.vue 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/template/TableTransfer.vue 106 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/MasterData/FormTempalteTest.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/MasterData/items.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/flow/flowPath.vue 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/integration/applicationForm.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/integration/systemInfo.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/modeling/Business.vue 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/modeling/LinkType.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/modeling/Version.vue 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/modeling/cycle.vue 333 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/modeling/original.vue 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/modeling/originalAdd.vue 167 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/modeling/status.vue 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/system/PasswordManagement/passwords.vue 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/system/dept.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/system/user.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/vue.config.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-flow-api/pom.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/bo/FileObjectBO.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/constant/FileBusConstant.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/constant/FileLifeConstant.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/dto/FileObjectDTO.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/dto/FileReleaseDTO.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/dto/FileShareDTO.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/entity/FileObject.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/life/FileLife.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/query/FileQuery.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/utils/FileDownloadUtil.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/utils/FileUtil.java 388 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/utils/ZipUtil.java 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/vo/FileObjectVO.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/controller/WorkController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/service/impl/FlowBusinessServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowModelController.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowProcessController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowTaskUserController.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/ProcessTSController.java 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUser.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUserC.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessStageAttr.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessTemplate.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowTaskUserMapper.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessStageAttrMapper.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessTemplateMapper.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowEngineService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowTaskUserService.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessStageAttrService.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessTemplateService.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowEngineServiceImpl.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowTaskUserServiceImpl.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessStageAttrServiceImpl.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessTemplateServiceImpl.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/AttachController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/FileController.java 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/endpoint/OssEndpoint.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/mapper/FileObjectMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/service/IFileService.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/service/impl/FileServiceImpl.java 536 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-code-api/src/main/java/com/vci/ubcs/code/bo/AttributeValue.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-code-api/src/main/java/com/vci/ubcs/code/vo/pagemodel/CodeImportTemplateVO.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-omd-api/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-omd-api/src/main/java/com/vci/ubcs/omd/feign/IWebSecretClient.java 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-omd-api/src/main/java/com/vci/ubcs/omd/feign/IWebSecretFallback.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-omd-api/src/main/java/com/vci/ubcs/omd/util/Tool.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-omd-api/src/main/java/com/vci/ubcs/omd/utils/VciOmdUtil.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/poi/util/ExcelUtil.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/util/DefaultAttrAssimtUtil.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/constant/FrameWorkBusLangCodeConstant.java 519 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/BaseEnum.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/DataSecretEnum.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/NewAppConstantEnum.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/ProcessTemplateTypeEnum.java 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/util/VciBaseUtil.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/util/WebUtil.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-workflow-api/src/main/java/com/vci/ubcs/code/constant/FlowConstant.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/mapper/CommonsMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/ICodeClassifyService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/MdmEngineService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyServiceImpl.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java 304 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmIOServiceImpl.java 1161 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/util/AttributeChecker.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/util/ClientBusinessObject.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/controller/AttributeController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/controller/RevisionRuleController.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/controller/StatusController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/feign/RevisionRuleClient.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/feign/StatusClient.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/feign/WebSecretClient.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/mapper/RevisionRuleMapper.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/mapper/StatusMapper.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/IAttributeService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/IRevisionRuleService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/IStatusService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/IWebSecretService.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/impl/AttributeServiceImpl.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/impl/RevisionRuleServiceImpl.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/impl/StatusServiceImpl.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/impl/WebSecretServiceImpl.java 376 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/resources/mapper/RevisionRuleMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-omd/src/main/resources/mapper/StatusMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/UserPwdstrategyController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/service/impl/UserServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/wrapper/UserWrapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/package-lock.json
ÎļþÌ«´ó
Source/UBCS-WEB/package.json
@@ -29,6 +29,7 @@
    "script-loader": "^0.7.2",
    "vue": "^2.6.10",
    "vue-axios": "^2.1.2",
    "vue-flowchart-editor": "^1.0.2",
    "vue-i18n": "^8.7.0",
    "vue-router": "^3.0.1",
    "vuex": "^3.1.1"
Source/UBCS-WEB/src/api/GetItem.js
@@ -2,7 +2,7 @@
export const MasterTable =(params)=>{
  return request({
    url: 'api/ubcs-code/ubcs-code/mdmEngineController/getUIInfoByClassifyOid',
    url: 'api/ubcs-code/mdmEngineController/getUIInfoByClassifyOid',
    method: 'get',
    params:{
      ...params
@@ -12,7 +12,7 @@
export const TableData =(params)=>{
  return request({
    url: 'api/ubcs-code/ubcs-code/mdmEngineController/gridTableDataByClassifyOid',
    url: 'api/ubcs-code/mdmEngineController/gridTableDataByClassifyOid',
    method: 'get',
    params:{
      ...params
Source/UBCS-WEB/src/api/omd/OmdAttribute.js
@@ -24,12 +24,12 @@
  })
}
export const remove = (ids) => {
export const remove = (oid) => {
  return request({
    url: '/api/ubcs-omd/attribute/remove',
    method: 'post',
    params: {
      ids,
      oid,
    }
  })
}
Source/UBCS-WEB/src/api/system/dept.js
@@ -12,13 +12,15 @@
  })
}
export const getLazyList = (parentId, params) => {
export const getLazyList = (parentId, params,current, size,) => {
  return request({
    url: '/api/ubcs-system/dept/lazy-list',
    method: 'get',
    params: {
      ...params,
      parentId
      parentId,
      current,
      size
    }
  })
}
Source/UBCS-WEB/src/api/system/passwords.js
@@ -49,3 +49,10 @@
    }
  })
}
export const combination = () => {
  return request({
    url: '/api/ubcs-system/combination/select',
    method: 'get',
  })
}
Source/UBCS-WEB/src/api/template/setPersonnel.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
import request from '@/router/axios';
// äººå‘˜è®¾ç½®åˆå§‹åŒ–
export const personnelInit = (params) => {
  return request({
    url: '/api/ubcs-flow/taskUser/list',
    method: 'get',
    params: params
  })
}
// äººå‘˜è®¾ç½®æ”¶è—
export const personnelCollect = (params) => {
  return request({
    url: '/api/ubcs-flow/taskUser/su',
    method: 'post',
    data: params
  })
}
// äººå‘˜è®¾ç½®å–消收藏
export const cancelCollect = (params) => {
  return request({
    url: '/api/ubcs-flow/taskUser/du',
    method: 'post',
    data: params
  })
}
// äººå‘˜è®¾ç½®ä¿å­˜
export const personnelSave = (params) => {
  return request({
    url: '/api/ubcs-flow/vciflow/start',
    method: 'get',
    params: params
  })
}
// äººå‘˜è®¾ç½®ä¿å­˜
export const personnelDict = (params) => {
    return request({
      url: '/api/ubcs-user/allPage',
      method: 'get',
      params: params
    })
  }
Source/UBCS-WEB/src/components/Crud/Crud.vue
@@ -6,7 +6,7 @@
          <FormTemplateDialog
            :visible.sync="addvisible"
            :type="add"
            :templateOid="this.templateOid"
            :templateOid="templateOid"
            :codeClassifyOid="this.codeClassifyOid"
            :codeRuleOid="this.codeRuleOid"
            :disabledProp="disabledProp"
@@ -16,7 +16,7 @@
          <FormTemplateDialog
            :visible.sync="editvisible"
            :type="edit"
            :templateOid="this.templateOids"
            :templateOid="templateOid"
            :codeClassifyOid="this.codeClassifyOid"
            :codeRuleOid="this.codeRuleOid"
            :disabledProp="disabledProp"
@@ -30,20 +30,24 @@
        <el-button size="small" type="primary" plain>删除</el-button>
        <el-button size="small" type="primary" plain>发布</el-button>
        <el-button size="small" type="primary" plain>数据更改</el-button>
        <el-button size="small" type="primary" plain>回收</el-button>
        <el-button size="small" type="primary" plain @click="huishouHandler">回收</el-button>
        <el-button size="small" type="primary" plain @click="openD">导出
          <integration-transfer :visible.sync="dialogPush" :data="transferData"
                                :props="transferProps" @save="handelTransferSave"></integration-transfer>
        </el-button>
        <el-button size="small" type="primary" plain @click="findvisible=true">查询
<<<<<<< HEAD
        <advanced-query  :visible.sync="findvisible" :options="options"></advanced-query>
=======
        <advanced-query  :visible.sync="findvisible" :options="this.options"></advanced-query>
>>>>>>> 859a64b36d107b147f44eccd0c0a76471c5e49ea
        </el-button>
        <el-button size="small" type="primary" plain>相似项查询</el-button>
        <el-button size="small" type="primary" plain style="margin-left: 1px;margin-top:10px">刷新</el-button>
        <el-input placeholder="请输入关键字按回车查询" style="width: 180px;margin-left: 5px;margin-top:10px" size="small"></el-input>
      </div>
      <el-row style="height: 700px;width: 100%">
        <el-table :data="tableData" style="" @cell-click="handleCellClick" max-height="700"  @selection-change="handleSelectionChange"  @sort-change="sortChange">
        <el-table :data="tableData" style="" @cell-click="handleCellClick" max-height="700"  v-loading="isLoading"  @selection-change="handleSelectionChange"  @sort-change="sortChange">
          <el-table-column
            type="selection"
            fixed
@@ -113,15 +117,20 @@
    },
    tableDataArray:{
      type:Array,
      default:[]
    },
    total:{
      type:String,
      default:""
    },
    templateOid:{
      type:String,
    },
    tableHeadDataFateher:{
      type:Array,
      default:[]
    },
    isLoading:{
      type:Boolean,
      default:false
    }
  },
  data() {
@@ -141,7 +150,6 @@
      editingRow:null,
      editShow: "",
      editAttr:"",
      loading: false,
      data: [],
      options:[],
      option: {
@@ -157,7 +165,6 @@
      },
      tableData:[],
      tableHeadData:[],
      tableHeadDataFateher:[],
      items:{},
      seniorQueryColumns:[]
    }
@@ -193,13 +200,30 @@
        this.page.total=newval;
      }
    },
    tableHeadData:{
    tableHeadDataFateher:{
      handler(newval,oldval){
        this.tableHeadDataFateher=newval
        let List=newval.tableDefineVO.cols[0];
        List.forEach(item=>{
          let columnItem = {
            label: item.title,
            prop: item.field,
            type: this.columnType[item.type],
            sortable: item.sort,
            width: item.minWidth
          };
          this.option.column.push(columnItem);
          this.option.column=this.tableHeadData;
        })
      }
    }
  },
  methods: {
    huishouHandler(){
      console.log('tem',this.templateOid)
      console.log('table',this.tableData)
      console.log('tabheadle',this.tableHeadData)
      console.log('tableFather',this.tableHeadDataFateher)
    },
    openD(){
      this.dialogPush=true;
      this.getListCodeByClassId()
@@ -219,25 +243,20 @@
      this.page.pageSize=val
      this.$emit('pageSize',val)
      this.CrudRend()
      console.log(this.tableData)
    },
    handleCurrentChange(val){
      this.page.currentPage=val
      this.$emit('currentPage',val)
      this.CrudRend()
      console.log(val)
      console.log(this.tableData)
    },
    // ç›‘听单元格点击事件并存储正在编辑的行
    handleCellClick(row, column) {
      this.editingRow = row;
      this.editShow = column.property;
      console.log(row)
      this.rowOid=row.oid
    },
    //删除
    enumDeleteRow(row) {
      console.log(row)
      this.tableData.splice(row, 1)
    },
    // å°†æ­£åœ¨ç¼–辑的行的状态变为 null ï¼Œå³é€€å‡ºç¼–辑状态
@@ -285,7 +304,6 @@
            this.option.column=this.tableHeadData;
            this.templateOid=res.data.tableDefineVO.oid
            this.$emit('templateOid',this.templateOid)
            console.log(this.templateOid)
          })
        })
      }
@@ -305,7 +323,7 @@
    },
    // æŽ’序
    sortChange(val) {
      this.loading = true;
      this.isLoading = true;
      let order = ""
      if (val.order == "ascending") {
        order = "asc";
@@ -322,7 +340,7 @@
      }).then(res => {
        setTimeout(() => {
          this.data = res.data.data;
          this.loading = false;
          this.isLoading = false;
        }, 100);
      })
    },
Source/UBCS-WEB/src/components/FormTemplate/index.vue
@@ -25,7 +25,8 @@
      v-if="
        type !== 'detail' &&
        dialogVisible &&
        (showCodeApply || showResembleQuery)
        (showCodeApply || showResembleQuery) &&
        type !== 'preview'
      "
    >
      <el-tabs v-model="activeName" type="border-card" @tab-click="handleClick">
@@ -59,7 +60,7 @@
    <div class="avue-dialog__footer" v-if="type !== 'detail'">
      <el-button @click="close()">取 æ¶ˆ</el-button>
      <el-button @click="submit()" type="primary" :loading="submitBtnLoading"
        >ç¡® å®š</el-button
        >{{ submitText }}</el-button
      >
      <el-button
        @click="resembleQuerySubmit"
@@ -104,6 +105,10 @@
      type: String,
      default: "",
    },
    submitText: {
      type: String,
      default: 'ç¡® å®š'
    }
  },
  data() {
    return {
Source/UBCS-WEB/src/components/Master/MasterTree.vue
@@ -82,7 +82,6 @@
        this.coderuleoid=res.data[0].attributes.coderuleoid;
        this.$emit("codeClassifyOid", this.codeClassifyOid )
        this.$emit("coderuleoid", this.coderuleoid )
        this.TableHeadRends()
      }).catch(res=>{
        console.log(res)
      })
@@ -108,44 +107,40 @@
        page: this.currentPage,
        limit: this.pageSize,
      }).then(res => {
        // this.page.total = res.data.total;
        // this.data = res.data.data;
        this.tableDataArray=res.data.data;
        this.$emit('tableDataArray',this.tableDataArray)
        this.$emit('total',res.data.total)
        console.log('table',this.tableDataArray)
      })
    },
    //表格头部
    TableHeadRend(){
      MasterTable({
        codeClassifyOid:this.nodeClickList.oid,
        functionId: 5,
      }).then(res=>{
        this.tableHeadDataFateher=res.data;
        this.templateOids=res.data.tableDefineVO.oid
        this.$emit("tableHeadDataFateher",this.tableHeadDataFateher)
        console.log("123",res)
      })
    },
    TableHeadRends(){
      MasterTable({
        codeClassifyOid:this.codeClassifyOid,
        functionId: 5,
      }).then(res=>{
        this.tableHeadDataFateher=res.data;
        this.templateOids=res.data.tableDefineVO.oid
        this.$emit("tableHeadDataFateher",this.tableHeadDataFateher)
        console.log("123",res)
    TableHeadRend() {
      return new Promise((resolve,reject)=>{
        MasterTable({
          codeClassifyOid: this.nodeClickList.oid,
          functionId: 5,
        }).then(res => {
          this.tableHeadDataFateher = res.data;
          this.templateOids = res.data.tableDefineVO.oid;
          this.$emit('tableHeadDataFateher', this.tableHeadDataFateher);
          resolve();
        }).catch(err=>{
          reject(err)
        })
      })
    },
    //树点击事件
    nodeClick(data){
      this.nodeClickList = data;
       this.TableHeadRend()
      this.TableRend()
      console.log('code',this.nodeClickList.oid)
      console.log('teoid',this.templateOids)
      console.log()
    async nodeClick(data) {
      try {
        this.nodeClickList = data;
        await this.TableHeadRend(); // å…ˆæ‰§è¡Œ TableHeadRend()
        this.TableRend(); // TableHeadRend() æ–¹æ³•完成后再执行 TableRend()
        this.$emit('nodeClick',this.templateOids)
        console.log(this.templateOids)
      } catch (error) {
        // å¤„理错误
        this.$message.error(error)
      }
    }
  }
}
Source/UBCS-WEB/src/components/Tree/TemplatePro.vue
@@ -5,11 +5,11 @@
      <attrCrud :ProData="ProData" :crudOid="crudOid" :crudArray="crudArray" :Formlist="Formlist" :codeClassifyOid="codeClassifyOid"></attrCrud>
    </span>
    <span v-else-if="type.prop==='tab2'">
       <FlowPath code="8b5e2017-990f-454a-9c39-4c4eeeb57553"></FlowPath>
       <FlowPath :code="this.codeClassifyOid"></FlowPath>
    </span>
    <span v-else-if="type.prop==='tab3'">
<!--          <stage :visible.sync="visibleStage" code="8b5e2017-990f-454a-9c39-4c4eeeb57553"></stage>-->
          <stage  :code="this.codeClassifyOid"></stage>
    </span>
  </basic-container>
@@ -51,318 +51,6 @@
  }
}
</script>
<!--<template>-->
<!--  &lt;!&ndash; ä½¿ç”¨ Element UI çš„表格组件展示数据 &ndash;&gt;-->
<!--  &lt;!&ndash; å¯¹æ¯è¡Œæ•°æ®æ¸²æŸ“一个表格行组件 &ndash;&gt;-->
<!--  <el-table :data="data">-->
<!--    <el-table-column v-for="column in columns" :key="column.prop" :label="column.label">-->
<!--      <template slot-scope="scope">-->
<!--        <template v-if="isEditing(scope.$index, column.prop)">-->
<!--          &lt;!&ndash; ä½¿ç”¨è‡ªå®šä¹‰è¾“入框,绑定数据并监听 blur äº‹ä»¶ &ndash;&gt;-->
<!--          <el-input v-model="editorModel[scope.$index][column.prop]" ref="editor"-->
<!--                    @blur="onEditorBlur(scope.$index, column.prop)">-->
<!--          </el-input>-->
<!--        </template>-->
<!--        <template v-else>-->
<!--          &lt;!&ndash; å°†æ•°æ®æ¸²æŸ“为表格单元格,绑定 click äº‹ä»¶ &ndash;&gt;-->
<!--          <div @click="onCellClick(scope.$index, column.prop)"-->
<!--               :style="{cursor: 'pointer', backgroundColor: isEditing(scope.$index, column.prop) ? '#F0F0F0' : 'transparent'}">-->
<!--            {{ scope.row[column.prop] === "" ? '' : scope.row[column.prop] }}-->
<!--          </div>-->
<!--        </template>-->
<!--      </template>-->
<!--    </el-table-column>-->
<!--  </el-table>-->
<!--</template>-->
<!--<script>-->
<!--export default {-->
<!--  data() {-->
<!--    // ç»„件的数据,包括表格的数据、列定义和当前正在编辑的行和列-->
<!--    return {-->
<!--      data: [-->
<!--        { id: 1, name: '张三', age: 18, attributegroup: '男', attributeDataTypeText: '广东省深圳市' },-->
<!--        { id: 2, name: '李四', age: 20, attributegroup: '女', attributeDataTypeText: '北京市海淀区' },-->
<!--        { id: 3, name: '王五', age: 22, attributegroup: '男', attributeDataTypeText: '上海市浦东新区' },-->
<!--        { id: 4, name: '赵六', age: 24, attributegroup: '女', attributeDataTypeText: '广东省广州市' }-->
<!--      ],-->
<!--      columns: [  // å®šä¹‰è¡¨æ ¼çš„列-->
<!--        {-->
<!--          label: "属性英文编号",-->
<!--          prop: "id",-->
<!--          fixed: true,-->
<!--          cell: false,-->
<!--          labelWidth: 110,-->
<!--          width: 125,-->
<!--          sortable: true,-->
<!--        },-->
<!--        {-->
<!--          label: "属性中文名称",-->
<!--          prop: "name",-->
<!--          fixed: true,-->
<!--          cell: false,-->
<!--          width: 125,-->
<!--          sortable: true-->
<!--        },-->
<!--        {-->
<!--          label: "属性分组",-->
<!--          prop: "attributegroup",-->
<!--          cell: false,-->
<!--          sortable: true,-->
<!--          width: 125,-->
<!--        },-->
<!--        {-->
<!--          label: "类型",-->
<!--          prop: "attributeDataTypeText",-->
<!--          cell: false,-->
<!--          sortable: true,-->
<!--        },-->
<!--        {-->
<!--          label: "列表宽度",-->
<!--          prop: "attrTableWidth",-->
<!--          cell: false,-->
<!--          sortable: true,-->
<!--          width: 105,-->
<!--        },-->
<!--        {-->
<!--          label: "关键属性",-->
<!--          prop: "keyattrflag",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "查询属性",-->
<!--          prop: "queryattrflag",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "高级查询属性",-->
<!--          prop: "seniorqueryattrflag",-->
<!--          width: 95,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "相似查询属性",-->
<!--          prop: "samerepeatattrflag",-->
<!--          width: 95,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "必输",-->
<!--          prop: "requireflag",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "表单显示",-->
<!--          prop: "formdisplayflag",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "列表显示",-->
<!--          prop: "tabledisplayflag",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "只读",-->
<!--          prop: "readonlyflag",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "列表排序",-->
<!--          prop: "sortattrflag",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "多行文本",-->
<!--          prop: "textareaflag",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "默认值",-->
<!--          prop: "defaultvalue",-->
<!--          sortable: true,-->
<!--          cell: false,-->
<!--          width: 95,-->
<!--        },-->
<!--        {-->
<!--          label: "前缀",-->
<!--          prop: "prefixvalue",-->
<!--          sortable: true,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "后缀",-->
<!--          prop: "suffixvalue",-->
<!--          sortable: true,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "组合规则",-->
<!--          prop: "componentrule",-->
<!--          sortable: true,-->
<!--          cell: false,-->
<!--          width: 105,-->
<!--        },-->
<!--        {-->
<!--          label: "验证规则",-->
<!--          prop: "verifyrule",-->
<!--          sortable: true,-->
<!--          cell: false,-->
<!--          width: 105,-->
<!--        },-->
<!--        {-->
<!--          label: "时间格式",-->
<!--          prop: "codedateformat",-->
<!--          sortable: true,-->
<!--          width: 105,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "分类注入",-->
<!--          prop: "classifyinvokelevel",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "枚举注入",-->
<!--          prop: "enumString",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "级联属性",-->
<!--          prop: "parentCode",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "参照配置",-->
<!--          prop: "referConfig",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "级联查询属性",-->
<!--          prop: "parentQueryAttr",-->
<!--          width: 105,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "选择库标识",-->
<!--          prop: "libraryIdentification",-->
<!--          width: 105,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "填写提示",-->
<!--          prop: "explain",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "表单显示样式",-->
<!--          prop: "formdisplaystyle",-->
<!--          width: 105,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "表格显示样式",-->
<!--          prop: "tabledisplaystyle",-->
<!--          width: 105,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "表单超链接",-->
<!--          prop: "formhref",-->
<!--          width: 95,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "表格超链接",-->
<!--          prop: "tablehref",-->
<!--          width: 95,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "表格显示js",-->
<!--          prop: "tabledisplayjs",-->
<!--          width: 95,-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "长度",-->
<!--          prop: "controllength",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "小数精度",-->
<!--          prop: "precisionlength",-->
<!--          cell: false,-->
<!--        },-->
<!--        {-->
<!--          label: "取值范围",-->
<!--          prop: "valuearea",-->
<!--          sortable: true,-->
<!--          cell: false,-->
<!--          width: 105,-->
<!--        },-->
<!--      ],-->
<!--      editingIndex: -1,  // å½“前正在编辑的行的索引-->
<!--      editingColumn: '',  // å½“前正在编辑的列的属性名-->
<!--      editorModel: []  // ç¼–辑框的数据,使用数组保存每个单元格的数据-->
<!--    };-->
<!--  },-->
<!--  created() {-->
<!--    // åœ¨ç»„件创建时,初始化编辑框的数据-->
<!--    this.editorModel = this.data.map(row => {-->
<!--      const editorRow = {};-->
<!--      this.columns.forEach(column => {-->
<!--        editorRow[column.prop] = row[column.prop];-->
<!--      });-->
<!--      return editorRow;-->
<!--    });-->
<!--  },-->
<!--  methods: {-->
<!--    // å•元格点击事件处理函数-->
<!--    onCellClick(rowIndex, columnProp) {-->
<!--      if (this.editingIndex >= 0 && this.editingColumn) {-->
<!--        this.onEditorBlur(this.editingIndex, this.editingColumn);-->
<!--        return;-->
<!--      }-->
<!--      const cellValue = this.data[rowIndex][columnProp];-->
<!--      if (cellValue === undefined || cellValue === null) {-->
<!--        this.data[rowIndex][columnProp] = '';-->
<!--      }-->
<!--      this.editingIndex = rowIndex;-->
<!--      this.editingColumn = columnProp;-->
<!--      this.$nextTick(() => {-->
<!--        this.$refs.editor.focus();-->
<!--      });-->
<!--    },-->
<!--    // ç¼–辑框失焦事件处理函数-->
<!--    onEditorBlur(rowIndex, columnProp) {-->
<!--      // å°†å½“前编辑框的数据保存到表格数据中-->
<!--      const editorValue = this.editorModel[rowIndex][columnProp];-->
<!--      if (editorValue === '') {-->
<!--        this.data[rowIndex][columnProp] = undefined;-->
<!--      } else {-->
<!--        this.data[rowIndex][columnProp] = editorValue;-->
<!--      }-->
<!--      this.editingIndex = -1;-->
<!--      this.editingColumn = '';-->
<!--    },-->
<!--    // åˆ¤æ–­æŒ‡å®šå•元格是否在编辑状态-->
<!--    isEditing(rowIndex, columnProp) {-->
<!--      return rowIndex === this.editingIndex && columnProp === this.editingColumn;-->
<!--    }-->
<!--  }-->
<!--};-->
<!--</script>-->
<style lang="scss">
//修改分类注入对话框公共样式
.mydialog .el-dialog__body {
Source/UBCS-WEB/src/components/Tree/attrCrud.vue
@@ -33,8 +33,12 @@
    </template>
<!--    ç»„合规则-->
    <template slot="menuLeft">
      <el-button size="small" @click="isShowformulaEdit=true">组合规则</el-button>
        <formula-editor :visible.sync="isShowformulaEdit" :systemVariableTableData="systemVariableTableData" :thisSceneTableData="thisSceneTableData"></formula-editor>
      <el-button size="small" @click="isShowHandler">组合规则</el-button>
        <formula-editor :visible.sync="isShowformulaEdit"
                        :systemVariableTableData="systemVariableTableData"
                        :thisSceneTableData="thisSceneTableData"
                        @updateFormulaContent="updataFormlaContent"
        ></formula-editor>
    </template>
    <!--        éªŒè¯è§„则-->
@@ -266,6 +270,7 @@
      type:Boolean,
      default:false
    },
  },
  data() {
    return {
@@ -696,20 +701,130 @@
          },
          {
            label: "使用说明",
            prop: "shiyong"
            prop: "description"
          }
        ]
      },
      //属性验证规则data
      rulesData: [
        {
          bds: "测试一",
          shiyong: "测试一"
        },
        {bds: '[\u3000\uff01-\uff5f]+', description: '全角符号'},
    {bds: '[^\u3000\uff01-\uff5f]+', description: '半角符号'},
    {bds: '(([-|+]{1}[\\d]+℃~[-|+]{1}[\\d]+℃)|无)', description: '温度范围,示例 -55℃~+125℃'},
    {bds: '[\\d]{15}|[\\d]{18}|[\\d]{17}X', description: '身份证号码(15或18位数字、17位数字X) '},
    {bds: '男|女|男性|女性', description: '中文性别'},
    {bds: '[\\d]+', description: '数字'},
    {bds: '[a-zA-Z]+', description: '字母'},
    {bds: '[A-Z]+', description: '大写字母'},
    {bds: '[a-z]+', description: '小写字母'},
    {bds: '[0-9a-zA-Z]+', description: '字母、数字组合'},
    {bds: '((0[\\d]{3}-[\\d]{7})|(0[\\d]{2}-[\\d]{8})|([\\d]{7,8}))', description: '电话号码'},
    {bds: '-?[1-9]\\d*', description: '整数'},
    {bds: '[1-9]\\d*', description: '正整数'},
    {bds: '-[1-9]\\d*', description: '负整数'},
    {bds: '-[1-9]\\d*|0', description: '非正整数(负整数+0)'},
    {bds: '[1-9]\\d*|0', description: '非负整数(正整数+0)'},
    {bds: '-?([1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*|0?\\.0+|0)', description: '浮点数'},
    {bds: '[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*', description: '正浮点数'},
    {bds: '-[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*', description: '负浮点数'},
    {bds: '[(-([1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*))|0?\\.0+|0', description: '非正浮点数(负浮点数 + 0)'},
    {bds: '[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*|0?\\.0+|0', description: '非负浮点数(正浮点数 + 0)'},
    {bds: 'x', description: '字符 x'},
    {bds: '\\\\', description: '反斜线字符'},
    {bds: '\\0n', description: '带有八进制值 0 çš„字符 n (0 <= n <= 7)'},
    {bds: '\\0nn', description: '带有八进制值 0 çš„字符 nn (0 <= n <= 7)'},
    {bds: '\\0mnn', description: '带有八进制值 0 çš„字符 mnn(0 <= m <= 3、0 <= n <= 7)'},
    {bds: '\\xhh', description: '带有十六进制值 0x çš„字符 hh'},
    {bds: '\\uhhhh', description: '带有十六进制值 0x çš„字符 hhhh'},
    {bds: '\\t', description: '制表符 (\'\u0009\')'},
    {bds: '\\n', description: '新行(换行)符 (\'\u000A\')'},
    {bds: '\\r', description: '回车符 (\'\u000D\')'},
    {bds: '\\f', description: '换页符 (\'\u000C\')'},
    {bds: '\\a', description: '报警 (bell) ç¬¦ (\'\u0007\')'},
    {bds: '\\e', description: '转义符 (\'\u001B\')'},
    {bds: '\\cx', description: '对应于 x çš„æŽ§åˆ¶ç¬¦'},
    {bds: '[abc]', description: 'a、b æˆ– c(简单类)'},
    {bds: '[^abc]', description: '任何字符,除了 a、b æˆ– c(否定)'},
    {bds: '[a-zA-Z]', description: 'a åˆ° z æˆ– A åˆ° Z,两头的字母包括在内(范围)'},
    {bds: '[a-d[m-p]]', description: 'a åˆ° d æˆ– m åˆ° p:[a-dm-p](并集)'},
    {bds: '[a-z&&[def]]', description: '\td、e æˆ– f(交集)'},
    {bds: '[a-z&&[^bc]]', description: 'a åˆ° z,除了 b å’Œ c:[ad-z](减去)'},
    {bds: '[a-z&&[^m-p]]', description: 'a åˆ° z,而非 m åˆ° p:[a-lq-z](减去)'},
    {bds: '.', description: '任何字符(与行结束符可能匹配也可能不匹配)'},
    {bds: '\\d', description: '数字:[0-9]'},
    {bds: '\\D', description: '非数字: [^0-9]'},
    {bds: '\\s', description: '空白字符:[ \\t\\n\x0B\\f\\r]'},
    {bds: '\\S', description: '非空白字符:[^\\s]'},
    {bds: '\\w', description: '单词字符:[a-zA-Z_0-9]'},
    {bds: '\\W', description: '非单词字符:[^\\w]'},
    {bds: '\\p{Lower}', description: '小写字母字符:[a-z]'},
    {bds: '\\p{Upper}', description: '大写字母字符:[A-Z]'},
    {bds: '\\p{ASCII}', description: '所有 ASCII:[\x00-\x7F]'},
    {bds: '\\p{Alpha}', description: '字母字符:[\\p{Lower}\\p{Upper}]'},
    {bds: '\\p{Digit}', description: '十进制数字:[0-9]'},
    {bds: '\\p{Alnum}', description: '字母数字字符:[\\p{Alpha}\\p{Digit}]'},
    {bds: '\\p{Punct}', description: '标点符号:!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'},
    {bds: '\\p{Graph}', description: '可见字符:[\\p{Alnum}\\p{Punct}]'},
    {bds: '\\p{Print}', description: '可打印字符:[\\p{Graph}\x20]'},
    {bds: '\\p{Blank}', description: '空格或制表符:[ \\t]'},
    {bds: '\\p{Cntrl}', description: '控制字符:[\x00-\x1F\x7F]'},
    {bds: '\\p{XDigit}', description: '十六进制数字:[0-9a-fA-F]'},
    {bds: '\\p{Space}', description: '空白字符:[ \\t\\n\x0B\\f\\r]'},
    {bds: '\\p{javaLowerCase}', description: '等效于 java.lang.Character.isLowerCase()'},
    {bds: '\\p{javaUpperCase}', description: '等效于 java.lang.Character.isUpperCase()'},
    {bds: '\\p{javaWhitespace}', description: '等效于 java.lang.Character.isWhitespace()'},
    {bds: '\\p{javaMirrored}', description: '等效于 java.lang.Character.isMirrored()'},
    {bds: '\\p{InGreek}', description: 'Greek å—(简单块)中的字符'},
    {bds: '\\p{Lu}', description: '大写字母(简单类别)'},
    {bds: '\\p{Sc}', description: '货币符号'},
    {bds: '\\P{InGreek}', description: '所有字符,Greek å—中的除外(否定)'},
    {bds: '[\\p{L}&&[^\\p{Lu}]]', description: '所有字母,大写字母除外(减去)'},
    {bds: '^', description: '行的开头'},
    {bds: '$', description: '行的结尾'},
    {bds: '\\b', description: '单词边界'},
    {bds: '\\B', description: '非单词边界'},
    {bds: '\\A', description: '输入的开头'},
    {bds: '\\G', description: '上一个匹配的结尾'},
    {bds: '\\Z', description: '输入的结尾,仅用于最后的结束符(如果有的话)'},
    {bds: '\\z', description: '输入的结尾'},
    {bds: 'X ?', description: 'X,一次或一次也没有'},
    {bds: 'X *', description: 'X,零次或多次'},
    {bds: 'X +', description: 'X,一次或多次'},
    {bds: 'X {n }', description: 'X,恰好 n æ¬¡'},
    {bds: 'X {n ,}', description: 'X,至少 n æ¬¡'},
    {bds: 'X {n ,m }', description: 'X,至少 n æ¬¡ï¼Œä½†æ˜¯ä¸è¶…过 m æ¬¡'},
    {bds: 'X ??', description: 'X,一次或一次也没有'},
    {bds: 'X *?', description: 'X,零次或多次'},
    {bds: 'X +?', description: 'X,一次或多次'},
    {bds: 'X {n }?', description: 'X,恰好 n æ¬¡'},
    {bds: 'X {n ,}?', description: 'X,至少 n æ¬¡'},
    {bds: 'X {n ,m }?', description: 'X,至少 n æ¬¡ï¼Œä½†æ˜¯ä¸è¶…过 m æ¬¡'},
    {bds: 'X ?+', description: 'X,一次或一次也没有'},
    {bds: 'X *+', description: 'X,零次或多次'},
    {bds: 'X ++', description: 'X,一次或多次'},
    {bds: 'X {n }+', description: 'X,恰好 n æ¬¡'},
    {bds: 'X {n ,}+', description: 'X,至少 n æ¬¡'},
    {bds: 'X {n ,m }+', description: 'X,至少 n æ¬¡ï¼Œä½†æ˜¯ä¸è¶…过 m æ¬¡'},
    {bds: 'XY', description: 'X åŽè·Ÿ Y'},
    {bds: 'X |Y', description: 'X æˆ– Y'},
    {bds: '(X )', description: 'X,作为捕获组'},
    {bds: '\\n', description: '任何匹配的 n<sup>th</sup> æ•获组'},
    {bds: '\\', description: 'Nothing,但是引用以下字符'},
    {bds: '\\Q', description: 'Nothing,但是引用所有字符,直到 \\E'},
    {bds: '\\E', description: 'Nothing,但是结束从 \\Q å¼€å§‹çš„引用'},
    {bds: '(?:X )', description: 'X,作为非捕获组'},
    {bds: '(?idmsux-idmsux)', description: 'Nothing,但是将匹配标志由 on è½¬ä¸º off'},
    {bds: '(?idmsux-idmsux:X )', description: 'X,作为带有给定标志 on - off çš„非捕获组'},
    {bds: '(?=X )', description: 'X,通过零宽度的正 lookahead'},
    {bds: '(?!X )', description: 'X,通过零宽度的负 lookahead'},
    {bds: '(?<=X )', description: 'X,通过零宽度的正 lookbehind'},
    {bds: '(?<!X )', description: 'X,通过零宽度的负 lookbehind'},
    {bds: '(?>X )', description: 'X,作为独立的非捕获组'}
      ],
      // æ–°å¢žä¸šåŠ¡ç±»åž‹
      businessData: [],
      businessOption: {
        indexClassName:"序号",
        indexLabelClassName:'序号',
        index: true,
        border: true,
        addBtn: false,
@@ -1178,7 +1293,9 @@
    },
    //验证规则检查
    rulesExamine() {
      if(this.RulesForm.expressionText.test(this.RulesForm.TestContent)){
        this.$message.success('校验成功')
      }
    },
    //点击分类注入按钮
    injectBtn(){
@@ -1273,6 +1390,16 @@
      //   console.log(res)
      // })
    },
    //组合规则
    isShowHandler(){
      if(this.CrudSelect.length>1){
        this.$message.warning('只能选择一条模板属性数据')
      }else if(this.CrudSelect.length<1){
        this.$message.warning('请选择一条模板属性数据')
      }else if(this.CrudSelect.length === 1){
       this.isShowformulaEdit=true;
      }
    },
    //全屏编辑
    fullscreenHandle(){
      if(this.crudArray.length<1){
@@ -1290,6 +1417,10 @@
      this.attrEditVisible=false;
      console.log(this.attrEditVisible)
    },
    updataFormlaContent(val){
      console.log(val)
      this.$set(this.attrRow,'componentRule',val)
    },
    // æŽ’序
    sortChange(val) {
      console.log(val)
Source/UBCS-WEB/src/components/Tree/classifyTrees.vue
@@ -77,7 +77,7 @@
                          @select="selectHandle"
               >
            <template slot="menuLeft">
              <el-button plain size="small" type="primary" @click="FindFormVisible = true;">查询</el-button>
              <el-button plain size="small" type="primary" @click="FindeHanler">查询</el-button>
              <el-button plain size="small" type="primary" @click="TemRefresh">刷新</el-button>
                    <el-button plain size="small" type="primary" @click="TreeEdit">修改</el-button>
            <el-button plain size="small" type="primary" @click="TreeDel">删除</el-button>
@@ -206,36 +206,36 @@
  inject: [, "crudTreeData"],
  data() {
    return {
      //表格option配置项
      crudTreeOption: {
        index: true,
        border: true,
        height:180,
        selection:true,
        addBtn:this.addFlag,
        column: [
          {
            label: "模板编号",
            prop: "id"
          },
          {
            label:"模板名称",
            prop:"name"
          },
          {
            label: "模板描述",
            prop:"description"
          },
          {
            label:"版本号",
            prop:"revisionSeq"
          },
          {
            label:"状态",
            prop:"lcStatusText"
          }
        ]
      },
      // //表格option配置项
      // crudTreeOption: {
      //   index: true,
      //   border: true,
      //   height:180,
      //   selection:true,
      //   addBtn:this.addFlag,
      //   column: [
      //     {
      //       label: "模板编号",
      //       prop: "id"
      //     },
      //     {
      //       label:"模板名称",
      //       prop:"name"
      //     },
      //     {
      //       label: "模板描述",
      //       prop:"description"
      //     },
      //     {
      //       label:"版本号",
      //       prop:"revisionSeq"
      //     },
      //     {
      //       label:"状态",
      //       prop:"lcStatusText"
      //     }
      //   ]
      // },
      addFlag:false,
      // è¡¨æ ¼å½“前行id
      crudOid:"",
@@ -433,6 +433,42 @@
  mounted() {
    this.type = this.tabOption.column[0];
    this.getAttr();
    console.log('11',this.nodeClickList)
  },
  computed:{
    crudTreeOption(){
      return{
        index: true,
        indexClassName:"序号",
        indexLabelClassName:'序号',
        border: true,
        height:180,
        selection:true,
        addBtn:this.Formlist.length<=0  && this.nodeClickList != "",
        column: [
          {
            label: "模板编号",
            prop: "id"
          },
          {
            label:"模板名称",
            prop:"name"
          },
          {
            label: "模板描述",
            prop:"description"
          },
          {
            label:"版本号",
            prop:"revisionSeq"
          },
          {
            label:"状态",
            prop:"lcStatusText"
          }
        ]
      }
    }
  },
  methods: {
    //行单选事件
@@ -639,7 +675,7 @@
    async nodeClick(data) {
      //定义一个模板属性id,数据是模板管理表格里面的oid
      this.nodeClickList = data
      console.log(data.oid)
      console.log(data)
      this.ProData=[]
      try {
        await TreeObjcet(data.oid).then(res => {
@@ -827,6 +863,14 @@
        })
      })
    },
    // æŸ¥è¯¢
    FindeHanler(){
      if(this.nodeClickList != ""){
        this.FindFormVisible=true
      }else {
        this.$message.warning('请从树上选择一条数据')
      }
    },
    //克隆模板选择确定
    Clonehandler(){
      if(this.CloneSelect.length <= 0){
Source/UBCS-WEB/src/components/flow-cycle/components/ContextMenu.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
<template>
  <context-menu class="contextMenu">
    <node-menu>
      <menu-li command="copy" text="拷贝" />
      <menu-li command="delete" text="删除" />
    </node-menu>
    <edge-menu>
      <menu-li command="delete" text="删除" />
    </edge-menu>
    <group-menu>
      <menu-li command="copy" text="拷贝" />
      <menu-li command="delete" text="删除" />
      <menu-li command="unGroup" icon="ungroup" text="取消编组" />
    </group-menu>
    <multi-menu>
      <menu-li command="copy" text="拷贝" />
      <menu-li command="paste" text="粘贴" />
      <menu-li command="addGroup" icon="group" text="编组" />
      <menu-li command="delete" text="删除" />
    </multi-menu>
    <canvas-menu>
      <menu-li command="undo" text="撤销" />
      <menu-li command="redo" text="重做" />
      <menu-li command="pasteHere" icon="paste" text="粘贴到这里" />
    </canvas-menu>
  </context-menu>
</template>
<script>
import {
  NodeMenu,
  EdgeMenu,
  GroupMenu,
  MultiMenu,
  CanvasMenu,
  ContextMenu,
} from 'vue-flowchart-editor'
import MenuLi from './ContextMenuItem'
export default {
  name: 'EditorContextMenu',
  components: {
    NodeMenu,
    EdgeMenu,
    GroupMenu,
    MultiMenu,
    CanvasMenu,
    ContextMenu,
    MenuLi,
  },
}
</script>
<style lang="scss" scoped>
.contextMenu {
  display: none;
  overflow: hidden;
  font-size: 12px;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
.contextMenu .command.disable .item {
  color: rgba(0, 0, 0, 0.25);
  cursor: auto;
}
.contextMenu .command.disable .item:hover {
  background: #fff;
}
.contextMenu .item {
  display: flex;
  align-items: center;
  padding: 5px 12px;
  cursor: pointer;
  transition: all 0.3s;
  user-select: none;
}
.contextMenu .item:hover {
  background: #e6f7ff;
}
.contextMenu .item i {
  margin-right: 8px;
  margin-top: 3px;
}
</style>
Source/UBCS-WEB/src/components/flow-cycle/components/ContextMenuItem.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
<template>
  <command :name="command">
    <div class="item">
      <icon :type="iconType" :title="text" />
      <span>{{ label }}</span>
    </div>
  </command>
</template>
<script>
import { Command } from 'vue-flowchart-editor'
import Icon from './Icon'
import upperFirst from 'lodash/upperFirst'
export default {
  name: 'EditorContextMenuItem',
  components: {
    Command,
    Icon,
  },
  props: ['command', 'icon', 'text'],
  computed: {
    iconType() {
      return `icon${this.icon || this.command}`
    },
    label() {
      return this.text || upperFirst(this.command)
    },
  },
}
</script>
Source/UBCS-WEB/src/components/flow-cycle/components/CustomCommand.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
<template>
  <div>
    <register-command
      name="generateData"
      :config="generateDataCommandConfig"
      extend="copy"
    />
    <register-command
      name="downloadImage"
      :config="downloadImageCommandConfig"
      extend="copy"
    />
  </div>
</template>
<script>
import { RegisterCommand } from 'vue-flowchart-editor'
export default {
  name: 'CustomCommand',
  components: {
    RegisterCommand,
  },
  inject: ['root'],
  props: ['save', 'download'],
  data() {
    const { propsAPI } = this.root
    const { save, download } = this
    return {
      generateDataCommandConfig: {
        queue: false, // æ˜¯å¦è¿›å…¥åˆ—队,默认为 true
        enable(/* editor */) {
          // å‘½ä»¤æ˜¯å¦å¯ç”¨
          return true
        },
        execute(/* editor */) {
          // æ­£å‘命令逻辑
          console.log('执行正向命令')
          const data = propsAPI.save()
          console.log(data)
          console.log(JSON.stringify(data))
          save(data)
          alert(JSON.stringify(data))
        },
        back(/* editor */) {
          // åå‘命令逻辑
          console.log('执行反向命令')
        },
      },
      downloadImageCommandConfig: {
        queue: false,
        enable() {
          return true
        },
        execute() {
          download()
        },
        back() {},
      },
    }
  },
}
</script>
Source/UBCS-WEB/src/components/flow-cycle/components/DetailForm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,208 @@
<template>
  <div class="right_box">
    <hr />
    <div v-if="type === 'node'">
      <el-form
        label-width="80px"
        :model="formModel"
        size="mini"
        ref="form"
        :rules="rules"
      >
        <el-form-item label="名称" prop="label">
          <el-input v-model.trim="formModel.label" :maxLength="20" disabled/>
        </el-form-item>
        <el-form-item label="形状">
          <el-select
            v-model="formModel.shape"
            placeholder="请选择形状"
            style="width: 100%"
          >
            <el-option
              v-for="item in shapeTypeList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="颜色">
          <el-input v-model.trim="formModel.color" clearable />
        </el-form-item>
        <el-form-item label="宽度" prop="width">
          <el-input v-model.trim.number="formModel.width" clearable>
            <template slot="prepend">宽</template>
          </el-input>
        </el-form-item>
        <el-form-item label="高度" prop="height">
          <el-input v-model.trim.number="formModel.height" clearable>
            <template slot="prepend">高</template>
          </el-input>
        </el-form-item>
      </el-form>
    </div>
    <div v-else-if="type === 'edge'">
      <el-form
        label-width="80px"
        :model="formModel"
        size="small"
        :rules="rules"
      >
        <el-form-item label="起始状态">
          <el-input v-model.trim="formModel.source" disabled/>
        </el-form-item>
        <el-form-item label="目标状态">
          <el-input v-model.trim="formModel.target" disabled/>
        </el-form-item>
        <el-form-item label="名称">
          <el-input v-model.trim="formModel.label"/>
        </el-form-item>
        <el-form-item label="形状">
          <el-select
            v-model="formModel.shape"
            placeholder="请选择形状"
            style="width: 100%"
          >
            <el-option
              v-for="item in lineTypeList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
    </div>
    <div class="btn_box">
      <el-button type="primary" size="mini" @click="handleSubmit"
        >更新属性</el-button
      >
    </div>
  </div>
</template>
<script>
import { cloneDeep } from 'lodash'
export default {
  name: 'EditorDetailForm',
  inject: ['root'],
  props: ['type', 'readOnly'],
  data() {
    return {
      formModel: {},
      fontSize: 12,
      shapeTypeList: [
        { label: '矩形', value: 'flow-rect' },
        { label: '椭圆', value: 'flow-circle' },
        { label: '菱形', value: 'flow-rhombus' },
        { label: '胶囊', value: 'flow-capsule' },
      ],
      lineTypeList: [
        { label: '曲线', value: 'flow-smooth' },
        { label: '折线', value: 'flow-polyline' },
        { label: '圆角折线', value: 'flow-polyline-round' },
      ],
      rules: {
        label: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
        width: [
          { required: true, message: '宽度不能为空', trigger: 'blur' },
          { pattern: /^[0-9]+$/, message: '宽度只能为数字', trigger: 'blur' },
        ],
        height: [
          { required: true, message: '高度不能为空', trigger: 'blur' },
          { pattern: /^[0-9]+$/, message: '高度只能为数字', trigger: 'blur' },
        ],
      },
    }
  },
  created() {
    const formModel = this.root.propsAPI.getSelected()[0].getModel()
    console.log(formModel, 'formModel');
    this.formModel = Object.assign(
      { width: 80, height: 48 },
      { shape: 'flow-smooth' },
      cloneDeep(formModel) // é˜²æ­¢è¯¯ç¼–辑
    )
  },
  methods: {
    async handleSubmit() {
      if (this.type === 'node') {
        await this.$refs.form.validate()
      }
      const { getSelected, executeCommand, update } = this.root.propsAPI
      const { formModel } = this
      setTimeout(() => {
        const item = getSelected()[0]
        if (!item) return
        // è‡ªåŠ¨è°ƒæ•´å°ºå¯¸
        const adjustSize = (model) => {
          if (model.type !== 'node' || model.shape !== 'flow-rect') {
            return model
          }
          const canvas = document.createElement('canvas')
          const canvasContext = canvas.getContext('2d')
          canvasContext.font = this.fontSize + 'px System'
          let label = model.label.replace('\n', '')
          let sourceWidth = this.formModel.width
          let sourceHeight = this.formModel.height
          const spacing = 10
          // èŽ·å–æ–‡å­—å®½åº¦
          const widthWithSpacing = canvasContext.measureText(label).width + spacing
          model.size = `${sourceWidth}*${sourceHeight}` // å…ˆæ¢å¤é»˜è®¤å°ºå¯¸
          if (widthWithSpacing <= sourceWidth) {
            return model
          }
          // è‡ªåŠ¨æŠ˜è¡Œ
          let multilineText = ''
          let multilineCount = 1
          let multilineTextWidth = 0
          for (const char of label) {
            const { width } = canvasContext.measureText(char)
            console.log(multilineTextWidth + width + spacing, 'multilineTextWidth');
            if (multilineTextWidth + width + spacing >= sourceWidth) {
              multilineText += '\n'
              multilineTextWidth = 0
              multilineCount++
            }
            multilineText += char
            multilineTextWidth += width
          }
          return {
            ...model,
            label: multilineText,
            size: `${sourceWidth}*${Math.max(
              sourceHeight,
              this.fontSize * multilineCount * 1.2 + spacing
            )}`,
          }
        }
        const newFormModel = adjustSize(formModel)
        console.log(newFormModel, 'newFormModel')
        executeCommand(() => {
          update(item, newFormModel)
        })
      }, 0)
    },
  },
}
</script>
<style lang="scss" scoped>
.btn_box {
  text-align: center;
}
</style>
Source/UBCS-WEB/src/components/flow-cycle/components/DetailPanel.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,119 @@
<template>
  <div>
    <div class="tree_data_box">
      <el-form
        ref="form"
        size="mini"
        label-width="80px"
        :model="newRowData"
        :rules="rules"
      >
        <el-form-item label="名称" prop="name">
          <el-input v-model.trim="newRowData.name" :maxLength="20" clearable />
        </el-form-item>
        <el-form-item label="标签" prop="label">
          <el-input v-model.trim="newRowData.label" clearable />
        </el-form-item>
        <el-form-item label="起始状态" prop="startState">
          <el-select
            v-model="newRowData.startState"
            placeholder="请选择起始状态"
            style="width: 100%"
          >
            <el-option
              v-for="item in []"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model.trim="newRowData.remark" type="textarea"></el-input>
        </el-form-item>
      </el-form>
    </div>
    <detail-panel>
      <template v-slot="{ status }">
        <node-panel :status="status">
          <detail-form type="node" />
        </node-panel>
        <edge-panel :status="status">
          <detail-form type="edge" />
        </edge-panel>
        <group-panel :status="status">
          <detail-form type="group" />
        </group-panel>
        <multi-panel :status="status" />
        <canvas-panel :status="status" />
      </template>
    </detail-panel>
  </div>
</template>
<script>
import {
  NodePanel,
  EdgePanel,
  GroupPanel,
  MultiPanel,
  CanvasPanel,
  DetailPanel,
} from "vue-flowchart-editor";
import DetailForm from "./DetailForm";
export default {
  name: "EditorDetailPanel",
  components: {
    NodePanel,
    EdgePanel,
    GroupPanel,
    MultiPanel,
    CanvasPanel,
    DetailPanel,
    DetailForm,
  },
  props: ["readOnly", "rowData"],
  data() {
    return {
      newRowData: {},
      rules: {
        name: [{ required: true, message: "名称不能为空", trigger: "blur" }],
        label: [{ required: true, message: "标签不能为空", trigger: "blur" }],
        startState: [
          // { required: true, message: "起始状态不能为空", trigger: "change" },
        ],
      },
    };
  },
  methods: {
    getNewRowDate() {
      return new Promise((resolve) => {
        this.$refs.form.validate((flag) => {
          if (!flag) {
            resolve(false);
          } else {
            resolve(this.newRowData);
          }
        });
      });
    },
  },
  watch: {
    rowData: {
      deep: true,
      immediate: true,
      handler(newV) {
        if (
          typeof newV === "object" &&
          newV !== null &&
          Object.keys(this.rowData).length > 0
        ) {
          this.newRowData = Object.assign({}, newV);
        }
      },
    },
  },
};
</script>
Source/UBCS-WEB/src/components/flow-cycle/components/EditorMinimap.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
<template>
  <minimap :height="200" />
</template>
<script>
import { Minimap } from 'vue-flowchart-editor'
export default {
  name: 'EditorMinimap',
  components: { Minimap },
}
</script>
Source/UBCS-WEB/src/components/flow-cycle/components/Icon.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
<template>
  <i class="action" :title="text">
    <svg width="1em" height="1em" fill="currentColor">
      <use :xlink:href="'#' + type" />
    </svg>
  </i>
</template>
<script>
import '../iconfont'
export default {
  name: 'EditorIcon',
  props: ['type', 'text'],
}
</script>
Source/UBCS-WEB/src/components/flow-cycle/components/ItemPanel.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,485 @@
<template>
  <div class="item_panel_box">
    <el-input size="mini" placeholder="输入关键字进行过滤" v-model="filterText">
    </el-input>
    <div class="box_item">
      <item-panel class="item-panel" v-loading="loading">
        <template v-for="(item, index) in filterNode">
          <item
            :key="index"
            :type="item.type || 'node'"
            :size="item.size || '80*48'"
            :shape="item.shape || 'flow-rect'"
            :model="{
              // must have model property
              color: item.color || '#1890FF',
              label: item.id || '节点'
            }"
          >
            <template v-if="item.src">
              <div class="item item-img">
                <img :src="item.src" :alt="item.id" />
              </div>
            </template>
            <template v-else>
              <div :class="'item item-' + (item.shape || 'flow-rect')">
                <span>{{ item.id }}</span>
              </div>
            </template>
          </item>
        </template>
      </item-panel>
    </div>
  </div>
</template>
<script>
import { Item, ItemPanel } from 'vue-flowchart-editor'
import { getPage } from '../../../api/omd/status'
export default {
  name: 'EditorItemPanel',
  components: { ItemPanel, Item },
  props: {
    // all nodes for drag to generate flowchart
    treeClick: {
      type: Function,
    },
  },
  data() {
    return {
      filterText: '',
      existList: [
        {
          id: 0,
          label: '生命周期模板列表',
          children: [
            {
              id: 1,
              label: '测试数据1',
              data: {
                nodes: [
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点1',
                    x: 358,
                    y: 262.66666412353516,
                    id: '5f2fae92',
                    index: 0,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点1',
                    x: 349,
                    y: 398.66666412353516,
                    id: '39784055',
                    index: 1,
                  },
                ],
                edges: [
                  {
                    source: '5f2fae92',
                    sourceAnchor: 2,
                    target: '39784055',
                    targetAnchor: 0,
                    id: '40ff05c5',
                    index: 2,
                  },
                ],
              },
            },
            {
              id: 2,
              label: '测试数据2',
              data: {
                nodes: [
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点1',
                    x: 319.5416564941406,
                    y: 396.66666412353516,
                    id: 'ee3b0618',
                    index: 0,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点2',
                    x: 192.54165649414062,
                    y: 277.66666412353516,
                    id: 'a96bfab6',
                    index: 4,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点3',
                    x: 360.5416564941406,
                    y: 152.66666412353516,
                    id: 'e76e769e',
                    index: 5,
                  },
                ],
                edges: [
                  {
                    source: 'e76e769e',
                    sourceAnchor: 2,
                    target: 'a96bfab6',
                    targetAnchor: 0,
                    id: '72117e49',
                    index: 1,
                  },
                  {
                    source: 'a96bfab6',
                    sourceAnchor: 2,
                    target: 'ee3b0618',
                    targetAnchor: 0,
                    id: '21db19e2',
                    index: 2,
                  },
                  {
                    source: 'e76e769e',
                    sourceAnchor: 1,
                    target: 'ee3b0618',
                    targetAnchor: 1,
                    id: '324dd9ae',
                    index: 3,
                  },
                ],
              },
            },
            {
              id: 3,
              label: '测试数据3',
              data: {
                nodes: [
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点1',
                    x: 130.54165649414062,
                    y: 108.66666412353516,
                    id: '9bc884ca',
                    index: 0,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点2',
                    x: 129.54165649414062,
                    y: 227.66666412353516,
                    id: 'd5997173',
                    index: 1,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点3',
                    x: 129.54165649414062,
                    y: 348.66666412353516,
                    id: '79e40c28',
                    index: 2,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点4',
                    x: 319.5416564941406,
                    y: 349.16666412353516,
                    id: '91a6982c',
                    index: 3,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点5',
                    x: 537.5416564941406,
                    y: 350.66666412353516,
                    id: '3939704b',
                    index: 4,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点6',
                    x: 533.5416564941406,
                    y: 230.66666412353516,
                    id: 'de373e3a',
                    index: 5,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点7',
                    x: 537.5416564941406,
                    y: 107.66666412353516,
                    id: '7bdf94ba',
                    index: 6,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点8',
                    x: 343.5416564941406,
                    y: 106.66666412353516,
                    id: '3e739b8e',
                    index: 7,
                  },
                ],
                edges: [
                  {
                    source: '9bc884ca',
                    sourceAnchor: 2,
                    target: 'd5997173',
                    targetAnchor: 0,
                    id: '88e19734',
                    index: 8,
                  },
                  {
                    source: 'd5997173',
                    sourceAnchor: 2,
                    target: '79e40c28',
                    targetAnchor: 0,
                    id: 'e38664d6',
                    index: 9,
                  },
                  {
                    source: '79e40c28',
                    sourceAnchor: 1,
                    target: '91a6982c',
                    targetAnchor: 3,
                    id: '3c95a9f2',
                    index: 10,
                  },
                  {
                    source: '91a6982c',
                    sourceAnchor: 1,
                    target: '3939704b',
                    targetAnchor: 3,
                    id: '5c517fcd',
                    index: 11,
                  },
                  {
                    source: '3939704b',
                    sourceAnchor: 0,
                    target: 'de373e3a',
                    targetAnchor: 2,
                    id: '037bce01',
                    index: 12,
                  },
                  {
                    source: 'de373e3a',
                    sourceAnchor: 0,
                    target: '7bdf94ba',
                    targetAnchor: 2,
                    id: 'b09bb221',
                    index: 13,
                  },
                  {
                    source: '7bdf94ba',
                    sourceAnchor: 3,
                    target: '3e739b8e',
                    targetAnchor: 1,
                    id: '466db0ea',
                    index: 14,
                  },
                  {
                    source: '3e739b8e',
                    sourceAnchor: 3,
                    target: '9bc884ca',
                    targetAnchor: 1,
                    id: '0ad68e07',
                    index: 15,
                  },
                ],
              },
            },
            {
              id: 4,
              label: '测试数据4',
              data: {
                nodes: [
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点6',
                    x: 387.5416564941406,
                    y: 310.66666412353516,
                    id: '61775a95',
                    index: 0,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点7',
                    x: 559.0416564941406,
                    y: 122.16666412353516,
                    id: '3ecf3a2c',
                    index: 4,
                  },
                  {
                    type: 'node',
                    size: '80*48',
                    shape: 'flow-rect',
                    color: '#1890FF',
                    label: '测试节点8',
                    x: 226.54165649414062,
                    y: 121.16666412353516,
                    id: '065c9aa9',
                    index: 5,
                  },
                ],
                edges: [
                  {
                    source: '065c9aa9',
                    sourceAnchor: 2,
                    target: '61775a95',
                    targetAnchor: 0,
                    id: 'd9ddab89',
                    index: 1,
                  },
                  {
                    source: '61775a95',
                    sourceAnchor: 0,
                    target: '3ecf3a2c',
                    targetAnchor: 2,
                    id: 'a010883c',
                    index: 2,
                  },
                  {
                    source: '3ecf3a2c',
                    sourceAnchor: 3,
                    target: '065c9aa9',
                    targetAnchor: 1,
                    id: '93207803',
                    index: 3,
                  },
                ],
              },
            },
          ],
        },
      ],
      nodeItems: [],
      loading: false
    }
  },
  created() {
      this.loading = true
    getPage(1, 99999).then(res => {
      this.loading = false
      if (res.data.code === 200) {
        this.nodeItems = res.data.data.records
      }
    })
  },
  computed: {
    filterNode() {
      return this.nodeItems.filter(item => item.id.includes(this.filterText))
    }
  },
}
</script>
<style lang="scss" scoped>
.item_panel_box {
  height: 100%;
  padding: 5px;
  overflow: hidden;
  .exist_list {
    max-height: 40%;
    overflow-y: scroll;
    .title {
      padding: 10px 0;
      text-align: center;
      font-size: 16px;
      font-weight: bold;
    }
  }
  .box_item {
    margin-top: 20px;
  }
}
.item-panel {
  width: 100%;
  height: 500px;
  text-align: center;
  overflow-y: scroll;
  .item {
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 12px;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 10px;
    user-select: none;
    &.item-flow-rect {
      padding: 6px;
      box-sizing: border-box;
      border: 1px solid rgb(24, 144, 255);
      background-color: rgba(24, 144, 255, 0.2);
    }
    &.item-flow-circle {
      width: 70px;
      height: 70px;
      border-radius: 60px;
      border: 1px solid rgb(250, 140, 22);
      background-color: rgba(250, 140, 22, 0.2);
    }
    &.item-flow-rhombus {
      width: 70px;
      height: 70px;
      margin: 25px auto;
      border: 1px solid rgb(19, 194, 194);
      background-color: rgba(19, 194, 194, 0.2);
      transform: rotate(45deg);
      span {
        transform: rotate(-45deg);
      }
    }
    &.item-img {
      max-width: 100px;
    }
  }
}
</style>
Source/UBCS-WEB/src/components/flow-cycle/components/Toolbar.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,130 @@
<template>
  <toolbar class="toolbar">
    <template>
      <toolbar-button command="undo" text="撤销" />
      <toolbar-button command="redo" text="重做" />
      <toolbar-button command="copy" text="复制" />
      <toolbar-button command="paste" text="粘贴" />
      <div class="split"></div>
    </template>
    <toolbar-button command="zoomIn" icon="zoom-in" text="放大" />
    <toolbar-button command="zoomOut" icon="zoom-out" text="缩小" />
    <toolbar-button command="autoZoom" icon="fit" text="自适应" />
    <toolbar-button command="resetZoom" icon="actual-size" text="实际尺寸" />
    <template>
      <div class="split"></div>
      <!-- <toolbar-button command="toBack" icon="to-back" text="向下一层" /> -->
      <!-- <toolbar-button command="toFront" icon="to-front" text="向上一层" /> -->
      <!-- <toolbar-button command="addGroup" icon="group" text="编组" /> -->
      <!-- <toolbar-button command="unGroup" icon="ungroup" text="取消编组" /> -->
      <toolbar-button command="selectAll" icon="select-all" text="全选" />
      <toolbar-button command="multiSelect" icon="select" text="框选" />
      <div class="split"></div>
      <toolbar-button command="delete" text="删除"/>
      <toolbar-button command="clear" icon="clear" text="清空画布" />
    </template>
    <template>
      <div class="split"></div>
      <toolbar-button
        command="downloadImage"
        icon="image"
        text="下载图像"
      />
    </template>
    <!-- right toolbar button -->
    <!-- <div class="pull-right">
      <toolbar-button
        command="generateData"
        icon="save"
        text="生成数据"
        label="保存数据"
      />
    </div> -->
  </toolbar>
</template>
<script>
import { Toolbar } from 'vue-flowchart-editor'
import ToolbarButton from './ToolbarButton'
export default {
  name: 'FlowToolbar',
  components: {
    Toolbar,
    ToolbarButton,
  },
  props: ['chartData', 'toggleReadOnly'],
  methods: {
  },
}
</script>
<style lang="scss" scoped>
.toolbar {
  display: flex;
  align-items: center;
  height: 27px;
  .split {
    width: 10px;
    height: 100%;
    border-right: 1px solid #eee;
    margin-right: 10px;
  }
  .pull-right {
    display: flex;
    align-items: center;
    margin-left: auto;
  }
  .command {
    margin-right: 15px;
    display: flex;
    color: #333;
    i {
      display: block;
      width: 27px;
      height: 27px;
      margin: 0 6px;
      padding-top: 10px;
      text-align: center;
      border: 1px solid #fff;
      cursor: pointer;
    }
    span {
      display: block;
      font-size: 12px;
      padding-top: 10px;
      margin-left: -6px;
      padding-right: 6px;
      line-height: 20px;
      cursor: pointer;
    }
    &:hover {
      color: #1890ff;
    }
  }
  .disable {
    color: rgba(0, 0, 0, 0.25);
    i {
      cursor: not-allowed;
    }
    span {
      cursor: not-allowed;
    }
    &:hover {
      color: rgba(0, 0, 0, 0.25);
    }
  }
}
</style>
Source/UBCS-WEB/src/components/flow-cycle/components/ToolbarButton.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
<template>
  <command :name="command">
    <icon :type="iconType" :title="text" />
    <span v-if="label">{{ label }}</span>
  </command>
</template>
<script>
import { Command } from 'vue-flowchart-editor'
import Icon from './Icon'
export default {
  name: 'EditorToolbarButton',
  props: ['command', 'icon', 'text', 'label'],
  computed: {
    iconType() {
      return `icon${this.icon || this.command}`
    },
  },
  components: {
    Command,
    Icon,
  },
}
</script>
Source/UBCS-WEB/src/components/flow-cycle/flowchartEditor.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,230 @@
<template>
  <vue-flowchart-editor class="vue-flowchart-editor" ref="flowChart">
    <div class="vfe-chart">
      <!-- Top Menu -->
      <div class="vfe-chart-header" v-if="type !== 'detail'">
        <editor-toolbar :chart-data="flowChartData" />
      </div>
      <div class="vfe-chart-container">
        <!-- Left Items -->
        <div class="vfe-chart-sidebar" v-if="type !== 'detail'">
          <editor-item-panel :node-items="flowChartNodeItems" />
        </div>
        <!-- Main Chart -->
        <div class="vfe-chart-main">
          <flow :data="flowChartData" :onAfterChange="onAfterChange" />
          <div class="tooltip">
            <template v-for="item in tooltipData">
              <p :key="item.name">{{ item.name }}: {{ item.value }}</p>
            </template>
          </div>
        </div>
        <div class="vfe-chart-panel" v-if="type !== 'detail'">
          <div class="vfe-chart-panel-detail">
            <editor-detail-panel :rowData="rowData" ref="EditorDetailPanel" />
          </div>
        </div>
      </div>
    </div>
    <!-- Mouse Right Button Context Menu -->
    <editor-context-menu v-if="type !== 'detail'" />
    <register-edge
      name="custom-polyline"
      extend="flow-polyline"
      :config="customEdgeConfig"
    />
    <custom-command :download="downloadImage" />
  </vue-flowchart-editor>
</template>
<script>
import VueFlowchartEditor, { Flow, RegisterEdge } from "vue-flowchart-editor";
import EditorToolbar from "./components/Toolbar";
import EditorItemPanel from "./components/ItemPanel";
import EditorDetailPanel from "./components/DetailPanel";
import EditorMinimap from "./components/EditorMinimap";
import EditorContextMenu from "./components/ContextMenu";
import CustomCommand from "./components/CustomCommand";
export default {
  name: "FlowchartEditor",
  components: {
    VueFlowchartEditor,
    Flow,
    EditorToolbar,
    EditorItemPanel,
    EditorDetailPanel,
    EditorMinimap,
    EditorContextMenu,
    CustomCommand,
    RegisterEdge,
  },
  props: ["chartData", "chartDataNodeItems", "saveData", "rowData", "type"],
  data() {
    return {
      flowChartData: this.chartData,
      flowChartNodeItems: this.chartDataNodeItems,
      customEdgeConfig: {
        getActivedStyle(/*item*/) {
          return {
            lineWidth: 3,
          };
        },
        getSelectedStyle(/*item*/) {
          return {
            lineWidth: 3,
          };
        },
      },
      tooltipShow: true,
      tooltipData: [],
    };
  },
  mounted() {
    if (this.type === "add") {
      this.$nextTick(() => {
        this.$refs.flowChart.propsAPI.executeCommand("autoZoom");
      });
    }
  },
  methods: {
    // onAfterChange(e) {
    //   const model = e.model
    //   console.log(JSON.parse(JSON.stringify(e)));
    //   if (!model.change) {
    //     model.id = model.label
    //     model.change = true
    //   } else {
    //     return
    //   }
    //   const { nodes } = this.$refs.flowChart.propsAPI.save()
    //   if (Array.isArray(nodes) && nodes.length > 0) {
    //   } else {
    //     this.$refs.flowChart.propsAPI.add("node", model);
    //   }
    //   throw '禁止原生新增方法'
    // },
    onAfterChange(e) {
      console.log(e);
      try {
        if (e.action === "add" && e.model.type === "node") {
          if (!e.model.change) {
            this.$refs.flowChart.propsAPI.remove(e.item);
            e.model.id = e.model.label;
            e.model.change = true;
            this.$refs.flowChart.propsAPI.add("node", e.model);
          }
        }
      } catch (err) {
        if (
          err.message ===
          `id:${e.model.label} has already been set, please set new one`
        ) {
          this.$message.error("不能添加已存在的节点!");
        }
      }
    },
    _downloadImage(data, filename = "flowchart.png") {
      const a = document.createElement("a");
      a.href = data;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
    },
    downloadImage() {
      const page = this.$refs["flowChart"].propsAPI.editor.getCurrentPage();
      this._downloadImage(page.saveImage().toDataURL("image/png"));
    },
    getNewRowData() {
      return this.$refs.EditorDetailPanel.getNewRowDate();
    },
    getFlowData() {
      return this.$refs.flowChart.propsAPI.save();
    },
  },
};
</script>
<style lang="scss" scoped>
.vue-flowchart-editor {
  display: flex;
  flex: 1;
  flex-direction: column;
  width: 100%;
  height: 100%;
  background: #fff;
}
.vfe-chart {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  .vfe-chart-header {
    border: 1px solid #e6e9ed;
    padding: 8px;
  }
  .vfe-chart-container {
    flex: 1;
    display: flex;
    height: 550px;
    overflow: hidden;
    .vfe-chart-main {
      position: relative;
      flex: 1;
      max-height: calc(100% - 5px); // fix scroll show
      .tooltip {
        position: absolute;
        display: none;
        top: 0;
        left: 0;
        width: 100px;
        height: auto;
        padding: 15px;
        border-radius: 10px;
        z-index: 999;
        opacity: 0.8;
        color: #ffffff;
        font-size: 12px;
        background-color: #000;
        p {
          margin: 0;
        }
      }
    }
    .vfe-chart-sidebar {
      position: relative;
      display: flex;
      justify-content: center;
      width: 15%;
      background-color: #fafafa;
      border-right: 1px solid #e6e9ed;
    }
    .vfe-chart-panel {
      position: relative;
      width: 300px;
      background-color: #fafafa;
      border-left: 1px solid #e6e9ed;
      .vfe-chart-panel-detail {
        box-sizing: border-box;
        padding: 10px;
      }
    }
  }
}
</style>
Source/UBCS-WEB/src/components/flow-cycle/iconfont.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
!function(v){var c,h='<svg><symbol id="iconto-back" viewBox="0 0 1024 1024"><path d="M640 726.016l0-86.016 86.016 0 0 86.016-86.016 0zM640 214.016l0-86.016 86.016 0 0 86.016-86.016 0zM214.016 297.984l0 512 512 0 0 86.016-512 0q-36.010667 0-61.013333-25.984t-25.002667-59.989333l0-512 86.016 0zM809.984 726.016l0-86.016 86.016 0q0 34.005333-25.984 59.989333t-59.989333 25.984zM809.984 384l0-86.016 86.016 0 0 86.016-86.016 0zM809.984 553.984l0-84.010667 86.016 0 0 84.010667-86.016 0zM384 726.016q-36.010667 0-61.013333-25.984t-25.002667-59.989333l86.016 0 0 86.016zM553.984 128l0 86.016-84.010667 0 0-86.016 84.010667 0zM809.984 128q34.005333 0 59.989333 25.984t25.984 59.989333l-86.016 0 0-86.016zM553.984 640l0 86.016-84.010667 0 0-86.016 84.010667 0zM384 128l0 86.016-86.016 0q0-34.005333 25.002667-59.989333t61.013333-25.984zM384 470.016l0 84.010667-86.016 0 0-84.010667 86.016 0zM384 297.984l0 86.016-86.016 0 0-86.016 86.016 0z"  ></path></symbol><symbol id="iconfit" viewBox="0 0 1024 1024"><path d="M597.333333 405.376c0-0.128 0.085333-0.256 0.085333-0.384C597.418667 404.821333 597.333333 404.650667 597.333333 404.522667L597.333333 192.768C597.333333 180.522667 606.933333 170.538667 618.666667 170.666667c11.733333-0.042667 21.376 9.813333 21.376 22.144L640.042667 384l191.189333 0c12.16 0 22.186667 9.6 22.101333 21.333333 0 11.733333-9.813333 21.333333-22.186667 21.333333l-211.754667 0c-0.128 0-0.256-0.085333-0.384-0.085333S618.837333 426.666667 618.709333 426.666667c-4.821333 0-9.045333-1.962667-12.629333-4.736-0.853333-0.64-1.749333-0.981333-2.432-1.706667-0.213333-0.213333-0.298667-0.469333-0.512-0.725333C599.68 415.744 597.333333 410.837333 597.333333 405.376zM362.666667 170.666667C350.933333 170.624 341.290667 180.48 341.290667 192.810667L341.290667 384 150.101333 384C137.898667 384 127.914667 393.6 128 405.333333 128 417.066667 137.813333 426.666667 150.186667 426.666667l211.754667 0c0.128 0 0.256-0.085333 0.384-0.085333S362.496 426.666667 362.624 426.666667c4.821333 0 9.045333-1.962667 12.629333-4.736 0.853333-0.64 1.749333-0.981333 2.432-1.706667 0.213333-0.213333 0.298667-0.469333 0.512-0.725333C381.653333 415.744 384 410.837333 384 405.376c0-0.128-0.085333-0.256-0.085333-0.384C383.914667 404.821333 384 404.650667 384 404.522667L384 192.768C384 180.522667 374.4 170.538667 362.666667 170.666667zM831.146667 640l-211.754667 0c-0.128 0-0.256 0.085333-0.384 0.085333S618.837333 640 618.709333 640c-4.821333 0-9.088 2.005333-12.672 4.778667-0.810667 0.597333-1.706667 0.938667-2.389333 1.664-0.213333 0.213333-0.298667 0.469333-0.512 0.725333C599.68 650.922667 597.333333 655.829333 597.333333 661.290667c0 0.128 0.085333 0.256 0.085333 0.384 0 0.170667-0.085333 0.341333-0.085333 0.469333l0 211.797333c0 12.202667 9.6 22.229333 21.333333 22.101333 11.733333 0.042667 21.376-9.813333 21.376-22.144L640.042667 682.666667l191.189333 0c12.16 0 22.186667-9.6 22.101333-21.333333C853.333333 649.6 843.52 640 831.146667 640zM378.154667 647.168c-0.213333-0.256-0.298667-0.512-0.512-0.725333-0.682667-0.725333-1.578667-1.066667-2.389333-1.664C371.712 642.005333 367.445333 640 362.624 640c-0.128 0-0.213333 0.085333-0.341333 0.085333S362.026667 640 361.898667 640L150.186667 640C137.813333 640 128 649.6 128 661.333333 127.914667 673.066667 137.898667 682.666667 150.101333 682.666667l191.189333 0 0 191.189333c0 12.288 9.642667 22.186667 21.376 22.144C374.4 896.128 384 886.144 384 873.898667l0-211.797333c0-0.128-0.085333-0.298667-0.085333-0.469333C383.914667 661.546667 384 661.418667 384 661.290667 384 655.829333 381.653333 650.922667 378.154667 647.168zM490.666667 469.333333c-35.328 0-64 28.672-64 64s28.672 64 64 64 64-28.672 64-64S525.994667 469.333333 490.666667 469.333333z"  ></path></symbol><symbol id="iconpaste" viewBox="0 0 1024 1024"><path d="M776 248 704 248 704 192l99.968 0C819.392 192 832 204.608 832 220.032l0 98.88-56 0L776 248zM255.104 904 184 904 184 248 256 248 256 192 156.032 192C140.608 192 128 204.608 128 220.032l0 712C128 947.392 140.608 960 156.032 960l99.136 0L255.168 904zM640 320 320 320 320 192l64 0L384 120C384 89.216 409.216 64 440 64l72.064 0c30.784 0 56 25.216 56 56L568.064 192 640 192 640 320zM512.128 120.128C512.064 120.064 512 120 512 120L440.064 120.064c0 0 0 0.064-0.064 0.064L440 192l72.064 0 0.064 0L512.128 120.128zM888.256 995.776 888.256 578.88l-182.4-192L351.488 386.88c-18.624 0-31.232 12.608-31.232 28.032l0 580.864c0 15.36 12.608 28.032 28.032 28.032l512 0C875.648 1023.744 888.256 1011.136 888.256 995.776zM824.256 586.88l-129.6 0L694.656 450.88 824.256 586.88zM832.256 970.88 376.256 970.88 376.256 442.88l265.6 0 0 196.864 190.4 0L832.256 970.88z"  ></path></symbol><symbol id="iconactual-size" viewBox="0 0 1024 1024"><path d="M829.013333 810.666667l-640 0c-58.794667 0-106.666667-47.829333-106.666667-106.666667l0-469.333333c0-58.794667 47.872-106.666667 106.666667-106.666667l640 0c58.837333 0 106.666667 47.872 106.666667 106.666667l0 469.333333C935.68 762.837333 887.850667 810.666667 829.013333 810.666667zM189.013333 170.666667c-35.285333 0-64 28.714667-64 64l0 469.333333c0 35.285333 28.714667 64 64 64l640 0c35.285333 0 64-28.714667 64-64l0-469.333333c0-35.285333-28.714667-64-64-64L189.013333 170.666667zM338.346667 640.256c0 11.733333-9.557333 21.333333-21.333333 21.333333s-21.333333-9.6-21.333333-21.333333l0-341.333333c0-11.818667 9.557333-21.333333 21.333333-21.333333s21.333333 9.514667 21.333333 21.333333L338.346667 640.256zM722.346667 640.256c0 11.733333-9.557333 21.333333-21.333333 21.333333s-21.333333-9.6-21.333333-21.333333l0-341.333333c0-11.818667 9.557333-21.333333 21.333333-21.333333s21.333333 9.514667 21.333333 21.333333L722.346667 640.256zM509.013333 341.333333c-23.594667 0-42.666667 19.072-42.666667 42.666667s19.072 42.666667 42.666667 42.666667 42.666667-19.072 42.666667-42.666667S532.565333 341.333333 509.013333 341.333333zM509.013333 512c-23.594667 0-42.666667 19.072-42.666667 42.666667s19.072 42.666667 42.666667 42.666667 42.666667-19.072 42.666667-42.666667S532.565333 512 509.013333 512z"  ></path></symbol><symbol id="iconredo" viewBox="0 0 1024 1024"><path d="M708.16 635.904c-39.36 35.968-48.32 41.344-50.496-25.856-3.968-49.152 0-103.552 0-103.552-1.408-3.072-86.464-35.008-227.072 25.856C290.048 593.28 195.2 783.36 178.432 842.88 177.088 877.248 132.288 943.616 128 841.472c-0.576-166.656 64.512-341.12 230.336-441.152 154.624-93.248 283.264-83.776 297.408-78.848 0.256 1.344 0.64 1.856 1.344 1.024 0.192-0.256-0.384-0.64-1.344-1.024-1.216-6.208 2.496-38.272 2.88-98.56-2.368-54.144 12.096-55.808 49.536-26.944 68.544 56.32 251.776 231.36 251.776 231.36S776.768 580.608 708.16 635.904z"  ></path></symbol><symbol id="iconundo" viewBox="0 0 1024 1024"><path d="M379.776 635.904c39.36 35.968 48.32 41.344 50.496-25.856 3.968-49.152 0-103.552 0-103.552 1.408-3.072 86.464-35.008 227.072 25.856 140.544 60.928 235.456 251.008 252.16 310.528 1.344 34.368 46.144 100.736 50.432-1.344 0.576-166.656-64.512-341.12-230.336-441.152C574.976 307.072 446.4 316.608 432.192 321.472c-0.256 1.344-0.64 1.856-1.344 1.024-0.192-0.256 0.384-0.64 1.344-1.024 1.216-6.208-2.496-38.272-2.88-98.56 2.368-54.144-12.096-55.808-49.536-26.944C311.168 252.288 128 427.264 128 427.264S311.168 580.608 379.776 635.904z"  ></path></symbol><symbol id="icondelete" viewBox="0 0 1024 1024"><path d="M677.647059 256l0-90.352941c0-37.436235-23.461647-60.235294-61.771294-60.235294L408.094118 105.411765c-38.249412 0-61.741176 22.799059-61.741176 60.235294l0 90.352941-180.705882 0 0 60.235294 60.235294 0 0 512c0 54.272 33.972706 90.352941 90.352941 90.352941l391.529412 0c55.085176 0 90.352941-33.490824 90.352941-90.352941l0-512 60.235294 0 0-60.235294L677.647059 256zM406.588235 165.647059l210.823529 0-1.264941 90.352941L406.588235 256 406.588235 165.647059zM737.882353 858.352941l-451.764706 0 0-542.117647 451.764706 0L737.882353 858.352941zM466.823529 376.470588l-58.729412 0-1.505882 391.529412 60.235294 0L466.823529 376.470588zM617.411765 376.470588l-60.235294 0 0 391.529412 60.235294 0L617.411765 376.470588z"  ></path></symbol><symbol id="iconzoom-in" viewBox="0 0 1024 1024"><path d="M1000.146824 957.500235l-311.597176-311.597176c58.729412-68.487529 94.509176-157.214118 94.509176-254.373647 0-215.883294-175.646118-391.529412-391.529412-391.529412-104.628706 0-202.932706 40.719059-276.901647 114.688-73.968941 73.908706-114.627765 172.272941-114.627765 276.841412 0 215.883294 175.646118 391.529412 391.529412 391.529412 97.099294 0 185.886118-35.779765 254.433882-94.509176l311.597176 311.597176 42.586353-42.646588zM391.529412 722.823529c-182.693647 0-331.294118-148.600471-331.294118-331.294118 0-88.545882 34.394353-171.730824 96.978824-234.315294 62.584471-62.524235 145.769412-96.978824 234.315294-96.978824 182.693647 0 331.294118 148.600471 331.294118 331.294118 0 182.693647-148.600471 331.294118-331.294118 331.294118zM421.647059 361.411765l120.470588 0 0 60.235294-120.470588 0 0 120.470588-60.235294 0 0-120.470588-120.470588 0 0-60.235294 120.470588 0 0-120.470588 60.235294 0 0 120.470588z"  ></path></symbol><symbol id="iconzoom-out" viewBox="0 0 1024 1024"><path d="M999.344139 955.925769l-311.084802-311.084802c58.63284-68.374912 94.35377-157.015739 94.35377-253.955368 0-215.528306-175.357294-390.8856-390.8856-390.8856-104.396523 0-202.599013 40.652102-276.50646 114.439276-73.787174 73.84731-114.439276 172.0498-114.37914 276.446324 0 215.528306 175.357294 390.8856 390.8856 390.8856 96.939629 0 185.640592-35.72093 254.015504-94.35377l311.084802 311.084802 42.516326-42.576462zM391.727508 721.634954c-182.333098 0-330.749354-148.356119-330.749354-330.749354-0.060136-88.400282 34.337797-171.448438 96.819356-233.869861 62.421424-62.48156 145.529716-96.879493 233.929998-96.879493 182.333098 0 330.749354 148.356119 330.749354 330.749354 0 182.333098-148.416256 330.749354-330.749354 330.749354zM241.386892 360.817477l300.681231 0 0 60.136246-300.681231 0 0-60.136246z"  ></path></symbol><symbol id="iconcopy" viewBox="0 0 1024 1024"><path d="M880 247.008l-162.016-166.016Q700.992 64 677.984 64h-316.992q-26.016 0-46.016 18.016-16.992 15.008-23.008 36.992H231.968q-43.008 0-73.504 31.008t-30.496 76v627.008q0 44 30.496 75.488T231.968 960h508q43.008 0 73.504-31.488t30.496-75.488v-63.008q23.008-6.016 37.504-25.504t14.496-44.512V287.008q0-24-16-40z m-168-160.992l-3.008-3.008z m98.016 177.984L744 196z m-126.016-116.992l108 110.016h-108V147.008zM676.992 128zM204.992 948q4 0.992 4.992 2.016-2.016-0.992-4.992-2.016z m27.008 4q-6.016 0-12-0.992 4.992 0.992 12 0.992z m543.008-99.008q0 15.008-10.016 25.504t-24.992 10.496H232q-14.016 0-24.512-10.496t-10.496-25.504V225.984q0-15.008 10.496-25.504t24.512-10.496h58.016v531.008q0 30.016 20.992 51.008t50.016 20.992H775.04v60z m52-132.992q0 2.016-2.016 2.016h-464q-2.016 0-2.016-2.016V136.992q0-2.016 2.016-2.016h251.008v156.992q0 15.008 10.016 24.992t24 10.016h180.992v392.992z m9.984 64q4-0.992 8.992-2.016-4.992 0.992-8.992 2.016z m-244-168.992h-107.008q-15.008 0-24.992 10.496t-10.016 24.992 10.016 24.992 24.992 10.496h107.008q14.016 0 24.512-10.496t10.496-24.992-10.496-24.992-24.512-10.496z m107.008-111.008h-214.016q-14.016 0-24.512 10.496t-10.496 24.992 10.496 24.992 24.512 10.496h214.016q14.016 0 24-10.496t10.016-24.992-10.016-24.992-24-10.496z m-240.992 36q0 4 0.992 8-0.992-4-0.992-8zM700 512z m12 52l4-2.016z m-260.992-135.488q0 14.496 10.496 24.992t24.512 10.496h214.016q14.016 0 24-10.496t10.016-24.992-10.016-24.992-24-10.496h-214.016q-14.016 0-24.512 10.496t-10.496 24.992z m8 1.504z"  ></path></symbol><symbol id="iconsave" viewBox="0 0 1024 1024"><path d="M886.4 265.6l-128-128c-6.4-6.4-12.8-9.6-22.4-9.6H160c-19.2 0-32 12.8-32 32v704c0 19.2 12.8 32 32 32h704c19.2 0 32-12.8 32-32V288c0-9.6-3.2-16-9.6-22.4zM352 192h320v256H352V192z m480 640H192V192h96v288c0 19.2 12.8 32 32 32h384c19.2 0 32-12.8 32-32V204.8l96 96V832z"  ></path><path d="M576 256c-19.2 0-32 12.8-32 32v64c0 19.2 12.8 32 32 32s32-12.8 32-32V288c0-19.2-12.8-32-32-32z"  ></path></symbol><symbol id="iconselect-all" viewBox="0 0 1024 1024"><path d="M128 213.333333h85.333333V128c-47.146667 0-85.333333 38.186667-85.333333 85.333333z m0 341.333334h85.333333v-85.333334H128v85.333334z m170.666667 341.333333h85.333333v-85.333333h-85.333333v85.333333zM128 384h85.333333v-85.333333H128v85.333333zM554.666667 128h-85.333334v85.333333h85.333334V128z m256 0v85.333333h85.333333c0-47.146667-38.186667-85.333333-85.333333-85.333333zM213.333333 896v-85.333333H128c0 47.146667 38.186667 85.333333 85.333333 85.333333z m-85.333333-170.666667h85.333333v-85.333333H128v85.333333zM384 128h-85.333333v85.333333h85.333333V128z m85.333333 768h85.333334v-85.333333h-85.333334v85.333333z m341.333334-341.333333h85.333333v-85.333334h-85.333333v85.333334z m0 341.333333c47.146667 0 85.333333-38.186667 85.333333-85.333333h-85.333333v85.333333z m0-512h85.333333v-85.333333h-85.333333v85.333333z m0 341.333333h85.333333v-85.333333h-85.333333v85.333333z m-170.666667 170.666667h85.333333v-85.333333h-85.333333v85.333333z m0-682.666667h85.333333V128h-85.333333v85.333333zM298.666667 725.333333h426.666666V298.666667H298.666667v426.666666z m85.333333-341.333333h256v256H384V384z" fill="" ></path></symbol><symbol id="iconselect" viewBox="0 0 1024 1024"><path d="M324.266667 34.133333h-102.4c-10.24 0-17.066667 6.826667-17.066667 17.066667s6.826667 17.066667 17.066667 17.066667h102.4c10.24 0 17.066667-6.826667 17.066666-17.066667S334.506667 34.133333 324.266667 34.133333zM597.333333 34.133333h-102.4c-10.24 0-17.066667 6.826667-17.066666 17.066667s6.826667 17.066667 17.066666 17.066667h102.4c10.24 0 17.066667-6.826667 17.066667-17.066667s-6.826667-17.066667-17.066667-17.066667zM324.266667 716.8h-102.4c-10.24 0-17.066667 6.826667-17.066667 17.066667s6.826667 17.066667 17.066667 17.066666h102.4c10.24 0 17.066667-6.826667 17.066666-17.066666s-6.826667-17.066667-17.066666-17.066667zM563.2 716.8h-68.266667c-10.24 0-17.066667 6.826667-17.066666 17.066667s6.826667 17.066667 17.066666 17.066666h68.266667c10.24 0 17.066667-6.826667 17.066667-17.066666s-6.826667-17.066667-17.066667-17.066667zM34.133333 597.333333c0 10.24 6.826667 17.066667 17.066667 17.066667s17.066667-6.826667 17.066667-17.066667v-102.4c0-10.24-6.826667-17.066667-17.066667-17.066666s-17.066667 6.826667-17.066667 17.066666v102.4zM51.2 341.333333c10.24 0 17.066667-6.826667 17.066667-17.066666v-102.4c0-10.24-6.826667-17.066667-17.066667-17.066667s-17.066667 6.826667-17.066667 17.066667v102.4c0 10.24 6.826667 17.066667 17.066667 17.066666zM768 477.866667c-10.24 0-17.066667 6.826667-17.066667 17.066666v68.266667c0 10.24 6.826667 17.066667 17.066667 17.066667s17.066667-6.826667 17.066667-17.066667v-68.266667c0-10.24-6.826667-17.066667-17.066667-17.066666zM785.066667 221.866667c0-10.24-6.826667-17.066667-17.066667-17.066667s-17.066667 6.826667-17.066667 17.066667v102.4c0 10.24 6.826667 17.066667 17.066667 17.066666s17.066667-6.826667 17.066667-17.066666v-102.4zM733.866667 102.4h68.266666c10.24 0 17.066667-6.826667 17.066667-17.066667v-68.266666c0-10.24-6.826667-17.066667-17.066667-17.066667h-68.266666c-10.24 0-17.066667 6.826667-17.066667 17.066667v68.266666c0 10.24 6.826667 17.066667 17.066667 17.066667zM85.333333 0h-68.266666C6.826667 0 0 6.826667 0 17.066667v68.266666c0 10.24 6.826667 17.066667 17.066667 17.066667h68.266666c10.24 0 17.066667-6.826667 17.066667-17.066667v-68.266666c0-10.24-6.826667-17.066667-17.066667-17.066667zM85.333333 682.666667h-68.266666c-10.24 0-17.066667 6.826667-17.066667 17.066666v68.266667c0 10.24 6.826667 17.066667 17.066667 17.066667h68.266666c10.24 0 17.066667-6.826667 17.066667-17.066667v-68.266667c0-10.24-6.826667-17.066667-17.066667-17.066666zM1013.76 788.48l-375.466667-204.8c-6.826667-3.413333-13.653333-3.413333-20.48 3.413333-3.413333 3.413333-3.413333 10.24-3.413333 17.066667l170.666667 409.6c3.413333 6.826667 6.826667 10.24 13.653333 10.24s13.653333-3.413333 13.653333-10.24l64.853334-133.12 133.12-64.853333c6.826667-3.413333 10.24-10.24 10.24-13.653334 3.413333-6.826667 0-10.24-6.826667-13.653333z" fill="" ></path></symbol><symbol id="iconto-front" viewBox="0 0 1024 1024"><path d="M128 554.666667h85.333333v-85.333334H128v85.333334z m0 170.666666h85.333333v-85.333333H128v85.333333z m85.333333 170.666667v-85.333333H128c0 47.146667 38.186667 85.333333 85.333333 85.333333zM128 384h85.333333v-85.333333H128v85.333333z m512 512h85.333333v-85.333333h-85.333333v85.333333z m170.666667-768H384c-47.146667 0-85.333333 38.186667-85.333333 85.333333v426.666667c0 47.146667 38.186667 85.333333 85.333333 85.333333h426.666667c47.146667 0 85.333333-38.186667 85.333333-85.333333V213.333333c0-47.146667-38.186667-85.333333-85.333333-85.333333z m0 512H384V213.333333h426.666667v426.666667zM469.333333 896h85.333334v-85.333333h-85.333334v85.333333z m-170.666666 0h85.333333v-85.333333h-85.333333v85.333333z"  ></path></symbol><symbol id="iconimage" viewBox="0 0 1024 1024"><path d="M847.657 64.016H175.703c-61.766 0-111.993 50.227-111.993 111.992v671.954c0 61.765 50.226 111.993 111.993 111.993h671.954c61.765 0 111.992-50.228 111.992-111.993V176.01c0-61.765-50.227-111.993-111.992-111.993z m55.995 783.946c0 30.87-25.127 55.997-55.996 55.997H175.703c-30.87 0-55.996-25.127-55.996-55.997V176.01c0-30.87 25.128-55.996 55.996-55.996h671.954c30.87 0 55.996 25.127 55.996 55.996v671.953zM835.19 544.686l-83.995-55.996c-10.444-6.945-23.54-5.688-32.782 1.722l-0.246-0.3-133.184 106.551-197.435-135.752c-0.083-0.055-0.164-0.055-0.218-0.11-2.297-1.53-4.895-2.379-7.52-3.199-0.874-0.273-1.666-0.875-2.57-1.04-2.378-0.492-4.811-0.218-7.273-0.081-1.121 0.082-2.27-0.218-3.363 0-1.23 0.218-2.35 0.984-3.554 1.394-2.27 0.739-4.566 1.367-6.616 2.707-0.083 0.055-0.192 0.055-0.274 0.11L188.17 572.684c-12.878 8.585-16.35 25.946-7.765 38.824 5.386 8.094 14.273 12.47 23.323 12.47 5.332 0 10.718-1.533 15.503-4.704L371.444 517.81 803.8 815.042a27.793 27.793 0 0 0 15.831 4.923c8.913 0 17.663-4.238 23.105-12.14 8.749-12.74 5.523-30.156-7.219-38.934L633.214 629.802l103.956-83.147 66.959 44.621c4.786 3.172 10.171 4.704 15.503 4.704 9.05 0 17.937-4.374 23.323-12.469 8.584-12.877 5.112-30.24-7.766-38.825zM581.674 427.991c69.476 0 125.992-56.516 125.992-125.99 0-69.477-56.516-125.993-125.992-125.993-69.475 0-125.99 56.516-125.99 125.992s56.516 125.991 125.99 125.991z m0-195.985c38.607 0 69.995 31.387 69.995 69.994s-31.388 69.995-69.995 69.995c-38.606 0-69.995-31.39-69.995-69.995 0-38.607 31.39-69.994 69.995-69.994z"  ></path></symbol><symbol id="iconclear" viewBox="0 0 1024 1024"><path d="M686.464 452.821333c5.461333-15.274667 20.394667-43.690667 40.533333-77.952 14.549333-24.746667 39.466667-55.978667 64.810667-87.466666 6.4-7.978667 13.909333-17.152 22.357333-27.562667l34.304 19.456c-8.533333 10.752-15.914667 19.968-22.186666 27.733333-25.770667 31.914667-50.261333 62.165333-65.024 87.296-8.576 14.634667-15.872 27.562667-21.76 38.741334l116.906666 66.304a77.013333 77.013333 0 0 1 28.970667 106.24l-197.973333 336.810666a80 80 0 0 1-108.245334 28.458667l-411.562666-233.344a77.013333 77.013333 0 0 1-28.970667-106.24l197.973333-336.810667a80 80 0 0 1 108.245334-28.501333l116.821333 66.261333c6.912-10.624 14.634667-23.253333 23.253333-37.888 14.762667-25.173333 29.226667-61.056 44.501334-98.986666 3.712-9.173333 8.106667-20.053333 13.354666-32.725334l34.304 19.456-13.141333 32.853334c-15.061333 37.248-30.165333 74.069333-44.714667 98.816-20.138667 34.261333-37.717333 61.184-48.469333 73.429333l-118.229333-67.029333c-33.152-18.773333-73.301333-11.989333-92.074667 19.882666l-167.552 285.056c-18.773333 31.914667-6.826667 73.088 26.325333 91.904l352.554667 199.893334c33.109333 18.773333 75.050667 8.106667 93.781333-23.765334l167.594667-285.056c18.773333-31.914667 5.034667-69.248-28.117333-88.021333l-118.613334-67.242667z m-43.690667-290.133333c22.613333-36.906667 90.026667-47.786667 146.432-15.786667 56.405333 32 80.554667 94.762667 59.306667 132.437334l-34.304-19.456c9.984-18.944-7.68-57.728-45.056-78.890667-37.290667-21.162667-80.341333-16.810667-92.074667 1.109333l-34.304-19.456zM314.112 418.858667l472.704 267.989333-21.888 37.248L292.224 456.106667l21.888-37.205334z"  ></path></symbol><symbol id="icongroup" viewBox="0 0 1024 1024"><path d="M912 820.1V203.9c28-9.9 48-36.6 48-67.9 0-39.8-32.2-72-72-72-31.3 0-58 20-67.9 48H203.9C194 84 167.3 64 136 64c-39.8 0-72 32.2-72 72 0 31.3 20 58 48 67.9v616.2C84 830 64 856.7 64 888c0 39.8 32.2 72 72 72 31.3 0 58-20 67.9-48h616.2c9.9 28 36.6 48 67.9 48 39.8 0 72-32.2 72-72 0-31.3-20-58-48-67.9zM888 112c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zM136 912c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24z m0-752c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24z m704 680H184V184h656v656z m48 72c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24z"  ></path><path d="M288 474h448c8.8 0 16-7.2 16-16V282c0-8.8-7.2-16-16-16H288c-8.8 0-16 7.2-16 16v176c0 8.8 7.2 16 16 16z m56-136h336v64H344v-64zM288 758h448c8.8 0 16-7.2 16-16V566c0-8.8-7.2-16-16-16H288c-8.8 0-16 7.2-16 16v176c0 8.8 7.2 16 16 16z m56-136h336v64H344v-64z"  ></path></symbol><symbol id="iconungroup" viewBox="0 0 1024 1024"><path d="M736 550H288c-8.8 0-16 7.2-16 16v176c0 8.8 7.2 16 16 16h448c8.8 0 16-7.2 16-16V566c0-8.8-7.2-16-16-16z m-56 136H344v-64h336v64zM888 816c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z m0 96c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24zM736 266H288c-8.8 0-16 7.2-16 16v176c0 8.8 7.2 16 16 16h448c8.8 0 16-7.2 16-16V282c0-8.8-7.2-16-16-16z m-56 136H344v-64h336v64zM888 208c39.8 0 72-32.2 72-72s-32.2-72-72-72-72 32.2-72 72 32.2 72 72 72z m0-96c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zM136 64c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z m0 96c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24zM136 816c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z m0 96c-13.3 0-24-10.7-24-24s10.7-24 24-24 24 10.7 24 24-10.7 24-24 24z"  ></path></symbol></svg>',l=(c=document.getElementsByTagName("script"))[c.length-1].getAttribute("data-injectcss");if(l&&!v.__iconfont__svg__cssinject__){v.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(c){console&&console.log(c)}}!function(c){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(c,0);else{var l=function(){document.removeEventListener("DOMContentLoaded",l,!1),c()};document.addEventListener("DOMContentLoaded",l,!1)}else document.attachEvent&&(o=c,e=v.document,z=!1,(h=function(){try{e.documentElement.doScroll("left")}catch(c){return void setTimeout(h,50)}t()})(),e.onreadystatechange=function(){"complete"==e.readyState&&(e.onreadystatechange=null,t())});function t(){z||(z=!0,o())}var o,e,z,h}(function(){var c,l,t,o,e,z;(c=document.createElement("div")).innerHTML=h,h=null,(l=c.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",t=l,(o=document.body).firstChild?(e=t,(z=o.firstChild).parentNode.insertBefore(e,z)):o.appendChild(t))})}(window);
Source/UBCS-WEB/src/components/refer/vciWebReferDefalut.vue
@@ -56,7 +56,7 @@
      page: {
        pageSize: 10,
        currentPage: 1,
        total: 0
        total: this.referConfig.options.data?this.referConfig.options.data.length :0
      },
      data:this.referConfig.options.data || [],
      selectionList: [],
@@ -84,6 +84,10 @@
    console.log(this.referConfig)
  },
  mounted() {
    if(this.referConfig.options.page){
      this.page.pageSize=this.referConfig.options.page.limit || this.referConfig.options.page.pageSize;
      this.page.currentPage=this.referConfig.options.page.page || this.referConfig.options.page.currentPage;
    }
  },
  computed:{
    valueInfo:function (){
@@ -194,10 +198,10 @@
    },
    setValue(){
      if(this.selectionList.length==0){
        this.$message.error( '没有选择数据');
        this.$message.warning( '没有选择数据');
        return false;
      }else if(this.selectionList.length>1 && !this.isMuti){
        this.$message.error( '每次只能选择一条数据');
        this.$message.warning( '每次只能选择一条数据');
        return false;
      }
@@ -255,7 +259,7 @@
    },
    selectionClear() {
      this.selectionList = [];
      this.$refs.referCrud.toggleSelection();
      this.$refs.referCrud.clearSelection();
    },
    refreshChange() {
      this.onLoad(this.page, this.query);
Source/UBCS-WEB/src/components/refer/vciWebReferTable.vue
@@ -19,6 +19,9 @@
                 @size-change="sizeChange"
                 @refresh-change="refreshChange"
                 @on-load="onLoad">
        <template slot="icon" slot-scope="scope">
          <i :class="scope.row.icon" style="font-size:24px"></i>
        </template>
      </avue-crud>
      <div class="avue-dialog__footer">
        <div class="avue-dialog__footer--left valueInfo">{{ valueInfo }}</div>
@@ -56,16 +59,10 @@
      page: {
        pageSize: 10,
        currentPage: 1,
        total: 0
        total: this.referConfig.options.data?this.referConfig.options.data.length :0
      },
      data:this.referConfig.options.data || [],
      selectionList: [],
      objTree: {//用于表格树,目前还没加上使用
        keyId: 'oid',//树形id字段名称
        keyPid: 'parentSaleProduct',//树形父id字段名称
        title: 'id',//以树形式显示的字段
        defaultShow: false//默认折叠
      },
      option: {
        addBtn: false,
        height: this.referConfig.options.height ? this.referConfig.options.height : 475,
@@ -80,6 +77,8 @@
        selection: true,
        dialogClickModal: false,
        highlightCurrentRow: true,
        rowKey:'oid',
        rowParentKey:'parentSaleProduct',
        column: []
      }
    };
@@ -90,6 +89,10 @@
    console.log(this.referConfig)
  },
  mounted() {
    if(this.referConfig.options.page){
      this.page.pageSize=this.referConfig.options.page.limit || this.referConfig.options.page.pageSize;
      this.page.currentPage=this.referConfig.options.page.page || this.referConfig.options.page.currentPage;
    }
  },
  computed:{
    valueInfo:function (){
@@ -255,10 +258,10 @@
    },
    setValue(){
      if(this.selectionList.length==0){
        this.$message.error( '没有选择数据');
        this.$message.warning( '没有选择数据');
        return false;
      }else if(this.selectionList.length>1 && !this.isMuti){
        this.$message.error( '每次只能选择一条数据');
        this.$message.warning( '每次只能选择一条数据');
        return false;
      }
@@ -316,7 +319,7 @@
    },
    selectionClear() {
      this.selectionList = [];
      this.$refs.referCrud.toggleSelection();
      this.$refs.referCrud.clearSelection();
    },
    refreshChange() {
      this.onLoad(this.page, this.query);
@@ -325,9 +328,9 @@
      if(this.url){
        this.loading = true;
        getList(Object.assign(params, this.query),page.currentPage, page.pageSize, this.url).then(res => {
          const data = res.data.data;
          this.page.total = data.total;
          this.data = data.records;
          debugger;
          this.page.total = res.total;
          this.data = res.data;
          this.loading = false;
          this.selectionClear();
        });
Source/UBCS-WEB/src/components/refer/vciWebReferTree.vue
@@ -119,6 +119,7 @@
          queryParams['replaceMap["' + key + '"]'] = this.options.replaceParams[key];//新的方式
        }
      }
      queryParams['parentValue']='\\IN(SELECT oid from PL_CODE_CLASSIFY where id =\'hesuanfenlei\')'
      this.params=queryParams;
    },
Source/UBCS-WEB/src/components/template/FlowPath.vue
@@ -1,11 +1,9 @@
<template>
        <avue-crud ref="crud" :table-loading="loading" :data="data" v-model="form" :option="option" :page.sync="page"
            :search.sync="search" @on-load="getDataList" @row-save="handleSave" @row-del="handleDelete"
            @row-update="handleEdit" @refresh-change="handleRefresh" @size-change="handleSizePage"
            @current-change="handleCurrentPage">
        </avue-crud>
</template>
<script>
@@ -19,11 +17,8 @@
            default: ""
        }
    },
    watch: {
    },
    data() {
        return {
            loading: false,
            page: {
                currentPage: 1,
@@ -53,6 +48,7 @@
                    {
                        label: '模板key',
                        prop: 'modelKey',
                        width:120,
                        sortable: true,
                        type: 'tree',
                        dicData: [],
@@ -74,19 +70,26 @@
                        label: '模板名称',
                        prop: 'modelName',
                        sortable: true,
                        width:220,
                        addDisabled: true,
                        editDisabled: true,
                    },
                    {
                        label: '流程模板用途',
                        label: '模板用途',
                        prop: 'buttonTypeKey',
                        type: 'tree',
                        width:120,
                        dicUrl: '/api/ubcs-flow/processTS/tt',
                        dicMethod: 'post',
                        props: {
                            value: "codee",
                            label: "namee",
                        },
                    },
                    {
                        label: '模板描述',
                        prop: 'description',
                        type:'textarea'
                    },
                ]
            },
@@ -143,8 +146,8 @@
        // ç¼–辑
        async handleEdit(row, index, done, loading) {
            console.log(row)
            const { modelName, modelKey, buttonTypeKey, id } = row
            let param = { modelName, modelKey, buttonTypeKey, id }
            const { modelName, modelKey, buttonTypeKey, id ,description} = row
            let param = { modelName, modelKey, buttonTypeKey, id,description }
            const response = await flowpathSave({ ...param, ...{ templateId: this.code } })
            if (response.status === 200) {
                loading()
Source/UBCS-WEB/src/components/template/SetPersonnel.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,210 @@
<template>
    <el-dialog :title="title" :visible.sync="dialogVisible" append-to-body="true">
        <div>
            <el-tag v-for="tag in tags" :key="tag" closable disable-transitions effect="dark" @click="handleClickTag(tag)"
                @close="handleCloseTag(tag)">
                <span> {{ tag.name }}</span>
            </el-tag>
        </div>
        <el-divider v-if="tags.length !== 0"></el-divider>
        <div class="btns-icon">
            <el-button type="primary" icon="el-icon-star-off" @click="handleCollect"></el-button>
            <!-- <el-button type="primary" icon="el-icon-refresh" ></el-button> -->
        </div>
        <el-form :model="saveParam" class="demo-form-inline" label-position="left">
            <el-form-item :label="item.taskName" v-for="(item, index) in initFrom" :key="index">
                <el-select style="width: 50%;" v-model="saveParam.flowTaskUsers[index]['userId']"
                    :placeholder="item.taskName" @change="handleSelect($event, index)">
                    <el-option :label="key.userNames" :value="key.userId" v-for="(key, keyi) in typeName"
                        :key="keyi"></el-option>
                </el-select>
            </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
            <el-button @click="handleCancel">取 æ¶ˆ</el-button>
            <el-button type="primary" @click="handleConfirm">ç¡® å®š</el-button>
        </div>
    </el-dialog>
</template>
<script>
import { personnelInit, personnelCollect, cancelCollect, personnelSave, personnelDict } from '@/api/template/setPersonnel.js'
export default {
    name: 'SetPersonnel',
    props: {
        // æ˜¯å¦æ‰“å¼€
        visible: {
            typeof: Boolean,
            default: false
        },
        // æ ‡é¢˜
        title: {
            typeof: String,
            default: '人员设置'
        },
        // æ¨¡æ¿id
        code: {
            typeof: String,
            default: ''
        },
        // æ¨¡æ¿ç”¨é€”
        type: {
            typeof: String,
            default: ''
        }
    },
    watch: {
        visible(n) {
            this.dialogVisible = n;
        },
        dialogVisible(n) {
            this.$emit('update:visible', n)
        },
    },
    data() {
        return {
            dialogVisible: this.visible,
            initFrom: [],
            tags: [],
            typeName: [],
            saveParam: {},
            users: [],
        }
    },
    mounted() {
        this.apiInit()
        this.apiDict()
    },
    methods: {
        async apiInit() {
            const response = await personnelInit({ type: this.type, templateId: this.code })
            if (response.status === 200) {
                console.log(response)
                this.initFrom = response.data.data.user
                this.tags = response.data.data.collect
                const { modelKey, templateId } = response.data.data.flow
                let flowTaskUsers = response.data.data.user
                this.saveParam = { modelKey, templateId, flowTaskUsers: flowTaskUsers }
                this.handleClickTag(this.tags[0])
            }
        },
        async apiDict() {
            const response = await personnelDict()
            if (response.status === 200) {
                console.log(response)
                const data = response.data.data
                this.typeName = data.map(item => {
                    const { account, deptName, id, realName } = item
                    let userNames = `${deptName} - ${realName} - ${account}`
                    return { userId: id, userName: realName, userNames: userNames }
                })
            }
        },
        handleCollect() {
            this.$prompt('请输入一个名字', '操作', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
            }).then(async ({ value }) => {
                console.log(this.users)
                this.saveParam.flowTaskUsers = this.users
                this.saveParam = { ...this.saveParam, name: value }
                console.log(this.saveParam)
                const response = await personnelCollect(this.saveParam)
                if (response.status === 200) {
                    this.$nextTick(() => {
                        this.apiInit()
                    })
                    console.log(response)
                }
            }).catch(() => {
            });
        },
        async canCollect(name) {
            const response = await cancelCollect({ name: name })
            if (response.status === 200) {
                console.log(response)
                this.apiInit()
                this.$message({
                    type: 'success',
                    message: response.data.msg
                });
            }
        },
        async apiSave() {
            try {
                const { modelKey, templateId } = this.saveParam
                const response = await personnelSave({ modelKey, templateId })
                if (response.status === 200) {
                    console.log(response)
                    this.$message({
                    type: 'success',
                    message: response.data.msg
                });
                    this.done()
                }
            } catch {
                console.error('接口调用失败')
            }
        },
        handleClickTag(event) {
            console.log(event)
            const flowTaskUsers = event.flowTaskUsers
            this.saveParam.flowTaskUsers = flowTaskUsers.map(item => {
                const { taskId, taskName, userId, userName } = item
                return { taskId, taskName, userId, userName }
            })
        },
        handleCloseTag(event) {
            console.log(event)
            this.canCollect(event.name)
        },
        handleSelect(event, index) {
            const res = this.typeName.find(item => item.userId === event)
            const { userName } = res
            let users = { ... this.saveParam.flowTaskUsers[index], userName }
            console.log(users)
            this.users[index] = users
        },
        done() {
            this.dialogVisible = false
        },
        handleCancel() {
            this.done()
        },
        handleConfirm() {
            console.log(this.users)
            console.log(this.saveParam)
            this.apiSave()
        }
    }
}
</script>
<style lang="scss">
.el-tag+.el-tag {
    margin-left: 10px;
    margin-top: 10px;
}
.button-new-tag {
    margin-left: 10px;
    height: 32px;
    line-height: 30px;
    padding-top: 0;
    padding-bottom: 0;
}
.input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: bottom;
}
.btns-icon {
    display: flex;
    justify-content: end;
    padding-bottom: 10px;
}
</style>
Source/UBCS-WEB/src/components/template/Stage.vue
@@ -1,5 +1,5 @@
<template>
    <el-dialog title="模板阶段" width="90%" append-to-body="true" :visible.sync="dialogVisible">
    <div>
        <avue-crud ref="crud" :table-loading="loading" :data="data" :option="option" :page.sync="page"
            @on-load="getDataList" @size-change="handleSizePage" @current-change="handleCurrentPage"
            @row-click="handleRowClick">
@@ -8,7 +8,7 @@
                    @click="handleMaintenance(row, index)">维护</el-button>
            </template>
        </avue-crud>
        <el-dialog title="模板阶段" width="50%" append-to-body="true" :visible.sync="dialogNode">
        <el-dialog title="模板阶段" width="50%"  append-to-body="true" :visible.sync="dialogNode">
            <avue-crud ref="crud" :table-loading="loading" :data="stageData" :option="stageOption" @on-load="getStagelist"
                @row-click="handleRowStageClick">
                <template slot-scope="{type,size,row,index}" slot="menu">
@@ -17,9 +17,9 @@
                </template>
            </avue-crud>
        </el-dialog>
        <table-transfer :visible.sync="dialogTransfer" v-model="listVal" :dataList="tableData" :columns="columns"
            keyName="oid" @save="handleSave"></table-transfer>
    </el-dialog>
        <table-transfer v-if="flag" :visible.sync="dialogTransfer" v-model="attributeValue" :dataList="attributeData"
            :columns="columns" keyName="oid" @save="handleSave" @close="handelClose"></table-transfer>
    </div>
</template>
<script>
@@ -31,11 +31,6 @@
        TableTransfer
    },
    props: {
        // æ˜¯å¦æ‰“å¼€
        visible: {
            typeof: Boolean,
            default: false
        },
        code: {
            typeof: String,
            required: true,
@@ -43,25 +38,7 @@
        }
    },
    watch: {
        visible(n) {
            this.dialogVisible = n;
        },
        dialogVisible(n) {
            this.$emit('update:visible', n)
        },
    },
    computed: {
        tableData() {
            return this.setTable()
        },
        listVal() {
            let data = this.setTable()
            let newdata = data.map(item => {
                return item.checked ? item.oid : undefined
            })
            console.log(newdata.filter(item => item))
            return newdata.filter(item => item)
        }
    },
    data() {
        const options = {
@@ -81,9 +58,9 @@
            editBtn: false,
        }
        return {
            list: [],
            listRight: [],
            dialogVisible: this.visible,
            attributeData: [],
            attributeValue: [],
            flag: false,
            dialogTransfer: false,
            dialogNode: false,
            visibleTable: false,
@@ -129,6 +106,7 @@
            },
            stageOption: {
                ...options,
              height:620,
                column: [
                    { label: '阶段编号', prop: 'taskId' },
                    { label: '阶段名称', prop: 'taskName' },
@@ -136,14 +114,11 @@
            },
        }
    },
    mounted() {
        this.getAttributeList()
    },
    methods: {
        setTable() {
            return this.list.map(item => {
                if (this.listRight.length !== 0) {
                    this.listRight.forEach(element => {
        setTable(data, list) {
            return data.map(item => {
                if (list.length !== 0) {
                    list.forEach(element => {
                        if (item.id === element.attrId) item.checked = true
                    });
                }
@@ -178,12 +153,22 @@
        // èŽ·å–å…¨éƒ¨å±žæ€§
        async getAttributeList() {
            const response = await attributeList({ 'conditionMap[classifyTemplateOid]': this.code })
            if (response.status === 200) {
                const data = response.data.data
                this.list = data.records.map(item => {
            const responseRight = await attributeListRight({ templateId: this.code, modelKey: this.modelKey, taskId: this.saveParam.taskId })
            if (response.status === 200 && responseRight.status === 200) {
                let datas = response.data.data.records
                let dataRight = responseRight.data.data
                datas = datas.map(item => {
                    const { oid, id, name, attributeGroup } = item
                    return { oid, id, name, attributeGroup, ...{ checked: false } }
                    item = { oid, id, name, attributeGroup, ...{ checked: false } }
                    if (dataRight.length !== 0) {
                        dataRight.forEach(element => { if (item.id === element.attrId) item.checked = true });
                        return item
                    }
                })
                let dataValue = datas.map(item => item.checked ? item.oid : undefined)
                this.attributeValue = dataValue.filter(item => item)
                this.attributeData = datas
                this.flag = true
            }
        },
        // èŽ·å–å·²ä¿å­˜å±žæ€§
@@ -205,17 +190,12 @@
            this.saveParam.modelKey = row.modelKey
        },
        handleMaintenanceTransfer(row) {
            console.log(row)
            this.dialogTransfer = true
            this.saveParam.taskId = row.taskId
            this.saveParam.taskName = row.taskName
            this.getAttributeListRight()
        },
        handleSizePage(event) {
            this.page.pageSize = event
        },
        handleCurrentPage(event) {
            this.page.currentPage = event
            this.getAttributeList()
            this.$nextTick(() => {
                this.dialogTransfer = true
            })
        },
        handleRowClick(row) {
            console.log(row)
@@ -224,10 +204,12 @@
            this.dialogNode = true
        },
        handleRowStageClick(row) {
            this.dialogTransfer = true
            this.saveParam.taskId = row.taskId
            this.saveParam.taskName = row.taskName
            this.getAttributeListRight()
            this.getAttributeList()
            this.$nextTick(() => {
                this.dialogTransfer = true
            })
        },
        async handleSave(event) {
            console.log(event)
@@ -250,9 +232,13 @@
                    type: 'success',
                    message: '新增数据成功!'
                })
                this.flag = false
                // done()
                // this.getDataList()
            }
        },
        handelClose() {
            this.flag = false
        }
    }
}
Source/UBCS-WEB/src/components/template/TableTransfer.vue
@@ -1,5 +1,5 @@
<template>
    <el-dialog :title="title" width="70%" append-to-body="true" :visible.sync="dialogVisible">
    <el-dialog :title="title" width="70%" append-to-body="true" :visible.sync="dialogVisible" @close="handelClose">
        <el-row :gutter="20">
            <el-col :span="11">
                <el-card class="box-card">
@@ -8,9 +8,9 @@
                        <el-input class="input" v-if="showSearch" v-model="searchLeft" placeholder="请输入搜索内容"
                            @keyup.enter.native="handleEnter"></el-input>
                    </div>
                    <el-table ref="transferLeftTable" :data="leftData" height="500" highlight-current-row
                        tooltip-effect="dark" @selection-change="handleLeftSelectionChange" @row-click="handleLeftRowClick">
                        <el-table-column type="selection" width="50" align="center" fixed="left" :selectable="selectable" />
                    <el-table ref="transferTable" :data="leftData" height="500" highlight-current-row tooltip-effect="dark"
                        @selection-change="handleLeftSelectionChange" @row-click="handleLeftRowClick">
                        <el-table-column type="selection" width="50" align="center" fixed="left" />
                        <div v-for="(item, index) in columns" :key="index">
                            <el-table-column v-if="item.visible" :label="item.label" align="center" :prop="item.key" />
                        </div>
@@ -74,7 +74,7 @@
        //主键key值
        keyName: {
            type: String,
            default: "id",
            default: "oid",
        },
        columns: {
            type: Array,
@@ -116,17 +116,12 @@
            },
            deep: true,
        },
        dataList: {
            handler(data) {
                console.log(data)
            },
            deep: true,
        }
    },
    data() {
        return {
            dialogVisible: this.visible,
            indeterminate: false,
            isCheck: false,
            searchLeft: "",
            leftIds: [],
            leftMultiple: true,
@@ -141,25 +136,26 @@
    },
    mounted() {
        this.init();
        console.log(this.$refs.transferTable)
    },
    methods: {
        selectable(row, index) {
            console.log(row)
            return row.checked === false //为true的时候可以选,为false则不可选择
        },
        init() {
            this.rightIds = this.value;
            console.log(this.rightIds)
            for (let i = 0; i < this.dataList.length; i++) {
                if (this.value.some((item) => item == this.dataList[i][this.keyName])) {
                    this.rightDataList.push(this.dataList[i]);
                } else {
                    this.leftDataList.push(this.dataList[i]);
            let that = this
            that.rightIds = that.value;
            for (let i = 0; i < that.dataList.length; i++) {
                if (that.value.some((item) => item == that.dataList[i][that.keyName])) {
                    that.rightDataList.push(that.dataList[i]);
                }
                // else{
                //     that.leftDataList.push(that.dataList[i])
                // }
                that.leftDataList.push(that.dataList[i])
            }
            this.leftData = [...this.leftDataList];
            this.rightData = [...this.rightDataList];
            that.leftData = [...that.leftDataList];
            that.rightData = [...that.rightDataList];
        },
        // left多选框选中数据
        handleLeftSelectionChange(selection) {
            this.leftIds = selection.map((item) => item[this.keyName]);
@@ -176,21 +172,26 @@
                let a = this.leftIds.findIndex(
                    (item) => item == this.leftDataList[i][this.keyName]
                );
                console.log(a)
                if (a !== -1) {
                    this.rightDataList.push(this.leftDataList[i]);
                    // this.leftDataList[i].checked = true
                    // this.$refs.transferLeftTable.toggleRowSelection(this.leftDataList[i],true)
                    this.$delete(this.leftDataList, i);
                    i--;
                    let moveLefti = this.leftDataList[i];//左边罗过来的
                    let moveLeftiKey = moveLefti['id'];
                    let isMove = true;
                    for (let j = 0; j < this.rightDataList.length; j++) {
                        let rifhtDataListi = this.rightDataList[j];//右边循环出来的每一个
                        let rightDataListiKey = rifhtDataListi['id'];//每一个key
                        if (rightDataListiKey == moveLeftiKey) {
                            isMove = false;
                            break;
                        }
                    }
                    if (isMove) {
                        this.rightDataList.push(this.leftDataList[i]);
                        this.leftDataList[i].checked = true
                        // this.$delete(this.leftDataList, i);
                        // i--;
                    }
                }
            }
            // let obj = {}
            // let filterright = this.rightDataList.reduce((cur, next) => {
            //     obj[next.id] ? "" : obj[next.id] = true && cur.push(next);
            //     return cur;
            // }, [])
            // console.log('filterright', filterright)
            this.leftData = this.setData(this.leftDataList, this.searchLeft);
            this.rightData = this.setData(this.rightDataList, this.searchRight);
            this.$emit(
@@ -205,17 +206,13 @@
                    (item) => item == this.rightDataList[i][this.keyName]
                );
                if (a !== -1) {
                    this.leftDataList.push(this.rightDataList[i]);
                    this.leftDataList[i].checked = false
                    // this.leftDataList.push(this.rightDataList[i]);
                    this.$delete(this.rightDataList, i);
                    i--;
                }
            }
            // let obj = {}
            // let filterleft = this.leftDataList.reduce((cur, next) => {
            //     obj[next.id] ? "" : obj[next.id] = true && cur.push(next);
            //     return cur;
            // }, [])
            // console.log('filterright', filterleft)
            console.log(this.rightDataList)
            this.leftData = this.setData(this.leftDataList, this.searchLeft);
            this.rightData = this.setData(this.rightDataList, this.searchRight);
            this.$emit(
@@ -233,9 +230,9 @@
        // å•选
        handleLeftRowClick(row) {
            if (this.leftData) {
                this.$refs.transferLeftTable.toggleRowSelection(row)
                this.$refs.transferTable.toggleRowSelection(row)
            } else {
                this.$refs.transferLeftTable.clearSelection()
                this.$refs.transferTable.clearSelection()
            }
        },
        // å•选
@@ -268,16 +265,23 @@
            console.log(this.value)
        },
        done() {
            this.leftData = []
            this.leftDataList = []
            this.rightDataList = []
            this.rightData = []
            this.dialogVisible = false
        },
        tableTransferSave() {
            this.$emit('save', this.rightData)
            this.leftData = [...this.rightData, ...this.leftData]
            this.leftDataList = [...this.rightDataList, ...this.leftDataList]
            this.rightDataList = []
            this.rightData = []
            this.done()
        }
        },
        // å…³é—­æ¸…除所有数据
        handelClose() {
            this.$emit('close')
            this.done()
        },
    },
}
</script>
Source/UBCS-WEB/src/views/MasterData/FormTempalteTest.vue
@@ -35,8 +35,8 @@
      disabledProp: ["id", 'lcstatus'],
      // è¡¨å•类型
      type: "add",
      templateOid: "78B8C7C5-A042-0B96-FE6D-65421451782A",
      codeClassifyOid: "4524E801-6CC6-92E8-1AC3-2AB9604E8F96",
      templateOid: "A12826E4-2B66-6D56-DE30-92BB1D7F607F",
      codeClassifyOid: "D9CF223F-317D-71EB-BD11-433A94CAD9F3",
      codeRuleOid: "B95872A6-9CEA-D490-8F1B-9D26548CAF96",
      rowOid: '6EF696C3-CD87-0E7C-1EA1-8DE3913A95C9'
    };
Source/UBCS-WEB/src/views/MasterData/items.vue
@@ -7,10 +7,10 @@
                       @coderuleoid="coderuleoidList"
                       :pageSize="this.pageSize"
                       :currentPage="this.currentPage"
                       :templateOid="this.templateOid"
                       @tableDataArray="tableDataArrays"
                       @tableHeadDataFateher="tableHeadDatas"
                       @total="totals"
                       @nodeClick="nodeClick"
                        ></master-tree>
        </basic-container>
      </el-aside>
@@ -21,10 +21,11 @@
                 :coderuleoid="this.coderuleoid"
                 @pageSize="pageSizes"
                 @currentPage="currentPages"
                 @templateOid="templateOids"
                 :tableDataArray="tableDataArray"
                 :total="this.total"
                 :tableHeadDataFateher="this.tableHeadDataFateher"
                 :isLoading="isLoading"
                 :templateOid="templateOid"
      ></TableCrud>
      </el-main>
    </el-container>
@@ -49,7 +50,9 @@
      templateOid:"",
      tableDataArray:[],
      tableHeadDataFateher:[],
      total:""
      total:"",
      isLoading: false,
    }
  },
  created() {
@@ -68,9 +71,6 @@
    currentPages(val){
      this.currentPage=val
    },
    templateOids(val){
      this.templateOid=val
    },
    tableDataArrays(val){
      this.tableDataArray=val
    },
@@ -79,7 +79,15 @@
    },
    tableHeadDatas(val){
      this.tableHeadDataFateher=val
    }
    },
    nodeClick(val){
      this.templateOid=val;
      console.log('val',val)
      this.isLoading=true;
      setTimeout(() => {
        this.isLoading = false;
      }, 2000);
}
  }
}
</script>
Source/UBCS-WEB/src/views/flow/flowPath.vue
@@ -1,82 +1,34 @@
<template>
    <div>
        <el-button @click="outerVisible = true">流程测试</el-button>
        <el-button @click="visibleFlow = true">模板流程</el-button>
        <el-button @click="visibleStage = true">模板阶段</el-button>
        <el-button @click="visibleTable = true">table穿梭框</el-button>
        <el-button @click="handleTable">人员设置</el-button>
        <flow-business :visible.sync="outerVisible"></flow-business>
        <flow-path :visible.sync="visibleFlow" code="8b5e2017-990f-454a-9c39-4c4eeeb57553"></flow-path>
        <stage :visible.sync="visibleStage" code="8b5e2017-990f-454a-9c39-4c4eeeb57553"></stage>
        <table-transfer :visible.sync="visibleTable" v-model="value" :dataList="list" :columns="columns" keyName="id"
            @change="change"></table-transfer>
       <set-personnel :visible.sync="visibleFlow" code="8b5e2017-990f-454a-9c39-4c4eeeb57553" type="PUBLIC"></set-personnel>
    </div>
</template>
<script>
import FlowBusiness from '@/components/template/Business'
import FlowPath from '@/components/template/FlowPath'
import Stage from '@/components/template/Stage'
import TableTransfer from '@/components/template/TableTransfer'
import SetPersonnel from '@/components/template/SetPersonnel'
export default {
    components: {
        FlowBusiness,
        FlowPath,
        Stage,
        TableTransfer
        SetPersonnel
    },
    data() {
        const getTables = () => {
            let data = []
            for (let i = 0; i < 5; i++) {
                let item = {
                    id: `${i+1}`,
                    name: 'name',
                    address: '集团码',
                    data:'',
                    checked:false,
                }
                data.push(item)
            }
            return data
        }
        return {
            list: getTables(),
            value: [],
            outerVisible: false,
            visibleFlow: false,
            visibleStage: false,
            visibleTable: false,
            columns: [
                {
                    key: "id",
                    label: "id",
                    visible: false,
                },
                {
                    key: "name",
                    label: "属性编号",
                    visible: true,
                },
                {
                    key: "address",
                    label: "属性名称",
                    visible: true,
                },
                {
                    key: "address",
                    label: "属性分组",
                    visible: true,
                },
            ],
        }
    },
    methods: {
        change(val) {
            console.log(val);
            console.log(this.value)
        handleSave(event) {
            console.log(event)
        },
        handleTable(){
            this.visibleFlow = true
        }
    }
}
</script>
Source/UBCS-WEB/src/views/integration/applicationForm.vue
@@ -117,9 +117,13 @@
        },
        async getDataList() {
            this.loading = true
            console.log(this.searchParam)
            const { pageSize, currentPage, total } = this.page
            let param = { size: pageSize, current: currentPage }
            console.log(this.searchParam)
            this.searchParam = Object.keys(this.searchParam)
                .filter((key) => this.searchParam[key] !== null && this.searchParam[key] !== undefined && this.searchParam[key] !== "")
                .reduce((acc, key) => ({ ...acc, [key]: this.searchParam[key] }), {});
            console.log(this.searchParam)
            const response = await getList({ ...param, ...this.searchParam })
            if (response.status === 200) {
                this.loading = false
@@ -137,8 +141,10 @@
        },
        handleReset() {
            this.searchParam = {}
            this.getDataList()
        },
        handleSearch(form, done) {
            console.log(form)
            const { id, groupCode, operationType } = form
            let dataTime = { id, groupCode, operationType }
            if (form.hasOwnProperty('createTime')) {
@@ -147,7 +153,6 @@
            if (form.hasOwnProperty('lastModifyTime')) {
                dataTime = { lastModifyTime: dateFormat(form.lastModifyTime), ...dataTime }
            }
            console.log(dataTime)
            this.searchParam = dataTime
            this.page.currentPage = 1
            this.getDataList()
Source/UBCS-WEB/src/views/integration/systemInfo.vue
@@ -5,8 +5,8 @@
            @refresh-change="handleRefresh" @size-change="handleSizePage" @current-change="handleCurrentPage"
            @selection-change="selectionChange" @row-click="handleRowClick">
            <template slot="menuLeft">
                <el-button icon="el-icon-search" size="small" type="primary" @click="handleStatus">查 è¯¢
                </el-button>
                <!-- <el-button icon="el-icon-search" size="small" type="primary" @click="handleStatus">查 è¯¢
                </el-button> -->
                <el-button icon="el-icon-delete" size="small" type="danger" @click="handleDeleteByIds">删 é™¤
                </el-button>
            </template>
@@ -68,7 +68,8 @@
                            required: true,
                            message: '系统编号不能为空',
                            trigger: 'blur'
                        }]
                        }],
                        // maxlength: 30,    //字数限制
                    }, {
                        label: '系统名称',
                        prop: 'name',
@@ -77,7 +78,8 @@
                            required: true,
                            message: '系统名称不能为空',
                            trigger: 'blur'
                        }]
                        }],
                        // maxlength: 30,    //字数限制
                    },
                    {
                        label: '系统描述',
@@ -95,6 +97,9 @@
            console.log(this.search)
            const { pageSize, currentPage } = this.page
            let param = { size: pageSize, current: currentPage }
            this.search = Object.keys(this.search)
                .filter((key) => this.search[key] !== null && this.search[key] !== undefined && this.search[key] !== "")
                .reduce((acc, key) => ({ ...acc, [key]: this.search[key] }), {});
            const response = await getSysInfoList({ ...param, ...this.search })
            if (response.status === 200) {
                console.log(response)
@@ -106,31 +111,36 @@
        },
        // æ–°å¢ž
        async handleSave(row, done, loading) {
            const response = await sysInfoAdd(row)
            if (response.status === 200) {
            try {
                const response = await sysInfoAdd(row)
                if (response.status === 200) {
                    this.$message({
                        type: 'success',
                        message: '新增数据成功!'
                    })
                    done(row)
                    // this.$refs.crud.refreshTable()
                    // this.getDataList()
                }
            } catch {
                loading()
                this.$message({
                    type: 'success',
                    message: '新增数据成功!'
                })
                done()
                this.$refs.crud.refreshTable()
                this.getDataList()
            }
        },
        // ç¼–辑
        async handleEdit(row, index, done, loading) {
            console.log(row)
            const { oid, id, name, description } = row
            const response = await sysInfoEdit({ oid, id, name, description })
            if (response.status === 200) {
            try {
                const { oid, id, name, description } = row
                const response = await sysInfoEdit({ oid, id, name, description })
                if (response.status === 200) {
                    loading()
                    this.$message({
                        type: 'success',
                        message: '修改数据成功!'
                    })
                    done(row)
                }
            } catch {
                loading()
                this.$message({
                    type: 'success',
                    message: '修改数据成功!'
                })
                done()
                this.getDataList()
            }
        },
        // åˆ é™¤å•条
Source/UBCS-WEB/src/views/modeling/Business.vue
@@ -4,7 +4,8 @@
      <el-button-group>
        <el-button type="primary" @click="businessAdd" size="small"> <i class="el-icon-plus"></i>&nbsp; æ–°å¢ž</el-button>
        <el-button type="primary" @click="businessEdit" size="small"><i class="el-icon-edit"></i>&nbsp; ä¿®æ”¹</el-button>
        <el-button type="primary" @click="selectFromTable" size="small"><i class="el-icon-thumb"></i>&nbsp; ä»Žå·²æœ‰ä¸­èŽ·å–</el-button>
        <el-button type="primary" @click="selectFromTable" size="small"><i class="el-icon-thumb"></i>&nbsp;
          ä»Žå·²æœ‰ä¸­èŽ·å–</el-button>
      </el-button-group>
    </el-header>
    <el-container>
@@ -27,14 +28,16 @@
          <basic-container>
            <p style="margin-top: 10px;font-weight: 570;font-size: 19px">基本信息</p>
            <el-descriptions class="margin-top" :column="3" :size="size" border>
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle" :contentStyle="descriptionOption.contentStyle">
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle"
                :contentStyle="descriptionOption.contentStyle">
                <template slot="label">
                  <i :class="icons.key"></i>
                  è‹±æ–‡åç§°
                </template>
                {{ obj.id }}
              </el-descriptions-item>
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle" :contentStyle="descriptionOption.contentStyle">
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle"
                :contentStyle="descriptionOption.contentStyle">
                <template slot="label">
                  <i :class="icons.name"></i>
                  ä¸­æ–‡åç§°
@@ -42,20 +45,22 @@
                {{ obj.name }}
              </el-descriptions-item>
              <el-descriptions-item>
                <template slot="label" :labelStyle="descriptionOption.labelStyle" :contentStyle="descriptionOption.contentStyle">
                <template slot="label" :labelStyle="descriptionOption.labelStyle"
                  :contentStyle="descriptionOption.contentStyle">
                  <i :class="icons.tableName"></i>
                  æ•°æ®åº“表名
                </template>
                {{ obj.tableName }}
              </el-descriptions-item>
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle" :contentStyle="descriptionOption.contentStyle">
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle"
                :contentStyle="descriptionOption.contentStyle">
                <template slot="label">
                  <i :class="icons.domain"></i>
                  æ‰€å±žé¢†åŸŸ
                </template>
                  <el-tag size="small">
                    {{ obj.domainText }}
                  </el-tag>
                <el-tag size="small">
                  {{ obj.domainText }}
                </el-tag>
              </el-descriptions-item>
              <!-- <el-descriptions-item>
            <template slot="label">
@@ -71,28 +76,31 @@
            </template>
            {{ obj.sss }}
          </el-descriptions-item> -->
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle" :contentStyle="descriptionOption.contentStyle">
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle"
                :contentStyle="descriptionOption.contentStyle">
                <template slot="label">
                  <i :class="icons.revisionRule"></i>
                  ç‰ˆæœ¬è§„则
                </template>
                {{ obj.versionRule }}
              </el-descriptions-item>
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle" :contentStyle="descriptionOption.contentStyle">
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle"
                :contentStyle="descriptionOption.contentStyle">
                <template slot="label">
                  <i :class="icons.lifeCycle"></i>
                  ç”Ÿå‘½å‘¨æœŸ
                </template>
                {{ obj.lifeCycleId }}
              </el-descriptions-item>
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle" :contentStyle="descriptionOption.contentStyle">
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle"
                :contentStyle="descriptionOption.contentStyle">
                <template slot="label">
                  <i :class="icons.view"></i>
                  è§†å›¾
                </template>
               <el-tag size="small">
                <el-tag size="small">
                  {{ obj.viewText }}
               </el-tag>
                </el-tag>
              </el-descriptions-item>
              <!-- <el-descriptions-item>
            <template slot="label">
@@ -101,7 +109,8 @@
            </template>
            {{ obj.implClass }}
          </el-descriptions-item> -->
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle" :contentStyle="descriptionOption.contentStyle">
              <el-descriptions-item :labelStyle="descriptionOption.labelStyle"
                :contentStyle="descriptionOption.contentStyle">
                <template slot="label">
                  <i :class="icons.desc"></i>
                  æè¿°
@@ -114,9 +123,9 @@
          <basic-container>
            <p style="margin-top: 10px;font-weight: 570;font-size: 19px">属性列表</p>
            <avue-crud class="attributeCrud" v-model="obj" :data="obj.attributes" :option="loadOption">
              <template slot="attrDataTypeText" slot-scope="{row}" >
                    <el-tag>{{row.attrDataTypeText}}</el-tag>
                </template>
              <template slot="attrDataTypeText" slot-scope="{row}">
                <el-tag>{{ row.attrDataTypeText }}</el-tag>
              </template>
            </avue-crud>
          </basic-container>
        </el-main>
@@ -129,7 +138,8 @@
          <div class="sep" style="height:7px">
          </div>
          <avue-crud class="businessCrud" v-model="ref.form" :option="ref.option" :data="ref.data" @selection-change="selectionChange">
          <avue-crud class="businessCrud" v-model="ref.form" :option="ref.option" :data="ref.data"
            @selection-change="selectionChange">
          </avue-crud>
          <span slot="footer" class="dialog-footer">
            <el-button @click="dialoghandelfalse">取 æ¶ˆ</el-button>
@@ -138,8 +148,9 @@
        </el-dialog>
      </el-container>
    </el-container>
    <business-add ref="btmAdd" :btmType="addOption.btmType" :domainOption="domainOptions" :icons="icons" @refreshTable="initTreeOnLoad">
  </business-add>
    <business-add ref="btmAdd" :btmType="addOption.btmType" :domainOption="domainOptions" :icons="icons"
      @refreshTable="initTreeOnLoad">
    </business-add>
  </el-container>
</template>
<script>
@@ -172,8 +183,8 @@
          children: 'childList',
        }
      },
      addOption:{
        btmType:{},
      addOption: {
        btmType: {},
      },
      loadOption: {
        border: true,
@@ -182,8 +193,8 @@
        addBtn: false,
        menu: false,
        highlightCurrentRow: true,
        refreshBtn:false,
        columnBtn:false,
        refreshBtn: false,
        columnBtn: false,
        column: [
          {
            label: '英文名称',
@@ -213,12 +224,12 @@
        ]
      },
      descriptionOption: {
        labelStyle:'text-align:center;width:120px',
        labelStyle: 'text-align:center;width:120px',
        contentStyle: 'width:240px;text-align:center;word-break;break-all;'
      },
      domain: null,
      domainOptions: [],
      icons:{
      icons: {
        key: 'el-icon-finished',
        name: 'el-icon-tickets',
        tableName: 'el-icon-date',
@@ -268,9 +279,13 @@
  },
  methods: {
    nodeClick(data) {
      getDetail(data.oid).then(res => {
        this.obj = res.data.data;
      })
      if (data.oid) {
        getDetail(data.oid).then(res => {
          this.obj = res.data.data;
        })
      }else{
        this.$message.warning('请点击子节点');
      }
    },
    //  åŸºæœ¬ä¿¡æ¯æ·»åŠ 
    basicSave(row, done, loading) {
@@ -330,17 +345,17 @@
        this.initTreeOnLoad();
      })
    },
    businessAdd(){
    businessAdd() {
      this.$refs.btmAdd.showSubmitDialog = true;
      this.ifRefreshBtmAddRefresh();
    },
    businessEdit(){
    businessEdit() {
      var json = JSON.stringify(this.obj);
      this.$refs.btmAdd.btmType = JSON.parse(json);
      this.$refs.btmAdd.showSubmitDialog = true;
      this.ifRefreshBtmAddRefresh();
    },
    ifRefreshBtmAddRefresh(){
    ifRefreshBtmAddRefresh() {
      // this.$refs.btmAdd.refreshAttrTable();
    }
  },
@@ -353,13 +368,14 @@
  border-radius: 10px;
}
.businessCrud > .el-card:nth-of-type(2) > .el-card__body > .avue-crud__menu{
        display: none !important;
.businessCrud>.el-card:nth-of-type(2)>.el-card__body>.avue-crud__menu {
  display: none !important;
}
.attributeCrud > .el-card:nth-of-type(2) > .el-card__body > .avue-crud__menu{
        display: none !important;
.attributeCrud>.el-card:nth-of-type(2)>.el-card__body>.avue-crud__menu {
  display: none !important;
}
.businessTreeContainer > .el-card > .el-card__body {
.businessTreeContainer>.el-card>.el-card__body {
  height: 775px;
}
</style>
}</style>
Source/UBCS-WEB/src/views/modeling/LinkType.vue
@@ -255,7 +255,6 @@
            this.addOption.linkType = JSON.parse(json);
            this.$refs.linkAdd.linkType = this.addOption.linkType;
            this.$refs.linkAdd.showSubmitDialog = true;
            console.log(this.obj);
        },
        // ä»Žå·²æœ‰ä¸­èŽ·å–æŒ‰é’®ç‚¹å‡»äº‹ä»¶
        selectFromTable() {
Source/UBCS-WEB/src/views/modeling/Version.vue
@@ -63,20 +63,38 @@
        searchMenuSpan:5,
        highlightCurrentRow: true,
        stripe:true,
        viewBtn:false,
        columnBtn:false,
        column:[
          {
            label: '',
            label: '选择',
            prop: 'radio',
            width: 120
            width: 120,
            display:false
          },
          {
            label:'英文名称',
            prop: 'id'
            prop: 'id',
            rules: [
              {
                required: true,
                message: '英文名称不能为空',
                trigger: 'blur'
              }
            ]
          },
          {
            label:"中文名称",
            prop:"name",
            search:true,
            required: true,
            rules: [
              {
                required: true,
                message: '中文名称不能为空',
                trigger: 'blur'
              }
            ]
          },
          {
            label:"跳跃字符",
@@ -84,11 +102,25 @@
          },
          {
            label: "初始值",
            prop:"startCode"
            prop:"startCode",
            rules: [
              {
                required: true,
                message: '初始值不能为空',
                trigger: 'blur'
              }
            ]
          },
          {
            label: "步长",
            prop: "serialStep"
            prop: "serialStep",
            rules: [
              {
                required: true,
                message: '步长不能为空',
                trigger: 'blur'
              }
            ]
          },
          {
            label: "前缀",
@@ -171,11 +203,16 @@
      })
    },
    searchChange(params, done) {
      if (done) done();
      this.params = params;
      this.page.currentPage = 1;
      this.getList();
      this.$message.success('搜索成功')
      var p = {"name_like" : params.name}
      getPage(this.page.currentPage,this.page.pageSize,p).then(res => {
        const data = res.data.data
        this.loading = false;
        this.page.total = data.total;
        this.data = data.records;
      });
      if (done) {
       done();
      }
    },
    refreshChange() {
      this.getList();
Source/UBCS-WEB/src/views/modeling/cycle.vue
@@ -1,190 +1,199 @@
<template>
  <el-container>
  <el-aside width="240px">
    <el-button @click="addHandlers"></el-button>
    <basic-container style="margin-top: 10px">
      <avue-tree id="basic" :data="treeData" :option="treeOption"  >
      </avue-tree>
    </basic-container>
  </el-aside>
  <basic-container >
    <el-button type="primary" @click="dialogTableVisible=true" size="small">创建模板</el-button>
    <el-button type="primary"  size="small" @click="addHandlers">编辑模板</el-button>
    <el-button type="primary" size="small" @click="$refs.flow.addNode('ffff')">添加节点</el-button>
    <br/><br/>
    <avue-flow ref="flow" v-model="form" :height="703" :option="option" :width="1500">
      <template slot="header" slot-scope="scope">
        <i class="el-icon-delete" @click="$refs.flow.deleteNode(scope.node.id)" style="margin-top: 8px"></i>
  <basic-container class="">
    <avue-crud :data="data" :option="option" @refresh-change="gettableList" :table-loading="loading">
      <template slot-scope="scope" slot="menuLeft">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="small"
          @click="openDialog('add', {})"
          >新增</el-button
        >
      </template>
      <div slot-scope="{node}">
        <span>{{ (node || {}).name }}</span>
      </div>
    </avue-flow>
    <!--    åˆ›å»ºå¯¹è¯æ¡†-->
    <el-dialog title="创建模板" :visible.sync="dialogTableVisible" append-to-body>
      <avue-form :data="addData" :option="addoption" v-model="forms">
        <template slot="filetype">
          <el-select v-model="forms.select" slot="prepend" placeholder="请选择" style="max-width: 300px">
            <el-option label="测试1" value="1"></el-option>
            <el-option label="测试2" value="2"></el-option>
            <el-option label="测试3" value="3"></el-option>
          </el-select>
          <el-button  type="primary" @click="handelLife" style="display: inline-block;margin-left: 5px">
            æ·»åŠ èµ·å§‹çŠ¶æ€
          </el-button>
        </template>
      </avue-form>
      <template slot-scope="{ row, index }" slot="menu">
        <el-button
          type="text"
          icon="el-icon-edit"
          size="mini"
          @click="openDialog('edit', row)"
          >编辑</el-button
        >
        <el-button
          type="text"
          icon="el-icon-view"
          size="mini"
          @click="openDialog('detail', row)"
          >预览</el-button
        >
      </template></avue-crud
    >
    <el-dialog
      :visible="visible"
      :width="dialogWidth"
      :title="title"
      append-to-body
      :before-close="() => {visible = false}"
      top="10vh"
    >
      <CycleFlow
        v-if="visible"
        class="cycle_flow"
        :type="type"
        :chart-data="rowData.data || {}"
        :chart-data-node-items="flowChartNodeItems"
        :rowData="rowData"
        ref="vueFlowchartEditor"
        @save-data="save"
      />
      <template #footer v-if="type !== 'detail'">
        <el-button type="primary" size="mini" @click="submit">保存</el-button>
        <el-button type="" size="mini" @click="visible = false">取消</el-button>
      </template>
    </el-dialog>
  </basic-container>
  </el-container>
</template>
<script>
import CycleFlow from "@/components/flow-cycle/flowchartEditor.vue";
export default {
  name: "cycle.vue",
  components: { CycleFlow },
  data() {
    return {
      //模板对话框,
      dialogTableVisible:false,
      forms:{
        select:""
      },
      addData:[],
      addoption:{
        formslot:true,
        column:[
      option: {
        border: true,
        align: "center",
        menuAlign: "center",
        menu: true,
        delBtn: false,
        editBtn: false,
        addBtn: false,
        column: [
          {
            label:"名称",
            prop:"name"
            label: "名称",
            prop: "name",
          },
          {
            label:"标签",
            prop:"tag"
            label: "标签",
            prop: "label",
          },
          {
            label:"起始状态",
            prop:"filetype",
            formslot: true,
            span:24
            label: "起始状态",
            prop: "startState",
          },
          {
            label: "描述",
            prop:"desc",
            type:"textarea",
            span:13
          }
        ]
      },
      count: 0,
      form: {},
      treeData: [{
        value: 0,
        label: '生命周期模板列表',
        children: [
          {
            value: 1,
            label: 'A',
            prop: "remark",
          },
          {
            value: 2,
            label: 'B',
          },
          {
            value: 3,
            label: 'C',
          },
          {
            value: 4,
            label: 'D',
          },
          {
            value: 5,
            label: 'E',
          }
        ]
      }],
      treeOption: {
        defaultExpandAll: true,
      },
      option: {
        nodeList: [
          {
            "id": "nodeA",
            "name": "流程A-节点A",
            "left": 39,
            "top": 110,
          },
          {
            "id": "nodeB",
            "name": "流程A-节点B",
            "left": 340,
            "top": 161,
          },
          {
            "id": "nodeC",
            "name": "流程A-节点C",
            "left": 739,
            "top": 161,
          },
          {
            "id": "nodeD",
            "name": "节点D",
            "left": 739,
            "top": 20,
          }
        ],
        lineList: [
          {
            "from": "nodeA",
            "to": "nodeB"
      },
      data: [
        {
          name: "我是name",
          label: "我是label",
          startState: "我是startState",
          remark: "我是remark",
          data: {
            nodes: [
              {
                type: "node",
                size: "80*48",
                shape: "flow-rect",
                color: "#1890FF",
                label: "Auditing",
                x: 110.50303650877106,
                y: 59.22389408123915,
                id: "Auditing",
                index: 0,
              },
              {
                type: "node",
                size: "80*48",
                shape: "flow-rect",
                color: "#1890FF",
                label: "Editing",
                x: 120.87992069414531,
                y: 156.76660542375714,
                id: "Editing",
                index: 1,
              },
              {
                type: "node",
                size: "80*48",
                shape: "flow-rect",
                color: "#1890FF",
                label: "Released",
                x: 100.12615232339681,
                y: 252.2339399292003,
                id: "Released",
                index: 2,
              },
            ],
            edges: [
              {
                source: "Auditing",
                sourceAnchor: 1,
                target: "Released",
                targetAnchor: 1,
              },
              {
                source: "Editing",
                sourceAnchor: 3,
                target: "Auditing",
                targetAnchor: 3,
              },
            ],
          },
          {
            "from": "nodeB",
            "to": "nodeC"
          },
          {
            "from": "nodeC",
            "to": "nodeD"
          }
        ]
      },
      computed: {
        nodeList() {
          return this.option.nodeList
        }
      },
      mounted() {
        this.form = this.nodeList[this.count].id;
      },
      methods: {
        handleClick(node) {
          this.$message.success(JSON.stringify(node))
          console.log(node)
        },
        addHandler(){
          this.dialogTableVisible=true
          console.log(1)
        },
        handelLife(){
          console.log("点击成功")
        },
        addHandlers(){
          console.log(111)
        }
      ],
      title: "预览生命周期流程图",
      visible: false,
      flowChartNodeItems: [],
      rowData: {},
      dialogWidth: "50%",
      type: "detail",
    };
  },
  methods: {
    gettableList() {
      this.loading = true
    },
    openDialog(type, row) {
      if (type === "detail") {
        this.title = "预览生命周期流程图";
        this.dialogWidth = "50%";
      } else if (type === "edit") {
        this.title = "编辑生命周期流程图";
        this.dialogWidth = "95%";
      } else if (type === "add") {
        this.title = "新增生命周期流程图";
        this.dialogWidth = "95%";
      }
    }
  }
}
      this.type = type;
      this.rowData = row;
      this.visible = true;
    },
    async submit() {
      const newRowData = await this.$refs.vueFlowchartEditor.getNewRowData();
      if (!newRowData) {
        return;
      }
      const flowData = this.$refs.vueFlowchartEditor.getFlowData();
      console.log(JSON.stringify(flowData));
    },
  },
};
</script>
<style lang="scss">
#basic {
  height: 761px;
  border-radius: 10px;
<style lang="scss" scoped>
/deep/ .el-dialog__body {
  padding: 0 20px;
}
.cycle_flow {
  height: 600px !important;
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
}
</style>
Source/UBCS-WEB/src/views/modeling/original.vue
@@ -8,15 +8,18 @@
            <el-radio v-model="selectRow" :label="row.$index">&nbsp;
            </el-radio>
          </template>
          <template slot="menu">
            <el-button icon="el-icon-edit" size="small" type="text" @click="updateSave">编辑</el-button>
            <el-button icon="el-icon-delete" size="small" type="text" @click="deleteSave">删除</el-button>
          <template slot="menu" slot-scope="{row,index}">
            <el-button icon="el-icon-edit" size="small" type="text" @click="updateSave(row,index)">编辑</el-button>
            <el-button icon="el-icon-delete" size="small" type="text" @click="deleteSave(row,index)">删除</el-button>
          </template>
          <template slot="menuLeft">
            <el-button size="small" type="primary" icon="el-icon-plus" @click="addSave">新&nbsp;&nbsp;增
            </el-button>
            <el-button size="small" plain type="primary" icon="el-icon-zoom-in" @click="applyRangeOpen">查看使用范围
            </el-button>
            <el-input placeholder="按属性英文名称查询" v-model="searchId" clearable prefix-icon="el-icon-search" class="attrSearch"
              size="small" @change="doSearch" type="text"></el-input>
            <el-button size="small" plain type="primary" icon="el-icon-search" @click="doSearch">&nbsp;搜索</el-button>
          </template>
          <template slot="typeValue" slot-scope="{row}">
            <el-tag>{{ row.typeValue }}</el-tag>
@@ -126,7 +129,7 @@
        </el-tabs>
      </basic-container>
    </el-aside>
    <originalAdd ref="originalAdd" :attribute="attribute" @refreshTable="refreshChange"></originalAdd>
    <originalAdd ref="originalAdd" @refreshTable="refreshChange"></originalAdd>
  </el-container>
</template>
@@ -154,6 +157,7 @@
      attribute: {
        nullable: true
      },
      editAttibute: {},
      applyRangeData: [],
      option: {
        height: "550px",
@@ -169,6 +173,7 @@
        addBtn: false,
        editBtn: false,
        delBtn: false,
        columnBtn:false,
        column: [{
          label: "选择",
          prop: "radio",
@@ -246,7 +251,8 @@
        itemData: {},
        activeName: "referTab",
        form: {}
      }
      },
      searchId: '',
    };
  },
  created() {
@@ -259,14 +265,21 @@
      this.$refs.originalAdd.showSubmitDialog = true;
      this.$refs.originalAdd.attribute = {};
    },
    updateSave() {
    updateSave(row,index) {
      this.selectRow = index;
      var json = JSON.stringify(row);
      this.editAttibute = JSON.parse(json);
      this.editAttibute.nullable = row.nullable == 'true' ? true : false;
      this.$refs.originalAdd.attribute = this.editAttibute;
      this.$refs.originalAdd.showSubmitDialog = true;
      this.$refs.originalAdd.attribute = this.attribute;
      this.refreshChange()
    },
    deleteSave() {
      remove(this.itemForm.itemData).then(res => {
    deleteSave(row,index) {
      console.log(row);
      remove(row.oid).then(res => {
        this.$message.success("删除成功");
      });
      this.refreshChange();
    },
    onLoad(page, params = {}) {
      this.loading = true;
@@ -303,6 +316,10 @@
      });
    },
    doSearch(){
      var params = {"id_like":this.searchId};
      this.onLoad(this.page,params);
    }
  },
  components: { Versionpackage }
}
@@ -312,4 +329,10 @@
.applyRangeTable>.el-card:nth-of-type(2)>.el-card__body>.avue-crud__menu {
  display: none !important;
}
.attrSearch {
  width:201px;
}
.attrSearch > .el-input__inner {
  width: 200px;
}
</style>
Source/UBCS-WEB/src/views/modeling/originalAdd.vue
@@ -27,10 +27,12 @@
                    <el-switch v-model="attribute.nullable" active-text="允许" inactive-text="不允许"></el-switch>
                </el-form-item>
                <el-form-item label="长度" label-width="100px" prop="maxLength">
                    <el-input-number v-model="attribute.maxLength" :min="1" :max="4000" :step="1" controls-position="right"></el-input-number>
                    <el-input-number v-model="attribute.maxLength" :min="1" :max="4000" :step="1"
                        controls-position="right"></el-input-number>
                </el-form-item>
                <el-form-item label="精度" label-width="100px" v-if="attribute.typeValue == 'VTDouble'">
                    <el-input-number v-model="attribute.precision" :min="1" :max="20" :step="1" controls-position="right" @change="changeNumber"></el-input-number>
                <el-form-item label="精度" label-width="100px" v-if="attribute.typeKey == 'VTDouble'">
                    <el-input-number v-model="attribute.precision" :min="1" :max="20" :step="1" controls-position="right"
                        @change="changeNumber"></el-input-number>
                </el-form-item>
                <el-form-item label="描述" label-width="100px">
                    <el-input v-model="attribute.description" type="text"></el-input>
@@ -59,7 +61,7 @@
                            </el-input>
                        </el-form-item>
                        <el-form-item label="枚举项" label-width="100px">
                        </el-form-item>
                    </el-tab-pane>
                </el-tabs>
@@ -74,7 +76,7 @@
                <el-container>
                    <el-aside>
                        <basic-container>
                           <span class="el-dialog__title"> {{ domain.treeOption.title }} </span>
                            <span class="el-dialog__title"> {{ domain.treeOption.title }} </span>
                            <div style="height:20px;"></div>
                            <avue-tree id="domain" :data="domain.data" :option="domain.treeOption" @node-click="nodeClick"
                                class="businessTree" style="height: 418px">
@@ -89,7 +91,8 @@
                    </el-aside>
                    <el-main>
                        <basic-container>
                            <avue-crud ref="btmTable" :option="btmRefer.option" :data="btmRefer.data" class="btmTable" @row-click="btmReferClick">
                            <avue-crud ref="btmTable" :option="btmRefer.option" :data="btmRefer.data" class="btmTable"
                                @row-click="btmReferClick">
                                <template slot="radio" slot-scope="{row}">
                                    <el-radio v-model="btmRefer.selectRow" :label="row.$index">&nbsp;
                                    </el-radio>
@@ -105,9 +108,10 @@
                </div>
            </el-dialog>
            <!-- é€‰æ‹©æžšä¸¾æ—¶çš„弹窗 -->
            <el-dialog title="枚举列表" :visible.sync="enumRefer.show" append-to-body @close="closeEnumDialog" width="70%"
            <el-dialog title="枚举列表" :visible.sync="enumRefer.show" append-to-body @close="closeEnumDialog" width="70%"
                style="height: 115vh;">
                <avue-crud ref="eunmTable" :option="enumRefer.option" :data="enumRefer.data" class="enumTable" @row-click="enumReferClick" :page.sync="enumRefer.enumPage">
                <avue-crud ref="eunmTable" :option="enumRefer.option" :data="enumRefer.data" class="enumTable"
                    @row-click="enumReferClick" :page.sync="enumRefer.enumPage">
                    <template slot="radio" slot-scope="{row}">
                        <el-radio v-model="enumRefer.selectRow" :label="row.$index">&nbsp;
                        </el-radio>
@@ -124,9 +128,9 @@
</template>
<script>
import { getDictionary,getParentList } from '@/api/omd/enum'
import { initTree,btmPage } from '@/api/omd/btmType'
import { add} from '@/api/omd/OmdAttribute'
import { getDictionary, getParentList } from '@/api/omd/enum'
import { initTree, btmPage } from '@/api/omd/btmType'
import { add } from '@/api/omd/OmdAttribute'
export default {
    name: 'originalAdd',
    props: {
@@ -181,24 +185,24 @@
                    highlightCurrentRow: true,
                    column: [
                        {
                        label: '',
                        prop: 'radio',
                        width: 60,
                        hide: false
                    },
                    {
                        label: '英文名称',
                        prop: 'id',
                        align: 'center',
                        searchSpan:8,
                        search: true,
                    }, {
                        label: '中文名称',
                        prop: 'name',
                        align: 'center',
                        searchSpan:8,
                        search: true,
                    }]
                            label: '',
                            prop: 'radio',
                            width: 60,
                            hide: false
                        },
                        {
                            label: '英文名称',
                            prop: 'id',
                            align: 'center',
                            searchSpan: 8,
                            search: true,
                        }, {
                            label: '中文名称',
                            prop: 'name',
                            align: 'center',
                            searchSpan: 8,
                            search: true,
                        }]
                },
                // å‚照页面表格数据
                data: [],
@@ -231,17 +235,17 @@
                        prop: 'radio',
                        width: 60,
                        hide: false
                    },{
                    }, {
                        label: '枚举代号',
                        prop: 'name',
                        align: 'center',
                        searchSpan:8,
                        searchSpan: 8,
                        search: true,
                    }, {
                        label: '枚举名称',
                        prop: 'label',
                        align: 'center',
                        searchSpan:8,
                        searchSpan: 8,
                        search: true,
                    }]
                },
@@ -283,30 +287,36 @@
            this.referToFlag = true;
            this.$refs.form.resetFields();
        },
        submitAttribute() {
            add(this.attribute).then(res => {
                this.$message.success("保存成功");
                this.showSubmitDialog = false;
                this.attribute = {};
                this.$emit('refreshTable');
            });
        submitAttribute() {
            const that = this;
            this.$refs.form.validate(function (pass, field) {
                if (pass) {
                    add(that.attribute).then(res => {
                        that.$message.success("保存成功");
                        that.showSubmitDialog = false;
                        that.attribute = {};
                        that.$emit('refreshTable');
                    });
                } else {
                    that.$message.error('必填');
                }
            })
        },
        cancleSubmit() {
            this.closeSubmitDialog();
        },
        closeEnumDialog() {
            this.cancleEnum();
         },
        closeReferDialog() {
        },
        closeReferDialog() {
            this.cancleBtm();
        },
        confirmBtm() {
        confirmBtm() {
            this.attribute.referToId = this.btmRefer.selectItem.oid;
            this.attribute.referToName = this.btmRefer.selectItem.name;
            this.btmRefer.show = false;
        },
        cancleBtm() {
        cancleBtm() {
            this.btmRefer.selectItem = {};
            this.btmRefer.show = false;
            this.btmRefer.selectRow = '';
@@ -316,8 +326,8 @@
            this.attribute.dictCode = this.enumRefer.selectItem.name;
            this.attribute.dictValue = this.enumRefer.selectItem.label;
            this.enumRefer.show = false;
         },
        cancleEnum() {
        },
        cancleEnum() {
            this.enumRefer.selectItem = {};
            this.enumRefer.show = false;
            this.enumRefer.selectRow = '';
@@ -340,19 +350,19 @@
        // å‚照类型树的点击事件
        nodeClick(data) {
            // åŒºåˆ†ä¸šåŠ¡ç±»åž‹çš„æŸ¥è¯¢å’Œé“¾æŽ¥ç±»åž‹çš„æŸ¥è¯¢
            if(this.attribute.referTypeKey == 'btmType'){
                btmPage(this.btmRefer.btmPage.currentPage,this.btmRefer.btmPage.pageSize,{domain:data.id}).then(res => {
            if (this.attribute.referTypeKey == 'btmType') {
                btmPage(this.btmRefer.btmPage.currentPage, this.btmRefer.btmPage.pageSize, { domain: data.id }).then(res => {
                    this.btmRefer.data = res.data.data.records;
                    this.btmRefer.btmPage.total = res.data.data.total;
                })
            }
            if(this.attribute.referTypeKey == 'linkType'){
            if (this.attribute.referTypeKey == 'linkType') {
            }
        },
        // æžšä¸¾ç±»åž‹è¾“入框获得焦点时的事件
        openEnumConfig() {
            getParentList(this.enumRefer.enumPage.currentPage,this.enumRefer.enumPage.pageSize).then(res => {
            getParentList(this.enumRefer.enumPage.currentPage, this.enumRefer.enumPage.pageSize).then(res => {
                this.enumRefer.enumPage.total = res.data.data.total;
                this.enumRefer.data = res.data.data.records;
            })
@@ -361,20 +371,20 @@
        // å±žæ€§ç±»åž‹ä¸‹æ‹‰æ¡†é€‰æ‹©äº‹ä»¶
        typeSelectChange(value) {
            if (value == 'VTString') {
                this.$set(this.attribute,"maxLength",150)
                this.$set(this.attribute, "maxLength", 150)
            } else if (value == 'VTInteger') {
                this.$set(this.attribute,"maxLength",50)
                this.$set(this.attribute, "maxLength", 50)
            } else if (value == 'VTBoolean') {
                this.$set(this.attribute,"maxLength",5)
                this.$set(this.attribute, "maxLength", 5)
            } else if (value == 'VTDouble') {
                this.$set(this.attribute,"maxLength",26)
                this.$set(this.attribute,"precision",8)
                this.$set(this.attribute, "maxLength", 26)
                this.$set(this.attribute, "precision", 8)
            } else if (value == 'VTLong') {
                this.$set(this.attribute,"maxLength",150)
                this.$set(this.attribute, "maxLength", 150)
            } else if (value == 'VTDate' || value == 'VTTime' || value == 'VTDateTime') {
                this.$set(this.attribute,"maxLength",6)
                this.$set(this.attribute, "maxLength", 6)
            } else {
                this.$set(this.attribute,"maxLength",50)
                this.$set(this.attribute, "maxLength", 50)
            }
            this.attribute.typeCode = 'attributeType';
            this.attribute.typeKey = value;
@@ -395,7 +405,7 @@
                this.$message.error('属性类型没找到或者未定义')
            })
        },
        initAttributeReferTypeList(){
        initAttributeReferTypeList() {
            getDictionary({ code: 'attributeReferType' }).then(res => {
                res.data.data.forEach(element => {
                    this.btmRefer.referTypeList.push(
@@ -406,33 +416,33 @@
                this.$message.error('参照类型没找到或者未定义')
            })
        },
        btmReferClick(row){
        btmReferClick(row) {
            this.btmRefer.selectItem = row;
            this.btmRefer.selectRow = row.$index;
        },
        enumReferClick(row){
        enumReferClick(row) {
            this.enumRefer.selectItem = row;
            this.enumRefer.selectRow = row.$index;
        },
        // å‚照名称点击清除数据
        clearReferTo(){
            this.$delete(this.attribute,'referToId');
            this.$delete(this.attribute,'referToName');
        clearReferTo() {
            this.$delete(this.attribute, 'referToId');
            this.$delete(this.attribute, 'referToName');
            this.btmRefer.selectItem = {};
            this.btmRefer.selectRow = '';
        },
        handleClick(tab){
            // å› ä¸ºåªèƒ½å‚照和枚举二选一。所以在切换的时候把属性给清空。
            this.$delete(this.attribute,'referTypeCode');
            this.$delete(this.attribute,'referTypeKey');
            this.$delete(this.attribute,'referTypeValue');
            this.$delete(this.attribute,'referToId');
            this.$delete(this.attribute,'referToName');
            this.$delete(this.attribute,'dictCode');
            this.$delete(this.attribute,'dictKey');
            this.$delete(this.attribute,'dictValue');
            this.$delete(this.attribute,'usingDict');
        }
        // handleClick(tab){
        //     // å› ä¸ºåªèƒ½å‚照和枚举二选一。所以在切换的时候把属性给清空。
        //     this.$delete(this.attribute,'referTypeCode');
        //     this.$delete(this.attribute,'referTypeKey');
        //     this.$delete(this.attribute,'referTypeValue');
        //     this.$delete(this.attribute,'referToId');
        //     this.$delete(this.attribute,'referToName');
        //     this.$delete(this.attribute,'dictCode');
        //     this.$delete(this.attribute,'dictKey');
        //     this.$delete(this.attribute,'dictValue');
        //     this.$delete(this.attribute,'usingDict');
        // }
    }
}
</script>
@@ -450,7 +460,6 @@
    width: 200px;
}
.attributeForm>.el-form-item>.el-form-item__content> .el-select>.el-input>.el-input__inner {
.attributeForm>.el-form-item>.el-form-item__content>.el-select>.el-input>.el-input__inner {
    width: 200px;
}
</style>
}</style>
Source/UBCS-WEB/src/views/modeling/status.vue
@@ -65,19 +65,30 @@
          stripe:true,
          column:[
            {
              label: '',
              label: '选择',
              prop: 'radio',
              width: 120
              width: 120,
              display: false
            },
            {
              label:'英文名称',
              prop: 'id',
              search: true
              search: true,
              rules: [{
                required: true,
                message: '英文名称不能为空',
                trigger: 'blur'
              }]
            },
            {
              label:'中文名称',
              prop:'name',
              search:true,
              rules: [{
                required: true,
                message: '中文名称不能为空',
                trigger: 'blur'
              }]
            },
            {
              label: '描述',
@@ -149,10 +160,22 @@
        })
      },
      searchChange(params, done) {
        if (done) done();
        this.params = params;
        this.loading = true;
        this.page.currentPage = 1;
        this.getList();
        const p = {};
        if(params.id){
          p["id_like"] = params.id;
        }
        if(params.name){
          p["name_like"] = params.name
        }
        getPage(this.page.currentPage,this.page.pageSize,p).then(res => {
          const data = res.data.data
          this.loading = false;
          this.page.total = data.total;
          this.data = data.records;
          done();
        })
        this.$message.success('搜索成功')
      },
      refreshChange() {
Source/UBCS-WEB/src/views/system/PasswordManagement/passwords.vue
@@ -33,7 +33,8 @@
  // getOnesearch,
  getadd,
  getupdata,
  getremove
  getremove,
  combination
} from "@/api/system/passwords";
export default {
  name: "passwords.vue",
@@ -189,24 +190,12 @@
              message: "请选择组合方法",
              trigger: "blur"
            }],
            dicData: [
              {
                label: "数字",
                value: '1638024706425188354'
              },
              {
                label: "符号",
                value: '1638097837516926977'
              },
              {
                label: "小写字母",
                value: '1638097772983365634'
              },
              {
                label: "大写字母",
                value: '1638097733707902977'
              },
            ],
            dicUrl: '/api/ubcs-system/combination/select',
            dicMethod: 'get',
            props: {
              value: "ID",
              label: "NAME",
            },
          },
          {
            label: '必填种类',
@@ -222,22 +211,22 @@
            }],
            dicData:[{
              label:'1种',
              value:0,
              value:1,
              disabled:false
              },
              {
                label:'2种',
                value:1,
                disabled:false
              },
              {
                label:'3种',
                value:2,
                disabled:false
              },
              {
                label:'4种',
                label:'3种',
                value:3,
                disabled:false
              },
              {
                label:'4种',
                value:4,
                disabled:false
              }
            ]
@@ -334,6 +323,9 @@
  },
  created() {
    this.onLoad()
    combination().then(res=>{
      console.log("111",res)
    })
  },
  mount() {
  },
@@ -497,9 +489,8 @@
        });
        done(row)
        this.onLoad()
        console.log(res)
      }).catch((res)=>{
        console.log(res)
        this.$message.warning(res)
      })
    },
    rowEdit(row){
@@ -544,8 +535,8 @@
        // this.loading = false;
        // this.selectionClear();
        console.log(res)
        this.page.total=res.data.data.totalElements
        this.data=res.data.data.content
        this.page.total=res.data.data.total
        this.data=res.data.data.records
      });
    }
  }
@@ -553,5 +544,5 @@
}
</script>
<style lang="scss">
<style lang="scss" scoped>
</style>
Source/UBCS-WEB/src/views/system/dept.vue
@@ -1,6 +1,7 @@
<template>
  <basic-container>
    <avue-crud :option="option"
               :page.sync="page"
      :table-loading="loading"
      :data="data"
      ref="crud"
@@ -75,7 +76,9 @@
        option: {
          lazy: true,
          tip: false,
          simplePage: true,
          height:'auto',
          maxHeight:600,
          // simplePage: true,
          searchShow: true,
          searchMenuSpan: 6,
          tree: true,
@@ -352,8 +355,9 @@
      },
      onLoad(page, params = {}) {
        this.loading = true;
        getLazyList(this.parentId, Object.assign(params, this.query)).then(res => {
          this.data = res.data.data;
        getLazyList(this.parentId,Object.assign(params, this.query),this.page.currentPage, this.page.pageSize).then(res => {
          this.data = res.data.data.records;
          this.page.total=res.data.data.total
          this.loading = false;
          this.selectionClear();
        });
@@ -361,7 +365,7 @@
      treeLoad(tree, treeNode, resolve) {
        const parentId = tree.id;
        getLazyList(parentId).then(res => {
          resolve(res.data.data);
          resolve(res.data.data.records);
        });
      }
    }
Source/UBCS-WEB/src/views/system/user.vue
@@ -777,10 +777,10 @@
      })
       //要传递的id,一个是数组另一个是字符串
       this.UserPwdstrategyVO.userIds=this.selid;
       this.UserPwdstrategyVO.pwdstrategyId=this.id;
       this.UserPwdstrategyVO.pwdstrategyId=this.id
      //请求
      insert(this.UserPwdstrategyVO).then(()=>{
      insert(this.UserPwdstrategyVO.userIds).then(()=>{
        this.passVisible=false
        this.$message({
          type: "success",
@@ -967,9 +967,10 @@
      if (this.selectionList.length === 1) {
        this.roleTreeObj = this.selectionList[0].roleId.split(",");
      }
      getRoleTree(this.selectionList[0].tenantId).then(res => {
      getRoleTree().then(res => {
        this.roleGrantList = res.data.data;
        this.roleBox = true;
      });
    },
    handlePlatform() {
Source/UBCS-WEB/vue.config.js
@@ -26,7 +26,8 @@
    proxy: {
      '/api': {
        //本地服务接口地址
         target: 'http://localhost:37000',
        target: 'http://localhost:37000',
        //  target: 'http://localhost:37000',
        // target: 'http://192.168.1.51:37000',
        // target: 'http://192.168.1.46:37000',
        // target: 'http://dev.vci-tech.com:37000',
@@ -36,6 +37,7 @@
        //target: 'http://192.168.3.7:37000',
        // target: 'http://dev.vci-tech.com:37000',
        //target: 'http://192.168.1.51:37000/',
        // target:'http://192.168.1.104:37000',
        //远程演示服务地址,可用于直接启动项目
        // target: 'https://saber.bladex.vip/api',
        ws: true,
Source/UBCS/ubcs-ops-api/ubcs-flow-api/pom.xml
@@ -14,6 +14,19 @@
    <version>${bladex.project.version}</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>com.vci.ubcs</groupId>
            <artifactId>ubcs-util-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.vci.ubcs</groupId>
            <artifactId>ubcs-user-api</artifactId>
            <version>3.0.1.RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>
Source/UBCS/ubcs-ops-api/ubcs-resource-api/pom.xml
@@ -23,6 +23,12 @@
            <groupId>org.springblade</groupId>
            <artifactId>blade-starter-tenant</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vci.ubcs</groupId>
            <artifactId>ubcs-util-api</artifactId>
            <version>3.0.1.RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/bo/FileObjectBO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.vci.ubcs.resource.bo;
import com.vci.ubcs.resource.vo.FileObjectVO;
import lombok.Data;
import java.io.InputStream;
/**
 * æ–‡ä»¶çš„业务对象
 * @author weidy
 * @date 2023/6/9
 */
@Data
public class FileObjectBO extends FileObjectVO {
    /**
     * åºåˆ—化
     */
    private static final long serialVersionUID = -4887973911424096779L;
    /**
     * æ–‡ä»¶çš„æµ
     */
    private InputStream inputStream;
    /**
     * æ–‡ä»¶æœ¬åœ°çš„信息
     */
    private String fileLocalPath;
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/constant/FileBusConstant.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.vci.ubcs.resource.constant;
/**
 * æ–‡ä»¶æœåŠ¡éƒ¨åˆ†çš„é™æ€å€¼
 * @author weidy
 * @date 2023/6/9
 */
public class FileBusConstant {
    /**
     * æ–‡ä»¶å¯¹è±¡
     */
    public static final String FILE_OBJECT = "fileObject";
    /**
     * æ–‡ä»¶ä¸‹è½½è®°å½•
     */
    public static final String FILE_DOWNLOAD_RECORD = "fileDownloadRecord";
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/constant/FileLifeConstant.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.vci.ubcs.resource.constant;
/**
 * æ–‡ä»¶çŠ¶æ€
 * @author weidy
 * @date 2023/6/9 9:07
 */
public class FileLifeConstant {
    /**
     * æ–‡ä»¶çš„状态
     */
    public static final String FILE = "fileStatus";
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/dto/FileObjectDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
package com.vci.ubcs.resource.dto;
import com.vci.ubcs.resource.entity.FileObject;
import lombok.Data;
/**
 * æ–‡ä»¶æ•°æ®ä¼ è¾“对象
 * @author weidy
 * @date 2023/6/9
 */
@Data
public class FileObjectDTO extends FileObject {
    /**
     * åºåˆ—化
     */
    private static final long serialVersionUID = 497836915363113260L;
    /**
     * æ˜¯å¦ä¿®æ”¹æ–‡ä»¶
     */
    private Boolean updateFileFlag ;
    /**
     * æ–‡ä»¶å¤¹è·¯å¾„
     */
    private String dirPath;
    /**
     * æ–‡ä»¶ä¸Šä¼ åŽæ˜¯å¦ç«‹å³ç”Ÿæ•ˆ
     */
    private Boolean effect = true;
    /**
     * ä¸Šä¼ åŽŸæ–‡ä»¶è·¯å¾„
     */
    private String sourceFilePath;
    /**
     * æ ¡éªŒç›¸åŒçš„名称的文件,必须在ownbiz有值的情况下
     */
    private Boolean checkSameFile = false;
    /**
     * æ¡¶çš„名称
     */
    private String bucketName;
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/dto/FileReleaseDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.vci.ubcs.resource.dto;
import lombok.Data;
import java.util.List;
/**
 * æ–‡ä»¶å‘布的数据操作对象
 * @author weidy
 * @date 2023/6/9
 */
@Data
public class FileReleaseDTO implements java.io.Serializable{
    /**
     * åºåˆ—化
     */
    private static final long serialVersionUID = -218379391237684940L;
    /**
     * æ‰€å±žæ•°æ®ä¸»é”®
     */
    private String ownbizOid;
    /**
     * æ‰€å±žæ•°æ®çš„业务类型
     */
    private String ownBtmName;
    /**
     * æ–‡ä»¶çš„主键
     */
    private List<String> oids;
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/dto/FileShareDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.vci.ubcs.resource.dto;
import lombok.Data;
import java.util.List;
/**
 * æ–‡ä»¶åˆ†äº«çš„æ•°æ®ä¼ è¾“对象
 * @author weidy
 * @date 2023/6/9
 */
@Data
public class FileShareDTO implements java.io.Serializable{
    /**
     * åºåˆ—化
     */
    private static final long serialVersionUID = -2947163604655993790L;
    /**
     * æ¥æºä¸šåŠ¡
     */
    private String sourceBus;
    /**
     * æ¥æºä¸šåŠ¡æ•°æ®ä¸»é”®
     */
    private String sourceBusOid;
    /**
     * ç›®æ ‡çš„业务
     */
    private String targetBus;
    /**
     * ç›®æ ‡çš„业务数据主键
     */
    private String targetBusOid;
    /**
     * æºæ–‡ä»¶çš„主键
     */
    private List<String> oids;
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/entity/FileObject.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
package com.vci.ubcs.resource.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.vci.ubcs.starter.revision.model.BaseModel;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * æ–‡ä»¶å¯¹è±¡
 * @author weidy
 * @date 2023/6/8
 */
@Data
@TableName("PL_SYS_FILEOBJECT")
@ApiModel(value = "文件对象", description = "存储业务数据关联的文件信息")
@EqualsAndHashCode(callSuper = true)
public class FileObject extends BaseModel {
    /**
     * åºåˆ—化
     */
    private static final long serialVersionUID = -7116754635114431150L;
    /**
     * æ˜¾ç¤ºçš„名称
     */
    private String id;
    /**
     * æ–‡ä»¶åç§°
     */
    private String name;
    /**
     * åœ¨minio里的名称
     */
    private String objectName;
    /**
     * æ–‡ä»¶åŽç¼€å
     */
    private String fileExtension;
    /**
     * æ–‡æ¡£ç±»åž‹ç¼–号
     */
    private String fileDocClassify;
    /**
     * æ–‡æ¡£ç±»åž‹æ–‡æœ¬
     */
    private String fileDocClassifyName;
    /**
     * æ–‡ä»¶å¤§å°
     */
    private Long fileSize;
    /**
     * å…³é”®è¯ä¿¡æ¯
     */
    private String keyInfos;
    /**
     * æ‰€å±žæ•°æ®ä¸»é”®
     */
    private String ownbizOid;
    /**
     * æ‰€å±žæ•°æ®çš„业务类型
     */
    private String ownBtmName;
    /**
     * å…³è”的数据的信息
     */
    private String linkInfos;
    /**
     * æ–‡ä»¶çš„存储路径
     */
    private String fileLink;
    /**
     * æ¡¶çš„名称
     */
    private String bucketName;
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/life/FileLife.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
package com.vci.ubcs.resource.life;
import com.vci.ubcs.starter.web.enumpck.BaseEnum;
/**
 * æ–‡ä»¶çš„状态集合
 * @author weidy
 * @date 2023/6/11
 */
public enum FileLife implements BaseEnum {
    /**
     * åˆå§‹åŒ–
     */
    INIT("fileInit","初始化"),
    /**
     * ä¸Šä¼ ä¸­
     */
    TRANSITING("fileTransiting","上传中"),
    /**
     * ä¸Šä¼ å®Œæˆ
     */
    TRANS_FINISH("fileTransitFinish","上传完成"),
    /**
     * å·²ç”Ÿæ•ˆ
     */
    FILE_RELEASE("fileRelease","已生效");
    /**
     * æžšä¸¾å€¼
     */
    private String value;
    /**
     * æžšä¸¾æ˜¾ç¤ºå€¼
     */
    private String text;
    /**
     * èŽ·å–æžšä¸¾å€¼
     * @return æžšä¸¾å€¼
     */
    @Override
    public String getValue() {
        return value;
    }
    /**
     * è®¾ç½®æžšä¸¾å€¼
     * @param value æžšä¸¾å€¼
     */
    public void setValue(String value) {
        this.value = value;
    }
    /**
     * èŽ·å–æ˜¾ç¤ºæ–‡æœ¬
     * @return æ˜¾ç¤ºæ–‡æœ¬
     */
    @Override
    public String getText() {
        return text;
    }
    /**
     * è®¾ç½®æ˜¾ç¤ºæ–‡æœ¬
     * @param text æ˜¾ç¤ºæ–‡æœ¬
     */
    public void setText(String text) {
        this.text = text;
    }
    /**
     * æžšä¸¾å†…部构造方法
     * @param value æžšä¸¾å€¼
     * @param text æ˜¾ç¤ºæ–‡æœ¬
     */
    private FileLife(String value, String text){
        this.value = value;
        this.text = text;
    }
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/query/FileQuery.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.vci.ubcs.resource.query;
import com.vci.ubcs.resource.entity.FileObject;
import com.vci.ubcs.starter.web.pagemodel.BladeQueryObject;
import lombok.Data;
import java.util.Date;
/**
 * æ–‡ä»¶çš„æŸ¥è¯¢
 * @author weidy
 * @date 2023/1/31
 */
@Data
public class FileQuery extends FileObject {
    /**
     * åºåˆ—化
     */
    private static final long serialVersionUID = 2442917107957942183L;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    private Date createTime_begin;
    /**
     * åˆ›å»ºæ—¶é—´ç»“束
     */
    private Date createTime_end;
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/utils/FileDownloadUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
package com.vci.ubcs.resource.utils;
import com.vci.ubcs.resource.bo.FileObjectBO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
/**
 * ä¸‹è½½æ–‡ä»¶çš„工具
 * @author weidy
 * @date 2023/6/9
 */
@Slf4j
public class FileDownloadUtil {
    /**
     * ä¸‹è½½æ–‡ä»¶
     * @param response å“åº”对象
     * @param fileObjectBO æ–‡ä»¶çš„信息,包含文件的输入流
     * @throws IOException ä¸‹è½½å¼‚常会抛出
     */
    public static void downloadFile(HttpServletResponse response, FileObjectBO fileObjectBO) throws IOException {
        downloadFile(response,fileObjectBO,true);
    }
    /**
     * ä¸‹è½½æ–‡ä»¶
     * @param response å“åº”对象
     * @param fileObjectBO æ–‡ä»¶çš„信息,包含文件的输入流
     * @param closeInputStream æ˜¯å¦å…³é—­æµ
     * @throws IOException ä¸‹è½½å‡ºé”™çš„æ—¶å€™æŠ›å‡ºå¼‚常
     */
    public static void downloadFile(HttpServletResponse response, FileObjectBO fileObjectBO,boolean closeInputStream) throws IOException {
        MediaType mediaType = MediaTypeFactory.getMediaType(fileObjectBO.getName() + "." + fileObjectBO.getFileExtension()).orElse(MediaType.APPLICATION_OCTET_STREAM);
        // è®¾ç½®å¼ºåˆ¶ä¸‹è½½ä¸æ‰“å¼€
        response.setContentType(mediaType.getType());
        try{
            String fileName = URLEncoder.encode(fileObjectBO.getName() + "." + fileObjectBO.getFileExtension(), "UTF8");
            response.addHeader("Content-Disposition", "attachment; filename="+ fileName+ ";filename*=utf-8''" + fileName);
        }catch(Exception e){
            if(log.isErrorEnabled()){
                log.error("设置文件的名称到响应流的时候出错",e);
            }
        }
        response.setCharacterEncoding("UTF-8");
        Cookie cookie = new Cookie("fileDownload", "true");
        cookie.setPath("/");
        response.addCookie(cookie);
        if(closeInputStream) {
            try (InputStream ins = (fileObjectBO.getInputStream() != null ? fileObjectBO.getInputStream() : new FileInputStream(fileObjectBO.getFileLocalPath()))) {
                IOUtils.copy(ins, response.getOutputStream());
            } catch (IOException e) {
                //有可能客户端的链接
                if (log.isErrorEnabled()) {
                    log.error("写入文件到响应流出错", e);
                }
                throw e;
            }
        }else{
            try {
                InputStream ins = (fileObjectBO.getInputStream() != null ? fileObjectBO.getInputStream() : new FileInputStream(fileObjectBO.getFileLocalPath()));
                IOUtils.copy(ins, response.getOutputStream());
            } catch (IOException e) {
                //有可能客户端的链接
                if (log.isErrorEnabled()) {
                    log.error("写入文件到响应流出错", e);
                }
                throw e;
            }
        }
    }
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/utils/FileUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,388 @@
package com.vci.ubcs.resource.utils;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import org.apache.commons.io.IOUtils;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.util.StringUtils;
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
 * æœ¬åœ°æ–‡ä»¶æ“ä½œç±»
 * @author weidy
 * @date 2021-04-19
 */
public class FileUtil {
    /**
     * åˆ é™¤æ–‡ä»¶å¤¹
     * @param file è¦åˆ é™¤çš„æ–‡ä»¶æˆ–者文件夹
     */
    public static void deleteFile(File file) {
        if(file == null || !file.exists()){
            return;
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                deleteFile(files[i]);
            }
        }
        file.delete();
    }
    /**
     * æ‹·è´æ–‡ä»¶
     * @param source æºæ–‡ä»¶
     * @param target ç›®æ ‡æ–‡ä»¶
     * @throws VciBaseException æ‹·è´æ–‡ä»¶å‡ºé”™çš„æ—¶å€™ä¼šæŠ›å‡ºå¼‚常
     */
    public static void copyFile(File source, File target) throws VciBaseException {
        try(FileInputStream is = new FileInputStream(source);
            FileOutputStream os = new FileOutputStream(target)){
            FileChannel sourceChannel = is.getChannel();
            FileChannel targetChannel = os.getChannel();
            int i=0;
            int length=2097152;
            while(true){
                if(sourceChannel.position()==sourceChannel.size()){
                    sourceChannel.close();
                    targetChannel.close();
                    break;
                }
                if((sourceChannel.size()-sourceChannel.position())<20971520) {
                    length = (int) (sourceChannel.size() - sourceChannel.position());
                }else {
                    length = 20971520;
                }
                sourceChannel.transferTo(sourceChannel.position(),length,targetChannel);
                sourceChannel.position(sourceChannel.position()+length);
                i++;
            }
        }catch(Throwable e){
            throw new VciBaseException("拷贝文件出错",new String[0],e);
        }
    }
    /**
     * ä¸´æ—¶æ–‡ä»¶å¤¹çš„前缀
     */
    public static String DEFAULT_TEMP_FOLDER_PREFIX = "";
    /**
     * èŽ·å–é»˜è®¤çš„ä¸´æ—¶æ–‡ä»¶å¤¹
     * @return ä¸´æ—¶æ–‡ä»¶å¤¹ï¼Œé»˜è®¤ä¸ºå½“前项目的运行路径下的tempFolder下的随机值
     */
    public static String getDefaultTempFolder() throws VciBaseException{
        String path = (!StringUtils.hasLength(DEFAULT_TEMP_FOLDER_PREFIX)?getProjectFolder():DEFAULT_TEMP_FOLDER_PREFIX) + File.separator + "temp" + File.separator + VciBaseUtil.getPk();
        File folder = new File(path);
        if(!folder.exists()){
            folder.mkdirs();
        }
        return path;
    }
    /**
     * èŽ·å–é¡¹ç›®çš„è·¯å¾„
     * @return é¡¹ç›®çš„路径
     * @throws VciBaseException èŽ·å–è·¯å¾„å‡ºçŽ°äº†é”™è¯¯ä¼šæŠ›å‡ºå¼‚å¸¸
     */
    public static String getProjectFolder() throws VciBaseException{
        return getProjectFolder(FileUtil.class);
    }
    /**
     * èŽ·å–æŸä¸ªclass所在项目的路径
     * @param classObj æŸä¸ªclass
     * @return é¡¹ç›®çš„路径
     * @throws VciBaseException èŽ·å–è·¯å¾„å‡ºçŽ°äº†é”™è¯¯ä¼šæŠ›å‡ºå¼‚å¸¸
     */
    public static String getProjectFolder(Class classObj) throws VciBaseException{
        String path = "";
        try {
            ApplicationHome h = new ApplicationHome(classObj == null? FileUtil.class:classObj);
            File jarF = h.getSource();
            if(jarF == null){
                jarF = h.getDir();
            }
            path =  jarF.getParentFile().toString();
            if(path.contains("!")){
                path = new File(path).getParentFile().getParent();
            }
        }catch (Throwable e){
            throw new VciBaseException("获取当前服务所在的文件夹出现了错误",new String[0],e);
        }
        if(path.startsWith("file:\\")){
            path = path.substring(6);
        }
        if (System.getProperty("os.name").toLowerCase().startsWith("win") && path.startsWith("/")) {
            path = path.substring(path.indexOf("/") + 1);
        }
        return path;
    }
    /**
     * åˆ é™¤ä¸´æ—¶æ–‡ä»¶
     * @param tempFile ä¸´æ—¶æ–‡ä»¶
     * @param deleteRandomFolder æ˜¯å¦åˆ é™¤éšæœºçš„那个文件夹
     * @throws VciBaseException åˆ é™¤å‡ºé”™çš„æ—¶å€™æŠ›å‡ºå¼‚常
     */
    public static void deleteTempFile(File tempFile,boolean deleteRandomFolder) throws VciBaseException{
        if(tempFile!=null){
            tempFile.delete();
            if(deleteRandomFolder){
                tempFile.getParentFile().delete();
            }
        }
    }
    /**
     * åˆ¤æ–­å‚数是否为空
     * @param s å‚数,第一个为参数,第二个为提示信息
     * @throws VciBaseException ä¸ºç©ºæ—¶æŠ›å‡ºè¿™ä¸ªå¼‚常
     */
    public static void alertNotNull(Object... s) throws VciBaseException{
        if(s!=null && s.length>0){
            for(int i = 0 ; i < s.length ; i ++){
                Object obj = s[i];
                if(obj==null ||!StringUtils.hasLength(obj.toString())){
                    String param = "";
                    try{
                        i++;
                        param = s[i].toString();
                    }catch(Exception e){
                    }
                    throw new VciBaseException("参数[" + param + "]不能为空");
                }
            }
        }
    }
    /**
     * èŽ·å–æ–‡ä»¶çš„åŽç¼€å
     * @param file æ–‡ä»¶å¯¹è±¡
     * @return åŽç¼€åï¼Œä¸åŒ…含.;如果文件不存在或者没有后缀名返回""
     */
    public static String getFileExtension(File file){
        if(file!=null){
            return getFileExtensionByName(file.getName());
        }
        return "";
    }
    /**
     * èŽ·å–æ–‡ä»¶ä¸å«åŽç¼€åçš„åç§°
     * @param file æ–‡ä»¶
     * @return åç§°
     */
    public static String getFileNameUnHasExtension(File file){
        if(file!=null){
            String name = file.getName();
            return name.contains(".")?name.substring(0,name.lastIndexOf(".")):name;
        }
        return "";
    }
    /**
     * èŽ·å–æ–‡ä»¶ä¸å«åŽç¼€åçš„åç§°
     * @param fileName æ–‡ä»¶åç§°
     * @return åç§°
     */
    public static String getFileNameUnHasExtensionByName(String fileName){
        if(fileName!=null){
            return fileName.contains(".")?fileName.substring(0,fileName.lastIndexOf(".")):fileName;
        }
        return "";
    }
    /**
     * èŽ·å–æ–‡ä»¶çš„åŽç¼€å
     * @param name æ–‡ä»¶åç§°
     * @return åŽç¼€åï¼Œä¸åŒ…含.;没有后缀名返回""
     */
    public static String getFileExtensionByName(String name){
        if(StringUtils.hasLength(name)){
            if(name.contains(".")){
                return name.substring(name.lastIndexOf(".")+1);
            }
        }
        return "";
    }
    /**
     * èŽ·å–ä¸Šä¼ æ–‡ä»¶çš„åç§°ï¼Œåœ¨IE浏览器上,上传会把全路径带过来
     * @param name æ–‡ä»¶çš„名称
     * @return æ›¿æ¢åŽçš„值
     */
    public static String getFileNameForIE(String name){
        if(!StringUtils.hasLength(name)){
            return name;
        }
        if(name.contains(File.separator)){
            return name.substring(name.lastIndexOf(File.separator)+1);
        }
        if(name.contains("\\")){
            return name.substring(name.lastIndexOf("\\") + 1);
        }
        return name;
    }
    /**
     * ä»Žå·¥ç¨‹ä¸­è¯»å–文件的内容
     * @param fileName æ–‡ä»¶çš„名称
     * @return æ–‡ä»¶çš„内容
     * @throws VciBaseException è¯»å–出错的时候会抛出异常
     */
    public static String readContentForFileInJar(String fileName) throws VciBaseException{
        if(!StringUtils.hasLength(fileName)){
            throw new VciBaseException("文件名为空");
        }
        if(!fileName.startsWith("/")){
            fileName = "/" + fileName;
        }
        InputStream in = null;
        ByteArrayOutputStream os = null;
        try{
            in = FileUtil.class.getResourceAsStream( fileName);
            if(in ==null){
                in=Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
            }
            os = new ByteArrayOutputStream();
            IOUtils.copy(in,os);
            return new String(os.toByteArray(),"UTF-8");
        }catch (Throwable e){
            throw new VciBaseException("读取文件的内容出现了错误",new String[0],e);
        }finally {
            IOUtils.closeQuietly(in);
            IOUtils.closeQuietly(os);
        }
    }
    /**
     * è¯»å–文件的内容,文件不能是jar里的
     * @param fileName æ–‡ä»¶çš„名称
     * @return æ–‡ä»¶çš„内容,是UTF-8的字符集
     * @throws VciBaseException æ–‡ä»¶ä¸å­˜åœ¨ï¼Œå’Œè¯»å–出错的时候会抛出异常
     */
    public static String readContentForFile(String fileName) throws VciBaseException{
        return new String(readDataForFile(fileName),StandardCharsets.UTF_8);
    }
    /**
     * è¯»å–文件里的数据
     * @param fileName æ–‡ä»¶åç§°
     * @return æ–‡ä»¶çš„æ•°æ®
     * @throws VciBaseException æ–‡ä»¶ä¸å­˜åœ¨ï¼Œå’ŒèŽ·å–å‡ºé”™çš„æ—¶å€™ä¼šæŠ›å‡ºå¼‚å¸¸
     */
    public static byte[] readDataForFile(String fileName) throws VciBaseException{
        File file = new File(fileName);
        if(!file.exists()){
            throw new VciBaseException("文件未找到,{0}",new String[]{fileName});
        }
        try(InputStream in = new FileInputStream( file);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
        ){
            IOUtils.copy(in,os);
            return os.toByteArray();
        }catch (Throwable e){
            throw new VciBaseException("读取文件的内容出现了错误",new String[0],e);
        }
    }
    /**
     * å†™å…¥å­—符串到文件
     * @param content å­—符串
     * @param fileName æ–‡ä»¶çš„名称
     * @throws VciBaseException å†™å…¥å‡ºé”™çš„æ—¶å€™ä¼šæŠ›å‡ºå¼‚常
     */
    public static void writeContentToFile(String content,String fileName) throws VciBaseException{
        File file = new File(fileName);
        if(!file.exists()){
            File parentFile = file.getParentFile();
            if(!parentFile.exists()){
                parentFile.mkdirs();
            }
            try {
                file.createNewFile();
            } catch (IOException e) {
                throw new VciBaseException("写入文件的内容时候出现了创建文件失败的问题,{}",new String[]{fileName},e);
            }
        }
        if(content == null){
            content = "";
        }
        try(OutputStream os = new FileOutputStream(file);){
            os.write(content.getBytes(StandardCharsets.UTF_8));
            os.flush();
        }catch(Throwable e){
            throw new VciBaseException("写入文件的内容时候出现了创错误,{}",new String[]{fileName},e);
        }
    }
    /**
     * ä»Žé¡¹ç›®é‡Œæˆ–者jar的文件到目标文件
     * @param fileInJar jar或者项目里的文件名称
     * @param target ç›®æ ‡æ–‡ä»¶
     * @throws VciBaseException æ‹·è´æ–‡ä»¶å‡ºçŽ°é”™è¯¯çš„æ—¶å€™ä¼šæŠ›å‡ºå¼‚å¸¸
     */
    public static void copyFileInJar(String fileInJar,String target) throws  VciBaseException{
        alertNotNull(fileInJar,"源文件",target,"目标文件");
        File targetFile = new File(target);
        File folder = targetFile.getParentFile();
        if(!folder.exists()){
            folder.mkdirs();
        }
        if(!targetFile.exists()){
            try {
                targetFile.createNewFile();
            } catch (IOException e) {
                throw new VciBaseException("创建目标文件的出现了错误",new String[0],e);
            }
        }
        if(!fileInJar.startsWith("/")){
            fileInJar = "/" + fileInJar;
        }
        InputStream in = null;
        FileOutputStream os = null;
        try{
            in =  FileUtil.class.getResourceAsStream( fileInJar);
            if(in ==null){
                in=Thread.currentThread().getContextClassLoader().getResourceAsStream(fileInJar);
            }
            os = new FileOutputStream(target);
            IOUtils.copy(in,os);
        }catch (Throwable e){
            throw new VciBaseException("拷贝文件的内容出现了错误.{0},{1}",new String[]{fileInJar,target},e);
        }finally {
            IOUtils.closeQuietly(in);
            IOUtils.closeQuietly(os);
        }
    }
    /**
     * æ–‡ä»¶è½¬æ¢ä¸ºè·¯å¾„
     * @param fileList æ–‡ä»¶åˆ—表
     * @return è·¯å¾„列表
     * @throws VciBaseException å‚数为空和文件不存在会抛出异常
     */
    public static List<String> fileToPatch(Collection<File> fileList) throws VciBaseException  {
        alertNotNull("文件列表",fileList);
        List<String> filePath = new ArrayList<>();
        for(File file : fileList){
            if(!file.exists()){
                throw new VciBaseException(file.getAbsolutePath() + "文件没有找到",new String[0]);
            }
            filePath.add(file.getAbsolutePath());
        }
        return filePath;
    }
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/utils/ZipUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,155 @@
package com.vci.ubcs.resource.utils;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.web.util.LangBaseUtil;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
 * zip相关的工具类
 * @author wanghong
 * @date 2021-02-02
 */
@Component
public class ZipUtil {
    /**
     * èŽ·å–zip的字符集
     * @return é»˜è®¤ä¸ºGBK,否则需要配置
     */
    private String getZipCharset(){
        return (File.separatorChar=='\\')?"GBK":"UTF-8";
    }
    /**
     * å°†æ–‡ä»¶å¤¹åŽ‹ç¼©æˆåŽ‹ç¼©åŒ…
     * @param folder æ–‡ä»¶å¤¹è·¯å¾„
     * @param zipFileName zip文件名
     * @throws VciBaseException å‚数为空或者添加出错的会抛出异常
     */
    public void folderToZipFile(String folder, String zipFileName) throws VciBaseException {
        folderToZipFile(folder,zipFileName,getZipCharset());
    }
    /**
     * å°†æ–‡ä»¶å¤¹åŽ‹ç¼©æˆåŽ‹ç¼©åŒ…
     * @param folder æ–‡ä»¶å¤¹è·¯å¾„
     * @param zipFileName zip文件名
     * @param zipEncode zip的字符集,windows应该为GBK
     * @throws VciBaseException å‚数为空或者添加出错的会抛出异常
     */
    public void folderToZipFile(String folder, String zipFileName,String zipEncode) throws VciBaseException{
        File sourceFile = new File(folder);
        if(!sourceFile.exists()){
            throw new VciBaseException("文件{0}没有找到",new String[]{folder});
        }
        try( ZipOutputStream zos =new ZipOutputStream(new FileOutputStream(zipFileName), StringUtils.hasLength(zipEncode)?Charset.forName(zipEncode): Charset.forName(getZipCharset()));) {
            //默认是UTF-8格式的
            addFileToZip(zos, new File(folder).listFiles(),folder + File.separator);
        }catch (Throwable e){
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[]{});
        }
    }
    /**
     * å°†æ–‡ä»¶å¤¹åŽ‹ç¼©æˆåŽ‹ç¼©åŒ…
     * @param zos zip输出流
     * @param files è¦åŽ‹ç¼©çš„æ–‡ä»¶
     * @param rootPath åŽ‹ç¼©çš„æ–‡ä»¶ä¸­çš„é¡¶å±‚ç›®å½•
     * @throws VciBaseException æ–‡ä»¶ä¸å­˜åœ¨ï¼Œæˆ–者内容出现错误会抛出异常
     */
    private void addFileToZip(ZipOutputStream zos,File[] files,String rootPath) throws VciBaseException{
        if(files!=null && files.length>0) {
            for (File file : files) {
                if(!StringUtils.hasLength(rootPath)){
                    try {
                        rootPath = file.getParent();
                        if (rootPath == null) {
                            rootPath = file.getPath();
                        }
                    }catch (Throwable e){
                        rootPath = file.getPath();
                    }
                }
                if (!file.exists()) {
                    throw new VciBaseException("文件{0}没有找到",new String[]{file.getAbsolutePath()});
                }
                if (file.isDirectory()) {
                    addFileToZip(zos, file.listFiles(),rootPath);
                }else{
                    try (InputStream is = new FileInputStream(file); ){
                        String entryName = file.getAbsolutePath().replace(rootPath,"");
                        if(entryName.startsWith("\\")) {
                            entryName = entryName.substring(1);
                        }
                        ZipEntry zipEntry = new ZipEntry(entryName);
                        zos.putNextEntry(zipEntry);
                        byte[] b = new byte[100];
                        int length = 0;
                        while ((length = is.read(b)) != -1) {
                            zos.write(b, 0, length);
                        }
                    } catch (Exception e) {
                        throw new VciBaseException("ZIP压缩出错{0}",new String[]{file.getAbsolutePath()},e);
                    }
                }
            }
        }
    }
    /**
     * å°†å•个文件添加到zip中
     * @param file æ–‡ä»¶
     * @param zipFile zip文件
     * @throws VciBaseException å‚数为空或者添加出错的会抛出异常
     */
    public void addFileToZip(File file, String zipFile) throws VciBaseException{
        if(file == null || !file.exists() ){
            throw new VciBaseException("文件{0}没有找到" ,new String[]{file.getAbsolutePath()});
        }
        if(!StringUtils.hasLength(zipFile)){
            throw new VciBaseException("zip文件{0}为空",new String[0]);
        }
        addFileToZip(new File[]{file},zipFile);
    }
    /**
     * å°†å¤šä¸ªä¸ªæ–‡ä»¶æ·»åŠ åˆ°zip中
     * @param files æ–‡ä»¶
     * @param zipFile zip文件
     * @throws VciBaseException å‚数为空或者添加出错的会抛出异常
     */
    public void addFileToZip(File[] files, String zipFile) throws VciBaseException{
       addFileToZip(files, zipFile,getZipCharset());
    }
    /**
     * å°†å¤šä¸ªä¸ªæ–‡ä»¶æ·»åŠ åˆ°zip中
     * @param files æ–‡ä»¶
     * @param zipFile zip文件
     * @param zipEncode zip的字符集
     * @throws VciBaseException å‚数为空或者添加出错的会抛出异常
     */
    public void addFileToZip(File[] files, String zipFile,String zipEncode) throws VciBaseException{
        if(files == null || files.length == 0){
            throw new VciBaseException("文件{0}内容是空",new String[0]);
        }
        if(!StringUtils.hasLength(zipFile)){
            throw new VciBaseException("zip文件{0}是空",new String[0]);
        }
        try (ZipOutputStream zos =new ZipOutputStream(new FileOutputStream(zipFile), StringUtils.hasLength(zipEncode)?Charset.forName(zipEncode): Charset.forName(getZipCharset()));){
            addFileToZip(zos, files,"");
        }catch (Throwable e){
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[]{},e);
        }
    }
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/vo/FileObjectVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.vci.ubcs.resource.vo;
import com.vci.ubcs.resource.entity.FileObject;
import lombok.Data;
/**
 * æ–‡ä»¶çš„æ˜¾ç¤ºå¯¹è±¡
 * @author weidy
 * @date 2023/6/9
 */
@Data
public class FileObjectVO extends FileObject {
    /**
     * åºåˆ—化
     */
    private static final long serialVersionUID = 2685482161288133481L;
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/controller/WorkController.java
@@ -27,13 +27,23 @@
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * æµç¨‹äº‹åŠ¡é€šç”¨æŽ¥å£
 *
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/service/impl/FlowBusinessServiceImpl.java
@@ -263,6 +263,7 @@
            variables = Kv.create();
        }
        variables.put(ProcessConstant.PASS_KEY, flow.isPass());
        variables.put("yn","y");
        // å®Œæˆä»»åŠ¡
        taskService.complete(taskId, variables);
        return true;
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowModelController.java
@@ -18,15 +18,20 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.vci.ubcs.flow.core.utils.TaskUtil;
import com.vci.ubcs.flow.engine.entity.FlowModel;
import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
import com.vci.ubcs.flow.engine.service.FlowEngineService;
import com.vci.ubcs.flow.engine.service.FlowTaskUserService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.springblade.core.launch.constant.FlowConstant;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
@@ -44,7 +49,7 @@
@RestController
@RequestMapping("model")
@AllArgsConstructor
//@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
//@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)t
public class FlowModelController {
    private final FlowEngineService flowEngineService;
@@ -63,6 +68,8 @@
        IPage<FlowModel> pages = flowEngineService.page(Condition.getPage(query), Condition.getQueryWrapper(flow, FlowModel.class)
            .select("id,model_key modelKey,name,description,version,created,last_updated lastUpdated")
            .orderByDesc("last_updated"));
        flowEngineService.getNodeByFlowableKey("process_t");
        return R.data(pages);
    }
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowProcessController.java
@@ -20,6 +20,12 @@
import com.vci.ubcs.flow.engine.service.FlowEngineService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.SubProcess;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.*;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springframework.web.bind.annotation.GetMapping;
@@ -28,7 +34,10 @@
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
 * æµç¨‹é€šç”¨æŽ§åˆ¶å™¨
@@ -44,6 +53,12 @@
    private static final String IMAGE_NAME = "image";
    private final FlowEngineService flowEngineService;
    private final RepositoryService repositoryService;
    private final RuntimeService runtimeService;
    private final HistoryService historyService;
    private final TaskService taskService;
    private final ProcessEngine processEngine;
    /**
     * èŽ·å–æµè½¬åŽ†å²åˆ—è¡¨
@@ -65,6 +80,7 @@
     */
    @GetMapping(value = "model-view")
    public R modelView(String processDefinitionId, String processInstanceId) {
        return R.data(flowEngineService.modelView(processDefinitionId, processInstanceId));
    }
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowTaskUserController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package com.vci.ubcs.flow.engine.controller;
import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
import com.vci.ubcs.flow.engine.service.FlowEngineService;
import com.vci.ubcs.flow.engine.service.FlowTaskUserService;
import lombok.AllArgsConstructor;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springframework.web.bind.annotation.*;
/**
 * æµç¨‹task审批控制
 *
 * @author wang1
 */
@NonDS
@RestController
@RequestMapping("taskUser")
@AllArgsConstructor
public class FlowTaskUserController {
    private final FlowTaskUserService taskUserService;
    /**
     * æµç¨‹task审批人员列表
     * @return
     */
    @GetMapping("list")
    public R<FlowTaskUserC> list() {
        return R.data(taskUserService.getUser());
    }
    /**
     * æ–°å¢žã€ä¿®æ”¹ä»»åŠ¡å¤„ç†äººå‘˜
     * @param flowTaskUserC
     * @return
     */
    @PostMapping("su")
    public R<String> saveUser(@RequestBody FlowTaskUserC flowTaskUserC) {
        taskUserService.saveOrUpdateUser(flowTaskUserC);
        return R.success("保存成功");
    }
    /**
     * åˆ é™¤ä»»åŠ¡å¤„ç†äººå‘˜
     * @param flowTaskUserC
     * @return
     */
    @PostMapping("du")
    public R<String> deleteUser(@RequestBody FlowTaskUserC flowTaskUserC) {
        taskUserService.deleteUser(flowTaskUserC.getName());
        return R.success("删除成功");
    }
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/ProcessTSController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,112 @@
package com.vci.ubcs.flow.engine.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
import com.vci.ubcs.flow.engine.entity.ProcessStageAttr;
import com.vci.ubcs.flow.engine.entity.ProcessTemplate;
import com.vci.ubcs.flow.engine.service.FlowEngineService;
import com.vci.ubcs.flow.engine.service.ProcessStageAttrService;
import com.vci.ubcs.flow.engine.service.ProcessTemplateService;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 *流程模板、流程阶段控制 processTemplate processStage
 *
 * @author wang1
 */
@NonDS
@RestController
@RequestMapping("processTS")
@AllArgsConstructor
public class ProcessTSController {
    private final FlowEngineService flowEngineService;
    private final ProcessTemplateService processTemplateService;
    private final ProcessStageAttrService processStageAttrService;
    /**
     * æµç¨‹æ¨¡æ¿åˆ†é¡µ
     */
    @GetMapping("/tlist")
    public R<IPage<ProcessTemplate>> tlist(@RequestParam Map<String, Object> flow, Query query) {
        IPage<ProcessTemplate> pages = processTemplateService.page(Condition.getPage(query), Condition.getQueryWrapper(flow, ProcessTemplate.class)
            .select("id,model_key modelKey,model_name modelName,button_Type_Key buttonTypeKey,button_Type_value buttonTypeValue")
            .orderByDesc("last_updated"));
        return R.data(pages);
    }
    /**
     * æµç¨‹æ¨¡æ¿ç”¨é€”属性
     * @return
     */
    @PostMapping("tt")
    public R<List<Map<String,String>>> processTemplateType() {
        return R.data(processTemplateService.processTemplateType());
    }
    /**
     * æµç¨‹æ¨¡æ¿æ–°å¢žã€ä¿®æ”¹
     * @param processTemplate
     * @return
     */
    @PostMapping("tsou")
    public R<ProcessTemplate> processTemplateSaveOrUpdate(@RequestBody ProcessTemplate processTemplate) {
        processTemplateService.saveOrUpdateUser(processTemplate);
        return R.success("保存成功");
    }
    /**
     * æµç¨‹æ¨¡æ¿åˆ é™¤
     * @param processTemplate
     * @return
     */
    @DeleteMapping("dt")
    public R<ProcessTemplate> deleteProcessTemplate(ProcessTemplate processTemplate) {
        processTemplateService.deleteProcessTemplate(processTemplate.getId());
        return R.success("删除成功");
    }
    /**
     * æµç¨‹é˜¶æ®µï¼Œè¿™ä¸ªæµç¨‹çš„各个节点
     */
    @GetMapping("/sslist")
    public R<List<Map<String,String>>> sslist(@RequestParam String modelKey) {
        return R.data(flowEngineService.getNodeByFlowableKey(modelKey));
    }
    /**
     * æµç¨‹é˜¶æ®µï¼Œè¿™ä¸ªæµç¨‹,这个节点,绑定的属性
     */
    @GetMapping("/ssslist")
    public R<List<ProcessStageAttr>> ssslist(@RequestParam String templateId,@RequestParam String modelKey,@RequestParam String taskId) {
        Map<String, Object> m = new HashMap<>();
        m.put("template_id", templateId);
        m.put("task_id", taskId);
        m.put("model_key", modelKey);
        QueryWrapper q = Condition.getQueryWrapper(m, ProcessStageAttr.class)
            .select("attr_id attrId,attr_name attrName,attr_group attrGroup");
        return R.data(processStageAttrService.list(q));
    }
    /**
     * æ¨¡æ¿é˜¶æ®µå±žæ€§æ–°å¢žã€ä¿®æ”¹
     * @param flowTaskUserC
     * @return
     */
    @PostMapping("sasou")
    public R<ProcessTemplate> stageAttributeSaveOrUpdate(@RequestBody FlowTaskUserC flowTaskUserC) {
        processStageAttrService.saveOrUpdateUser(flowTaskUserC);
        return R.success("保存成功");
    }
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUser.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.vci.ubcs.flow.core.utils.TaskUtil;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 * æµç¨‹æ¯ä¸€ä¸ªèŠ‚ç‚¹å®¡æ ¸äºº
 *
 * @author wang1
 */
@Data
@TableName("ACT_DE_TASK_USER")
public class FlowTaskUser implements Serializable {
    private static final long serialVersionUID = 1L;
    private String id;
    private String name;//保存的这个收藏名称
    private String modelKey;
    private String classifyId;
    private String templateId;
    private String taskId;//流程taskid
    private String taskName;
    private String userId;
    private String userName;
    private String description;
    private Date created;
    private Date lastUpdated;
    private String createdBy;
    private String lastUpdatedBy;
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUserC.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * æµç¨‹èŠ‚ç‚¹å®¡æ ¸äººæ”¶è—
 *
 * @author wang1
 */
@Data
public class FlowTaskUserC implements Serializable {
    private static final long serialVersionUID = 1L;
    private String createdBy;
    private String name;//保存的这个收藏名称
    private String modelKey;
    private String classifyId;
    private String templateId;
    private String taskId;//阶段id,就是流程taskid
    private String taskName;//阶段名称
    private List<FlowTaskUser> flowTaskUsers;//每个节点收藏人
    private List<ProcessStageAttr> processStageAttr;//流程阶段保存的属性
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessStageAttr.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 * æµç¨‹é˜¶æ®µ
 *
 * @author wang1
 */
@Data
@TableName("ACT_DE_PROCESS_STAGE_ATTR")
public class ProcessStageAttr implements Serializable {
    private static final long serialVersionUID = 1L;
    private String id;
    private String modelKey;
    private String classifyId;
    private String templateId;
    private String taskId;//阶段id,就是流程taskid
    private String taskName;//阶段名称
    private String attrOid;//属性这条数据的id
    private String attrId;//属性这条数据的oid
    private String attrName;//属性中文名称
    private String attrGroup;//属性分组
    private String description;
    private Date created;
    private Date lastUpdated;
    private String createdBy;
    private String lastUpdatedBy;
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessTemplate.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * æµç¨‹æ¨¡æ¿
 *
 * @author wang1
 */
@Data
@TableName("ACT_DE_PROCESS_TEMPLATE")
public class ProcessTemplate implements Serializable {
    private static final long serialVersionUID = 1L;
    private String id;
    private String templateId;//当前模板id
    private String modelKey;//流程模型key,部署key
    private String modelName;//部署流程名称
    private String buttonTypeKey;//应用按钮,ProcessTemplateTypeEnum的key
    private String buttonTypeValue;//应用按钮,ProcessTemplateTypeEnum的value
    private String description;
    private Date created;
    private Date lastUpdated;
    private String createdBy;
    private String lastUpdatedBy;
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowMapper.java
@@ -19,6 +19,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.vci.ubcs.flow.engine.entity.FlowModel;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -43,4 +44,5 @@
     * @return
     */
    List<FlowModel> findByParentModelId(String parentModelId);
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowTaskUserMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.vci.ubcs.flow.engine.entity.FlowModel;
import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * æµç¨‹é˜¶æ®µå®¡æ ¸äººå‘˜
 *
 * @author wang1
 */
public interface FlowTaskUserMapper extends BaseMapper<FlowTaskUser> {
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessStageAttrMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.vci.ubcs.flow.engine.entity.ProcessStageAttr;
/**
 * æµç¨‹é˜¶æ®µ
 *
 * @author wang1
 */
public interface ProcessStageAttrMapper extends BaseMapper<ProcessStageAttr> {
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessTemplateMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
import com.vci.ubcs.flow.engine.entity.ProcessTemplate;
/**
 * æµç¨‹æ¨¡æ¿
 *
 * @author wang1
 */
public interface ProcessTemplateMapper extends BaseMapper<ProcessTemplate> {
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowEngineService.java
@@ -23,6 +23,7 @@
import com.vci.ubcs.flow.engine.entity.FlowModel;
import com.vci.ubcs.flow.engine.entity.FlowProcess;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@@ -163,4 +164,13 @@
     * @return
     */
    byte[] getModelEditorXML(FlowModel model);
    /**
     * æ ¹æ®æµç¨‹æ¨¡åž‹key获取XML中节点配置的处理人,读取节点名称和配置的值,流程模型key已经限制不重复
     *
     * @param key
     * @return
     */
    List<Map<String,String>> getNodeByFlowableKey(String key);
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowTaskUserService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vci.ubcs.flow.core.entity.BladeFlow;
import com.vci.ubcs.flow.engine.entity.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
/**
 * FlowService
 *
 * @author wang1
 */
public interface FlowTaskUserService extends IService<FlowTaskUser> {
    /**
     * æŸ¥è¯¢å½“前登陆人对这个流程的taskUser
     * @return
     */
    FlowTaskUserC getUser();
    /**
     * æ–°å¢ž/修改流程节点审核人配置、并且修改流程xml部署文件
     * @param flowTaskUserC
     * @return
     */
    void saveOrUpdateUser(FlowTaskUserC flowTaskUserC);
    /**
     * åˆ é™¤æµç¨‹å®¡æ ¸äººå‘˜
     * @param name
     */
    void deleteUser(String name);
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessStageAttrService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
import com.vci.ubcs.flow.engine.entity.ProcessStageAttr;
import java.util.List;
/**
 * æµç¨‹é˜¶æ®µæœåŠ¡
 *
 * @author wang1
 */
public interface ProcessStageAttrService extends IService<ProcessStageAttr> {
    /**
     * æ–°å¢ž/修改流程阶段
     * @param flowTaskUserC
     * @return
     */
    void saveOrUpdateUser(FlowTaskUserC flowTaskUserC);
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessTemplateService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
import com.vci.ubcs.flow.engine.entity.ProcessTemplate;
import com.vci.ubcs.starter.web.enumpck.ProcessTemplateTypeEnum;
import java.util.List;
import java.util.Map;
/**
 * æµç¨‹æ¨¡æ¿æœåŠ¡
 *
 * @author wang1
 */
public interface ProcessTemplateService extends IService<ProcessTemplate> {
    /**
     * æ–°å¢ž/修改流程模板
     * @param processTemplate
     * @return
     */
    void saveOrUpdateUser(ProcessTemplate processTemplate);
    /**
     * åˆ é™¤æµç¨‹æ¨¡æ¿
     * @param id
     * @return
     */
    void deleteProcessTemplate(String id);
    /**
     * æµç¨‹æ¨¡æ¿ç”¨é€”
     * @return
     */
    List<Map<String,String>> processTemplateType();
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowEngineServiceImpl.java
@@ -16,6 +16,8 @@
 */
package com.vci.ubcs.flow.engine.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -34,9 +36,11 @@
import com.vci.ubcs.system.user.entity.User;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.impl.util.IoUtil;
import org.flowable.common.engine.impl.util.io.StringStreamSource;
@@ -47,6 +51,7 @@
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.DeploymentQuery;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.engine.runtime.ProcessInstance;
@@ -54,6 +59,7 @@
import org.flowable.engine.task.Comment;
import org.flowable.image.ProcessDiagramGenerator;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.FileUtil;
@@ -61,11 +67,17 @@
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.util.*;
/**
@@ -90,6 +102,12 @@
    private final HistoryService historyService;
    private final TaskService taskService;
    private final ProcessEngine processEngine;
    /**
     * æ•°æ®æ“ä½œå¯¹è±¡
     */
    @Resource
    private FlowMapper flowMapper;
    @Override
    public IPage<FlowModel> selectFlowPage(IPage<FlowModel> page, FlowModel flowModel) {
@@ -296,6 +314,7 @@
    @Override
    public boolean deployModel(String modelId, String category, List<String> tenantIdList) {
        FlowModel model = this.getById(modelId);
        if (model == null) {
            throw new ServiceException("未找到模型 id: " + modelId);
@@ -346,6 +365,12 @@
    @Override
    public FlowModel submitModel(FlowModel model) {
        //验证重复key
        if(StringUtils.isEmpty(model.getId())&&getFlowModelByKey(model.getModelKey())!=null){
            throw new ServiceException("you cannot definition repetition æµç¨‹key!");
        }
        FlowModel flowModel = new FlowModel();
        flowModel.setId(model.getId());
        flowModel.setVersion(Func.toInt(model.getVersion(), 0) + 1);
@@ -467,6 +492,33 @@
    }
    /**
     * æ ¹æ®æµç¨‹æ¨¡åž‹key获取XML中节点配置的处理人
     *
     * @param key
     * @return
     */
    @Override
    public List<Map<String,String>> getNodeByFlowableKey(String key){
        String processDefinitionId = repositoryService.createProcessDefinitionQuery().latestVersion().processDefinitionKey(key).singleResult().getId();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        Process process = bpmnModel.getProcesses().get(0);//只有一个
        List<Map<String,String>> ll = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(process.getFlowElements())) {
            for (FlowElement flowElement : process.getFlowElements()) {
                if (flowElement instanceof UserTask) {
                    Map<String,String> mi = new HashMap<>();
                    mi.put("taskId",flowElement.getId());
                    mi.put("taskName",flowElement.getName());
                    ll.add(mi);
                }
            }
        }
        return ll;
    }
    /**
     * æ˜¯å¦å·²å®Œç»“
     *
     * @param processInstanceId æµç¨‹å®žä¾‹id
@@ -476,7 +528,6 @@
        return historyService.createHistoricProcessInstanceQuery().finished()
            .processInstanceId(processInstanceId).count() > 0;
    }
    /**
     * xml转bpmn json
@@ -556,4 +607,10 @@
        }
    }
    public FlowModel getFlowModelByKey(String key){
        Map kv = new HashMap();
        kv.put("model_key",key);
        return baseMapper.selectOne(Condition.getQueryWrapper(kv, FlowModel.class));
    }
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowTaskUserServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,146 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.vci.ubcs.flow.core.entity.BladeFlow;
import com.vci.ubcs.flow.core.enums.FlowModeEnum;
import com.vci.ubcs.flow.core.utils.TaskUtil;
import com.vci.ubcs.flow.engine.constant.FlowEngineConstant;
import com.vci.ubcs.flow.engine.entity.*;
import com.vci.ubcs.flow.engine.mapper.FlowMapper;
import com.vci.ubcs.flow.engine.mapper.FlowTaskUserMapper;
import com.vci.ubcs.flow.engine.service.FlowEngineService;
import com.vci.ubcs.flow.engine.service.FlowTaskUserService;
import com.vci.ubcs.flow.engine.utils.FlowCache;
import com.vci.ubcs.system.user.cache.UserCache;
import com.vci.ubcs.system.user.entity.User;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.impl.util.IoUtil;
import org.flowable.common.engine.impl.util.io.StringStreamSource;
import org.flowable.editor.language.json.converter.BpmnJsonConverter;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.engine.task.Comment;
import org.flowable.image.ProcessDiagramGenerator;
import org.springblade.core.launch.constant.FlowConstant;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.FileUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.util.*;
/**
 * å·¥ä½œæµæœåŠ¡å®žçŽ°ç±»
 *
 * @author wang1
 */
@Slf4j
@Service
@AllArgsConstructor
public class FlowTaskUserServiceImpl extends ServiceImpl<FlowTaskUserMapper, FlowTaskUser> implements FlowTaskUserService {
    private FlowEngineService flowEngineService;
    private FlowTaskUserMapper flowTaskUserMapper;
    /**
     * æŸ¥è¯¢å½“前登陆人对这个流程的taskUser
     * @return
     */
    @Override
    public FlowTaskUserC getUser(){
        QueryWrapper<FlowTaskUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("CREATED_BY", AuthUtil.getUserId());
        List<FlowTaskUser> flowTaskUsers = baseMapper.selectList(queryWrapper);
        FlowTaskUserC flowTaskUserCR = new FlowTaskUserC();
        if(flowTaskUsers.size()==0){
            return flowTaskUserCR;
        }
        flowTaskUserCR.setName(flowTaskUsers.get(0).getName());//收藏名称
        flowTaskUserCR.setFlowTaskUsers(flowTaskUsers);
        return flowTaskUserCR;
    }
    @Override
    public void saveOrUpdateUser(FlowTaskUserC flowTaskUserC){
        List<FlowTaskUser> flowTaskUsers = flowTaskUserC.getFlowTaskUsers();
        String name = flowTaskUserC.getName();//收藏名称
        //新增情况下验证收藏名称不重复
        if(flowTaskUsers.get(0).getId()!=null) {
            Map<String, Object> m = new HashMap<>();
            m.put("name", name);
            QueryWrapper q = Condition.getQueryWrapper(m, FlowTaskUser.class)
                .select("id,model_key modelKey,name,description,version,created,last_updated lastUpdated");
            if(flowTaskUserMapper.selectCount(q)>0){
                throw new ServiceException("收藏名称已经存在!");
            }
        }
        for (FlowTaskUser flowTaskUseri:flowTaskUsers){
            flowTaskUseri.setName(name);
        }
        //新增、修改
        this.saveOrUpdateBatch(flowTaskUsers);
    }
    @Override
    public void deleteUser(String name){
        Map<String, Object> m = new HashMap<>();
        m.put("name", name);
        m.put("created_by", AuthUtil.getUserId());
        baseMapper.deleteByMap(m);
    }
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessStageAttrServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
import com.vci.ubcs.flow.engine.entity.ProcessStageAttr;
import com.vci.ubcs.flow.engine.mapper.ProcessStageAttrMapper;
import com.vci.ubcs.flow.engine.service.ProcessStageAttrService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.support.Condition;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * æµç¨‹é˜¶æ®µæœåŠ¡å®žçŽ°ç±»
 *
 * @author wang1
 */
@Slf4j
@Service
@AllArgsConstructor
public class ProcessStageAttrServiceImpl extends ServiceImpl<ProcessStageAttrMapper, ProcessStageAttr> implements ProcessStageAttrService {
    /**
     * æ–°å¢ž/修改流程阶段
     * @param flowTaskUserC
     * @return
     */
    @Transactional
    public void saveOrUpdateUser(FlowTaskUserC flowTaskUserC){
        List<ProcessStageAttr> processStageAttrs = flowTaskUserC.getProcessStageAttr();
        String modelKey = flowTaskUserC.getModelKey();
        String templateId = flowTaskUserC.getTemplateId();
        String taskId = flowTaskUserC.getTaskId();
        String taskName = flowTaskUserC.getTaskName();
        //直接删除以前的
        Map<String, Object> m = new HashMap<>();
        m.put("template_id", templateId);
        m.put("model_key", modelKey);
        m.put("task_id", taskId);
        QueryWrapper q = Condition.getQueryWrapper(m, FlowTaskUser.class)
            .select("id,model_key modelKey,name,description,version,created,last_updated lastUpdated");
        int i = baseMapper.deleteByMap(m);
        System.out.println("删除的属性个数: "+i);
        List<ProcessStageAttr> processStages = flowTaskUserC.getProcessStageAttr();
        for (ProcessStageAttr processStageAttr:processStages){
            processStageAttr.setModelKey(modelKey);
            processStageAttr.setTemplateId(templateId);
            processStageAttr.setTaskId(taskId);
            processStageAttr.setTaskName(taskName);
        }
        if(processStages.size()!=0) {
            this.saveOrUpdateBatch(processStages);
        }
    }
}
Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessTemplateServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,107 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.flow.engine.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vci.ubcs.flow.core.utils.TaskUtil;
import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
import com.vci.ubcs.flow.engine.entity.ProcessTemplate;
import com.vci.ubcs.flow.engine.mapper.FlowTaskUserMapper;
import com.vci.ubcs.flow.engine.mapper.ProcessTemplateMapper;
import com.vci.ubcs.flow.engine.service.FlowEngineService;
import com.vci.ubcs.flow.engine.service.FlowTaskUserService;
import com.vci.ubcs.flow.engine.service.ProcessTemplateService;
import com.vci.ubcs.starter.web.enumpck.ProcessTemplateTypeEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.launch.constant.FlowConstant;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springframework.stereotype.Service;
import java.util.*;
/**
 * æµç¨‹æ¨¡æ¿æœåŠ¡å®žçŽ°ç±»
 *
 * @author wang1
 */
@Slf4j
@Service
@AllArgsConstructor
public class ProcessTemplateServiceImpl extends ServiceImpl<ProcessTemplateMapper, ProcessTemplate> implements ProcessTemplateService {
    /**
     * æ–°å¢ž/修改流程模板
     * @param processTemplate
     * @return
     */
    public void saveOrUpdateUser(ProcessTemplate processTemplate){
        //校验这个模板下,一类按钮只能有一个模板
        QueryWrapper<ProcessTemplate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("button_type_key", processTemplate.getButtonTypeKey());
        if(StringUtils.isNotEmpty(processTemplate.getId())) {//修改的时候,id为空就是新增
            queryWrapper.ne("id", processTemplate.getId());
        }
        if(baseMapper.selectOne(queryWrapper)!=null){
            throw new ServiceException(processTemplate.getButtonTypeValue()+"功能已经配置了流程!");
        }
        if(StringUtils.isEmpty(processTemplate.getButtonTypeValue())){
            processTemplate.setButtonTypeValue(ProcessTemplateTypeEnum.getTextByValue(processTemplate.getButtonTypeKey()));
        }
        //新增或者修改
        if(StringUtils.isEmpty(processTemplate.getId())){
            processTemplate.setCreated(Calendar.getInstance().getTime());
            processTemplate.setCreatedBy(TaskUtil.getTaskUser());
            processTemplate.setLastUpdated(Calendar.getInstance().getTime());
            processTemplate.setLastUpdatedBy(TaskUtil.getTaskUser());
        }
        this.saveOrUpdate(processTemplate);
    }
    /**
     * åˆ é™¤æµç¨‹æ¨¡æ¿
     * @param id
     * @return
     */
    public void deleteProcessTemplate(String id){
        baseMapper.deleteById(id);
    }
    /**
     * æµç¨‹æ¨¡æ¿ç”¨é€”
     * @return
     */
    public List<Map<String,String>> processTemplateType(){
        ProcessTemplateTypeEnum[] es = ProcessTemplateTypeEnum.values();
        List<Map<String,String>> ll = new ArrayList<>();
        for (ProcessTemplateTypeEnum p:es){
            Map<String,String> mi = new HashMap<>();
            String value = p.getValue();
            String text = p.getText();
            mi.put("codee",value);
            mi.put("namee",text);
            ll.add(mi);
        }
        return ll;
    }
}
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/AttachController.java
@@ -38,6 +38,8 @@
/**
 * é™„件表 æŽ§åˆ¶å™¨
 *
 *
 *
 * @author Chill
 */
@NonDS
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/FileController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,170 @@
package com.vci.ubcs.resource.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.vci.ubcs.resource.dto.FileObjectDTO;
import com.vci.ubcs.resource.dto.FileReleaseDTO;
import com.vci.ubcs.resource.dto.FileShareDTO;
import com.vci.ubcs.resource.query.FileQuery;
import com.vci.ubcs.resource.service.IFileService;
import com.vci.ubcs.resource.utils.FileDownloadUtil;
import com.vci.ubcs.resource.vo.FileObjectVO;
import com.vci.ubcs.starter.web.util.LangBaseUtil;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import org.springblade.core.mp.support.Query;
import org.springblade.core.oss.MinioTemplate;
import org.springblade.core.tool.api.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.List;
/**
 * æ–‡ä»¶æŽ§åˆ¶å™¨
 * @author weidy
 * @date 2023-6/9
 */
@RestController()
@RequestMapping("/fileController")
public class FileController {
    /**
     * æ–‡ä»¶æœåŠ¡
     */
    @Autowired
    private IFileService fileService;
    /**
     * minio的配置
     */
    @Autowired
    private MinioTemplate minioTemplate;
    /**
     * æ ¹æ®æ–‡ä»¶ä¸»é”®ä¸‹è½½æ–‡ä»¶
     * @param fileOids æ–‡ä»¶çš„主键
     * @param response å“åº”的对象
     * @return æ‰§è¡Œç»“果,只有下载失败的时候才会这样
     */
    @RequestMapping(value = "/downloadFilesByOids",method = {RequestMethod.GET,RequestMethod.POST})
    public R downloadFilesByOids(@RequestParam String fileOids, HttpServletResponse response){
        try{
            FileDownloadUtil.downloadFile(response, fileService.downloadFileByOids(VciBaseUtil.str2List(fileOids)));
        }catch (Throwable e){
            return R.fail(LangBaseUtil.getErrorMsg(e));
        }
        return R.success("下载完成");
    }
    /**
     * æ–‡ä»¶åˆ é™¤
     * @param oids æ–‡ä»¶çš„主键
     * @return æ–‡ä»¶å†…容
     */
    @DeleteMapping("/deleteFile")
    public R deleteFile(@RequestBody Collection<String> oids){
        fileService.deleteFiles(oids);
        return R.success("删除成功");
    }
    /**
     * å‰ç«¯é¡µé¢å•文件上传。(先数据,后文件模式上传)
     * @param file ä¸Šä¼ çš„æ–‡ä»¶
     * @param fileObjectDTO æ–‡ä»¶ä¿¡æ¯ä¼ è¾“对象
     * @return æ–‡ä»¶ä¿¡æ¯æ˜¾ç¤ºå¯¹è±¡
     */
    @PostMapping("/uploadFile")
    public R<FileObjectVO> uploadFile(MultipartFile file, FileObjectDTO fileObjectDTO){
        if (file != null ) {
            return fileService.uploadFile(file, fileObjectDTO);
        } else {
            return R.fail("无上传的文件");
        }
    }
    /**
     * åœ¨ä¸Šä¼ æ–‡ä»¶åŽï¼Œä¿å­˜æ–‡ä»¶çš„信息
     * @param fileObjectDTO æ–‡ä»¶ä¿¡æ¯ä¼ è¾“对象
     * @return æ–‡ä»¶ä¿¡æ¯æ˜¾ç¤ºå¯¹è±¡
     */
    @PostMapping("/saveFileAfterUpload")
    public R<FileObjectVO> saveFileAfterUpload( @RequestBody FileObjectDTO fileObjectDTO){
       return fileService.saveFileAfterUpload(fileObjectDTO);
    }
    /**
     * å°†åŽŸæ•°æ®ä¸‹çš„æ‰€æœ‰æ–‡ä»¶å…±äº«åˆ°å…¶ä»–çš„ä¸šåŠ¡æ•°æ®ä¸‹
     * @param shareDTO æ–‡ä»¶åˆ†äº«
     * @return æ–‡ä»¶ä¿¡æ¯æ˜¾ç¤ºå¯¹è±¡,是多个
     */
    @PostMapping("/shareFiles")
    public R<List<FileObjectVO>> shareFiles(@RequestBody FileShareDTO shareDTO){
        return fileService.shareFiles(shareDTO);
    }
    /**
     * ä¿®æ”¹æ–‡ä»¶ä¿¡æ¯(不含文件),注意objectName和filePath不会变化
     * @param fileDTOs æ–‡ä»¶çš„æ•°æ®å¯¹è±¡
     * @return æ‰§è¡Œç»“æžœ
     */
    @PostMapping("/updateFileInfos")
    public R updateFileInfos(@RequestBody Collection<FileObjectDTO> fileDTOs){
        return fileService.updateFileInfos(fileDTOs);
    }
    /**
     * æ–‡ä»¶ç”Ÿæ•ˆ
     * @param ids æ–‡ä»¶çš„主键
     * @return æ‰§è¡Œç»“æžœ
     */
    @PutMapping("/releasedFiles")
    public R releasedFiles(@RequestBody Collection<String> ids){
        return fileService.releasedFiles(ids);
    }
    /**
     * æ‰¹é‡æŒ‡å®šæ–‡ä»¶ä¸šåŠ¡æ•°æ®åŽç”Ÿæ•ˆ
     * @param releaseDTOS ç”Ÿæ•ˆçš„相关信息
     * @return æ‰§è¡Œç»“æžœ
     */
    @PutMapping("/releasedFilesForOwn")
    public R releasedFilesForOwn(@RequestBody Collection<FileReleaseDTO> releaseDTOS){
        return fileService.releasedFilesForOwn(releaseDTOS);
    }
    /**
     * ä½¿ç”¨ä¸šåŠ¡ç±»åž‹æŸ¥è¯¢æ–‡ä»¶çš„ä¿¡æ¯ï¼Œæä¾›ç»™é¡µé¢è°ƒç”¨
     * @param fileQuery æŸ¥è¯¢å¯¹è±¡
     * @return æ–‡ä»¶çš„æ˜¾ç¤ºå¯¹è±¡
     */
    @RequestMapping(value = "/listFiles",method = {RequestMethod.GET,RequestMethod.POST})
    public R<IPage<FileObjectVO>> listFiles(FileQuery fileQuery, Query query){
        return R.data(fileService.listFiles(fileQuery,query));
    }
    /**
     * ä½¿ç”¨æ–‡ä»¶ä¸»é”®èŽ·å–å¯¹è±¡
     * @param oid ä¸»é”®
     * @return æ–‡ä»¶æ˜¾ç¤ºå¯¹è±¡
     */
    @GetMapping("/get")
    public FileObjectVO get(String oid){
        return fileService.get(oid);
    }
    /**
     * ä½¿ç”¨æ–‡ä»¶çš„主键批量获取对象
     * @param oids æ–‡ä»¶çš„主键集合
     * @return æ–‡ä»¶çš„æ˜¾ç¤ºä¿¡æ¯
     */
    @GetMapping("/listFilesByOids")
    public List<FileObjectVO> listFilesByOids( Collection<String> oids){
        return fileService.listFilesByOids(oids);
    }
}
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/endpoint/OssEndpoint.java
@@ -17,6 +17,10 @@
package com.vci.ubcs.resource.endpoint;
import com.vci.ubcs.resource.entity.Attach;
import com.vci.ubcs.resource.service.IFileService;
import com.vci.ubcs.resource.utils.FileDownloadUtil;
import com.vci.ubcs.starter.web.util.LangBaseUtil;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
@@ -28,11 +32,16 @@
import org.springblade.core.tool.utils.Func;
import com.vci.ubcs.resource.builder.oss.OssBuilder;
import com.vci.ubcs.resource.service.IAttachService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
/**
 * å¯¹è±¡å­˜å‚¨ç«¯ç‚¹
 *
 * è¿™ä¸ªç±»ä¸ä½¿ç”¨ï¼Œç»Ÿä¸€ç”¨fileController
 *
 * @author Chill
 */
@@ -41,6 +50,7 @@
@AllArgsConstructor
@RequestMapping("/oss/endpoint")
@Api(value = "对象存储端点", tags = "对象存储端点")
@Deprecated
public class OssEndpoint {
    /**
@@ -52,6 +62,7 @@
     * é™„件表服务
     */
    private final IAttachService attachService;
    /**
     * åˆ›å»ºå­˜å‚¨æ¡¶
@@ -68,7 +79,7 @@
    }
    /**
     * åˆ›å»ºå­˜å‚¨æ¡¶
     * åˆ é™¤å­˜å‚¨æ¡¶
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @return R
@@ -107,6 +118,7 @@
    public R<OssFile> statFile(@RequestParam String fileName) {
        return R.data(ossBuilder.template().statFile(fileName));
    }
    /**
     * èŽ·å–æ–‡ä»¶ç›¸å¯¹è·¯å¾„
@@ -160,37 +172,37 @@
        return R.data(bladeFile);
    }
    /**
     * ä¸Šä¼ æ–‡ä»¶å¹¶ä¿å­˜è‡³é™„件表
     *
     * @param file æ–‡ä»¶
     * @return ObjectStat
     */
    @SneakyThrows
    @PostMapping("/put-file-attach")
    public R<BladeFile> putFileAttach(@RequestParam MultipartFile file) {
        String fileName = file.getOriginalFilename();
        BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream());
        Long attachId = buildAttach(fileName, file.getSize(), bladeFile);
        bladeFile.setAttachId(attachId);
        return R.data(bladeFile);
    }
//    /**
//     * ä¸Šä¼ æ–‡ä»¶å¹¶ä¿å­˜è‡³é™„件表
//     *
//     * @param file æ–‡ä»¶
//     * @return ObjectStat
//     */
//    @SneakyThrows
//    @PostMapping("/put-file-attach")
//    public R<BladeFile> putFileAttach(@RequestParam MultipartFile file) {
//        String fileName = file.getOriginalFilename();
//        BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream());
//        Long attachId = buildAttach(fileName, file.getSize(), bladeFile);
//        bladeFile.setAttachId(attachId);
//        return R.data(bladeFile);
//    }
    /**
     * ä¸Šä¼ æ–‡ä»¶å¹¶ä¿å­˜è‡³é™„件表
     *
     * @param fileName å­˜å‚¨æ¡¶å¯¹è±¡åç§°
     * @param file     æ–‡ä»¶
     * @return ObjectStat
     */
    @SneakyThrows
    @PostMapping("/put-file-attach-by-name")
    public R<BladeFile> putFileAttach(@RequestParam String fileName, @RequestParam MultipartFile file) {
        BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream());
        Long attachId = buildAttach(fileName, file.getSize(), bladeFile);
        bladeFile.setAttachId(attachId);
        return R.data(bladeFile);
    }
//    /**
//     * ä¸Šä¼ æ–‡ä»¶å¹¶ä¿å­˜è‡³é™„件表
//     *
//     * @param fileName å­˜å‚¨æ¡¶å¯¹è±¡åç§°
//     * @param file     æ–‡ä»¶
//     * @return ObjectStat
//     */
//    @SneakyThrows
//    @PostMapping("/put-file-attach-by-name")
//    public R<BladeFile> putFileAttach(@RequestParam String fileName, @RequestParam MultipartFile file) {
//        BladeFile bladeFile = ossBuilder.template().putFile(fileName, file.getInputStream());
//        Long attachId = buildAttach(fileName, file.getSize(), bladeFile);
//        bladeFile.setAttachId(attachId);
//        return R.data(bladeFile);
//    }
    /**
     * æž„建附件表
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/mapper/FileObjectMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package com.vci.ubcs.resource.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.vci.ubcs.resource.entity.FileObject;
/**
 * æ–‡ä»¶çš„æ•°æ®æ“ä½œç±»
 * @author weidy
 * @date 2023/6/9
 */
public interface FileObjectMapper extends BaseMapper<FileObject> {
}
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/service/IFileService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,111 @@
package com.vci.ubcs.resource.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vci.ubcs.resource.bo.FileObjectBO;
import com.vci.ubcs.resource.dto.FileObjectDTO;
import com.vci.ubcs.resource.dto.FileReleaseDTO;
import com.vci.ubcs.resource.dto.FileShareDTO;
import com.vci.ubcs.resource.entity.FileObject;
import com.vci.ubcs.resource.query.FileQuery;
import com.vci.ubcs.resource.vo.FileObjectVO;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collection;
import java.util.List;
/**
 * æ–‡ä»¶çš„æœåŠ¡
 * @author weidy
 * @date 2023/1/31
 */
public interface IFileService extends IService<FileObject> {
    /**
     * ä¸‹è½½ï¼Œæ³¨æ„å¤šä¸ªæ–‡ä»¶çš„æ—¶å€™ï¼Œä¼šè‡ªåŠ¨ä¸‹è½½ä¸ºä¸€ä¸ªåŽ‹ç¼©åŒ…
     * @param oids ä¸»é”®é›†åˆ
     * @return æ–‡ä»¶çš„信息
     */
    FileObjectBO downloadFileByOids(Collection<String> oids);
    /**
     * åˆ é™¤æ–‡ä»¶
     * @param oids ä¸»é”®é›†åˆ
     * @return æ‰§è¡Œç»“æžœ
     */
    void deleteFiles(Collection<String> oids);
    /**
     * ä¸Šä¼ æ–‡ä»¶
     * @param file æ–‡ä»¶çš„信息
     * @param fileObjectDTO æ–‡ä»¶çš„相关信息
     * @return æ–‡ä»¶ä¸Šä¼ åŽçš„信息
     */
    R<FileObjectVO> uploadFile(MultipartFile file, FileObjectDTO fileObjectDTO);
    /**
     * ä¿®æ”¹æ–‡ä»¶çš„信息(不会改objectName和filePath)
     * @param fileDTOs æ–‡ä»¶çš„信息
     * @return ä¿®æ”¹åŽçš„信息
     */
    R<List<FileObjectVO>> updateFileInfos(Collection<FileObjectDTO> fileDTOs);
    FileObjectVO do2Vo(FileObject fileObject);
    List<FileObjectVO> do2Vos(Collection<FileObject> fileObjects);
    /**
     * åˆ†äº«æ–‡ä»¶åˆ°å…¶ä»–数据中
     *
     * @param shareDTO æ¥æºä¸šåŠ¡
     * @return åˆ†äº«åŽçš„æ–‡ä»¶ä¿¡æ¯
     */
    R<List<FileObjectVO>> shareFiles(FileShareDTO shareDTO);
    /**
     * æ–‡ä»¶åˆ—表查询
     * @param fileQuery æ–‡ä»¶æŸ¥è¯¢
     * @param query åˆ†é¡µæŸ¥è¯¢å¯¹è±¡
     * @return æ–‡ä»¶çš„æ˜¾ç¤ºä¿¡æ¯
     */
    IPage<FileObjectVO> listFiles(FileQuery fileQuery, Query query);
    /**
     * ä½¿ç”¨æ–‡ä»¶çš„主键批量获取对象
     * @param oids æ–‡ä»¶çš„主键集合
     * @return æ–‡ä»¶çš„æ˜¾ç¤ºä¿¡æ¯
     */
    List<FileObjectVO> listFilesByOids(Collection<String> oids);
    /**
     * æ–‡ä»¶ç”Ÿæ•ˆ
     * @param oids ä¸»é”®é›†åˆ
     * @return æ‰§è¡Œç»“æžœ
     */
    R releasedFiles(Collection<String> oids);
    /**
     * æ‰¹é‡æŒ‡å®šæ–‡ä»¶ä¸šåŠ¡æ•°æ®åŽç”Ÿæ•ˆ
     * @param releaseDTOS ç”Ÿæ•ˆçš„相关信息
     * @return æ‰§è¡Œç»“æžœ
     */
    R releasedFilesForOwn(Collection<FileReleaseDTO> releaseDTOS);
    /**
     * åœ¨ä¸Šä¼ æ–‡ä»¶åŽï¼Œä¿å­˜æ–‡ä»¶çš„信息
     * @param fileObjectDTO æ–‡ä»¶ä¿¡æ¯ä¼ è¾“对象
     * @return æ–‡ä»¶ä¿¡æ¯æ˜¾ç¤ºå¯¹è±¡
     */
    R<FileObjectVO> saveFileAfterUpload(FileObjectDTO fileObjectDTO);
    /**
     * èŽ·å–å¯¹è±¡
     * @param oid ä¸»é”®
     * @return æ–‡ä»¶çš„æ˜¾ç¤ºå¯¹è±¡
     */
    FileObjectVO get(String oid);
}
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/service/impl/FileServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,536 @@
package com.vci.ubcs.resource.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vci.ubcs.resource.bo.FileObjectBO;
import com.vci.ubcs.resource.dto.FileObjectDTO;
import com.vci.ubcs.resource.dto.FileReleaseDTO;
import com.vci.ubcs.resource.dto.FileShareDTO;
import com.vci.ubcs.resource.entity.Attach;
import com.vci.ubcs.resource.entity.FileObject;
import com.vci.ubcs.resource.life.FileLife;
import com.vci.ubcs.resource.mapper.FileObjectMapper;
import com.vci.ubcs.resource.query.FileQuery;
import com.vci.ubcs.resource.service.IFileService;
import com.vci.ubcs.resource.utils.FileUtil;
import com.vci.ubcs.resource.utils.ZipUtil;
import com.vci.ubcs.resource.vo.FileObjectVO;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.web.enumpck.BaseEnum;
import com.vci.ubcs.starter.web.enumpck.UserSecretEnum;
import com.vci.ubcs.starter.web.util.BeanUtil;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.oss.MinioTemplate;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.oss.model.OssFile;
import org.springblade.core.oss.props.OssProperties;
import org.springblade.core.oss.rule.OssRule;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
/**
 * æ–‡ä»¶æœåŠ¡
 * @author weidy
 * @date 2023/2/1
 */
@Service
@Slf4j
public class FileServiceImpl extends ServiceImpl<FileObjectMapper, FileObject> implements IFileService {
    /**
     * æ–‡ä»¶çš„æ•°æ®æ“ä½œç±»
     */
    @Resource
    private FileObjectMapper fileObjectMapper;
    /**
     * å¯¹è±¡çš„æ¨¡ç‰ˆ
     */
    @Autowired
    private OssTemplate ossTemplate;
    /**
     * æ–‡ä»¶æœåŠ¡çš„é…ç½®
     */
    @Autowired
    private OssProperties ossProperties;
    /**
     * åŽ‹ç¼©æ–‡ä»¶çš„å·¥å…·ç±»
     */
    @Autowired
    private ZipUtil zipUtil;
    /***
     * æ–‡ä»¶çš„规则
     */
    @Autowired
    private OssRule ossRule;
    /**
     * ä¸‹è½½ï¼Œæ³¨æ„å¤šä¸ªæ–‡ä»¶çš„æ—¶å€™ï¼Œä¼šè‡ªåŠ¨ä¸‹è½½ä¸ºä¸€ä¸ªåŽ‹ç¼©åŒ…
     *
     * @param oids ä¸»é”®é›†åˆ
     * @return æ–‡ä»¶çš„信息
     */
    @Override
    public FileObjectBO downloadFileByOids(Collection<String> oids) {
        VciBaseUtil.alertNotNull(oids,"文件的主键集合");
        if(log.isDebugEnabled()){
            log.debug("下载文件,",oids.stream().collect(Collectors.joining(",")));
        }
        Collection<FileObjectVO> fileVOs = listFilesByOids(oids);
        FileObjectBO fileObjectBO = new FileObjectBO();
        if(fileVOs.size()==1){
            //只有一个
            FileObjectVO objectVO = fileVOs.stream().findFirst().get();
            BeanUtil.convert(objectVO,fileObjectBO);
            OssFile ossFile = ossTemplate.statFile(objectVO.getBucketName(), objectVO.getObjectName());
            if(ossFile == null || !StringUtils.hasLength(ossFile.getLink())){
                throw new VciBaseException("文件在存储里没有找到",oids.toArray(new String[0]));
            }
            URL url = null;
            try {
                url = new URL(ossFile.getLink());
            } catch (MalformedURLException e) {
                throw new VciBaseException("文件的获取路径有问题",new String[]{ossFile.getLink()},e);
            }
            try {
                fileObjectBO.setInputStream(url.openStream());
            }catch (Throwable e){
                throw new VciBaseException("获取文件的流有问题",new String[]{ossFile.getLink()},e);
            }
        }else{
            //有多个,需要使用zip进行压缩
            String tempFolder = FileUtil.getDefaultTempFolder();
            fileVOs.stream().forEach(fileVO->{
                String fileName = tempFolder + File.separator + fileVO.getName() + "." + fileVO.getFileExtension();
                File file = new File(fileName);
                try {
                    if(!file.exists()) {
                        file.createNewFile();
                    }
                }catch (Throwable e){
                    throw new VciBaseException("创建文件出错,{0}",new String[]{fileName});
                }
                OssFile ossFile = ossTemplate.statFile(fileVO.getBucketName(), fileVO.getObjectName());
                if(ossFile == null || !StringUtils.hasLength(ossFile.getLink())){
                    throw new VciBaseException("文件在存储里没有找到",oids.toArray(new String[0]));
                }
                URL url = null;
                try {
                    url = new URL(ossFile.getLink());
                } catch (MalformedURLException e) {
                    throw new VciBaseException("文件的获取路径有问题",new String[]{ossFile.getLink()},e);
                }
                try(OutputStream os = new FileOutputStream(file);
                    InputStream ins = url.openStream();
                ){
                    IOUtils.copy(ins,os);
                }catch (Throwable e){
                    throw new VciBaseException("下载文件到临时文件夹里出错,{0}",new String[]{fileName});
                }
            });
            String zipName = new File(tempFolder).getPath() + File.separator + fileVOs.stream().findFirst().get().getName() + "等"+fileVOs.size() + "个文件.zip";
            zipUtil.folderToZipFile(tempFolder,zipName);
            fileObjectBO.setFileLocalPath(zipName);
            if(log.isDebugEnabled()){
                log.debug("下载文件的信息,",zipName);
            }
        }
        return fileObjectBO;
    }
    /**
     * åˆ é™¤æ–‡ä»¶
     *
     * @param oids ä¸»é”®é›†åˆ
     * @return æ‰§è¡Œç»“æžœ
     */
    @Override
    @Transactional()
    public void deleteFiles(Collection<String> oids) {
        VciBaseUtil.alertNotNull(oids,"文件的主键集合");
        if(log.isDebugEnabled()){
            log.debug("删除文件,",oids.stream().collect(Collectors.joining(",")));
        }
        Collection<FileObject> fileObjects = listByIds(oids);
        if(!CollectionUtils.isEmpty(fileObjects)){
            VciBaseUtil.switchCollectionForOracleIn(fileObjects).stream().forEach(fileDOs->{
                fileObjectMapper.deleteBatchIds(fileDOs.stream().map(FileObject::getId).collect(Collectors.toList()));
            });
            //删除minio里的文件
            fileObjects.parallelStream().forEach(fileObject -> {
                ossTemplate.removeFile(fileObject.getBucketName(),fileObject.getObjectName());
            });
        }
    }
    /**
     * ä¸Šä¼ æ–‡ä»¶
     *
     * @param file          æ–‡ä»¶çš„信息
     * @param fileObjectDTO æ–‡ä»¶çš„相关信息
     * @return æ–‡ä»¶ä¸Šä¼ åŽçš„信息
     */
    @Override
    @Transactional
    public R<FileObjectVO> uploadFile(MultipartFile file, FileObjectDTO fileObjectDTO) {
        VciBaseUtil.alertNotNull(fileObjectDTO,"文件的信息");
        String sourceFileName = file.getOriginalFilename();
        String fileExtension = FileUtil.getFileExtensionByName(sourceFileName);
        String fileNameNoExtension = FileUtil.getFileNameUnHasExtensionByName(sourceFileName);
        if(fileObjectDTO.getUpdateFileFlag()==null || !fileObjectDTO.getUpdateFileFlag()) {
            return R.data(add(fileObjectDTO,file));
        }else{
            //修改,需要先获取
            VciBaseUtil.alertNotNull(fileObjectDTO.getOid(),"文件的主键");
            FileObject fileObject = getById(fileObjectDTO.getOid());
            if (StringUtils.hasLength(fileObjectDTO.getId())) {
                fileObject.setId(fileNameNoExtension);
            }
            fileObject.setName(fileNameNoExtension);
            fileObject.setFileExtension(fileExtension);
            fileObject.setFileSize(file.getSize());
            //以前的信息先获取
            String oldObjectName = fileObject.getObjectName();
            String oldBucketName = fileObject.getBucketName();
            String bucketName = StringUtils.hasLength(fileObjectDTO.getBucketName())?fileObjectDTO.getBucketName():ossProperties.getBucketName();
            BladeFile bladeFile = ossTemplate.putFile(bucketName,file.getOriginalFilename(),file);
            fileObject.setBucketName(bucketName);
            fileObject.setObjectName(bladeFile.getName());
            fileObject.setFileLink(bladeFile.getLink());
            fileObjectMapper.updateById(fileObject);
            //删除以前的
            ossTemplate.removeFile(oldBucketName,oldObjectName);
            if(log.isDebugEnabled()){
                log.debug("修改文件",fileObject.toString(),oldObjectName,oldBucketName);
            }
            FileObjectVO fileObjectVO = do2Vo(fileObject);
            return R.data(fileObjectVO);
        }
    }
    private FileObjectVO add(FileObjectDTO fileObjectDTO,MultipartFile file){
        String sourceFileName = file.getOriginalFilename();
        String fileExtension = FileUtil.getFileExtensionByName(sourceFileName);
        String fileNameNoExtension = FileUtil.getFileNameUnHasExtensionByName(sourceFileName);
        //存储业务数据与文件信息
        FileObject fileObject = new FileObject();
        BeanUtil.convert(fileObjectDTO, fileObject);
        if (!StringUtils.hasLength(fileObject.getId())) {
            fileObject.setId(fileNameNoExtension);
        }
        if (!StringUtils.hasLength(fileObject.getName())) {
            fileObject.setName(fileNameNoExtension);
        }
        fileObject.setFileExtension(fileExtension);
        fileObject.setFileSize(file.getSize());
        if (!StringUtils.hasLength(fileObject.getOid())) {
            fileObject.setOid(VciBaseUtil.getPk());
        }
        if (fileObjectDTO.getEffect() != null && fileObjectDTO.getEffect()) {
            fileObject.setLcStatus(FileLife.FILE_RELEASE.getValue());
        } else {
            fileObject.setLcStatus(FileLife.TRANS_FINISH.getValue());
        }
        if (fileObject.getSecretGrade() == null || fileObject.getSecretGrade() == 0) {
            // VciBaseUtil.getCurrentUserSecret()还需要处理,在进入服务的时候,根据当前用户的信息获取用户的对象
            fileObject.setSecretGrade( VciBaseUtil.getCurrentUserSecret());
        }
        String bucketName = StringUtils.hasLength(fileObjectDTO.getBucketName())?fileObjectDTO.getBucketName():ossProperties.getBucketName();
        //先存到Minio后再说
        BladeFile bladeFile = ossTemplate.putFile(bucketName,file.getOriginalFilename(),file);
        fileObject.setBucketName(bucketName);
        fileObject.setObjectName(bladeFile.getName());
        fileObject.setFileLink(bladeFile.getLink());
        fileObjectMapper.insert(fileObject);
        if(log.isDebugEnabled()){
            log.debug("新增文件",fileObject.toString());
        }
        FileObjectVO fileObjectVO = do2Vo(fileObject);
        return fileObjectVO;
    }
    /**
     * æ•°æ®å¯¹è±¡è½¬æ˜¾ç¤ºå¯¹è±¡
     * @param fileObject æ–‡ä»¶çš„æ•°æ®å¯¹è±¡
     * @return æ˜¾ç¤ºå¯¹è±¡
     */
    @Override
    public FileObjectVO do2Vo(FileObject fileObject) {
        FileObjectVO fileObjectVO = new FileObjectVO();
        BeanUtil.convert(fileObject,fileObjectVO);
        fileObjectVO.setLcStatusText(BaseEnum.getTextByValue(FileLife.class,fileObjectVO.getLcStatus()));
        //fileObjectVO.setSecretGradeText(UserSecretEnum);
        return fileObjectVO;
    }
    @Override
    public List<FileObjectVO> do2Vos(Collection<FileObject> fileObjects){
        List<FileObjectVO> fileObjectVOList = new ArrayList<>();
        Optional.ofNullable(fileObjects).orElseGet(ArrayList::new).stream().forEach(fo->{
            fileObjectVOList.add(do2Vo(fo));
        });
        return fileObjectVOList;
    }
    /**
     * åˆ†äº«æ–‡ä»¶åˆ°å…¶ä»–数据中
     *
     * @param shareDTO æ¥æºä¸šåŠ¡
     * @return åˆ†äº«åŽçš„æ–‡ä»¶ä¿¡æ¯
     */
    @Override
    @Transactional
    public R<List<FileObjectVO>> shareFiles(FileShareDTO shareDTO) {
        VciBaseUtil.alertNotNull(shareDTO,"分享的信息",shareDTO.getTargetBus(),"目标的业务名称",shareDTO.getTargetBusOid(),"目标的业务数据主键");
        List<FileObject> fileObjectList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(shareDTO.getOids())){
            fileObjectList.addAll(listByIds(shareDTO.getOids()));
        }
        LambdaQueryWrapper<FileObject> queryWrapper = new LambdaQueryWrapper<FileObject>(FileObject.class);
        if(StringUtils.hasLength(shareDTO.getSourceBus())) {
            queryWrapper.in(FileObject::getOwnBtmName, VciBaseUtil.str2List(shareDTO.getSourceBus()));
        }
        if(StringUtils.hasLength(shareDTO.getSourceBusOid())){
            queryWrapper.in(FileObject::getOwnbizOid,VciBaseUtil.str2List(shareDTO.getSourceBusOid()));
        }
        fileObjectList.addAll(fileObjectMapper.selectList(queryWrapper));
        if(CollectionUtils.isEmpty(fileObjectList)){
            throw new VciBaseException("没有找到可以分享的文件");
        }
        BladeUser user = AuthUtil.getUser();
        Date now = new Date();
        List<FileObject> newFileObjects = new ArrayList<>();
        fileObjectList.stream().forEach(fileObject -> {
            FileObject newFileObject = new FileObject();
            BeanUtil.convert(fileObject,newFileObject);
            newFileObject.setId(VciBaseUtil.getPk());
            newFileObject.setNameOid(VciBaseUtil.getPk());
            newFileObject.setRevisionOid(VciBaseUtil.getPk());
            newFileObject.setCreator(user.getAccount());
            newFileObject.setCreateTime(now);
            newFileObject.setLastModifier(user.getAccount());
            newFileObject.setLastModifyTime(now);
            newFileObject.setTs(now);
            newFileObject.setOwnBtmName(shareDTO.getTargetBus());
            newFileObject.setOwnbizOid(shareDTO.getTargetBusOid());
            newFileObject.setObjectName(ossRule.fileName( "." + fileObject.getFileExtension()));
            //下载文件后,上传文件
            ossTemplate.copyFile(fileObject.getBucketName(),fileObject.getObjectName(),fileObject.getBucketName(),newFileObject.getObjectName());
            newFileObject.setFileLink(ossTemplate.fileLink(newFileObject.getBucketName(),newFileObject.getObjectName()));
            newFileObjects.add(newFileObject);
        });
        newFileObjects.stream().forEach(fileObject -> {
            fileObjectMapper.insert(fileObject);
        });
        return R.data(do2Vos(newFileObjects));
    }
    /**
     * ä¿®æ”¹æ–‡ä»¶çš„信息(不会改objectName和filePath)
     *
     * @param fileDTOs æ–‡ä»¶çš„信息
     * @return ä¿®æ”¹åŽçš„信息
     */
    @Override
    @Transactional
    public R<List<FileObjectVO>> updateFileInfos(Collection<FileObjectDTO> fileDTOs) {
        VciBaseUtil.alertNotNull(fileDTOs,"要更新的文件的信息");
        if(fileDTOs.stream().anyMatch(s->!StringUtils.hasLength(s.getId()))){
            throw new VciBaseException("要更新的文件信息的主键不能为空");
        }
        Map<String, FileObject> fileObjectMap = Optional.ofNullable(listByIds(fileDTOs.stream().map(FileObjectDTO::getId).collect(Collectors.toList()))).orElseGet(ArrayList::new).stream().collect(Collectors.toMap(s -> s.getOid(), t -> t, (o1, o2) -> o1));
        BladeUser user = AuthUtil.getUser();
        Date now = new Date();
        fileDTOs.stream().forEach(fileDTO->{
            if(!fileObjectMap.containsKey(fileDTO.getOid())){
                throw new VciBaseException("名称为{0}的文件在系统里不存在",new String[]{StringUtils.hasLength(fileDTO.getId())?fileDTO.getId():fileDTO.getName()});
            }
            FileObject fileObject = fileObjectMap.get(fileDTO.getId());
            String oldObjectName = fileObject.getObjectName();
            String oldBucketName = fileObject.getBucketName();
            String filePath = fileObject.getFileLink();
            BeanUtil.convert(fileDTO,fileObject);
            fileObject.setObjectName(oldObjectName);
            fileObject.setBucketName(oldBucketName);
            fileObject.setFileLink(filePath);
            fileObject.setLastModifier(user.getAccount());
            fileObject.setLastModifyTime(now);
            fileObject.setTs(now);
        });
       fileObjectMap.values().stream().forEach(fileObject -> {
           fileObjectMapper.updateById(fileObject);
        });
        return R.data(do2Vos(fileObjectMap.values()));
    }
    /**
     * æ–‡ä»¶åˆ—表查询
     *
     * @param fileQuery æ–‡ä»¶æŸ¥è¯¢
     * @return æ–‡ä»¶çš„æ˜¾ç¤ºä¿¡æ¯
     */
    @Override
    public IPage<FileObjectVO> listFiles(FileQuery fileQuery, Query query){
        IPage<FileObject> pages = page(Condition.getPage(query), Condition.getQueryWrapper(fileQuery));
        return pages.convert((fileObject -> do2Vo(fileObject)));
    }
    /**
     * ä½¿ç”¨æ–‡ä»¶çš„主键批量获取对象
     *
     * @param oids æ–‡ä»¶çš„主键集合
     * @return æ–‡ä»¶çš„æ˜¾ç¤ºä¿¡æ¯
     */
    @Override
    public List<FileObjectVO> listFilesByOids(Collection<String> oids) {
        return do2Vos(listByIds(oids));
    }
    /**
     * æ–‡ä»¶ç”Ÿæ•ˆ
     *
     * @param oids ä¸»é”®é›†åˆ
     * @return æ‰§è¡Œç»“æžœ
     */
    @Override
    @Transactional
    public R releasedFiles(Collection<String> oids) {
        Collection<FileObject> fileObjects = listByIds(oids);
        if(!CollectionUtils.isEmpty(fileObjects)){
            fileObjects.stream().forEach(obj->{
                obj.setLcStatus(FileLife.FILE_RELEASE.getValue());
                fileObjectMapper.updateById(obj);
            });
        }
        return R.success("生效成功");
    }
    /**
     * æ‰¹é‡æŒ‡å®šæ–‡ä»¶ä¸šåŠ¡æ•°æ®åŽç”Ÿæ•ˆ
     *
     * @param releaseDTOS ç”Ÿæ•ˆçš„相关信息
     * @return æ‰§è¡Œç»“æžœ
     */
    @Override
    @Transactional
    public R releasedFilesForOwn(Collection<FileReleaseDTO> releaseDTOS) {
        VciBaseUtil.alertNotNull(releaseDTOS,"发布的信息");
        List<FileObject> fileObjectList = new ArrayList<>();
        List<String> oids = new ArrayList<>();
        releaseDTOS.stream().filter(s->!CollectionUtils.isEmpty(s.getOids())).forEach(dtos->{
            oids.addAll(dtos.getOids());
        });
        if(!CollectionUtils.isEmpty(oids)){
            fileObjectList.addAll(listByIds(oids));
        }
        releaseDTOS.stream().forEach(dto->{
            LambdaQueryWrapper<FileObject> queryWrapper =   new LambdaQueryWrapper<>(FileObject.class);
            if(StringUtils.hasLength(dto.getOwnBtmName())) {
                queryWrapper.in(FileObject::getOwnBtmName, VciBaseUtil.str2List(dto.getOwnBtmName()));
            }
            if(StringUtils.hasLength(dto.getOwnbizOid())) {
                queryWrapper.in(FileObject::getOwnbizOid, VciBaseUtil.str2List(dto.getOwnbizOid()));
            }
            fileObjectList.addAll(fileObjectMapper.selectList(queryWrapper));
        });
        if(!CollectionUtils.isEmpty(fileObjectList)){
            fileObjectList.stream().forEach(objs->{
                objs.setLcStatus(FileLife.FILE_RELEASE.getValue());
                fileObjectMapper.updateById(objs);
            });
        }
        return R.success("生效成功");
    }
    /**
     * åœ¨ä¸Šä¼ æ–‡ä»¶åŽï¼Œä¿å­˜æ–‡ä»¶çš„信息
     *
     * @param fileObjectDTO æ–‡ä»¶ä¿¡æ¯ä¼ è¾“对象
     * @return æ–‡ä»¶ä¿¡æ¯æ˜¾ç¤ºå¯¹è±¡
     */
    @Override
    @Transactional
    public R<FileObjectVO> saveFileAfterUpload(FileObjectDTO fileObjectDTO) {
        if(fileObjectDTO.getEffect() !=null && fileObjectDTO.getEffect() && !StringUtils.hasLength(fileObjectDTO.getLcStatus())){
            fileObjectDTO.setLcStatus(FileLife.FILE_RELEASE.getValue());
        }
        return R.data(addOnlyInfo(fileObjectDTO));
    }
    /**
     * èŽ·å–å¯¹è±¡
     *
     * @param oid ä¸»é”®
     * @return æ–‡ä»¶çš„æ˜¾ç¤ºå¯¹è±¡
     */
    @Override
    public FileObjectVO get(String oid) {
        return do2Vo(getById(oid));
    }
    /**
     * ä»…添加信息
     * @param fileObjectDTO æ–‡ä»¶çš„æ•°æ®ä¼ è¾“对象
     * @return æ˜¾ç¤ºå¯¹è±¡
     */
    public FileObjectVO addOnlyInfo(FileObjectDTO fileObjectDTO){
        //存储业务数据与文件信息
        FileObject fileObject = new FileObject();
        BeanUtil.convert(fileObjectDTO, fileObject);
        if (!StringUtils.hasLength(fileObject.getOid())) {
            fileObject.setOid(VciBaseUtil.getPk());
        }
        if (fileObject.getSecretGrade() == null || fileObject.getSecretGrade() == 0) {
            // VciBaseUtil.getCurrentUserSecret()还需要处理,在进入服务的时候,根据当前用户的信息获取用户的对象
            fileObject.setSecretGrade( VciBaseUtil.getCurrentUserSecret());
        }
        fileObjectMapper.insert(fileObject);
        if(log.isDebugEnabled()){
            log.debug("新增文件",fileObject.toString());
        }
        return do2Vo(fileObject);
    }
}
Source/UBCS/ubcs-service-api/ubcs-code-api/src/main/java/com/vci/ubcs/code/bo/AttributeValue.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.vci.ubcs.code.bo;
import org.omg.CORBA.portable.IDLEntity;
public class AttributeValue implements IDLEntity {
    public String attrName = "";
    public String attrVal = "";
    public AttributeValue() {
    }
    public AttributeValue(String attrName, String attrVal) {
        this.attrName = attrName;
        this.attrVal = attrVal;
    }
}
Source/UBCS/ubcs-service-api/ubcs-code-api/src/main/java/com/vci/ubcs/code/vo/pagemodel/CodeImportTemplateVO.java
@@ -1,13 +1,22 @@
package com.vci.ubcs.code.vo.pagemodel;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/****
 * æ‰¹é‡ç”³è¯·redis缓存对象
 * @author xiejun
 * @date 2023-06-14
 */
@Data
public class CodeImportTemplateVO {
    private List<ColumnVO> cloNamesList=new ArrayList<>();
    private CodeClassifyTemplateVO codeClstemplateVO;
    private CodeClassifyTemplateVO codeClassifyTemplateVO;
    private CodeClassifyVO codeClassifyVO;
}
Source/UBCS/ubcs-service-api/ubcs-omd-api/pom.xml
@@ -20,6 +20,12 @@
            <artifactId>ubcs-util-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.vci.ubcs</groupId>
            <artifactId>ubcs-user-api</artifactId>
            <version>3.0.1.RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>
Source/UBCS/ubcs-service-api/ubcs-omd-api/src/main/java/com/vci/ubcs/omd/feign/IWebSecretClient.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,184 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.omd.feign;
import com.vci.ubcs.omd.entity.Enum;
import com.vci.ubcs.omd.entity.EnumItem;
import com.vci.ubcs.omd.vo.EnumVO;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.system.user.vo.UserVO;
import io.swagger.models.auth.In;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.mp.support.BladePage;
import org.springblade.core.tool.api.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
 * æžšä¸¾å®šä¹‰ Feign接口类
 *
 * @author yuxc
 * @since 2023-05-08
 */
@FeignClient(
    value = AppConstant.APPLICATION_NAME_OMD,
    fallback = IWebSecretFallback.class
)
public interface IWebSecretClient {
    String API_PREFIX = "/client";
    String MINUSER = API_PREFIX + "/secret/min-user";
    String MINDATA = API_PREFIX + "/secret/min-data";
    String MINIP = API_PREFIX + "/secret/min-ip";
    String USER = API_PREFIX + "/secret/user";
    String USERVO = API_PREFIX + "/secret/uservo";
    String CHECKDATA = API_PREFIX + "/secret/check-data";
    String CHECKUSERDATA = API_PREFIX + "/secret/chec-user-data";
    String CHECKUSERIDDATA = API_PREFIX + "/secret/chec-userid-data";
    String CHECKVO = API_PREFIX + "/secret/checkvo";
    String IP = API_PREFIX + "/secret/ip";
    String IPUSER = API_PREFIX + "/secret/ip-user";
    String IPSECRET = API_PREFIX + "/secret/ip-secret";
    String IPUSERID = API_PREFIX + "/secret/ip-userid";
    String IPUSERVO = API_PREFIX + "/secret/ip-uservo";
    /**
     * èŽ·å–ç”¨æˆ·å¯†çº§çš„æœ€å°å€¼
     * @return å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    @GetMapping(MINUSER)
    R<Integer> getMinUserSecret() throws VciBaseException;
    /**
     * èŽ·å–æ•°æ®å¯†çº§çš„é»˜è®¤å€¼
     * @return å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    @GetMapping(MINDATA)
    R<Integer> getMinDataSecret() throws VciBaseException;
    /**
     * èŽ·å–IP密级的默认值
     * @return å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    @GetMapping(MINIP)
    R<Integer> getMinIpSecret() throws VciBaseException;
    /**
     * èŽ·å–ç”¨æˆ·å¯†çº§
     * @param userId ç”¨æˆ·ä¸»é”®
     * @return ç”¨æˆ·çš„密级
     * @throws VciBaseException å‚数错误,用户不存在会抛出异常
     */
    @GetMapping(USER)
    R<Integer> getUserSecret(@RequestParam("userId") String userId) throws VciBaseException ;
    /**
     * èŽ·å–ç”¨æˆ·å¯†çº§
     * @param userVO ç”¨æˆ·çš„æ˜¾ç¤ºå¯¹è±¡
     * @return ç”¨æˆ·çš„密级
     * @throws VciBaseException å‚数错误,用户不存在会抛出异常
     */
    @GetMapping(USERVO)
    R<Integer> getUserSecret(@RequestBody UserVO userVO) throws VciBaseException;
    /**
     * æ ¡éªŒå½“前用户是否有权限访问数据
     * @param secret æ•°æ®çš„密级
     * @return true表示允许访问
     */
    @GetMapping(CHECKDATA)
    R<Boolean> checkDataSecret(@RequestParam("secret") int secret);
    /**
     * æ ¡éªŒç”¨æˆ·çš„密级是否是否有权限访问数据
     * @param secret æ•°æ®çš„密级
     * @param userSecret ç”¨æˆ·å¯†çº§
     * @return true表示允许访问
     */
    @GetMapping(CHECKUSERDATA)
    R<Boolean> checkDataSecret(@RequestParam("secret") int secret, @RequestParam("userSecret") int userSecret) ;
    /**
     * æ ¹æ®ç”¨æˆ·åæ¥æ ¡éªŒæ•°æ®å¯†çº§
     * @param secret æ•°æ®çš„密级
     * @param userId ç”¨æˆ·å
     * @return true表示允许访问
     * @throws VciBaseException å‚数错误,用户不存在会抛出异常
     */
    @GetMapping(CHECKUSERIDDATA)
    R<Boolean> checkDataSecret(@RequestParam("secret") int secret, @RequestParam("userId") String userId) throws VciBaseException;
    /**
     * æ ¹æ®ç”¨æˆ·å¯¹è±¡æ¥æ ¡éªŒæ•°æ®å¯†çº§
     * @param secret  æ•°æ®çš„密级
     * @param userVO ç”¨æˆ·çš„æ˜¾ç¤ºå¯¹è±¡
     * @return true表示允许访问
     */
    @GetMapping(CHECKVO)
    R<Boolean> checkDataSecret(@RequestParam("secret") int secret,@RequestBody UserVO userVO) ;
    /**
     * èŽ·å–IP地址的密级
     * @param ip ip地址
     * @return å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™çš„æ—¶å€™ä¼šæŠ›å‡ºå¼‚常
     */
    @GetMapping(IP)
    R<Integer> getIpSecret(@RequestParam("ip") String ip) throws VciBaseException;
    /**
     * æ£€æŸ¥æœºå™¨å¯†çº§
     * @param ipSecret æœºå™¨å¯†çº§
     * @param userSecret ç”¨æˆ·çš„密级
     * @return å¯†çº§çš„值
     */
    @GetMapping(IPUSER)
    R<Boolean> checkIpSecret(@RequestParam("ipSecret") int ipSecret, @RequestParam("userSecret") int userSecret);
    /**
     * æ£€æŸ¥å½“前用户是否符合机器密级
     * @param ipSecret æœºå™¨å¯†çº§
     * @return true表示允许访问
     */
    @GetMapping(IPSECRET)
    R<Boolean> checkIpSecret(@RequestParam("ipSecret") int ipSecret) ;
    /**
     * æ ¡éªŒæŒ‡å®šip和用户是否符合机器密级
     * @param ip ip地址
     * @param userId ç”¨æˆ·å
     * @return true表示允许访问
     * @throws VciBaseException å‚数错误,用户不存在会抛出异常
     */
    @GetMapping(IPUSERID)
    R<Boolean> checkIpSecret(@RequestParam("ip") String ip, @RequestParam("userId") String userId) throws VciBaseException;
    /**
     * æ ¡éªŒæŒ‡å®šIP和用户对象符合机器密级
     * @param ip ip地址
     * @param userVO ç”¨æˆ·å¯¹è±¡
     * @return  true表示允许访问
     */
    @GetMapping(IPUSERVO)
    R<Boolean> checkIpSecret(@RequestParam("ip") String ip,@RequestBody UserVO userVO) ;
}
Source/UBCS/ubcs-service-api/ubcs-omd-api/src/main/java/com/vci/ubcs/omd/feign/IWebSecretFallback.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,101 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.omd.feign;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.system.user.vo.UserVO;
import org.springblade.core.tool.api.R;
import org.springframework.stereotype.Component;
/**
 * Feign失败配置
 *
 * @author Chill
 */
@Component
public class IWebSecretFallback implements IWebSecretClient {
    @Override
    public R<Integer> getMinUserSecret() throws VciBaseException {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Integer> getMinDataSecret() throws VciBaseException {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Integer> getMinIpSecret() throws VciBaseException {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Integer> getUserSecret(String userId) throws VciBaseException {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Integer> getUserSecret(UserVO userVO) throws VciBaseException {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Boolean> checkDataSecret(int secret) {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Boolean> checkDataSecret(int secret, int userSecret) {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Boolean> checkDataSecret(int secret, String userId) throws VciBaseException {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Boolean> checkDataSecret(int secret, UserVO userVO) {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Integer> getIpSecret(String ip) throws VciBaseException {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Boolean> checkIpSecret(int ipSecret, int userSecret) {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Boolean> checkIpSecret(int ipSecret) {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Boolean> checkIpSecret(String ip, String userId) throws VciBaseException {
        return R.fail("获取数据失败");
    }
    @Override
    public R<Boolean> checkIpSecret(String ip, UserVO userVO) {
        return R.fail("获取数据失败");
    }
}
Source/UBCS/ubcs-service-api/ubcs-omd-api/src/main/java/com/vci/ubcs/omd/util/Tool.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.vci.ubcs.omd.util;
import java.util.ArrayList;
public class Tool {
    public static final String ALLOWNULL = "allowNull";
    public static final String BTM = "btm";
    public static final String ISFIXLEN = "isFixLen";
    public static final String LENGTH = "length";
    public static final String ENUMNAME = "enumName";
    public static final String ACCURACY = "accuracy";
    public static final String LINKTYPENAME = "linkTypeName";
    public static final String VERSION = "version";
    public static ArrayList<String> convertArrayToList(String[] array) {
        ArrayList<String> list = new ArrayList();
        for(int i = 0; i < array.length; ++i) {
            list.add(array[i]);
        }
        return list;
    }
    public static String getOtherValueByType(String other, String type) {
        String[] otherArray = other.split(";");
        for(int i = 0; i < otherArray.length; ++i) {
            String otherValue = otherArray[i];
            if (otherValue.contains(type)) {
                return otherValue.substring(otherValue.indexOf("=") + 2, otherValue.length());
            }
        }
        return null;
    }
}
Source/UBCS/ubcs-service-api/ubcs-omd-api/src/main/java/com/vci/ubcs/omd/utils/VciOmdUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.vci.ubcs.omd.utils;
import com.vci.ubcs.omd.vo.EnumVO;
import com.vci.ubcs.starter.web.pagemodel.KeyValue;
import java.util.ArrayList;
import java.util.List;
public class VciOmdUtil {
    /**
     * å°†List<EnumVO> è½¬æ¢ä¸ºKeyValue ç±»åž‹
     * @param enums æžšä¸¾é›†åˆ
     * @return KeyValue集合
     */
    public static List<KeyValue> enumsToListKeyVale(List<EnumVO> enums) {
        List<KeyValue> keyValues = new ArrayList<>();
        for (EnumVO anEnum : enums) {
            KeyValue keyValue = new KeyValue();
            keyValue.setKey(anEnum.getItemName());
            keyValue.setValue(anEnum.getItemValue());
            keyValues.add(keyValue);
        }
        return keyValues;
    }
}
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/poi/util/ExcelUtil.java
@@ -61,6 +61,10 @@
    private static Logger logger = LoggerFactory.getLogger(ExcelUtil.class);
    public static final String KEY_ATTR_CHAR = "☆";
    public static final String REQUIRED_CHAR = "*";
    /**
     * æ›¿æ¢å­—符
     */
    public static final String SPECIAL_CHAR  = "VCI";
    public ExcelUtil() {
    }
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/util/DefaultAttrAssimtUtil.java
@@ -1,6 +1,6 @@
package com.vci.ubcs.starter.util;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.revision.model.BaseModel;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
@@ -9,8 +9,11 @@
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
/**
 * æ–°å¢žæ—¶é»˜è®¤å€¼å±žæ€§èµ‹å€¼
@@ -50,7 +53,7 @@
            baseModel.setVersionSeq(1);
            baseModel.setVersionRule("0");
            baseModel.setVersionValue("1");
            baseModel.setNameOid(VciBaseUtil.getPk());
            baseModel.setRevisionOid(VciBaseUtil.getPk());
            baseModel.setLastModifier(userId);
        }catch (VciBaseException e){
            e.printStackTrace();
@@ -79,4 +82,68 @@
        return (T)baseModel;
    }
    /**
     * æ–°å¢žæ—¶å¡«å……默认值
     * @param object ç»§æ‰¿äº†BaseModel的实体对象
     * @param <T>   è¿”回值的类型
     * @return
     * @throws VciBaseException
     */
    public static <T extends BaseModel> T copplyDefaultAttrAssimt(Map<String,String> dataMap, T object) throws VciBaseException {
        BaseModel baseModel = object;
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            baseModel.setOid(dataMap.getOrDefault("OID",""));
            String createTime=dataMap.getOrDefault("CREATETIME","");
            baseModel.setCreateTime(chageStringToDate(createTime));
            baseModel.setNameOid(dataMap.getOrDefault("NAMEOID",""));
            String lastModifyTime=dataMap.getOrDefault("LASTMODIFYTIME","");
            baseModel.setLastModifyTime(chageStringToDate(lastModifyTime));
            String ts=dataMap.getOrDefault("TS","");
            baseModel.setTs(chageStringToDate(ts));
            baseModel.setRevisionOid(dataMap.getOrDefault("REVISIONOID",""));
            //用户id
            String userId = AuthUtil.getUserId().toString();
            baseModel.setBtmname(dataMap.getOrDefault("BTMNAME",""));
            baseModel.setCreator(dataMap.getOrDefault("CREATOR",""));
            baseModel.setFirstR(dataMap.getOrDefault("FIRSTR",""));
            baseModel.setFirstV(dataMap.getOrDefault("FIRSTV",""));
            baseModel.setLastR(dataMap.getOrDefault("LASTR",""));
            baseModel.setLastV(dataMap.getOrDefault("LASTV",""));
            baseModel.setRevisionSeq(chageStringToInt(dataMap.getOrDefault("REVISIONSEQ","")));
            baseModel.setOwner(dataMap.getOrDefault("OWNER",""));
            baseModel.setVersionSeq(chageStringToInt(dataMap.getOrDefault("VERSIONSEQ","")));
            baseModel.setVersionRule(dataMap.getOrDefault("VERSIONRULE",""));
            baseModel.setVersionValue(dataMap.getOrDefault("VERSIONVALUE",""));
            baseModel.setRevisionOid(dataMap.getOrDefault("REVISIONOID",""));
            baseModel.setLastModifier(userId);
        }catch (VciBaseException e){
            e.printStackTrace();
        }
        return (T)baseModel;
    }
    private static int chageStringToInt(String value){
        int newValue=0;
        if(StringUtils.isNotBlank(value)){
            newValue = Integer.parseInt(value);
        }
        return newValue;
    }
    private static Date chageStringToDate(String value){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date=new Date();
        if(StringUtils.isNotBlank(value)){
            try {
                date = format.parse(value);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return date;
    }
}
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/constant/FrameWorkBusLangCodeConstant.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,519 @@
package com.vci.ubcs.starter.web.constant;
/**
 * åŸºç¡€æ¡†æž¶ä¸­ä¸šåŠ¡éƒ¨åˆ†çš„å¤šè¯­è¨€ä»£ç 
 * @author weidy
 * @date 2020/4/25
 */
public class FrameWorkBusLangCodeConstant {
    //登陆部分的
    /**
     * ç”¨æˆ·å·²ç»ç™»å½•
     */
    public static final String USER_IS_LOGINED = "userIsLogined";
    /**
     * ç”¨æˆ·æ²¡æœ‰æ‰¾åˆ°
     */
    public static final String USER_NOT_FOUND = "userNotFound";
    /**
     * ç”¨æˆ·å·²ç»åœç”¨
     */
    public static final String USER_IS_DISABLED = "userIsDisabled";
    /**
     * ç”¨æˆ·å·²ç»è¢«é”å®š
     */
    public static final String USER_IS_LOCK = "userIsLocked";
    /**
     * ç”¨æˆ·å·²ç»è¶…过失效时间
     */
    public static final String USER_MORE_THAN_DISABLE_DATE = "moreDisableDate";
    /**
     * ç”¨æˆ·å¯†ç é”™è¯¯è¢«é”å®š
     */
    public static final String USER_PWD_LOCK = "userPwdErrorLock";
    /**
     * ç”¨æˆ·å¯†ç ä¸ç›¸ç­‰
     */
    public static final String USER_PWD_NOT_EQUAL = "userPwdNotEqual";
    //密码相关
    /**
     * ç¡®è®¤å¯†ç ä¸ç›¸åŒ
     */
    public static final String CHANGE_PWD_NOT_EQUAL="changePwdNotEqual";
    /**
     * æ²¡æœ‰å¯†ç ç­–ç•¥
     */
    public static final String HAS_NOT_PWD_STRATEGY="hasNotPasswordStrategy";
    /**
     * å¯†ç å®‰å…¨ç­–略未找到
     */
    public static final String PASSWORD_STRATEGY_NOT_FOUND = "passwordStrategyNotFound";
    /**
     * å¯†ç æ‰€éœ€å­—符类型为空
     */
    public static final String REQUIRE_CHAR_TYPE_NULL = "requireCharTypeNull";
    /**
     * å¯†ç çš„字符类型不符合要求
     */
    public static final String REQUIRE_CHAR_TYPE_NOT_EXIST = "requireCharTypeNotExist";
    /**
     * å¯†ç å¤æ‚度不符合要求
     */
    public static final String LESS_CHAR_TYPE = "lessCharType";
    /**
     * å¯†ç ä¸åŒ…含小写字母
     */
    public static final String NOT_HAS_LOW_LETTER= "notHasLowLetter";
    /**
     * å¯†ç ä¸åŒ…含数字
     */
    public static final String NOT_HAS_NUMBER = "notHasNumber";
    /**
     * å¯†ç ä¸åŒ…含特殊字母
     */
    public static final String NOT_HAS_SPECIAL ="notHasSpecial";
    /**
     * å¯†ç ä¸ç¬¦åˆæœ€å°é•¿åº¦è¦æ±‚
     */
    public static final String LESS_MIN_LENGTH = "lessMinLength";
    /**
     * å¯†ç ä¸ç¬¦åˆæœ€å¤§é•¿åº¦è¦æ±‚
     */
    public static final String MORE_MAX_lENGTH ="moreMaxLength";
    /**
     * å¯†ç å³å°†è¿‡æœŸ
     */
    public static final String PASSWORD_REMAIN_DAY = "passwordRemainDay";
    //组织
    //部门
    //职务
    //职级
    //用户
    //角色
    //权限
    //地区分类
    //地点
    //联系人
    //物料基本信息
    //物料
    /**
     * ç‰©æ–™çš„序列号
     */
    public static final String BD_MATERIAL_SERIAL_NUMBER_REPEAT = "materialSerialNumberRepeat";
    //库房类型
    /**
     * åº“房分类的内部标识不全是英文
     */
    public static final String BD_WAREHOUSE_CLASSIFY_ID_NOT_LETTER = "warehouseClassifyIdNotLetter";
    /**
     * å› ä¸ºå·²ç»æœ‰å­˜åœ¨ä½¿ç”¨å½“前分类的库房,所以只是修改名称,描述和上级分类
     */
    public static final String BD_WAREHOUSE_CLASSIFY_LINK_BY_WAREHOUSE ="warehouseClassifyLinkByWarehouse" ;
    /**
     * ä¸Žä¸Šçº§åº“房基本分类的库房类型不相同
     */
    public static final String BD_WAREHOUSE_CLASSIFY_TYPE_NOT_EQUAL_PARENT = "warehouseClassifyParentNotEqualType";
    //库房管理
    /**
     * ä¸Žä¸Šçº§åº“房的库房分类不相同
     */
    public static final String BD_WAREHOUSE_PARENT_WAREHOUSE_NOT_EQUAL_CLASSIFY = "warehouseParentNotEqualClassify";
    /**
     * æœ‰æ•°æ®ä¸èƒ½ä¿®æ”¹åº“房的所属基本分类
     */
    public static final String BD_WAREHOUSE_HAS_DATA_NOT_EDIT_CLASSIFY = "warehouseHasDataNotEditClassify";
    /**
     * æ²¡æœ‰ä¼ é€’用户的主键,不能设置管理员
     */
    public static final String BD_WAREHOUSE_ADMIN_USEROID_NOT_HAS = "warehouseAdminUserOidNotHas";
    /**
     * ä¸ºåº“房设置管理员成功
     */
    public static final String BD_WAREHOUSE_ADMIN_LINK_SUCCESS = "warehouseAdminLinkSuccess";
    /**
     * åº“房分类的主键不存在
     */
    public static final String BD_WAREHOUSE_CLASSIFY_OID_NOT_EXIST = "warehouseClassifyOidNotExsit";
    /**
     * å½“前用户没有库房的权限
     */
    public static final String BD_WAREHOUSE_NOT_RIGHT = "warehouseNotRight";
    //货位
    /**
     * ä¸Šçº§ä¸æ˜¯ä¸€ä¸ªè´§æž¶
     */
    public static final String BD_GOODS_LOCATION_PARENT_NOT_SHELF = "goodsLocationParentNotShelf";
    //Feign
    /**
     * å½“前用户没有对该库房的操作权限
     */
    public static final String BD_FEIGN_WAREHOUSEADMIN_NOT_PERMISSION = "feignCheckWareHouseAdminPermissions";
    //计量单位
    /**
     * è®¡é‡å•位不存在
     */
    public static final String UNIT_NOT_EXIST_BY_IDS = "unitNotExistByIds";
    /**
     * æ·»åŠ æˆåŠŸ
     */
    public static final String ADD_SUCCESS ="addSuccess";
    /**
     * æ·»åŠ å¤±è´¥
     */
    public static final String ADD_FAIL = "addFailInDB";
    /**
     * ä¿®æ”¹æˆåŠŸ
     */
    public static final String EDIT_SUCCESS = "editSuccess";
    /**
     * ä¿®æ”¹å¤±è´¥
     */
    public static final String EDIT_FAIL = "editFail";
    /**
     * åˆ é™¤æˆåŠŸ
     */
    public static final String DELETE_SUCCESS = "deleteSuccess";
    /**
     * çº§è”删除成功
     */
    public static final String DELETE_SUCCESS_CASCADE = "deleteSuccessCascade";
    /**
     * åˆ é™¤å¤±è´¥
     */
    public static final String DELETE_FAIL = "deleteFail";
    /**
     * å¯ç”¨æˆåŠŸ
     */
    public static final String ENABLE_SUCCESS ="enableSuccess";
    /**
     * é”å®šæˆåŠŸ
     */
    public static final String LOCK_SUCCESS = "lockSuccess";
    /**
     * é”å®šå¤±è´¥
     */
    public static final String LOCK_FAIL = "lockFail";
    /**
     * è§£é”æˆåŠŸ
     */
    public static final String UNLOCK_SUCCESS = "unlockSuccess";
    /**
     * è§£é”å¤±è´¥
     */
    public static final String UNLOCK_FAIL = "unlockFail";
    /**
     * çº§è”启用成功
     */
    public static final String ENABLE_SUCCESS_CASCADE = "enableSuccessCascade";
    /**
     * å¯ç”¨å¤±è´¥
     */
    public static final String ENABLE_FAIL = "enableFail";
    /**
     * åœç”¨æˆåŠŸ
     */
    public static final String DISABLE_SUCCESS = "disableSuccess";
    /**
     * çº§è”停用成功
     */
    public static final String DISABLE_SUCCESS_CASCADE = "disableSuccessCascade";
    /**
     * åœç”¨å¤±è´¥
     */
    public static final String DISABLE_FAIL = "disableFail";
    /**
     * å‡ç‰ˆæœ¬å·æˆåŠŸ
     */
    public static final String UP_REVISION_SUCCESS = "dataUpRevisionSuccess";
    /**
     * å‡ç‰ˆæœ¬å·å¤±è´¥
     */
    public static final String UP_REVISION_FAIL = "dataUpRevisionFail";
    /**
     * å‡ç‰ˆæ¬¡æˆåŠŸ
     */
    public static final String UP_VERSION_SUCCESS = "dataUpVersionSuccess";
    /**
     * å‡ç‰ˆæ¬¡å¤±è´¥
     */
    public static final String UP_VERSION_FAIL = "dataUpVersionFail";
    /**
     * æäº¤æˆåŠŸ
     */
    public static final String SUBMIT_SUCCESS= "submitSuccess";
    /**
     * æäº¤å¤±è´¥
     */
    public static final String SUBMIR_FAIL = "submitFail";
    /**
     * å‘布成功
     */
    public static final String RELEASE_SUCCESS = "releaseSuccess";
    /**
     * å‘布失败
     */
    public static final String RELEASE_FAIL = "releaseFail";
    /**
     * ç‰ˆæœ¬å·é‡å¤
     */
    public static final String REVISION_REPEAT = "revisionRepeat";
    /**
     * ç‰ˆæ¬¡å·é‡å¤
     */
    public static final String VERSION_REPEAT= "versionRepeat";
    /**
     * æ ¹æ®ä¸»é”®æŸ¥è¯¢æ•°æ®ä¸å­˜åœ¨
     */
    public static final String DATA_OID_NOT_EXIST = "dataOidNotExist";
    /**
     * æ ¹æ®ä¸»é”®æŸ¥è¯¢çš„æ•°æ®ä¸å­˜åœ¨
     */
    public static final String DATA_ID_NOT_EXIST = "dataIdNotExist";
    /**
     * æ ¹æ®åç§°æŸ¥è¯¢çš„æ•°æ®ä¸å­˜åœ¨
     */
    public static final String DATA_NAME_NOT_EXIST = "dataNameNotExist";
    /**
     * å±žæ€§å€¼é‡å¤
     */
    public static final String DATA_ATTR_REPEAT = "dataRepeat";
    /**
     * è€ç‰ˆæœ¬çš„æ•°æ®ä¸å­˜åœ¨
     */
    public static final String OLD_REVISION_DATA_NOT_EXIST = "oldRevsionDataNotExist";
    /**
     * ä¸Šçº§ä¸»é”®å®žé™…是当前节点的下级节点,会引起死循环
     */
    public static final String PARENT_OID_IS_CHILD ="parentIsChild";
    /**
     * æ•°æ®è¢«å¼•用,不允许删除
     */
    public static final String DATA_LINKED_NOT_DELETE = "dataLinkedNotDelete";
    /**
     * æ•°æ®çš„子节点也被引用,不允许删除
     */
    public static final String DATA_CASCADE_LINKED_NOT_DELETE = "dataCascadeLinkedNotDelete";
    /**
     * æ•°æ®è¢«å¼•用,不允许修改
     */
    public static final String DATA_LINKED_NOT_EDIT ="dataLinkedNotEdit";
    /**
     * æ•°æ®ä¸å¼•用,不允许修改某个属性
     */
    public static final String DATA_LINKED_NOT_EDIT_ATTR="dataLinkedNotEditAttr";
    /**
     * ä¸Šçº§æ¡£æ¡ˆä¸å­˜åœ¨
     */
    public static final String DATA_PARENT_NOT_EXIST = "parentNotExist";
    /**
     * åˆ†ç±»æ•°æ®ä¸å­˜åœ¨
     */
    public static final String DATA_CLASSIFY_NOT_EXIST = "classifyNotExist";
    /**
     * å½“前状态下不允许修改数据
     */
    public static final String LCSTATUS_CAN_NOT_EDIT = "lcStatusCannotEditData";
    /**
     * å½“前状态下不允许删除数据
     */
    public static final String LCSTATUS_CAN_NOT_DELETE = "lcStatusCannotDeleteData";
    /**
     * å¯¼å…¥æˆåŠŸ
     */
    public static final String IMPORT_SUCCESS = "importSuccess";
    /**
     * å¯¼å…¥å¤±è´¥
     */
    public static final String IMPORT_FAIL = "importFail";
    /**
     * å¯¼å…¥çš„æ¨¡æ¿æ–‡ä»¶ä¸å­˜åœ¨
     */
    public static final String IMPORT_TEMPLATE_FILE_NOT_FOUND = "importTemplateFileNotFound";
    /**
     * å¯¼å‡ºæˆåŠŸ
     */
    public static final String EXPORT_SUCCESS = "exportSuccess";
    /**
     * å¯¼å‡ºå¤±è´¥
     */
    public static final String EXPORT_FAIL = "exportFail";
    /**
     * ä¸Šä¼ æˆåŠŸ
     */
    public static final String UPLOAD_SUCCESS = "uploadSuccess";
    /**
     * ä¸Šä¼ å¤±è´¥
     */
    public static final String UPLOAD_FAIL = "uploadFail";
    /**
     * ä¸‹è½½æˆåŠŸ
     */
    public static final String DOWNLOAD_SUCCESS = "downloadSuccess";
    /**
     * ä¸‹è½½å¤±è´¥
     */
    public static final String DOWNLOAD_FAIL = "downloadFail";
    /**
     * æ–‡ä»¶ä¸å­˜åœ¨
     */
    public static final String FILE_NOT_EXIST = "fileNotExist";
    /**
     * å®¡æ‰¹æˆåŠŸ
     */
    public static final String AUDIT_SUCCESS = "auditSuccess";
    /**
     * å®¡æ‰¹å¤±è´¥
     */
    public static final String AUDIT_FAIL = "auditFail";
    /**
     * ä¸‹å‘成功
     */
    public static final String ISSUED_SUCCESS = "issuedSuccess";
    /**
     * ä¸‹å‘失败
     */
    public static final String ISSUED_FAIL = "issuedFail";
    /**
     * æŽ¥æ”¶æˆåŠŸ
     */
    public static final String RECEIVE_SUCCESS = "receiveSuccess";
    /**
     * æŽ¥æ”¶å¤±è´¥
     */
    public static final String RECEIVE_FAIL = "receiveFail";
    /**
     * è®¡åˆ’的制造依据不存在
     */
    public static final String PLAN_SOURCE_NOT_EXIST = "planSourceNotExist";
    /**
     * è®¡åˆ’的制造目标不存在
     */
    public static final String PLAN_TARGET_NOT_EXIST = "planTargetNotExist";
    /**
     * æ´¾å‘成功
     */
    public static final String DISPATCH_SUCCESS = "dispatchSuccess";
    /**
     * æ´¾å‘失败
     */
    public static final String DISPATCH_FAIL = "dispatchFail";
    /**
     * è¯¥è®¡åˆ’下不存在派发过的任务
     */
    public static final String DISPATCH_TASK_NOT_EXIST_BY_PLAN = "dispatchTaskNotExistByPlan";
}
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/BaseEnum.java
@@ -1,7 +1,55 @@
package com.vci.ubcs.starter.web.enumpck;
import com.alibaba.druid.util.StringUtils;
public interface BaseEnum {
    String getValue();
    String getText();
    /**
     * ä½¿ç”¨æžšä¸¾çš„值获取枚举对象的通用方法
     * @param clazz æžšä¸¾æ‰€å±žç±»
     * @param value æžšä¸¾çš„值
     * @param <T> ç±»åž‹
     * @return ç»“æžœ
     */
    public static  <T extends BaseEnum> T getEnumByValue(Class<T> clazz,Object value){
        if(value == null){
            return null;
        }
        T[] enums = clazz.getEnumConstants();
        if (enums == null || enums.length == 0) {
            return null;
        }
        for (T e : enums) {
            if (value instanceof String) {
                if (StringUtils.equalsIgnoreCase((String) value, (String) ((BaseEnum) e).getValue())) {
                    return e;
                }
            } else {
                if (value.equals(e.getValue())) {
                    return e;
                }
            }
        }
        return null;
    }
    /**
     * ä½¿ç”¨æžšä¸¾çš„值获取显示文本的方法
     * @param clazz æžšä¸¾æ‰€å±žçš„ç±»
     * @param value æžšä¸¾çš„值
     * @param <T> ç±»åž‹
     * @return ç»“æžœ
     */
    public static <T extends BaseEnum> String getTextByValue(Class<T> clazz,String value){
        T e = getEnumByValue(clazz, value);
        if (e == null) {
            return "";
        }
        return ((BaseEnum) e).getText();
    }
}
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/DataSecretEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
package com.vci.ubcs.starter.web.enumpck;
public enum DataSecretEnum implements BaseEnumInt {
    NONE(10, "非密"),
    INNER(15, "内部"),
    SECRET(20, "秘密"),
    PRIVACY(30, "机密");
    private int value;
    private String text;
    public int getValue() {
        return this.value;
    }
    public void setValue(int value) {
        this.value = value;
    }
    public String getText() {
        return this.text;
    }
    public void setText(String text) {
        this.text = text;
    }
    private DataSecretEnum(int secret, String secretText) {
        this.value = secret;
        this.text = secretText;
    }
    public static String getSecretText(int secret) {
        DataSecretEnum[] var1 = values();
        int var2 = var1.length;
        for(int var3 = 0; var3 < var2; ++var3) {
            DataSecretEnum eu = var1[var3];
            if (eu.value == secret) {
                return eu.text;
            }
        }
        return NONE.text;
    }
    public static int getSecretValueByText(String text) {
        DataSecretEnum[] var1 = values();
        int var2 = var1.length;
        for(int var3 = 0; var3 < var2; ++var3) {
            DataSecretEnum eu = var1[var3];
            if (eu.text.equalsIgnoreCase(text)) {
                return eu.value;
            }
        }
        return NONE.value;
    }
    public static boolean isValid(int secret) {
        DataSecretEnum[] var1 = values();
        int var2 = var1.length;
        for(int var3 = 0; var3 < var2; ++var3) {
            DataSecretEnum eu = var1[var3];
            if (eu.value == secret) {
                return true;
            }
        }
        return false;
    }
}
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/NewAppConstantEnum.java
@@ -8,6 +8,7 @@
     * ç¼–码规则,服务启动名
     */
    APPLICATION_NAME_CODE(AppConstant.APPLICATION_NAME_CODE,"主数据"),
    APPLICATION_FLOW_NAME(AppConstant.APPLICATION_FLOW_NAME,"ubcs-flow"),
    ;
    /**
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/ProcessTemplateTypeEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,134 @@
package com.vci.ubcs.starter.web.enumpck;
/**
 * æµç¨‹æ¨¡æ¿åº”用按钮类型
 * @author wang1
 */
public enum ProcessTemplateTypeEnum implements BaseEnum {
    /**
     * å‘布
     */
    PUBLIC("PUBLIC","发布"),
    /**
     * å˜æ›´
     */
    EDIT("EDIT","变更"),
    /**
     * åœç”¨
     */
    ENABLE("ENABLE","停用"),
    /**
     * å¯ç”¨
     */
    DISABLE("DISABLE","启用");
    /**
     * æžšä¸¾çš„值
     */
    private String value;
    /**
     * æžšä¸¾æ˜¾ç¤ºæ–‡æœ¬
     */
    private String text;
    /**
     * èŽ·å–æžšä¸¾å€¼
     *
     * @return æžšä¸¾å€¼
     */
    @Override
    public String getValue() {
        return value;
    }
    /**
     * è®¾ç½®æžšä¸¾å€¼
     *
     * @param value æžšä¸¾å€¼
     */
    public void setValue(String value) {
        this.value = value;
    }
    /**
     * èŽ·å–æžšä¸¾æ˜¾ç¤ºæ–‡æœ¬
     *
     * @return æ˜¾ç¤ºæ–‡æœ¬
     */
    @Override
    public String getText() {
        return text;
    }
    /**
     * è®¾ç½®æ˜¾ç¤ºæ–‡æœ¬
     *
     * @param text æ˜¾ç¤ºæ–‡æœ¬
     */
    public void setText(String text) {
        this.text = text;
    }
    /**
     * æž„造函数
     *
     * @param value å€¼
     * @param text  æ˜¾ç¤ºæ–‡æœ¬
     */
    private ProcessTemplateTypeEnum(String value, String text) {
        this.value = value;
        this.text = text;
    }
    /**
     * æ ¹æ®åç§°èŽ·å–å¯¹åº”çš„æžšä¸¾å€¼
     *
     * @param text åç§°
     * @return æžšä¸¾å€¼
     */
    public static String getValueByText(String text) {
        for (ProcessTemplateTypeEnum wenum : ProcessTemplateTypeEnum.values()) {
            if (wenum.getText().equalsIgnoreCase(text)) {
                return wenum.getValue();
            }
        }
        return "";
    }
    /**
     * æ ¹æ®æžšä¸¾å€¼èŽ·å–åç§°
     *
     * @param value æžšä¸¾å€¼
     * @return åç§°
     */
    public static String getTextByValue(String value) {
        for (ProcessTemplateTypeEnum wenum : ProcessTemplateTypeEnum.values()) {
            if (wenum.getValue().equalsIgnoreCase(value)) {
                return wenum.getText();
            }
        }
        return "";
    }
    /**
     * æ ¹æ®æžšä¸¾å€¼èŽ·å–æžšä¸¾å¯¹è±¡
     *
     * @param value æžšä¸¾å€¼
     * @return æžšä¸¾å¯¹è±¡ï¼Œä¸å­˜åœ¨æ—¶å€™è¿”回null
     */
    public static ProcessTemplateTypeEnum forValue(String value) {
        for (ProcessTemplateTypeEnum wenum : ProcessTemplateTypeEnum.values()) {
            if (wenum.getValue().equalsIgnoreCase(value)) {
                return wenum;
            }
        }
        return null;
    }
}
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/util/VciBaseUtil.java
@@ -1143,7 +1143,38 @@
    public static <T> Collection<Collection<T>> switchCollectionForOracleIn(Collection<T> list) {
        return switchCollectionForOracleIn(list, 500);
    }
    /**
     * oracle in æŸ¥è¯¢ä¸èƒ½è¶…过1000,转换一下集合
     * ç”±äºŽSQL语句1000个可能很长,超过oracle10g,所以牺牲性能分配为500个数组
     * @param list éœ€è¦è½¬æ¢çš„列表内容
     * @return åˆ†ç»„后的list
     */
    public static <T> List<List<T>> switchListForOracleIn(List<T> list) {
        List<List<T>> listHasList = new ArrayList<List<T>>();
        if(list == null){
            return listHasList;
        }
        List<T> newList = new ArrayList<T>();
        for(Object obj : list){
            //为了让list还可以添加内容,因为使用sublist后,list不能再Add了
            newList.add((T)obj);
        }
        int muti = 1;
        if(newList.size() >500){
            int balance = newList.size()%500;
            muti = (newList.size() - balance)/500 + (balance == 0?0:1);
        }
        for(int i = 0 ; i < muti; i ++){
            int start = i*500;
            int end = start + 500;
            if(i == muti-1 || end >newList.size() ){
                end = newList.size();
            }
            List subList = newList.subList(start,end);
            listHasList.add(subList);
        }
        return listHasList;
    }
    public static <T> Collection<Collection<T>> switchCollectionForOracleIn(Collection<T> collection, int preSize) {
        Collection<Collection<T>> listHasList = new ArrayList();
        if (collection == null) {
Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/util/WebUtil.java
@@ -724,5 +724,18 @@
        }
        return listHasList;
    }
    /**
     * æ˜¯å¦é»˜è®¤çš„属性
     * @param fieldNames å±žæ€§çš„名字
     * @return true为默认
     */
    public static boolean isDefaultField(String fieldNames){
        if(VciQueryWrapperForDO.BASIC_FIELD_MAP.containsKey(fieldNames) || VciQueryWrapperForDO.LIFECYCLE_MANAGE_FIELD_MAP.containsKey(fieldNames)
            || VciQueryWrapperForDO.REVISION_MANAGE_FIELD_MAP.containsKey(fieldNames) ) {
            return true;
        }
        return false;
    }
}
Source/UBCS/ubcs-service-api/ubcs-workflow-api/src/main/java/com/vci/ubcs/code/constant/FlowConstant.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.vci.workflow.constant;
public class FlowConstant {
    public static final String MAPPER_SCAN = "com.dragon.*.dao.*";
    /**
     * æäº¤äººçš„变量名称
     */
    public static final String FLOW_SUBMITTER_VAR = "initiator";
    /**
     * æäº¤äººèŠ‚ç‚¹åç§°
     */
    public static final String FLOW_SUBMITTER = "提交人";
    /**
     * è‡ªåŠ¨è·³è¿‡èŠ‚ç‚¹è®¾ç½®å±žæ€§
     */
    public static final String FLOWABLE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED";
    /**
     * æŒ‚起状态
     */
    public static final int SUSPENSION_STATE = 2;
    /**
     * æ¿€æ´»çŠ¶æ€
     */
    public static final int ACTIVATE_STATE = 1;
    //后加签
    public static final String AFTER_ADDSIGN = "after";
    //前加签
    public static final String BEFORE_ADDSIGN = "before";
}
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java
@@ -12,10 +12,9 @@
import com.vci.ubcs.code.vo.pagemodel.*;
import com.vci.ubcs.starter.annotation.VciBusinessLog;
import com.vci.ubcs.starter.revision.model.BaseModel;
import com.vci.ubcs.starter.revision.model.TreeQueryObject;
import com.vci.ubcs.starter.util.LocalFileUtil;
import com.vci.ubcs.starter.web.pagemodel.BaseQueryObject;
import com.vci.ubcs.starter.web.pagemodel.DataGrid;
import com.vci.ubcs.starter.web.pagemodel.Tree;
import com.vci.ubcs.starter.web.pagemodel.*;
import com.vci.ubcs.starter.web.util.ControllerUtil;
import com.vci.ubcs.starter.web.util.LangBaseUtil;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
@@ -531,4 +530,25 @@
//        return engineService.updateBatchByBaseModel("wupin", models);
//        return engineService.getUIInfoByClassifyOid(codeClassifyOid,functionId);
    }
    /**
     * é»˜è®¤çš„参照列表
     * @param referConfigVO å‚照的配置信息
     * @return æ‰§è¡Œçš„结果
     */
    @GetMapping("/defaultReferDataGrid")
    public DataGrid defaultReferDataGrid(UIFormReferVO referConfigVO, PageHelper pageHelper){
        return engineService.referDataGrid(referConfigVO,pageHelper);
    }
    /**
     * é»˜è®¤çš„æ ‘形参照列表
     * @param referConfigVO å‚照的配置信息
     * @return æ‰§è¡Œçš„结果
     */
    @GetMapping("/defaultReferTree")
    public List<Tree> defaultReferTree(UIFormReferVO referConfigVO, TreeQueryObject queryObject){
        return engineService.referTree(referConfigVO,queryObject);
    }
}
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/mapper/CommonsMapper.java
@@ -20,6 +20,9 @@
    List<String> selectById(@Param("inSql") String inSql);
    int  queryCountBySql(@Param("inSql") String inSql);
    List<Map> selectBySql(@Param("inSql") String inSql);
    List<Map<String,String>> queryByOnlySqlForMap(@Param("inSql") String inSql);
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/ICodeClassifyService.java
@@ -32,6 +32,20 @@
     */
    List<CodeClassify> selectByWrapper(Wrapper wrapper);
    /**
     * ä½¿ç”¨æŸ¥è¯¢å°è£…器来查询
     * @param wrapper æŸ¥è¯¢å°è£…器
     * @return æ•°æ®å¯¹è±¡
     */
    List<String> select1(Wrapper wrapper);
    /**
     * è‡ªå®šä¹‰åˆ†é¡µ
     *
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/MdmEngineService.java
@@ -12,6 +12,7 @@
import com.vci.ubcs.code.vo.pagemodel.UITableFieldVO;
import com.vci.ubcs.code.vo.pagemodel.*;
import com.vci.ubcs.starter.revision.model.BaseModel;
import com.vci.ubcs.starter.revision.model.TreeQueryObject;
import com.vci.ubcs.starter.web.pagemodel.*;
import org.springblade.core.tool.api.R;
@@ -395,4 +396,19 @@
     */
    R updateBatchByBaseModel(String btmType, List<BaseModel> baseModels);
    /**
     * é»˜è®¤åˆ—表
     * @param referConfigVO
     * @param pageHelper
     * @return
     */
    DataGrid referDataGrid(UIFormReferVO referConfigVO, PageHelper pageHelper);
    /**
     * èŽ·å–æ ‘å½¢çš„å‚ç…§
     * @param referConfigVO å‚照的配置
     * @return æ ‘形的数据
     */
    List<Tree> referTree(UIFormReferVO referConfigVO, TreeQueryObject queryObject);
}
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyServiceImpl.java
@@ -106,6 +106,20 @@
        return codeClassifyMapper.selectList(wrapper);
    }
    /**
     * æŸ¥è¯¢
     * @param wrapper æŸ¥è¯¢å°è£…器
     * @return
     */
    @Override
    public List<String> select1(Wrapper wrapper) {
        return codeClassifyMapper.selectObjs(wrapper);
    }
    @Override
    public IPage<CodeClassifyVO> selectPlCodeClassifyPage(IPage<CodeClassifyVO> page, CodeClassifyVO plCodeClassify) {
        return page.setRecords(codeClassifyMapper.selectPlCodeClassifyPage(page, plCodeClassify));
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java
@@ -1,6 +1,7 @@
package com.vci.ubcs.code.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
@@ -21,16 +22,18 @@
import com.vci.ubcs.code.vo.pagemodel.UITableFieldVO;
import com.vci.ubcs.code.vo.pagemodel.UITablePageVO;
import com.vci.ubcs.code.vo.pagemodel.*;
import com.vci.ubcs.omd.feign.IAttributeClient;
import com.vci.ubcs.omd.feign.IBtmTypeClient;
import com.vci.ubcs.omd.feign.IEnumClient;
import com.vci.ubcs.omd.feign.IRevisionRuleClient;
import com.vci.ubcs.omd.constant.BtmTypeLcStatusConstant;
import com.vci.ubcs.omd.entity.BtmTypeAttribute;
import com.vci.ubcs.omd.cache.EnumCache;
import com.vci.ubcs.omd.feign.*;
import com.vci.ubcs.omd.utils.VciOmdUtil;
import com.vci.ubcs.omd.vo.BtmTypeAttributeVO;
import com.vci.ubcs.omd.vo.BtmTypeVO;
import com.vci.ubcs.omd.vo.EnumVO;
import com.vci.ubcs.omd.vo.RevisionRuleVO;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.revision.model.BaseModel;
import com.vci.ubcs.starter.revision.model.TreeQueryObject;
import com.vci.ubcs.starter.revision.model.TreeWrapperOptions;
import com.vci.ubcs.starter.revision.service.RevisionModelUtil;
import com.vci.ubcs.starter.web.constant.QueryOptionConstant;
@@ -49,9 +52,12 @@
import com.vci.ubcs.system.user.feign.IUserClient;
import net.logstash.logback.encoder.org.apache.commons.lang3.StringUtils;
import oracle.sql.TIMESTAMP;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.StringPool;
@@ -63,21 +69,15 @@
import javax.annotation.Resource;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static com.vci.ubcs.code.constant.FrameWorkLangCodeConstant.DATA_OID_NOT_EXIST;
@@ -100,8 +100,6 @@
    @Resource
    private CodeClstemplateServiceImpl templateService;
    @Resource
    private IAttributeClient attributeClient;
    /**
     * ç”Ÿæˆç¼–码的服务
@@ -119,6 +117,11 @@
     */
    @Resource
    ISysClient iSysClient;
    /**
     * ç³»ç»Ÿçš„æœåŠ¡
     */
    @Resource
    private IWebSecretClient secretService;
    /**
     * ç”¨æˆ·æœåŠ¡
     */
@@ -266,7 +269,7 @@
    /**
     * æ›¿æ¢å­—符
     */
    public static final String SPECIAL_CHAR  = "VCI";
    public static final String SPECIAL_CHAR = "VCI";
//    @Autowired
//    private CodeOsbtmtypeMapper codeOsbtmtypeMapper;----
@@ -312,7 +315,7 @@
//             Dict dict = new Dict();
//            dict.setParentId(Long.valueOf(attrVO.getEnumid()));
            R<List<EnumVO>> list = enumClient.getList(attrVO.getEnumId());
            if(list.isSuccess()){
            if (list.isSuccess()) {
                for (EnumVO datum : list.getData()) {
                    KeyValue keyValue = new KeyValue();
                    keyValue.setKey(datum.getItemValue());
@@ -323,7 +326,6 @@
        }
        return comboboxKVs;
    }
    /**
     * ä¿®æ”¹çŠ¶æ€
     *
@@ -846,9 +848,7 @@
            }
            int secret = VciBaseUtil.getInt(String.valueOf(cbo.getSecretGrade()));
            //后续看密级服务是否可用
//            if (secret == 0 || !secretService.checkDataSecret(secret)) {
            if (secret == 0 ) {
            if (secret == 0 || !secretService.checkDataSecret(secret).getData()) {
                Integer userSecret = VciBaseUtil.getCurrentUserSecret();
//                cbo.setAttributeValue(SECRET_FIELD, String.valueOf((userSecret == null || userSecret == 0) ? UserSecretEnum.NONE.getValue() : userSecret));
                cbo.setSecretGrade(userSecret == null || userSecret == 0 ? UserSecretEnum.NONE.getValue() : userSecret);
@@ -1184,7 +1184,7 @@
            //处理所有的列,这个模板没有合并的表头的情况
            List<UITableFieldVO> fieldVOList = new ArrayList<>();
            resembleAttrList.forEach(attrVO -> {
                UITableFieldVO tableFieldVO = templateAttr2TableField(attrVO,false);
                UITableFieldVO tableFieldVO = templateAttr2TableField(attrVO, false);
                tableFieldVO.setHidden(false);
                fieldVOList.add(tableFieldVO);
            });
@@ -1199,12 +1199,12 @@
    /**
     * æ¨¡æ¿å±žæ€§è½¬æ¢ä¸ºè¡¨æ ¼æ˜¾ç¤ºçš„配置
     *
     * @param attrVO æ¨¡æ¿å±žæ€§
     * @param attrVO  æ¨¡æ¿å±žæ€§
     * @param forEdit æ˜¯å¦æ˜¯ç¼–辑所需
     * @return è¡¨æ ¼çš„字段
     */
    @Override
    public UITableFieldVO templateAttr2TableField(CodeClassifyTemplateAttrVO attrVO,boolean forEdit) {
    public UITableFieldVO templateAttr2TableField(CodeClassifyTemplateAttrVO attrVO, boolean forEdit) {
        UITableFieldVO fieldVO = new UITableFieldVO();
        if (SECRET_FILED.equalsIgnoreCase(attrVO.getId())) {
            attrVO.setEnumId(MY_DATA_SECRET);
@@ -1215,9 +1215,9 @@
        fieldVO.setSort(true);
        fieldVO.setSortField(fieldVO.getField());
        fieldVO.setQueryField(fieldVO.getField());
        if (forEdit){
        if (forEdit) {
            fieldVO.setHidden(!VciBaseUtil.getBoolean(attrVO.getFormDisplayFlag()));
        }else {
        } else {
            fieldVO.setHidden(!VciBaseUtil.getBoolean(attrVO.getTableDisplayFlag()));
        }
        if (attrVO.getAttrTableWidth() != null && attrVO.getAttrTableWidth() > 0) {
@@ -1237,9 +1237,9 @@
                if (StringUtils.isBlank(attrVO.getEnumId())) {
                    fieldVO.setComboxKey(fieldVO.getField() + "_data");
                }
            }else {
//                List<KeyValue> osEnumItemVOList= enumService.getEnum(attrVO.getEnumId());
//                fieldVO.setData(osEnumItemVOList);
            } else {
                List<KeyValue> osEnumItemVOList= VciOmdUtil.enumsToListKeyVale(EnumCache.getList(attrVO.getEnumId()));
                fieldVO.setData(osEnumItemVOList);
            }
        }
        //看是否有参照
@@ -1407,8 +1407,8 @@
                }
            }
            queryValue = String.format(temp, (trim ? value.trim() : value));
            temp = temp.replace("to_single_byte('%s')","to_single_byte(%s)");
            queryKey = String.format(temp, "t."+attrId);
            temp = temp.replace("to_single_byte('%s')", "to_single_byte(%s)");
            queryKey = String.format(temp, "t." + attrId);
            conditionMap.put(queryKey, QueryOptionConstant.OR + queryValue);
        }
    }
@@ -1427,7 +1427,7 @@
    public DataGrid<Map<String, String>> queryGrid(String btmType, CodeClassifyTemplateVO templateVO, Map<String, String> conditionMap, PageHelper pageHelper) {
        CodeTemplateAttrSqlBO sqlBO = getSqlByTemplateVO(btmType, templateVO, conditionMap, pageHelper);
//        List<Map> maps = boService.queryByOnlySqlForMap(sqlBO.getSqlHasPage());
        List<Map<String,String>> maps = commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlHasPage());
        List<Map<String, String>> maps = commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlHasPage());
        DataGrid<Map<String, String>> dataGrid = new DataGrid<>();
        List<Map<String, String>> dataList = new ArrayList<>();
@@ -1480,7 +1480,7 @@
     * @param dataMap              æ•°æ®çš„æ˜ å°„
     * @param templateVO           æ¨¡æ¿çš„属性
     * @param onlySelectAttrIdList ä»…仅查询的属性字段
     * @param form è¡¨å•里使用
     * @param form                 è¡¨å•里使用
     */
    @Override
    public void wrapperData(List<Map<String, String>> dataMap, CodeClassifyTemplateVO templateVO,
@@ -1511,15 +1511,15 @@
            //处理枚举
            wrapperEnum(enumAttrVOs, data);
            String lcstatus = data.get(VciQueryWrapperForDO.LC_STATUS_FIELD);
            String copyFromVersion = data.getOrDefault(COPY_FROM_VERSION,"");
            String copyFromVersion = data.getOrDefault(COPY_FROM_VERSION, "");
            if ((CodeDefaultLC.EDITING.getValue().equalsIgnoreCase(lcstatus) || CodeDefaultLC.AUDITING.getValue().equalsIgnoreCase(lcstatus))
                && StringUtils.isBlank(copyFromVersion)
            ) {
                data.put(VciQueryWrapperForDO.ID_FIELD, "******");
            }
            data.put(VciQueryWrapperForDO.LC_STATUS_FIELD_TEXT.toLowerCase(Locale.ROOT), CodeDefaultLC.getTextByValue(lcstatus));
            if(CodeDefaultLC.EDITING.getValue().equalsIgnoreCase(lcstatus)
                && StringUtils.isNotBlank(copyFromVersion)){
            if (CodeDefaultLC.EDITING.getValue().equalsIgnoreCase(lcstatus)
                && StringUtils.isNotBlank(copyFromVersion)) {
                data.put(VciQueryWrapperForDO.LC_STATUS_FIELD_TEXT.toLowerCase(Locale.ROOT), "修改中");
            }
            if (data.containsKey("creator")) {
@@ -1532,12 +1532,12 @@
        if (!CollectionUtils.isEmpty(userIds)) {
            Map<String, User> userVOMap = new HashMap<>();
            for (String userId : userIds) {
                if(!StringUtils.isNumeric(userId)){
                if (!StringUtils.isNumeric(userId)) {
                    continue;
                }
                User data = iUserClient.userInfoById(Long.valueOf(userId)).getData();
                if(data != null){
                    userVOMap.put(String.valueOf(data.getId()),data);
                if (data != null) {
                    userVOMap.put(String.valueOf(data.getId()), data);
                }
            }
//            Map<String, SmUserVO> userVOMap = Optional.ofNullable(userQueryService.listUserByUserIds(userIds)).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
@@ -1670,7 +1670,7 @@
//                selectFieldList.add(attrId.getOid());
//            }
//        });
        if(allAttributeByBtmId.getData() != null ){
        if (allAttributeByBtmId.getData() != null) {
            for (BtmTypeAttributeVO attribute : allAttributeByBtmId.getData().getAttributes()) {
                if (!selectFieldList.contains(attribute.getId()) && !"secretgrade".equalsIgnoreCase(attribute.getId())) {
                    selectFieldList.add(attribute.getId());
@@ -1741,7 +1741,7 @@
        if (attrVOMap.keySet().contains("secretgrade")) {
            Integer userSecret = VciBaseUtil.getCurrentUserSecret();
            if (userSecret == null || userSecret == 0) {
//                userSecret = secretService.getMinUserSecret();
                userSecret = secretService.getMinUserSecret().getData();
            }
            whereSql += " and ( t.secretGrade <= " + userSecret + ") ";
        }
@@ -2060,8 +2060,6 @@
//        return codeList.size() > 0 ? codeList.get(0) : "";
        //修改的时候,编码是不变的
//        BatchCBO batchCBO = new BatchCBO();
//        batchCBO.getUpdateCbos().add(cbo);
@@ -2106,10 +2104,10 @@
        //只能删除自己创建的数据
        String userId = AuthUtil.getUser().getUserName();
        for (CodeWupin clientBusinessObject:cboList){
        for (CodeWupin clientBusinessObject : cboList) {
            String creator = clientBusinessObject.getCreator();
            if(!userId.equalsIgnoreCase(creator)){
                throw new VciBaseException("编码为"+clientBusinessObject.getId()+"的数据不是当前用户创建,不能删除!");
            if (!userId.equalsIgnoreCase(creator)) {
                throw new VciBaseException("编码为" + clientBusinessObject.getId() + "的数据不是当前用户创建,不能删除!");
            }
        }
@@ -2519,11 +2517,11 @@
        String btmId = topClassifyVO.getBtmtypeid();
        //查询数据
        Map<String, String> conditionMap = new HashMap<>();
        conditionMap.put("t.oid",oid);
        conditionMap.put("t.oid", oid);
        CodeTemplateAttrSqlBO sqlBO = getSqlByTemplateVO(btmId, templateVO, conditionMap, new PageHelper(-1));
        //我们使用和业务类型的来查询
        List<Map> cbosB = commonsMapper.selectBySql(sqlBO.getSqlUnPage());
        List<Map<String,String>> cbos = new ArrayList<>();
        List<Map<String, String>> cbos = new ArrayList<>();
        cbosB.stream().forEach(map -> {
            Map<String, String> data = new HashMap<>();
            for (Object o : map.keySet()) {
@@ -2537,7 +2535,7 @@
            throw new VciBaseException("数据在系统中不存在,是否因为修改过业务类型?");
        }
//        Map<String, String> data = new HashMap<>();
        Map<String,String> cbo = cbos.get(0);
        Map<String, String> cbo = cbos.get(0);
//        WebUtil.copyValueToMapFromCbos(cbo, data);
        List<Map<String, String>> dataList = new ArrayList<>();
        dataList.add(cbo);
@@ -2633,10 +2631,10 @@
        QueryWrapper<CodeWupin> wrapper = new QueryWrapper();
        if (conditionMap.get("oid").contains(",")) {
//            oidMap.put("oid", QueryOptionConstant.IN +"("+ VciBaseUtil.toInSql(oidList.toArray(new String[0])) + ")");
            wrapper.in("oid",oidList);
            wrapper.in("oid", oidList);
        } else {
//            oidMap.put("oid", conditionMap.get("oid"));
            wrapper.in("oid",conditionMap.get("oid"));
            wrapper.in("oid", conditionMap.get("oid"));
        }
        if (CollectionUtils.isEmpty(oidMap)) {
            throw new VciBaseException("业务数据主键不能为空");
@@ -2669,18 +2667,18 @@
        CodeClassifyTemplateVO templateVO = templateService.codeClassifyTemplateDO2VO(templateDOList.get(0));
        templateVO.setAttributes(codeClassifyTemplateAttrService.codeClassifyTemplateAttrDO2VOs(attrDOList));
        try {
            if (oidList.size() > 1){
                DataGrid<Map<String,String>> allDataGrid = new DataGrid<>();
                List<Map<String,String>> allData = new ArrayList<>();
            if (oidList.size() > 1) {
                DataGrid<Map<String, String>> allDataGrid = new DataGrid<>();
                List<Map<String, String>> allData = new ArrayList<>();
                oidList.forEach(oid -> {
                    Map<String,String> condition = new HashMap<>();
                    condition.put("oid",oid);
                    Map<String, String> condition = new HashMap<>();
                    condition.put("oid", oid);
                    DataGrid<Map<String, String>> dataGrid = queryGrid(btmType, templateVO, condition, pageHelper);
                    allData.addAll(dataGrid.getData());
                });
                allDataGrid.setData(allData);
                return allDataGrid;
            }else {
            } else {
                return queryGrid(btmType, templateVO, conditionMap, pageHelper);
            }
        } catch (Exception e) {
@@ -2700,20 +2698,20 @@
        MdmUIInfoVO uiInfoVO = new MdmUIInfoVO();
        CodeClassifyTemplateVO templateVO = getUsedTemplateByClassifyOid(codeClassifyOid);
        uiInfoVO.setTemplateVO(templateVO);
        UITableDefineVO uiTableDefineVO = wrapperTableDefineByTemplate(templateVO,true);
        UITableDefineVO uiTableDefineVO = wrapperTableDefineByTemplate(templateVO, true);
        List<String> phaseAttrIdList = listPhaseAttrByClassifyOid(codeClassifyOid, phase);
        uiTableDefineVO.getCols().stream().forEach(list -> {
            List<UITableFieldVO> visiableTableField=new ArrayList<>();
            if(StringUtils.isNotBlank(phase)) {
            List<UITableFieldVO> visiableTableField = new ArrayList<>();
            if (StringUtils.isNotBlank(phase)) {
                visiableTableField = list.stream().filter(col ->
                    phaseAttrIdList.stream().anyMatch(s -> StringUtils.equalsIgnoreCase(col.getField(), s) ||
                        (StringUtils.equalsIgnoreCase(col.getFieldType(), "combox") && StringUtils.equalsIgnoreCase(col.getSortField(), s))
                        || (StringUtils.equalsIgnoreCase(col.getFieldType(), "refer") && StringUtils.equalsIgnoreCase(col.getQueryField(), s))
                    )).collect(Collectors.toList());
            }else{
                visiableTableField=  list.stream().filter(col ->
            } else {
                visiableTableField = list.stream().filter(col ->
                    templateVO.getAttributes().stream().anyMatch(s ->
                        (!s.getReadOnlyFlag().equalsIgnoreCase("true")&& StringUtils.equalsIgnoreCase(col.getField(), s.getId())) ||
                        (!s.getReadOnlyFlag().equalsIgnoreCase("true") && StringUtils.equalsIgnoreCase(col.getField(), s.getId())) ||
                            (StringUtils.equalsIgnoreCase(col.getFieldType(), "combox") && StringUtils.equalsIgnoreCase(col.getSortField(), s.getId()))
                            || (StringUtils.equalsIgnoreCase(col.getFieldType(), "refer") && StringUtils.equalsIgnoreCase(col.getQueryField(), s.getId()))
                    )).collect(Collectors.toList());
@@ -2725,9 +2723,9 @@
                    setReferConfig2EditConfig(vo);
                } else if ("combox".equalsIgnoreCase(vo.getFieldType())) {
                    setComboxConfig2EditConfig(vo);
                } else if (StringUtils.isNotBlank(vo.getDateFormate())){
                } else if (StringUtils.isNotBlank(vo.getDateFormate())) {
                    vo.setEdit("date");
                }else {
                } else {
                    vo.setEdit(vo.getFieldType());
                }
            });
@@ -2807,14 +2805,14 @@
     * @param vo è¡¨æ ¼å­—段显示对象
     */
    private void setReferConfig2EditConfig(UITableFieldVO vo) {
        if (!CollectionUtils.isEmpty(vo.getReferConfig().getWhere())){
        if (!CollectionUtils.isEmpty(vo.getReferConfig().getWhere())) {
            vo.getReferConfig().getWhere().keySet().forEach(key -> {
                vo.getReferConfig().getWhere().put(key, "'" + vo.getReferConfig().getWhere().get(key) + "'");
            });
        }
        if (StringUtils.isNotBlank(vo.getReferConfig().getParentValue())){
        if (StringUtils.isNotBlank(vo.getReferConfig().getParentValue())) {
            String parentValue = vo.getReferConfig().getParentValue();
            parentValue ="\\" +  parentValue.replaceAll("'","{vci-quote}").replaceAll("=","{vci-equals}");
            parentValue = "\\" + parentValue.replaceAll("'", "{vci-quote}").replaceAll("=", "{vci-equals}");
            vo.getReferConfig().setParentValue(parentValue);
        }
        String referConfig = vo.getReferConfig().toString()
@@ -2838,16 +2836,16 @@
     */
    private void setComboxConfig2EditConfig(UITableFieldVO vo) {
        vo.setEditConfig("{editable:true,comboxKey:'" + vo.getComboxKey() + "'");
        if (!CollectionUtils.isEmpty(vo.getData())){
            vo.setEditConfig(vo.getEditConfig()+", comboxConfig:");
        if (!CollectionUtils.isEmpty(vo.getData())) {
            vo.setEditConfig(vo.getEditConfig() + ", comboxConfig:");
            for (int i = 0; i < vo.getData().size(); i++) {
                KeyValue data = vo.getData().get(i);
                if (i == vo.getData().size() -1){
                    vo.setEditConfig(vo.getEditConfig() + "{attributes:"+data.getAttributes()+",key:'"+data.getKey()+"',value:'"+data.getValue()+"'}]}");
                }else if (i == 0){
                    vo.setEditConfig(vo.getEditConfig() + "{data:[{attributes:"+data.getAttributes()+",key:'"+data.getKey()+"',value:'"+data.getValue()+"'},");
                }else{
                    vo.setEditConfig(vo.getEditConfig() + "{attributes:"+data.getAttributes()+",key:'"+data.getKey()+"',value:'"+data.getValue()+"'},");
                if (i == vo.getData().size() - 1) {
                    vo.setEditConfig(vo.getEditConfig() + "{attributes:" + data.getAttributes() + ",key:'" + data.getKey() + "',value:'" + data.getValue() + "'}]}");
                } else if (i == 0) {
                    vo.setEditConfig(vo.getEditConfig() + "{data:[{attributes:" + data.getAttributes() + ",key:'" + data.getKey() + "',value:'" + data.getValue() + "'},");
                } else {
                    vo.setEditConfig(vo.getEditConfig() + "{attributes:" + data.getAttributes() + ",key:'" + data.getKey() + "',value:'" + data.getValue() + "'},");
                }
            }
            vo.setEditConfig(vo.getEditConfig() + ",valueField:'" + vo.getQueryField() + "'");
@@ -2865,7 +2863,7 @@
    @Override
    public MdmUIInfoVO getFormDefineByClassifyIdPath(String idPath) {
        CodeClassifyVO classifyVO = classifyService.getObjectByIdPath(idPath);
        if(classifyVO !=null){
        if (classifyVO != null) {
            return getFormDefineByClassifyOid(classifyVO.getOid());
        }
        return null;
@@ -2910,7 +2908,7 @@
        MdmUIInfoVO uiInfoVO = new MdmUIInfoVO();
        uiInfoVO.setTemplateVO(templateVO);
        //我们需要将模板转换为表格相关的显示信息
        uiInfoVO.setTableDefineVO(wrapperTableDefineByTemplate(uiInfoVO.getTemplateVO(),false));
        uiInfoVO.setTableDefineVO(wrapperTableDefineByTemplate(uiInfoVO.getTemplateVO(), false));
        //需要去看扩展的按钮,只有列表里面本身才添加进去,工具栏上的单独获取
        List<CodeClassifyTemplateButtonVO> buttonVOS = templateButtonService.listButtonByTemplateOid(templateVO.getOid(), true);
        if (!CollectionUtils.isEmpty(buttonVOS)) {
@@ -2949,8 +2947,8 @@
    @Override
    public MdmUIInfoVO getUIInfoByClassifyIdPath(String codeClassifyIdPath, String functionId) {
        CodeClassifyVO classifyVO = classifyService.getObjectByIdPath(codeClassifyIdPath);
        if(classifyVO !=null){
            return getUIInfoByClassifyOid(classifyVO.getOid(),functionId);
        if (classifyVO != null) {
            return getUIInfoByClassifyOid(classifyVO.getOid(), functionId);
        }
        return null;
    }
@@ -2965,12 +2963,11 @@
    @Override
    public MdmUIInfoVO getUIInfoByClassifyOid(String codeClassifyOid, String functionId) {
        VciBaseUtil.alertNotNull(codeClassifyOid, "主题库分类主键");
        MdmUIInfoVO uiInfoVO = getTableDefineByTemplateVO(getUsedTemplateByClassifyOid(codeClassifyOid));
        uiInfoVO.setLeaf(classifyService.countChildrenByClassifyOid(codeClassifyOid) == 0);
        if (StringUtils.isNotBlank(functionId) && !"~".equalsIgnoreCase(functionId)) {
            List<Menu> buttonVOS = iSysClient.getMenuButtonByType(uiInfoVO.getTemplateVO().getBtmTypeId()).getData();
            //功能按钮服务还未实现,等实现了,在进行调用
//            List<SmOperationVO> operationVOS = operationService.listButtonByFunctionId(functionId);
//            if (operationVOS == null) {
//                operationVOS = new ArrayList<>();
@@ -3062,7 +3059,7 @@
     * ä¼ å…¥ä¸šåŠ¡ç±»åž‹ä»¥åŠç›¸oid集合查询数据进行返回
     *
     * @param btmType ä¸šåŠ¡ç±»åž‹
     * @param oids      éœ€è¦æŸ¥è¯¢çš„oid集合 é€—号分开
     * @param oids    éœ€è¦æŸ¥è¯¢çš„oid集合 é€—号分开
     * @return æŸ¥è¯¢å‡ºçš„æ•°æ®
     */
    @Override
@@ -3070,7 +3067,7 @@
        //使用传入的业务类型查询表
        R<List<BtmTypeVO>> listR = btmTypeClient.selectByIdCollection(Collections.singletonList(btmType));
        if(listR.getData().size() == 0){
        if (listR.getData().size() == 0) {
            throw new VciBaseException("传入业务类型未查询到相应表单,请检查!");
        }
        //查询数据
@@ -3215,4 +3212,149 @@
        return R.success("更新成功!");
    }
    /**
     * èŽ·å–å‚ç…§çš„ä¿¡æ¯
     *
     * @param referConfigVO å‚照的配置
     * @param pageHelper    åˆ†é¡µçš„工具
     * @return åˆ—表数据
     */
    @Override
    public DataGrid referDataGrid(UIFormReferVO referConfigVO, PageHelper pageHelper) {
//        checkReferConfig(referConfigVO);
        //使用业务类型查询
        R<BtmTypeVO> allAttributeByBtmId = btmTypeClient.getAllAttributeByBtmId(referConfigVO.getReferType());
        BtmTypeVO btmTypeVO = allAttributeByBtmId.getData();
        if (referConfigVO.getWhere() == null) {
            referConfigVO.setWhere(new HashMap<>());
        }
        /**
         * åŠ ä¸ŠæŸ¥è¯¢æœ€æ–°ç‰ˆæ¬¡
         */
        Map<String, String> conditionMap = new HashMap<>();
        conditionMap.put("lastr", "1");
        conditionMap.put("lastv", "1");
        referConfigVO.getWhere().putAll(conditionMap);
        if (VciBaseUtil.containsKeyUnCaseForMap(referConfigVO.getWhere(), VciQueryWrapperForDO.LC_STATUS_FIELD) &&
            BtmTypeLcStatusConstant.FRAME_WORK_LIFE_CYCLE_NAME.equalsIgnoreCase(btmTypeVO.getLifeCycleId())) {
            referConfigVO.getWhere().put(VciQueryWrapperForDO.LC_STATUS_FIELD, FrameworkDataLCStatus.ENABLED.getValue());
        }
        if (VciBaseUtil.containsKeyUnCaseForMap(referConfigVO.getWhere(), VciQueryWrapperForDO.LC_STATUS_FIELD) &&
            BtmTypeLcStatusConstant.RELEASE_LIFE_CYCLE.equalsIgnoreCase(btmTypeVO.getLifeCycleId())) {
            referConfigVO.getWhere().put(VciQueryWrapperForDO.LC_STATUS_FIELD, CodeDefaultLC.RELEASED.getValue());
        }
        BaseQueryObject baseQueryObject = new BaseQueryObject();
        Map<String, String> where = referConfigVO.getWhere();
        where.put("domain", AppConstant.APPLICATION_NAME_CODE);
        baseQueryObject.setConditionMap(where);
        baseQueryObject.setPage(pageHelper.getPage());
        baseQueryObject.setSort(pageHelper.getSort());
        baseQueryObject.setLimit(pageHelper.getLimit());
        baseQueryObject.setOrder(pageHelper.getOrder());
        R<List<BtmTypeVO>> ref = btmTypeClient.getRef(baseQueryObject);
        DataGrid<BtmTypeVO> btmTypeVODataGrid = new DataGrid<>();
        List<BtmTypeVO> data = ref.getData();
        btmTypeVODataGrid.setData(data);
        btmTypeVODataGrid.setCode(ref.getCode());
        btmTypeVODataGrid.setLimit(pageHelper.getLimit());
        btmTypeVODataGrid.setMsg(ref.getMsg());
        btmTypeVODataGrid.setSort(pageHelper.getSort());
        btmTypeVODataGrid.setOrder(pageHelper.getOrder());
        btmTypeVODataGrid.setPage(pageHelper.getPage());
        return btmTypeVODataGrid;
    }
    /**
     * èŽ·å–æ ‘å½¢çš„å‚ç…§
     *
     * @param referConfigVO å‚照的配置
     * @return æ ‘形的数据
     */
    @Override
    public List<Tree> referTree(UIFormReferVO referConfigVO, TreeQueryObject queryObject) {
        if (queryObject.getConditionMap() == null) {
            queryObject.setConditionMap(new HashMap<>());
        }
        if (queryObject.getParentOid()==null){
            LambdaQueryWrapper<CodeClassify> lqw = new LambdaQueryWrapper<>();
            String parentValue = referConfigVO.getParentValue().substring(3);
            lqw.inSql(CodeClassify::getOid,parentValue);
            List<String> codeClassifies = classifyService.select1(lqw);
            String oid = codeClassifies.get(0);
            queryObject.setParentOid(oid);
        }
        String oidFieldName = StringUtils.isNotBlank(referConfigVO.getParentUsedField()) ? referConfigVO.getParentUsedField() : referConfigVO.getValueField();
        if (queryObject.isQueryAllLevel()) {
            String parentOidSql = "";
            if (StringUtils.isNotBlank(referConfigVO.getParentValue())) {
                String temp = referConfigVO.getParentValue();
                if (temp.startsWith(QueryOptionConstant.IN)) {
                    temp = temp.substring((QueryOptionConstant.IN).length()).trim();
                    parentOidSql = " in " + ((temp.startsWith("(") && temp.endsWith(")")) ? temp : "(" + temp + ")");
                } else if (temp.startsWith(QueryOptionConstant.NOTIN)) {
                    parentOidSql = " not in " + ((temp.startsWith("(") && temp.endsWith(")")) ? temp : "(" + temp + ")");
                } else if (temp.startsWith(QueryOptionConstant.NOTEQUAL)) {
                    temp = temp.substring((QueryOptionConstant.NOTEQUAL).length()).trim();
                    parentOidSql = QueryOptionConstant.NOTEQUAL + " " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
                } else if (temp.startsWith(QueryOptionConstant.MORETHAN)) {
                    temp = temp.substring((QueryOptionConstant.MORETHAN).length()).trim();
                    parentOidSql = QueryOptionConstant.MORETHAN + " " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
                } else if (temp.startsWith(QueryOptionConstant.MORE)) {
                    temp = temp.substring((QueryOptionConstant.MORE).length()).trim();
                    parentOidSql = QueryOptionConstant.MORE + " " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
                } else if (temp.startsWith(QueryOptionConstant.LESSTHAN)) {
                    temp = temp.substring((QueryOptionConstant.LESSTHAN).length()).trim();
                    parentOidSql = QueryOptionConstant.LESSTHAN + " " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
                } else if (temp.startsWith(QueryOptionConstant.LESS)) {
                    temp = temp.substring((QueryOptionConstant.LESS).length()).trim();
                    parentOidSql = QueryOptionConstant.LESS + " " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
                } else if (temp.startsWith(QueryOptionConstant.ISNOTNULL)) {
                    parentOidSql = " is not null";
                } else if (temp.startsWith(QueryOptionConstant.ISNULL)) {
                    parentOidSql = " is  null";
                } else if (temp.contains("*")) {
                    parentOidSql = " like " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'").replace("*", "%");
                } else {
                    parentOidSql = " = " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
                }
            }
            //查询全部的信息
            queryObject.getConditionMap().put("oid", QueryOptionConstant.IN + "(select oid from " +
                    getTableName(referConfigVO.getReferType())+
                " START WITH " + referConfigVO.getParentFieldName() + " " +
                parentOidSql +
                " CONNECT BY PRIOR " + oidFieldName + " = " + referConfigVO.getParentFieldName() + ")");
        } else {
            if (StringUtils.isNotBlank(referConfigVO.getParentFieldName()) && StringUtils.isNotBlank(queryObject.getParentOid())) {
                queryObject.getConditionMap().put(referConfigVO.getParentFieldName(), queryObject.getParentOid());
            }
        }
        LambdaQueryWrapper<CodeClassify> lqw = new LambdaQueryWrapper<>();
        String sql = queryObject.getConditionMap().get("oid").substring(3);
        lqw.inSql(CodeClassify::getOid,sql);
        List<CodeClassify> codeClassifies = classifyService.selectByWrapper(lqw);
        TreeWrapperOptions treeWrapperOptions = new TreeWrapperOptions(referConfigVO.getParentFieldName());
        treeWrapperOptions.setOidFieldName(oidFieldName);
        treeWrapperOptions.setTextFieldName(referConfigVO.getTextField());
        treeWrapperOptions.setMultipleSelect(referConfigVO.isMuti());
        treeWrapperOptions.setParentOid(queryObject.getParentOid());
        return revisionModelUtil.doList2Trees(codeClassifies, treeWrapperOptions, null);
    }
    private String getTableName(String refertype){
        if ("codeclassify".equals(refertype)){
            return "pl_code_classify";
        }
        if ("table".equals(refertype)){
            return "pl_code_test_table";
        }
        if ("testBtmType".equals(refertype)){
            return "PLBT_code_testBtmType";
        }
        return "pl_code_"+refertype.trim().toLowerCase();
    }
}
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmIOServiceImpl.java
@@ -1,11 +1,17 @@
package com.vci.ubcs.code.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.StringUtils;
import com.vci.ubcs.code.bo.AttributeValue;
import com.vci.ubcs.code.bo.CodeClassifyFullInfoBO;
import com.vci.ubcs.code.bo.CodeTemplateAttrSqlBO;
import com.vci.ubcs.code.dto.CodeOrderDTO;
import com.vci.ubcs.code.service.ICodeClassifyService;
import com.vci.ubcs.code.service.MdmEngineService;
import com.vci.ubcs.code.service.MdmIOService;
import com.vci.ubcs.code.enumpack.CodeDefaultLC;
import com.vci.ubcs.code.enumpack.CodeLevelTypeEnum;
import com.vci.ubcs.code.mapper.CommonsMapper;
import com.vci.ubcs.code.service.*;
import com.vci.ubcs.code.util.ClientBusinessObject;
import com.vci.ubcs.code.vo.CodeKeyAttrRepeatVO;
import com.vci.ubcs.code.vo.pagemodel.*;
import com.vci.ubcs.code.vo.webserviceModel.attrmap.DataObjectVO;
import com.vci.ubcs.code.vo.webserviceModel.attrmap.RowDatas;
@@ -17,14 +23,20 @@
import com.vci.ubcs.starter.poi.bo.SheetRowData;
import com.vci.ubcs.starter.poi.bo.WriteExcelOption;
import com.vci.ubcs.starter.poi.util.ExcelUtil;
import com.vci.ubcs.starter.revision.model.BaseModel;
import com.vci.ubcs.starter.util.DefaultAttrAssimtUtil;
import com.vci.ubcs.starter.util.LocalFileUtil;
import com.vci.ubcs.starter.web.enumpck.BooleanEnum;
import com.vci.ubcs.starter.web.enumpck.VciFieldTypeEnum;
import com.vci.ubcs.starter.web.pagemodel.DataGrid;
import com.vci.ubcs.starter.web.pagemodel.KeyValue;
import com.vci.ubcs.starter.web.util.LangBaseUtil;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import com.vci.ubcs.starter.web.util.VciDateUtil;
import com.vci.ubcs.starter.web.pagemodel.PageHelper;
import com.vci.ubcs.starter.web.pagemodel.UIFormReferVO;
import com.vci.ubcs.starter.web.toolmodel.DateConverter;
import com.vci.ubcs.starter.web.util.*;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
@@ -33,6 +45,8 @@
import org.apache.poi.ss.usermodel.Workbook;
import org.springblade.core.redis.cache.BladeRedis;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -40,23 +54,31 @@
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Collectors;
import static com.alibaba.druid.util.FnvHash.Constants.LIMIT;
import static com.vci.ubcs.code.constant.MdmEngineConstant.*;
import static com.vci.ubcs.starter.poi.util.ExcelUtil.KEY_ATTR_CHAR;
import static com.vci.ubcs.starter.poi.util.ExcelUtil.REQUIRED_CHAR;
import static com.vci.ubcs.starter.poi.util.ExcelUtil.*;
@AllArgsConstructor
@RequiredArgsConstructor
@Service
@Slf4j
public class MdmIOServiceImpl implements MdmIOService {
    @Value("${batchadd.redis.time:6000000}")
    public int BATCHADD_REDIS_TIME;
    /**
     * ä¸»é¢˜åº“分类的服务
     */
    @Resource
    private ICodeClassifyService classifyService;
    /**
     * é€šç”¨æŸ¥è¯¢
     */
    @Resource
    CommonsMapper commonsMapper;
    /**
     * æ¨¡æ¿çš„æœåŠ¡
@@ -69,9 +91,26 @@
     */
    @Resource
    private MdmEngineService engineService;
    /***
     * resdis缓存服务
     */
    private final BladeRedis bladeRedis;
    /**
     * ç”Ÿæˆç¼–码的服务
     */
    @Resource
    private MdmProductCodeService productCodeService;
    /**
     * å…³é”®å±žæ€§çš„配置
     */
    @Autowired
    private ICodeKeyAttrRepeatService keyRuleService;
    /**
     * å…¬å¼çš„æœåŠ¡
     */
    @Autowired
    private FormulaServiceImpl formulaService;
    /**
     * ç”Ÿæˆå¯¼å…¥çš„æ–‡ä»¶
     *
@@ -350,125 +389,140 @@
     */
    private String batchImportCodes(CodeOrderDTO orderDTO,CodeClassifyTemplateVO templateVO,SheetDataSet dataSet,Map<String,String> errorMap,boolean isEnumType){
        List<String> codeList=new ArrayList<>();
//        CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid());
        CodeClassifyFullInfoBO classifyFullInfo = classifyService.getClassifyFullInfo(orderDTO.getCodeClassifyOid());
        //规则的主键需要去获取
//        CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo);
//        //1.判断规则中除了流水码段,是否有其他码段
//        engineService.checkSecValueOnOrder(ruleVO,orderDTO);
//        List<SheetRowData> rowDataList = dataSet.getRowData();
//
//        //除去默认的属性.还有只有表单显示的字段才导入
//        List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s ->
//            !DEFAULT_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormdisplayflag())
//        ).collect(Collectors.toList());
//        Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap = new HashMap<>();
//        List<String> titleRowData = dataSet.getColName();
//        Map<String/**中文名称**/, String/**英文名称**/> attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT),(o1, o2)->o2));
//        getFieldIndexMap(titleRowData,attrNameIdMap,fieldIndexMap);
//
//        //需要判断是否所有的属性都在模板上了
//        List<CodeClassifyTemplateAttrVO> unExistAttrVOs = attrVOS.stream().filter(s -> !fieldIndexMap.containsValue(s.getId().toLowerCase(Locale.ROOT))
//            && StringUtils.isBlank(s.getComponentrule()) && StringUtils.isBlank(s.getClassifyinvokeattr())//组合规则和分类注入确实没给用户导出去
//        ).collect(Collectors.toList());
//        if(!CollectionUtils.isEmpty(unExistAttrVOs)){
//            throw new VciBaseException("【" + unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName) + "】这些属性在列表中没有找到");
//        }
//        List<ClientBusinessObject> cboList = new ArrayList<>();
//        String fullPath = getFullPath(classifyFullInfo);
//        excelToCbo(classifyFullInfo,fieldIndexMap,rowDataList,templateVO,cboList,fullPath,true);
//
//        //都转换完了。需要批量检查
//        //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
//        //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
//        batchCheckRequiredAttrOnOrder(templateVO,cboList,errorMap);
//        //3.判断关键属性
//        CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList);
//        Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
//        Set<String> keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList();
//        if(!CollectionUtils.isEmpty(selfRepeatRowIndexList)){
//            selfRepeatRowIndexList.stream().forEach(rowIndex->{
//                errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";在当前处理的数据文件中关键属性重复" );
//            });
//        }
//        if(!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)){
//            keyAttrRepeatRowIndexList.stream().forEach(rowIndex->{
//                errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";关键属性与系统中的重复" );
//            });
//        }
//        //分类注入
//        batchSwitchClassifyAttrOnOrder(attrVOS,cboList,classifyFullInfo,false);
//        //boolean
//        reSwitchBooleanAttrOnOrder(attrVOS,cboList);
//        //4.校验规则
//        batchCheckVerifyOnOrder(attrVOS, cboList,errorMap);
//        if(isEnumType) {//是否需要校验枚举/参照
//            //5.校验枚举是否正确
//            batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap);
//            //7.处理参照的情况
//            batchSwitchReferAttrOnOrder(attrVOS,cboList,errorMap);
//        }
//        //6.时间格式的验证
//        //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss
//        batchSwitchDateAttrOnOrder(attrVOS,cboList,errorMap);
//        //最后弄组合规则
//        batchSwitchComponentAttrOnOrder(attrVOS,cboList);
//        String uuid=redisService.getUUIDEveryDay();
//        Map<String, ClientBusinessObject> rowIndexCboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t));
//
//        if(errorMap.size()>0) {
//            createRedisDatas(uuid + "-error",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, errorMap,false);
//        }
//        boolean isCreateUUid=false;
//        List<ClientBusinessObject> needSaveCboList = cboList.stream().filter(cbo -> {
//            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
//            return !errorMap.containsKey(rowIndex);
//        }).collect(Collectors.toList());
//        //相似校验
//        Map<String,String>resembleMap=new HashMap<>();
//        List<DataResembleVO> dataResembleVOS=new ArrayList<>();
//        String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmtypeid();
//        bathcResembleQuery(orderDTO.getCodeClassifyOid(),templateVO,needSaveCboList,resembleMap,btmtypeid,dataResembleVOS);
//        if(resembleMap.size()>0) {
//            isCreateUUid=true;
//            if(!CollectionUtils.isEmpty(dataResembleVOS)) {
//                redisService.setCacheList(uuid + "-resemble-data", dataResembleVOS);
//                createRedisDatas(uuid + "-resemble",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false);
//            }
//        }
//        //排除错误的,剩下正确的
//        Map<String,String> newErrorMap=new HashMap<>();
//        newErrorMap.putAll(resembleMap);
//        newErrorMap.putAll(errorMap);
//        needSaveCboList = cboList.stream().filter(cbo -> {
//            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
//            return !newErrorMap.containsKey(rowIndex);
//        }).collect(Collectors.toList());
//        if((errorMap.size()>0&&needSaveCboList.size()>0)||resembleMap.size()>0){
//            isCreateUUid=true;
//        }
//        createRedisByCodeClassify(uuid + "-class",templateVO,dataSet,fieldIndexMap,false);
//        if(newErrorMap.size()>0) {
//            createRedisDatas(uuid + "-ok",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, newErrorMap,true);
//        }else {
//            uuid="";
//            //要把以上的错误的都抛出后,再继续处理时间和组合规则
//            needSaveCboList = cboList.stream().filter(cbo -> {
//                String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
//                return !newErrorMap.containsKey(rowIndex);
//            }).collect(Collectors.toList());
//            if (!CollectionUtils.isEmpty(needSaveCboList)) {
//                //9.我们处理业务数据
//                //生成编码的内容
//                codeList = productCodeService.productCodeAndSaveData(classifyFullInfo, templateVO, ruleVO, orderDTO.getSecDTOList(), needSaveCboList);
//                //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
//                engineService.batchSaveSelectChar(templateVO, needSaveCboList);
//            }
//        }
//        if(!isCreateUUid){
//            return uuid="";
//        }
//        return uuid;
        return null;
        CodeRuleVO ruleVO = engineService.getCodeRuleByClassifyFullInfo(classifyFullInfo);
        //1.判断规则中除了流水码段,是否有其他码段
        engineService.checkSecValueOnOrder(ruleVO,orderDTO);
        List<SheetRowData> rowDataList = dataSet.getRowData();
        //除去默认的属性.还有只有表单显示的字段才导入
        List<CodeClassifyTemplateAttrVO> attrVOS = templateVO.getAttributes().stream().filter(s ->
            !DEFAULT_ATTR_LIST.contains(s.getId()) && VciBaseUtil.getBoolean(s.getFormDisplayFlag())
        ).collect(Collectors.toList());
        Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap = new HashMap<>();
        List<String> titleRowData = dataSet.getColName();
        Map<String/**中文名称**/, String/**英文名称**/> attrNameIdMap = attrVOS.stream().collect(Collectors.toMap(s -> s.getName(), t -> t.getId().toLowerCase(Locale.ROOT),(o1, o2)->o2));
        getFieldIndexMap(titleRowData,attrNameIdMap,fieldIndexMap);
        //需要判断是否所有的属性都在模板上了
        List<CodeClassifyTemplateAttrVO> unExistAttrVOs = attrVOS.stream().filter(s -> !fieldIndexMap.containsValue(s.getId().toLowerCase(Locale.ROOT))
            && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeAttr())//组合规则和分类注入确实没给用户导出去
        ).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(unExistAttrVOs)){
            throw new VciBaseException("【" + unExistAttrVOs.stream().map(CodeClassifyTemplateAttrVO::getName) + "】这些属性在列表中没有找到");
        }
        List<ClientBusinessObject> cboList = new ArrayList<>();
        String fullPath = getFullPath(classifyFullInfo);
        excelToCbo(classifyFullInfo,fieldIndexMap,rowDataList,templateVO,cboList,fullPath,true);
        //都转换完了。需要批量检查
        //如果出错了,我们依然执行有效的数据,无效的数据写回到excel中
        //2.判断必输项。。需要全部的属性,如果是必输,但是表单里面不显示的,只能是分类注入或者组合规则
        batchCheckRequiredAttrOnOrder(templateVO,cboList,errorMap);
        //3.判断关键属性
        CodeImportResultVO keyResultVO = batchCheckKeyAttrOnOrder(classifyFullInfo, templateVO, cboList);
        Set<String> selfRepeatRowIndexList = keyResultVO.getSelfRepeatRowIndexList();
        Set<String> keyAttrRepeatRowIndexList = keyResultVO.getKeyAttrRepeatRowIndexList();
        if(!CollectionUtils.isEmpty(selfRepeatRowIndexList)){
            selfRepeatRowIndexList.stream().forEach(rowIndex->{
                errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";在当前处理的数据文件中关键属性重复" );
            });
        }
        if(!CollectionUtils.isEmpty(keyAttrRepeatRowIndexList)){
            keyAttrRepeatRowIndexList.stream().forEach(rowIndex->{
                errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";关键属性与系统中的重复" );
            });
        }
        //分类注入
        batchSwitchClassifyAttrOnOrder(attrVOS,cboList,classifyFullInfo,false);
        //boolean
        reSwitchBooleanAttrOnOrder(attrVOS,cboList);
        //4.校验规则
        batchCheckVerifyOnOrder(attrVOS, cboList,errorMap);
        if(isEnumType) {//是否需要校验枚举/参照
            //5.校验枚举是否正确
            batchSwitchEnumAttrOnOrder(attrVOS, cboList, errorMap);
            //7.处理参照的情况
            batchSwitchReferAttrOnOrder(attrVOS,cboList,errorMap);
        }
        //6.时间格式的验证
        //6.时间的,必须统一为yyyy-MM-dd HH:mm:ss
        batchSwitchDateAttrOnOrder(attrVOS,cboList,errorMap);
        //最后弄组合规则
        batchSwitchComponentAttrOnOrder(attrVOS,cboList);
        String uuid=VciBaseUtil.getPk();
        Map<String, ClientBusinessObject> rowIndexCboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t));
        if(errorMap.size()>0) {
            createRedisDatas(uuid + "-error",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, errorMap,false);
        }
        boolean isCreateUUid=false;
        List<ClientBusinessObject> needSaveCboList = cboList.stream().filter(cbo -> {
            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
            return !errorMap.containsKey(rowIndex);
        }).collect(Collectors.toList());
        //相似校验
        Map<String,String>resembleMap=new HashMap<>();
        List<DataResembleVO> dataResembleVOS=new ArrayList<>();
        String btmtypeid= classifyFullInfo.getTopClassifyVO().getBtmtypeid();
        bathcResembleQuery(orderDTO.getCodeClassifyOid(),templateVO,needSaveCboList,resembleMap,btmtypeid,dataResembleVOS);
        if(resembleMap.size()>0) {
            isCreateUUid=true;
            if(!CollectionUtils.isEmpty(dataResembleVOS)) {
                bladeRedis.set(uuid + "-resemble-data", dataResembleVOS);
                createRedisDatas(uuid + "-resemble",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, resembleMap, false);
            }
        }
        //排除错误的,剩下正确的
        Map<String,String> newErrorMap=new HashMap<>();
        newErrorMap.putAll(resembleMap);
        newErrorMap.putAll(errorMap);
        needSaveCboList = cboList.stream().filter(cbo -> {
            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
            return !newErrorMap.containsKey(rowIndex);
        }).collect(Collectors.toList());
        if((errorMap.size()>0&&needSaveCboList.size()>0)||resembleMap.size()>0){
            isCreateUUid=true;
        }
        createRedisByCodeClassify(uuid + "-class",templateVO,dataSet,fieldIndexMap,false);
        if(newErrorMap.size()>0) {
            createRedisDatas(uuid + "-ok",templateVO, rowIndexCboMap, dataSet, fieldIndexMap, newErrorMap,true);
        }else {
            uuid="";
            //要把以上的错误的都抛出后,再继续处理时间和组合规则
            /*dataCBOList = cboList.stream().filter(cbo -> {
                String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                return !newErrorMap.containsKey(rowIndex);
            }).collect(Collectors.toList());
*/            List<String> dataCBOIdList=new ArrayList<>();
            List<BaseModel> dataCBOList=new ArrayList<>();
            cboList.stream().forEach(clientBusinessObject -> {
                BaseModel baseModel=new BaseModel();
                BeanUtil.convert(clientBusinessObject,baseModel);
                baseModel.setData(VciBaseUtil.objectToMapString(clientBusinessObject));
                dataCBOList.add(baseModel);
                dataCBOIdList.add(baseModel.getOid());
            });
            if (!CollectionUtils.isEmpty(needSaveCboList)) {
                //9.我们处理业务数据
                //生成编码的内容
                try {
                    codeList = productCodeService.productCodeAndSaveData(classifyFullInfo,templateVO,ruleVO, orderDTO.getSecDTOList(),dataCBOList);
                    //如果是编码生成失败,则直接就失败了,其他的判断出来有错误的我们都统一返回到excel里面
                    engineService.batchSaveSelectChar(templateVO, dataCBOIdList);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("批了申请时失败");
                }
            }
        }
        if(!isCreateUUid){
            return uuid="";
        }
        return uuid;
    }
    @Override
@@ -629,6 +683,587 @@
    }
    /**
     * excel转换为cbo的对象
     * @param classifyFullInfo åˆ†ç±»çš„全部信息
     * @param fieldIndexMap å­—段的位置
     * @param rowDataList excel里的行数据
     * @param templateVO æ¨¡æ¿çš„æ˜¾ç¤ºå¯¹è±¡
     * @param cboList æ•°æ®çš„列表
     * @param fullPath å…¨è·¯å¾„
     * @param newCode æ˜¯å¦ä¸ºæ‰¹é‡ç”³è¯·
     */
    private void excelToCbo(CodeClassifyFullInfoBO classifyFullInfo,Map<Integer,String> fieldIndexMap,List<SheetRowData> rowDataList,
                            CodeClassifyTemplateVO templateVO,List<ClientBusinessObject> cboList,
                            String fullPath,boolean newCode){
        rowDataList.stream().forEach(rowData -> {
            ClientBusinessObject cbo=new ClientBusinessObject();
             DefaultAttrAssimtUtil.addDefaultAttrAssimt(cbo, classifyFullInfo.getTopClassifyVO().getBtmtypeid());
            rowData.getData().forEach((index,value)->{
                String field = fieldIndexMap.get(index);
                if (StringUtils.isBlank(field)) {
                    throw new VciBaseException("第" + (index + 1) + "列的标题在系统中不存在");
                }
                try {
                    cbo.setAttributeValueWithNoCheck(field, value);
                    if (WebUtil.isDefaultField(field)) {
                        WebUtil.setValueToField(field, cbo, value);
                    }
                } catch (VciBaseException e) {
                    log.error("设置属性的值错误", e);
                }
            });
            try {
                cbo.setAttributeValue(CODE_TEMPLATE_OID_FIELD,templateVO.getOid());
                cbo.setAttributeValue(IMPORT_ROW_INDEX,rowData.getRowIndex());
                if(newCode){
                    cbo.setAttributeValue(CODE_CLASSIFY_OID_FIELD,classifyFullInfo.getCurrentClassifyVO().getOid());
                    cbo.setAttributeValue(CODE_FULL_PATH_FILED,fullPath);
                    //cbo.setLcStatus(CodeDefaultLC.EDITING.getValue());
                    int secret = VciBaseUtil.getInt(cbo.getAttributeValue(SECRET_FIELD));
                    /*if(secret == 0 || !secretService.checkDataSecret(secret) ){
                        Integer userSecret = VciBaseUtil.getCurrentUserSecret();
                        cbo.setAttributeValue(SECRET_FIELD,String.valueOf((userSecret==null || userSecret ==0)? UserSecretEnum.NONE.getValue():userSecret));
                    }*/
                }else{
                    //此时还没有转换路径
                    //cbo.setAttributeValue(CODE_FULL_PATH_FILED, childOidPathMap.getOrDefault(rowData.getData().getOrDefault(CODE_CLASSIFY_OID_FIELD,""),fullPath));
                    cbo.setLcStatus(CodeDefaultLC.RELEASED.getValue());
                }
            }catch (Throwable e){
                log.error("设置默认的属性的值错误",e);
            }
            cboList.add(cbo);
        });
    }
    /**
     * æ£€æŸ¥æ ¡éªŒè§„则没有通过的内容
     * @param attrVOS éœ€è¦æ ¡éªŒçš„属性
     * @param dataList æ•°æ®çš„列表
     * @param errorMap é”™è¯¯çš„信息映射
     * @return æ ¡éªŒä¸é€šè¿‡çš„行数
     */
    private void batchCheckVerifyOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS, List<ClientBusinessObject> dataList,Map<String,String> errorMap) {
        Map<String, CodeClassifyTemplateAttrVO> verifyAttrVOMap = attrVOS.stream().filter(s -> StringUtils.isNotBlank(s.getVerifyRule()) && StringUtils.isBlank(s.getComponentRule())
            &&StringUtils.isBlank(s.getClassifyInvokeAttr())
        ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
        if(!CollectionUtils.isEmpty(verifyAttrVOMap)){
            Map<String/**行号**/,List<String>/**校验不通过的属性**/> unPassCheckMap = new HashMap<>();
            verifyAttrVOMap.forEach((attrId,attrVO)->{
                dataList.stream().forEach(cbo -> {
                    String value = cbo.getAttributeValue(attrId);
                    if(StringUtils.isNotBlank(value) && !value.matches(attrVO.getVerifyRule())){
                        String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                        List<String> unPassAttrs = unPassCheckMap.getOrDefault(rowIndex, new ArrayList<>());
                        unPassAttrs.add(attrVO.getName());
                        unPassCheckMap.put(rowIndex,unPassAttrs);
                    }
                });
            });
            if(!CollectionUtils.isEmpty(unPassCheckMap)){
                unPassCheckMap.forEach((rowIndex,unPassAttrs)->{
                    errorMap.put(rowIndex,";属性[" + unPassAttrs.stream().collect(Collectors.joining(",")) + "]内容不符合校验规则的要求");
                });
            }
        }
    }
    /**
     * æ‰¹é‡è½¬æ¢æ—¶é—´éƒ½ä¸ºæŒ‡å®šçš„æ ¼å¼
     * @param attrVOS æ¨¡æ¿å±žæ€§
     * @param cboList æ•°æ®çš„列表
     * @param errorMap é”™è¯¯çš„信息
     */
    private void batchSwitchDateAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> cboList,Map<String,String> errorMap){
        Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap =attrVOS.stream().filter(s ->
            StringUtils.isNotBlank(s.getCodeDateFormat()) && VciBaseUtil.getBoolean(s.getCodeDateFormat()) && StringUtils.isBlank(s.getComponentRule())
                && StringUtils.isBlank(s.getClassifyInvokeAttr())
        ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
        if(!CollectionUtils.isEmpty(dateAttrVOMap)) {
            dateAttrVOMap.forEach((attrId, attrVO) -> {
                cboList.stream().forEach(cbo -> {
                    String value = cbo.getAttributeValue(attrId);
                    if (value == null) {
                        value = "";
                    }
                    if (StringUtils.isNotBlank(value)) {
                        boolean formated = false;
                        if(StringUtils.isNotBlank(attrVO.getCodeDateFormat())){
                            try {
                                Date date = VciDateUtil.str2Date(value, attrVO.getCodeDateFormat());
                                if(date!=null){
                                    cbo.setAttributeValue(attrId,value);
                                    formated = true;
                                }
                            } catch (Exception e) {
                                //说明不是这个格式
                            }
                        }
                        if(!formated) {
                            try {
                                DateConverter dateConverter = new DateConverter();
                                dateConverter.setAsText(value);
                                value = VciDateUtil.date2Str(dateConverter.getValue(), VciDateUtil.DateTimeMillFormat);
                                cbo.setAttributeValue(attrId,value);
                            }catch (Throwable e){
                                //转换不了
                                String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                                errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";属性[" + attrVO.getName() + "]时间格式不正确" );
                            }
                        }
                    }
                });
            });
        }
    }
    /**
     * è½¬ç§»boolean型的属性
     * @param attrVOS å±žæ€§çš„对象
     * @param dataList æ•°æ®
     */
    private void reSwitchBooleanAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList){
        Map<String, CodeClassifyTemplateAttrVO> booleanAttrMap = attrVOS.stream().filter(
            s -> VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(s.getAttributeDataType())
        ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
        if (!CollectionUtils.isEmpty(booleanAttrMap)) {
            booleanAttrMap.forEach((attrId, attrVO) -> {
                dataList.stream().forEach(cbo -> {
                    String text = cbo.getAttributeValue(attrId);
                    try {
                        if (BooleanEnum.TRUE.getValue().equalsIgnoreCase(text) || "是".equalsIgnoreCase(text)) {
                            cbo.setAttributeValue(attrId, BooleanEnum.TRUE.getValue());
                        } else {
                            cbo.setAttributeValue(attrId, BooleanEnum.FASLE.getValue());
                        }
                    }catch (Throwable e){
                    }
                });
            });
        }
    }
    /**
     * å¤„理组合规则
     * @param attrVOS æ¨¡æ¿å±žæ€§
     * @param dataList excel的数据内容
     */
    private void batchSwitchComponentAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList) {
        Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap = attrVOS.stream().filter(s -> StringUtils.isNotBlank(s.getComponentRule())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
        if(!CollectionUtils.isEmpty(dateAttrVOMap)) {
            dateAttrVOMap.forEach((attrId, attrVO) -> {
                dataList.stream().forEach(cbo -> {
                    //从excel上把属性转换为map
                    Map<String,String> thisRowDataMap = new HashMap<>();
                    copyValueToMapFromCbos(cbo,thisRowDataMap);
                    //组合内容
                    String value = formulaService.getValueByFormula(thisRowDataMap,attrVO.getComponentRule());
                    if(value == null){
                        value = "";
                    }
                    try {
                        cbo.setAttributeValue(attrId, value);
                    }catch (Throwable e){
                        log.error("设置属性的错误",e);
                    }
                });
            });
        }
    }
    /**
     * è½¬æ¢å‚照的值
     * @param attrVOS å±žæ€§çš„æ˜¾ç¤ºå¯¹è±¡
     * @param dataList æ•°æ®åˆ—表
     * @param errorMap é”™è¯¯çš„信息
     */
    private void batchSwitchReferAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList,Map<String,String> errorMap){
        Map<String, CodeClassifyTemplateAttrVO> referAttrVOMap = attrVOS.stream().filter(
            s -> (StringUtils.isNotBlank(s.getReferBtmId()) || StringUtils.isNotBlank(s.getReferConfig()))
        ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
        if(!CollectionUtils.isEmpty(referAttrVOMap)){
            Map<String/**表格和值的属性**/,Map<String/**显示属性的值**/,List<String>/**表格里的值**/>> linkValueMap = new HashMap<>();
            referAttrVOMap.forEach((attrId,attrVO)->{
                dataList.stream().forEach(cbo -> {
                    String text = cbo.getAttributeValue(attrId);
                    if(StringUtils.isNotBlank(text)){
                        UIFormReferVO referVO = getReferVO(attrVO);
                        String valueField = getValueField(referVO);
                        String showText = getTextField(referVO);
                        String tableAndAttr = VciBaseUtil.getTableName(referVO.getReferType()) + "#" + valueField;
                        Map<String, List<String>> showTextMap = linkValueMap.getOrDefault(tableAndAttr, new HashMap<>());
                        List<String> textList = showTextMap.getOrDefault(showText, new ArrayList<>());
                        if(!textList.contains(text)) {
                            textList.add(text);
                        }
                        showTextMap.put(showText,textList);
                        linkValueMap.put(tableAndAttr,showTextMap);
                    }
                });
            });
            if(!CollectionUtils.isEmpty(linkValueMap)){
                //需要逐个表的值字段,逐个查询
                Map<String/**表格和值属性**/,Map<String/**显示属性**/, Map<String/**值**/,String/**显示的值**/>>> linkCboMap = new HashMap<>();
                linkValueMap.forEach((tableAndAttr,showValueMap)->{
                    String[] split = tableAndAttr.split("#");
                    String table = split[0];
                    String valueField = split[1].toLowerCase(Locale.ROOT);
                    Map<String,Map<String,String>> dataMap = new HashMap<>();
                    showValueMap.forEach((showText,valueList)->{
                        Map<String,String> valueOidTextMap = new HashMap<>();
                        List<List<String>> valueCollections = VciBaseUtil.switchListForOracleIn(valueList);
                        String sql = "select " + valueField + "," + showText.toLowerCase(Locale.ROOT) +" from " + table + "  where " + showText + " in (%s)";
                        valueCollections.stream().forEach(values->{
                            List<Map<String,String>> dataMapList = commonsMapper.queryByOnlySqlForMap(String.format(sql, VciBaseUtil.toInSql(values.toArray(new String[0]))));
                            List<ClientBusinessObject> cbos=    ChangeMapTOClientBusinessObjects(dataMapList);
                            if(!CollectionUtils.isEmpty(cbos)){
                                valueOidTextMap.putAll(cbos.stream().collect(Collectors.toMap(s->s.getAttributeValue(valueField),t->t.getAttributeValue(showText))));
                            }
                        });
                        dataMap.put(showText,valueOidTextMap);
                    });
                    linkCboMap.put(tableAndAttr,dataMap);
                });
                referAttrVOMap.forEach((attrId,attrVO)->{
                    dataList.stream().forEach(cbo -> {
                        String text = cbo.getAttributeValue(attrId);
                        if (StringUtils.isNotBlank(text)) {
                            UIFormReferVO referVO = getReferVO(attrVO);
                            String valueField = getValueField(referVO);
                            String showText = getTextField(referVO);
                            String tableAndAttr = VciBaseUtil.getTableName(referVO.getReferType()) + "#" + valueField;
                            if(!linkCboMap.containsKey(tableAndAttr)){
                                String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                                errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在" );
                            }else{
                                Map<String, Map<String, String>> dataMap = linkCboMap.get(tableAndAttr);
                                if(!dataMap.containsKey(showText)){
                                    String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                                    errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在" );
                                }else{
                                    Map<String, String> data = dataMap.get(showText);
                                    final boolean[] fined = {false};
                                    data.forEach((key,value)->{
                                        if(value.equalsIgnoreCase(text)){
                                            fined[0] = true;
                                            try {
                                                cbo.setAttributeValue(attrId, key);
                                            }catch (Throwable e){
                                            }
                                        }
                                    });
                                    if(!fined[0]){
                                        String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                                        errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";参数属性[" + attrVO.getName() + "]的值在系统中不存在" );
                                    }
                                }
                            }
                        }
                    });
                });
            }
        }
    }
    /**
     * ä»Žå±žæ€§ä¸ŠèŽ·å–å‚ç…§çš„å†…å®¹
     * @param attrVO å±žæ€§çš„信息
     * @return å‚照的内容
     */
    private UIFormReferVO getReferVO(CodeClassifyTemplateAttrVO attrVO){
        UIFormReferVO referVO = null;
        if(StringUtils.isNotBlank(attrVO.getReferConfig())){
            referVO = JSONObject.parseObject(attrVO.getReferConfig(),UIFormReferVO.class);
        }else{
            referVO = new UIFormReferVO();
            referVO.setReferType(attrVO.getReferBtmId());
            referVO.setValueField(VciQueryWrapperForDO.OID_FIELD);
            referVO.setTextField("name");
        }
        return referVO;
    }
    /**
     * èŽ·å–å‚ç…§ä¸­çš„å€¼çš„å­—æ®µ
     * @param referVO å‚照的对象
     * @return é»˜è®¤ä¸ºOid,有多个的时候,获取第一个
     */
    private String getValueField(UIFormReferVO referVO){
        String showText = referVO.getValueField();
        if(StringUtils.isBlank(showText)){
            return "oid";
        }
        if(showText.contains(",")){
            //防止万一有多个,看看有没有oid
            List<String> strings = VciBaseUtil.str2List(showText);
            if(strings.contains("oid")){
                showText = "oid";
            }else{
                showText = strings.get(0);
            }
        }
        return showText;
    }
    /**
     * èŽ·å–å‚ç…§ä¸­çš„æ˜¾ç¤ºå†…å®¹çš„å­—æ®µ
     * @param referVO å‚照的对象
     * @return é»˜è®¤ä¸ºname,有多个的时候,获取第一个
     */
    private String getTextField(UIFormReferVO referVO){
        String showText = referVO.getTextField();
        if(StringUtils.isBlank(showText)){
            return "name";
        }
        if(showText.contains(",")){
            //防止万一有多个,看看有没有name
            List<String> strings = VciBaseUtil.str2List(showText);
            if(strings.contains("name")){
                showText = "name";
            }else{
                showText = strings.get(0);
            }
        }
        return showText;
    }
    /**
     * å¤„理枚举的显示对象
     * @param attrVOS æ¨¡æ¿å±žæ€§
     * @param dataList excel的数据内容
     * @param errorMap é”™è¯¯ä¿¡æ¯çš„æ˜ å°„
     */
    private void batchSwitchEnumAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList,
                                            Map<String,String> errorMap ) {
        Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap = attrVOS.stream().filter(
            s -> (StringUtils.isNotBlank(s.getEnumString()) || StringUtils.isNotBlank(s.getEnumId()))
        ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
        if (!CollectionUtils.isEmpty(dateAttrVOMap)) {
            dateAttrVOMap.forEach((attrId, attrVO) -> {
                dataList.stream().forEach(cbo -> {
                    String text = cbo.getAttributeValue(attrId);
                    if(StringUtils.isNotBlank(text)){
                        List<KeyValue> valueList = engineService.listComboboxItems(attrVO);
                        boolean fined = false;
                        for (int i = 0; i < valueList.size(); i++) {
                            KeyValue keyValue = valueList.get(i);
                            //if(keyValue.getValue().equalsIgnoreCase(text)){
                            if(keyValue.getValue().equalsIgnoreCase(text)||keyValue.getKey().equalsIgnoreCase(text)){
                                try {
                                    cbo.setAttributeValue(attrId, keyValue.getKey());
                                }catch (Throwable e){
                                    log.error("设置属性出错");
                                }
                                fined = true;
                                break;
                            }
                        }
                        if(!fined){
                            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                            errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";属性[" + attrVO.getName() + "]的值不符合下拉的要求");
                        }
                    }
                });
            });
        }
    }
    /**
     * æ‰¹é‡æ ¡éªŒæ•°æ®çš„信息
     * @param templateVO æ¨¡æ¿çš„æ˜¾ç¤ºå¯¹è±¡
     * @param cboList æ•°æ®çš„内容
     */
    private void batchCheckRequiredAttrOnOrder(CodeClassifyTemplateVO templateVO,List<ClientBusinessObject> cboList,Map<String,String> errorMap){
        Map<String, CodeClassifyTemplateAttrVO> requiredAttrMap = templateVO.getAttributes().stream().filter(s ->
            VciBaseUtil.getBoolean(s.getRequireFlag()) && StringUtils.isBlank(s.getComponentRule()) && StringUtils.isBlank(s.getClassifyInvokeLevel())//不能是组合的和分类注入的
        ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
        //与MdmEngineServiceImpl里面的checkRequiredAttrOnOrder é€»è¾‘应该相似
        if(!CollectionUtils.isEmpty(requiredAttrMap)) {
            Set<String> nullRowIndex = cboList.stream().filter(cbo -> requiredAttrMap.keySet().stream().anyMatch(attrId -> StringUtils.isBlank(cbo.getAttributeValue(attrId)))).map(cbo -> cbo.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toSet());
            if(!CollectionUtils.isEmpty(nullRowIndex)){
                String checkAttr = requiredAttrMap.values().stream().map(CodeClassifyTemplateAttrVO::getName).collect(Collectors.joining(","));
                nullRowIndex.stream().forEach(rowIndex->{
                    errorMap.put(rowIndex,errorMap.getOrDefault(rowIndex,"") + ";校验规则不通过,有校验的属性为" + checkAttr);
                });
            }
        }
    }
    /**
     * å¤„理分类注入
     * @param attrVOS æ¨¡æ¿å±žæ€§
     * @param dataList excel的数据内容
     * @param classifyFullInfo åˆ†ç±»çš„全路径
     */
    private void batchSwitchClassifyAttrOnOrder(Collection<CodeClassifyTemplateAttrVO> attrVOS,List<ClientBusinessObject> dataList,
                                                CodeClassifyFullInfoBO classifyFullInfo,boolean isImPort) {
        Map<String, CodeClassifyTemplateAttrVO> dateAttrVOMap = attrVOS.stream().filter(
            s -> StringUtils.isNotBlank(s.getClassifyInvokeAttr()) && StringUtils.isNotBlank(s.getClassifyInvokeAttr())
        ).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
        Map<String,CodeClassifyFullInfoBO> classifyFullInfoMap=new HashMap<>();
        classifyFullInfoMap.put(classifyFullInfo.getCurrentClassifyVO().getOid(),classifyFullInfo);
        if (!CollectionUtils.isEmpty(dateAttrVOMap)) {
            dataList.stream().forEach(cbo -> {
                dateAttrVOMap.forEach((attrId, attrVO) -> {
                    //分类注入的编号或者名称,
                    //层级包含指定层和最小层
                    CodeClassifyVO classifyVO = null;
                    if(!CodeLevelTypeEnum.MIN.getValue().equalsIgnoreCase(attrVO.getClassifyInvokeLevel()) && !"min".equalsIgnoreCase(attrVO.getClassifyInvokeLevel())) {
                        //指定了层级的
                        //注意,因为查询上级分类出来的层级是倒序的,即顶层节点是最大的值
                        if(isImPort){
                            if(!classifyFullInfoMap.containsKey(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD))) {
                                CodeClassifyFullInfoBO currentClassifyFullInfo = classifyService.getClassifyFullInfo(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD));
                                classifyFullInfoMap.put(currentClassifyFullInfo.getCurrentClassifyVO().getOid(), currentClassifyFullInfo);
                            }
                        }
                        CodeClassifyFullInfoBO newClassifyFullInfo= classifyFullInfoMap.get(cbo.getAttributeValue(CODE_CLASSIFY_OID_FIELD));
                        List<CodeClassifyVO> classifyVOS = newClassifyFullInfo.getParentClassifyVOs().stream().sorted(((o1, o2) -> o2.getDataLevel().compareTo(o1.getDataLevel()))).collect(Collectors.toList());
                        int level = VciBaseUtil.getInt(attrVO.getClassifyInvokeLevel());
                        if (classifyVOS.size()>=level && level > 0 ) {
                            classifyVO = classifyVOS.get(level-1);
                        }
                    }else{
                        //当前的分类
                        classifyVO = classifyFullInfo.getCurrentClassifyVO();
                    }
                    try {
                        if (classifyVO == null) {
                            //说明层级有误
                            cbo.setAttributeValue(attrId, "分类树上没有层级[" + attrVO.getClassifyInvokeLevel() + "]");
                        } else {
                            Map<String, String> classifyDataMap = VciBaseUtil.objectToMapString(classifyVO);
                            String value = classifyDataMap.getOrDefault(attrVO.getClassifyInvokeAttr(), "");
                            cbo.setAttributeValue(attrId, value);
                        }
                    } catch (Throwable e) {
                        log.error("设置属性错误", e);
                    }
                });
            });
        }
    }
    /**
     * æ ¡éªŒå…³é”®å±žæ€§
     * @param classifyFullInfo åˆ†ç±»çš„全部信息
     * @param templateVO æ¨¡æ¿çš„内容,必须包含模板属性
     * @param cboList æ‰¹é‡çš„æ•°æ®
     */
    private CodeImportResultVO batchCheckKeyAttrOnOrder(CodeClassifyFullInfoBO classifyFullInfo, CodeClassifyTemplateVO templateVO,
                                                        List<ClientBusinessObject> cboList) {
        //与MdmEngineServiceImpl里的checkKeyAttrOnOrder相似
        //先获取关键属性的规则,也利用继承的方式
        CodeKeyAttrRepeatVO keyRuleVO = keyRuleService.getRuleByClassifyFullInfo(classifyFullInfo);
        //注意的是keyRuleVO可能为空,表示不使用规则控制
        //获取所有的关键属性
        Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> ketAttrMap = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getKeyAttrFlag())).collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
        boolean trimAll =keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag());
        //全部去空的优先级大于去空
        boolean trim =keyRuleVO ==null?false:  VciBaseUtil.getBoolean(keyRuleVO.getIgnorespaceflag());
        boolean ignoreCase = keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnorecaseflag());
        boolean ignoreWidth = keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnorewidthflag());
        //1. æˆ‘们需要先判断excel导入的内容是否正确
        CodeImportResultVO resultVO = new CodeImportResultVO();
        resultVO.setKeyAttrRuleInfo(String.format(keyRuleVO ==null?"":"查询规则:去除空格--{0},忽略大小写--{1},忽略全半角--{2},忽略全部空格--{3}",
            new String[]{trim?"是":"否",ignoreCase?"是":"否",ignoreWidth?"是":"否",trimAll?"是":"否"}));
        resultVO.setSelfRepeatRowIndexList(getSelfRepeatRowIndex(ketAttrMap,cboList,keyRuleVO));
        if(!CollectionUtils.isEmpty(resultVO.getSelfRepeatRowIndexList())){
            //我们移除本身重复的数据
            cboList = cboList.stream().filter(s->!resultVO.getSelfRepeatRowIndexList().contains(s.getAttributeValue(IMPORT_ROW_INDEX))).collect(Collectors.toList());
        }
        //2.判断关键属性在系统里是否重复
        //因为数据量很大,所以得想办法并行
        //SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
        Map<String,List<ClientBusinessObject>> indexTODataMap=new HashMap<>();
        List<ClientBusinessObject> repeatDataMap = cboList.parallelStream().filter(cbo -> {
            //每行都得查询.如果其中出现了错误,我们就直接抛出异常,其余的显示
            //VciBaseUtil.setCurrentUserSessionInfo(sessionInfo);
            Map<String, String> conditionMap = new HashMap<>();
            ketAttrMap.forEach((attrId, attrVO) -> {
                String value =cbo.getAttributeValue(attrId.toLowerCase(Locale.ROOT));
                if (value == null) {
                    value = "";
                }
                value= value.replace(REQUIRED_CHAR,SPECIAL_CHAR);
                engineService.wrapperKeyAttrConditionMap(value, keyRuleVO, attrId, trim, ignoreCase, ignoreWidth, trimAll, conditionMap);
            });
            if (!CollectionUtils.isEmpty(ketAttrMap)) {
                CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(classifyFullInfo.getTopClassifyVO().getBtmtypeid(), templateVO, conditionMap, null);
                boolean isKeyCheck= commonsMapper.queryCountBySql(sqlBO.getSqlCount()) > 0;
                if(isKeyCheck){
                    List<Map<String,String>> newDataList=  commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage());
                    List<ClientBusinessObject> newCboList=    ChangeMapTOClientBusinessObjects(newDataList);
                    indexTODataMap.put(cbo.getAttributeValue(IMPORT_ROW_INDEX),newCboList);
                }
                return isKeyCheck;
            }else{
                return false;
            }
        }).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(repeatDataMap)){
            resultVO.setKeyAttrRepeatRowIndexList(repeatDataMap.stream().map(s->s.getAttributeValue(IMPORT_ROW_INDEX)).collect(Collectors.toSet()));
        }
        //resultVO.setIndexTODataMap(indexTODataMap);
        //resultVO.setSuccess(true);
        return resultVO;
    }
    /**
     * èŽ·å–å¯¼å…¥çš„å†…å®¹ä¸­å…³é”®å±žæ€§é‡å¤çš„è¡Œå·
     * @param ketAttrMap å…³é”®å±žæ€§çš„æ˜ å°„
     * @param dataList å¯¼å…¥çš„æ•°æ®
     * @param keyRuleVO å…³é”®å±žæ€§æŽ§åˆ¶è§„则
     * @return é‡å¤çš„行号
     */
    private Set<String> getSelfRepeatRowIndex(Map<String/**属性的编号**/, CodeClassifyTemplateAttrVO> ketAttrMap,
                                              List<ClientBusinessObject> dataList,CodeKeyAttrRepeatVO keyRuleVO){
        Set<String> selfRepeatRowIndexList = new CopyOnWriteArraySet<>();
        boolean trimAll =keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnoreallspaceflag());
        //全部去空的优先级大于去空
        boolean trim =keyRuleVO ==null?false:  VciBaseUtil.getBoolean(keyRuleVO.getIgnorespaceflag());
        boolean ignoreCase = keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnorecaseflag());
        boolean ignoreWidth = keyRuleVO ==null?false: VciBaseUtil.getBoolean(keyRuleVO.getIgnorewidthflag());
        //必须将属性按照顺序排序好
        List<CodeClassifyTemplateAttrVO> attrVOList = ketAttrMap.values().stream().sorted(((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum()))).collect(Collectors.toList());
        Map<String/**行号**/,String/**关键属性的组合内容**/> rowIndexKeyStringMap = new HashMap<>();
        dataList.parallelStream().forEach(cbo-> {
            String rowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < attrVOList.size(); i++) {
                CodeClassifyTemplateAttrVO attrVO = attrVOList.get(i);
                String attrId = attrVO.getId().toLowerCase(Locale.ROOT);
                String value = cbo.getAttributeValue( attrId);
                if (value == null) {
                    value = "";
                }
                if(trim){
                    value = value.trim();
                }
                if(trimAll){
                    value = value.replace(" ","");
                }
                if(ignoreCase){
                    value = value.toLowerCase(Locale.ROOT);
                }
                if(ignoreWidth){
                    value = VciBaseUtil.toDBC(value);
                }
                sb.append(value).append("${ks}");
            }
            String keyString = sb.toString();
            if(rowIndexKeyStringMap.containsValue(keyString) && StringUtils.isNotBlank(keyString)){
                selfRepeatRowIndexList.add(rowIndex);
            }else {
                rowIndexKeyStringMap.put(rowIndex, sb.toString());
            }
        });
        //因为只是关键属性重复,所以我们不能重复的多条选一条来报错
        return selfRepeatRowIndexList;
    }
    /**
     * excel的标题上获取字段所在的位置
     * @param titleRowData æ ‡é¢˜çš„内容
     * @param attrNameIdMap æ¨¡æ¿ä¸­å±žæ€§åç§°å’Œè‹±æ–‡çš„æ˜ å°„
@@ -653,6 +1288,272 @@
            }
        }
    }
    private List<ClientBusinessObject> ChangeMapTOClientBusinessObjects(List<Map<String,String>> oldDataMap){
        List<ClientBusinessObject> clientBusinessObjectList=new CopyOnWriteArrayList<>();
        oldDataMap.parallelStream().forEach(dataMap->{
            ClientBusinessObject clientBusinessObject=new ClientBusinessObject();
            DefaultAttrAssimtUtil.copplyDefaultAttrAssimt(dataMap,clientBusinessObject);
            dataMap.forEach((key,value)->{
                clientBusinessObject.setAttributeValue(key,value);
            });
        });
        return clientBusinessObjectList;
    }
    /***
     * æ­£ç¡®é”™è¯¯æ•°æ®redis缓存
     * @param uuid
     * @param templateVO
     * @param rowIndexCbo
     * @param dataSet
     * @param fieldIndexMap
     * @param errorMap
     * @param isok
     */
    private void createRedisDatas(String uuid,CodeClassifyTemplateVO templateVO,Map<String,ClientBusinessObject> rowIndexCbo, SheetDataSet dataSet, Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap,Map<String,String> errorMap,boolean isok){
        List<SheetRowData>  needsheetRowDataList =new ArrayList<>();
        if(errorMap.size()>0) {
            //要把以上的错误的都抛出后,再继续处理时间和组合规则
            needsheetRowDataList = dataSet.getRowData().stream().filter(cbo -> {
                String rowIndex=cbo.getRowIndex();
                return  isok? !errorMap.containsKey(rowIndex):errorMap.containsKey(rowIndex);
            }).collect(Collectors.toList());
        }else{
            needsheetRowDataList= dataSet.getRowData();
        }
        Map<String/**中文名称**/, SheetRowData/**英文名称**/> rowIdexDataMap = needsheetRowDataList.stream().collect(Collectors.toMap(s -> s.getRowIndex(), t -> t,(o1, o2)->o2));
        Map<String,CodeImprotDataVO> clsfDataMap=new HashMap<>();
        rowIndexCbo .forEach((rowIndex, cbo) -> {
            CodeImprotDataVO codeImprotDataVO = new CodeImprotDataVO();
            codeImprotDataVO.setTemplateOid(templateVO.getOid());
            List<Map<String, String>> dataList = new ArrayList<>();
            if(rowIdexDataMap.containsKey(rowIndex)){
                SheetRowData sheetRowData=rowIdexDataMap.get(rowIndex);
                Map<String, String> dataMap = new HashMap<>();
                Map<Integer, String> data = sheetRowData.getData();
                fieldIndexMap.forEach((integer, s) -> {
                    String field = fieldIndexMap.get(integer);
                    if (data.containsKey(integer)) {
                        String vlues = data.get(integer);
                        dataMap.put(field, vlues);
                    }
                });
                dataMap.put("oid",cbo.getOid());
                dataList.add(dataMap);
            }
            if(clsfDataMap.containsKey(templateVO.getOid())){
                codeImprotDataVO=clsfDataMap.get(templateVO.getOid());
                dataList.addAll(codeImprotDataVO.getDatas());
            }
            codeImprotDataVO.setColNames(dataSet.getColName());
            codeImprotDataVO.setDatas(dataList);
            clsfDataMap.put(templateVO.getOid(),codeImprotDataVO);
        });
        if(!CollectionUtils.isEmpty(clsfDataMap)) {
            Collection codeImprotDataVOS=clsfDataMap.values();
            List<CodeImprotDataVO> codeImprotDataVOList=new ArrayList<>();
            codeImprotDataVOList.addAll(codeImprotDataVOS);
            bladeRedis.set(uuid+"-"+templateVO.getOid(), codeImprotDataVOList);
            bladeRedis.expire(uuid+"-"+templateVO.getOid(),BATCHADD_REDIS_TIME);//redis过期时间
        }
    }
    /****
     * æ•°æ®ç›¸ä¼¼é¡¹æ•°æ®æ ¡éªŒredis缓存
     * @param codeClassifyOid
     * @param templateVO
     * @param cboList
     * @param resembleMap
     * @param btmtypeid
     * @param dataResembleVOS
     */
    private void bathcResembleQuery(String codeClassifyOid, CodeClassifyTemplateVO templateVO, List<ClientBusinessObject> cboList,Map<String,String>resembleMap,String btmtypeid,List<DataResembleVO> dataResembleVOS){
        CodeClassifyFullInfoBO fullInfoBO = classifyService.getClassifyFullInfo(codeClassifyOid);
        Map<String, String> conditionMap = new HashMap<>();
        CodeResembleRuleVO resembleRuleVO = Optional.ofNullable(engineService.getUseResembleRule(fullInfoBO, fullInfoBO.getCurrentClassifyVO())).orElseGet(() -> new CodeResembleRuleVO());
        //需要获取是否有相似查询属性
        Map<String, CodeClassifyTemplateAttrVO> attrVOs = templateVO.getAttributes().stream().filter(s -> VciBaseUtil.getBoolean(s.getSameRepeatAttrFlag())).collect(Collectors.toMap(s -> s.getId(), t -> t));
        if (CollectionUtils.isEmpty(attrVOs)) {
            return;
        }
        Map<String,CodeImprotResembleVO> codeImprotResembleVOMap=new HashMap<>();
        List<CodeImprotResembleVO> codeImprotResembleVOList=new ArrayList<>();
        Map<String,String> rowIndePathMap=new HashMap<>();
        cboList.stream().forEach(clientBusinessObject -> {
            CodeImprotResembleVO codeImprotResembleVO=new CodeImprotResembleVO();
            final String[] path = {""};
            List<String> fieldList=new ArrayList<>();
            List<String> rowIndeList=new ArrayList<>();
            String rowIndex = clientBusinessObject.getAttributeValue(IMPORT_ROW_INDEX);
            attrVOs.forEach((attrId, attrVO) -> {
                String value="";
                /*if (VciQueryWrapperForDO.BASIC_FIELD_MAP.containsKey(attrId)) {
                    value = WebUtil.getStringValueFromObject(WebUtil.getValueFromField(WebUtil.getFieldForObject(attrId, orderDTO.getClass()).getName(), orderDTO));
                }else {*/
                value= clientBusinessObject.getAttributeValue(attrId);
                // }
                fieldList.add(attrId);
                value=StringUtils.isBlank(value)?"":value;
                path[0] +=value+"#";
                engineService.wrapperResembleConditionMap(value, resembleRuleVO, attrId, conditionMap);
            });
            List<Map<String,String>> dataMap=new ArrayList<>();
            if(codeImprotResembleVOMap.containsKey(path[0])) {
                codeImprotResembleVO=codeImprotResembleVOMap.get(path[0]);
                rowIndeList=codeImprotResembleVO.getRownIndex();
                dataMap=  codeImprotResembleVO.getDataList();
                resembleMap.put(rowIndex, "存在相似数据");
            }else{
                if (!CollectionUtils.isEmpty(conditionMap)) {
                    Map<String, String> andConditionMap = new HashMap<>();
                    andConditionMap.put("islastr", "1");
                    andConditionMap.put("islastv", "1");
                    conditionMap.putAll(andConditionMap);
                    PageHelper pageHelper = new PageHelper(-1);
                    pageHelper.addDefaultDesc("id");
                    CodeTemplateAttrSqlBO sqlBO = engineService.getSqlByTemplateVO(btmtypeid, templateVO, conditionMap, pageHelper);
                    List<Map<String,String>> dataMapList=commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlUnPage());
                    List<ClientBusinessObject> resembleCboList=    ChangeMapTOClientBusinessObjects(dataMapList);
                    if(!CollectionUtils.isEmpty(resembleCboList)) {
                        List<Map<String, String>> finalDataMap = dataMap;
                        resembleCboList.stream().forEach(cbo->{
                            Map<String,String> resembDataMap=new HashMap<>();
                            fieldList.stream().forEach(field->{
                                String value=cbo.getAttributeValue(field);
                                value=StringUtils.isBlank(value)?"":value;
                                resembDataMap.put(field,value);
                            });
                            resembDataMap.put("codetemplateoid",templateVO.getOid());
                            resembDataMap.put("id",StringUtils.isBlank(cbo.getAttributeValue("id"))?"":cbo.getAttributeValue("id"));
                            resembDataMap.put("rowIndex","");
                            resembDataMap.put("oid",cbo.getOid());
                            finalDataMap.add(resembDataMap);
                        });
                        resembleMap.put(rowIndex, "存在相似数据");
                    }
                }
            }
            rowIndePathMap.put(rowIndex,path[0]);
            rowIndeList.add(rowIndex);
            codeImprotResembleVO.setPath(path[0]);
            codeImprotResembleVO.setRownIndex(rowIndeList);
            codeImprotResembleVO.setConditionMap(conditionMap);
            codeImprotResembleVO.setFields(fieldList);
            codeImprotResembleVO.setDataList(dataMap);
            codeImprotResembleVOMap.put(path[0],codeImprotResembleVO);
        });
        Map<String, ClientBusinessObject> cboMap = cboList.stream().filter(cbo -> cbo != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(s -> s.getAttributeValue((IMPORT_ROW_INDEX)), t -> t));
        if(!CollectionUtils.isEmpty(rowIndePathMap)){
            rowIndePathMap.forEach((rowIndex, path) -> {
                if(codeImprotResembleVOMap.containsKey(path)){
                    CodeImprotResembleVO codeImprotResembleVO=  codeImprotResembleVOMap.get(path);
                    List<String> fieldList=codeImprotResembleVO.getFields();
                    List<String> rownIndexList= codeImprotResembleVO.getRownIndex();
                    List<String> newRownIndexList = rownIndexList.stream().filter(cbo -> {
                        return rowIndex!=cbo;
                    }).collect(Collectors.toList());
                    newRownIndexList.stream().forEach(s -> {
                        resembleMap.put(s, "存在相似数据");
                    });
                    List<Map<String, String>>newDataList=new ArrayList<>();
                    DataResembleVO dataResembleVO=new DataResembleVO();
                    dataResembleVO.setOid(cboMap.get(rowIndex).getOid());
                    List<ClientBusinessObject> needSaveCboList = cboList.stream().filter(cbo -> {
                        String newRowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                        return rownIndexList.contains(newRowIndex)&&(!newRowIndex.equalsIgnoreCase(rowIndex));
                    }).collect(Collectors.toList());
                    if(!CollectionUtils.isEmpty(needSaveCboList)) {
                        needSaveCboList.stream().forEach(cbo -> {
                            String newRowIndex = cbo.getAttributeValue(IMPORT_ROW_INDEX);
                            Map<String, String> resembDataMap = new HashMap<>();
                            fieldList.stream().forEach(field -> {
                                String value = cbo.getAttributeValue(field);
                                value = StringUtils.isBlank(value) ? "" : value;
                                resembDataMap.put(field, value);
                            });
                            resembDataMap.put("codetemplateoid",templateVO.getOid());
                            resembDataMap.put("id",StringUtils.isBlank(cbo.getAttributeValue("id"))?"":cbo.getAttributeValue("id"));
                            resembDataMap.put("rowIndex", newRowIndex);
                            resembDataMap.put("oid",cbo.getOid());
                            newDataList.add(resembDataMap);
                        });
                    }
                    List<Map<String, String>>dataList=codeImprotResembleVO.getDataList();
                    newDataList.addAll(dataList);
                    dataResembleVO.setDataList(newDataList);
                    dataResembleVOS.add(dataResembleVO);
                }
            });
        }
    }
    /***
     * å­˜å‚¨åˆ†ç±»å¯¹è±¡åŠå…¶åˆ—名
     * @param uuid
     * @param templateVOList
     * @param dataSet
     * @param fieldIndexMap
     * @param iscContain
     */
    private  void createRedisByCodeClassify(String uuid,CodeClassifyTemplateVO templateVOList,SheetDataSet dataSet, Map<Integer/**列号**/,String/**字段的名称**/> fieldIndexMap,boolean iscContain){
        List<ColumnVO> columnVOList = new ArrayList<>();
        List<String> outNameList = dataSet.getColName();
        fieldIndexMap.forEach((integer, s) -> {
            ColumnVO columnVOS = new ColumnVO();
            String field = fieldIndexMap.get(integer);
            String outName = outNameList.get(integer);
            columnVOS.setField(field);
            columnVOS.setTitle(outName);
            columnVOList.add(columnVOS);
        });
        CodeImportTemplateVO codeImportTemplateVO=new CodeImportTemplateVO();
        codeImportTemplateVO.setCodeClassifyTemplateVO(templateVOList);
        codeImportTemplateVO.setCloNamesList(columnVOList);
        List<CodeImportTemplateVO> codeImportTemplateVOs= new ArrayList<>();
        codeImportTemplateVOs.add(codeImportTemplateVO);
        if(codeImportTemplateVOs.size()>0) {
            bladeRedis.set(uuid, codeImportTemplateVOs);
            bladeRedis.expire(uuid, BATCHADD_REDIS_TIME);//redis过期时间
        }
    }
    /**
     * æ‹·è´ä¸šåŠ¡ç±»åž‹åˆ°map
     * @param cbo ä¸šåŠ¡æ•°æ®
     * @param map map
     */
    public static void copyValueToMapFromCbos(ClientBusinessObject cbo,Map<String,String> map){
        if(cbo!=null){
            copyValueToMapFromBos(cbo,map);
        }
    }
    /**
     * æ‹·è´ä¸šåŠ¡ç±»åž‹åˆ°map
     * @param bo ä¸šåŠ¡æ•°æ®
     * @param map map
     */
    public static void copyValueToMapFromBos(ClientBusinessObject bo,Map<String,String> map){
        if(bo!=null ){
            //先把所有的字段映射找到
            AttributeValue[] newAList = bo.newAttrValList;
            AttributeValue[] hisAList = bo.hisAttrValList;
            if(hisAList!=null&&hisAList.length>0){//
                for(int i = 0 ; i < hisAList.length;i++){
                    AttributeValue av = hisAList[i];
                    String attrName = av.attrName.toLowerCase();
                    map.put(attrName, av.attrVal);
                }
            }
            if(newAList!=null&&newAList.length>0){//NEW的优先级高些
                for(int i = 0 ; i < newAList.length;i++){
                    AttributeValue av = newAList[i];
                    String attrName = av.attrName.toLowerCase();
                    map.put(attrName, av.attrVal);
                }
            }
        }
    }
}
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/util/AttributeChecker.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,115 @@
package com.vci.ubcs.code.util;
import com.vci.ubcs.omd.feign.IAttributeClient;
import com.vci.ubcs.omd.util.Tool;
import com.vci.ubcs.omd.vo.AttributeVO;
import org.springblade.core.tool.api.R;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class AttributeChecker {
    @Autowired(required = false)
    private  IAttributeClient attributeClient;
    public static HashMap<String, AttributeVO> attrItemMap = new HashMap();
    public static List<AttributeVO> attrItems = new ArrayList<AttributeVO>();
    public void getAllAttribute() {
        if (attrItems == null) {
            R<List<AttributeVO>> R = attributeClient.getAll();
            attrItems=R.getData();
            List<AttributeVO> var4;
            int var3 = (var4 = attrItems).size();
            for(int var2 = 0; var2 < var3; ++var2) {
                AttributeVO attrItem = var4.get(var2);
                attrItemMap.put(attrItem.getName(), attrItem);
            }
        }
    }
    public int isAttrValValid(String attrName, String attrVal) {
//        if (!BusinessConstants.BO_CONSTANTS.containsKey(attrName.toUpperCase())) {
            if (attrVal != null && !attrVal.trim().equals("")) {
                this.getAllAttribute();
                AttributeVO attributeVO = (AttributeVO)attrItemMap.get(attrName);
                if (attributeVO == null) {
                    return 0;
                } else {
                    String attrType = attributeVO.getTypeKey();
                    int rs;
                    if (attrType.equals("VTString")) {
                    //    rs = this.checkVTStringValValid(attributeVO, attrName, attrVal);
                        rs = 0;
                    } else if (attrType.equals("VTInteger")) {
                    //    rs = this.checkVTIntegerValValid(attributeVO, attrName, attrVal);
                        rs = 0;
                    } else if (attrType.equals("VTLong")) {
                    //    rs = this.checkVTLongValValid(attributeVO, attrName, attrVal);
                        rs = 0;
                    } else if (attrType.equals("VTDouble")) {
                    //    rs = this.checkVTDoubleValValid(attributeVO, attrName, attrVal);
                        rs = 0;
                    } else if (attrType.equals("VTBoolean")) {
                        rs = 0;
                    } else if (attrType.equals("VTImage")) {
                        rs = 0;
                    } else if (attrType.equals("VTDate")) {
                        rs = 0;
                    } else if (attrType.equals("VTTime")) {
                        rs = 0;
                    } else if (attrType.equals("VTDateTime")) {
                        rs = 0;
                    } else if (attrType.equals("VTNote")) {
                        rs = 0;
                    } else if (attrType.equals("VTFilePath")) {
                        rs = 0;
                    } else {
                        rs = 0;
                    }
                    return rs;
                }
            } else {
                return 0;
            }
//        } else {
//            return 0;
//        }
    }
    /*private int checkVTStringValValid(AttributeVO attributeVO, String attrName, String attrVal) {
        String other ="";
        int maxLength = Integer.valueOf(Tool.getOtherValueByType(other, "length"));
        int length = attrVal.length();
        return length > maxLength ? 1 : 0;
    }
    private int checkVTIntegerValValid(AttributeVO attributeVO, String attrName, String attrVal) {
        VTInteger obj = new VTInteger(Integer.valueOf(attrVal));
        return !obj.checkRageValueByRage(attributeVO.rage) ? 2 : 0;
    }
    private int checkVTLongValValid(AttributeVO attributeVO, String attrName, String attrVal) {
        VTLong obj = new VTLong(Long.valueOf(attrVal));
        return !obj.checkRageValueByRage(attributeVO.rage) ? 2 : 0;
    }
    private int checkVTDoubleValValid(AttributeVO attributeVO, String attrName, String attrVal) {
        VTDouble obj = new VTDouble(Double.valueOf(attrVal));
        String other = attributeVO.other;
        int maxLength = Integer.valueOf(Tool.getOtherValueByType(other, "length"));
        int length = String.valueOf(attrVal).length() - 1;
        if (length >= maxLength && !obj.checkRageValueByRage(attributeVO.rage)) {
            return 3;
        } else if (!obj.checkRageValueByRage(attributeVO.rage)) {
            return 2;
        } else {
            return length >= maxLength ? 1 : 0;
        }
    }*/
}
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/util/ClientBusinessObject.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,110 @@
package com.vci.ubcs.code.util;
import com.vci.ubcs.code.bo.AttributeValue;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.revision.model.BaseModel;
import lombok.Data;
import java.util.ArrayList;
@Data
public class ClientBusinessObject extends BaseModel {
    public AttributeValue[] newAttrValList;
    public AttributeValue[] hisAttrValList;
    public void setAttributeValue(String attributeName, String attributeValue) throws VciBaseException {
        this.setAttributeValue(attributeName, attributeValue, false);
    }
    public void setAttributeValue(String attributeName, String attributeValue, boolean isCreate) throws VciBaseException {
        int isValid = (new AttributeChecker()).isAttrValValid(attributeName, attributeValue);
        if (isValid == 1) {
            throw getLocalError("P0010SOF-00017", new String[]{attributeName, attributeValue});
        } else if (isValid == 2) {
            throw this.getLocalError("P0010SOF-00018", new String[]{attributeName, attributeValue});
        } else if (isValid == 3) {
            throw this.getLocalError("P0010SOF-00019", new String[]{attributeName, attributeValue});
        } else {
            this.setAttributeValueWithNoCheck(attributeName, attributeValue, isCreate);
        }
    }
    public void setAttributeValueWithNoCheck(String attributeName, String attributeValue) throws VciBaseException {
        this.setAttributeValueWithNoCheck(attributeName, attributeValue, false);
    }
    public void setAttributeValueWithNoCheck(String attributeName, String attributeValue, boolean isCreate) throws VciBaseException {
        /*if (isCreate) {//&& BusinessConstants.BO_CONSTANTS.containsKey(attributeName.toUpperCase())
            this.setConstantsAttrVal(attributeName, attributeValue);
        } else {*/
            AttributeValue[] attrValues = this.newAttrValList;
            ArrayList<AttributeValue> attrValList = new ArrayList();
            AttributeValue attrVal;
            int i;
            if (attrValues != null && attrValues.length > 0) {
                AttributeValue[] var9 = attrValues;
                i = attrValues.length;
                for(int var7 = 0; var7 < i; ++var7) {
                    attrVal = var9[var7];
                    attrValList.add(attrVal);
                }
            }
            attrVal = null;
            boolean isExist = false;
            for(i = 0; i < attrValList.size(); ++i) {
                attrVal = (AttributeValue)attrValList.get(i);
                if (attrVal.attrName.toUpperCase().equals(attributeName.toUpperCase())) {
                    attrVal.attrVal = attributeValue;
                    isExist = true;
                    break;
                }
            }
            if (!isExist) {
                attrVal = new AttributeValue();
                attrVal.attrName = attributeName.toUpperCase();
                attrVal.attrVal = attributeValue;
                attrValList.add(attrVal);
            }
            this.newAttrValList = (AttributeValue[])attrValList.toArray(new AttributeValue[attrValList.size()]);
    //    }
    }
    public String getAttributeValue(String attrName) {
        String res = "";
        boolean existInNewAttr = false;
        int i;
        if (this.newAttrValList != null) {
            for(i = 0; i < this.newAttrValList.length; ++i) {
                if (this.newAttrValList[i].attrName.toUpperCase().equals(attrName.toUpperCase())) {
                    existInNewAttr = true;
                    res = this.newAttrValList[i].attrVal;
                }
            }
        }
        if (existInNewAttr) {
            return res;
        } else if (this.hisAttrValList == null) {
            return "";
        } else {
            for(i = 0; i < this.hisAttrValList.length; ++i) {
                if (this.hisAttrValList[i].attrName.toUpperCase().equals(attrName.toUpperCase())) {
                    res = this.hisAttrValList[i].attrVal;
                }
            }
            return res;
        }
    }
    public VciBaseException getLocalError(String error_code ,String[] error_messages) {
        return new VciBaseException(error_code, error_messages);
    }
}
Source/UBCS/ubcs-service/ubcs-omd/pom.xml
@@ -75,6 +75,12 @@
            <version>3.0.1.RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.vci.ubcs</groupId>
            <artifactId>ubcs-user-api</artifactId>
            <version>3.0.1.RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <build>
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/controller/AttributeController.java
@@ -134,15 +134,15 @@
    /**
     * åˆ é™¤
     * @param ids ä¸»é”®é›†åˆ
     * @param oid ä¸»é”®é›†åˆ
     * @return æ‰§è¡Œç»“æžœ
     */
    @PostMapping("/remove")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "删除", notes = "主键集合")
    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String oid) {
        CacheUtil.clear(OmdCacheConstant.ATTR_CACHE);
        return R.status(attributeService.removeAttrs(ids));
        return attributeService.remove(oid);
    }
    /**
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/controller/RevisionRuleController.java
@@ -1,5 +1,6 @@
package com.vci.ubcs.omd.controller;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.vci.ubcs.omd.dto.RevisionRuleDTO;
@@ -12,11 +13,14 @@
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.util.List;
import java.util.Map;
/**
 * Description: ç‰ˆæœ¬è§„则控制器
@@ -49,8 +53,8 @@
    @GetMapping("page")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "分页查询版本规则",notes = "分页查询版本规则")
    public R<IPage<RevisionRuleVO>> page(BaseQueryObject baseQueryObject){
        return R.data(revisionRuleService.pageQueryVO(baseQueryObject));
    public R<IPage<RevisionRuleVO>> page(@ApiIgnore @RequestParam Map<String, Object> condition, Query query){
        return R.data(revisionRuleService.pageQueryVO(condition,query));
    }
    /**
@@ -60,7 +64,11 @@
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "新增或修改",notes = "传入版本规则页面对象")
    public R<RevisionRuleVO> submit(@RequestBody RevisionRuleDTO ruleDTO){
        return R.data(revisionRuleService.addSave(ruleDTO));
        if (StringUtils.isBlank(ruleDTO.getOid())) {
            return R.data(revisionRuleService.addSave(ruleDTO));
        }else {
            return R.data(revisionRuleService.editSave(ruleDTO));
        }
    }
    /**
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/controller/StatusController.java
@@ -1,5 +1,6 @@
package com.vci.ubcs.omd.controller;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.vci.ubcs.omd.entity.Status;
@@ -11,9 +12,11 @@
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.util.HashMap;
import java.util.List;
@@ -50,12 +53,8 @@
    @GetMapping("page")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "分页查询状态池",notes = "分页查询状态池")
    public R<IPage<StatusVO>> page(BaseQueryObject baseQueryObject){
        Map<String, String> conditionMap = baseQueryObject.getConditionMap();
        if (conditionMap == null){
            conditionMap = new HashMap<>();
        }
        return R.data(statusService.listStatus(conditionMap,baseQueryObject.getPageHelper()));
    public R<IPage<StatusVO>> page(@ApiIgnore @RequestParam Map<String, Object> condition, Query query){
        return R.data(statusService.listStatus(condition,query));
    }
    /**
@@ -65,7 +64,11 @@
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "新增或修改",notes = "传入状态池页面对象")
    public R<StatusVO> submit(@RequestBody StatusVO statusVO){
        return R.data(statusService.addSave(statusVO));
        if (StringUtils.isBlank(statusVO.getOid())){
            return R.data(statusService.addSave(statusVO));
        }else {
            return R.data(statusService.editSave(statusVO));
        }
    }
    /**
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/feign/RevisionRuleClient.java
@@ -13,6 +13,7 @@
import org.springblade.core.mp.support.Query;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -54,7 +55,16 @@
    @GetMapping(GET_REF_PAGE)
    @Override
    public R<IPage<RevisionRuleVO>> getRefPage(BaseQueryObject baseQueryObject) {
        return R.data(service.pageQueryVO(baseQueryObject));
        Map<String, String> conditionMap = baseQueryObject.getConditionMap();
        if (conditionMap == null){
            conditionMap = new HashMap<>();
        }
        Query query = new Query();
        query.setSize(baseQueryObject.getLimit());
        query.setCurrent(baseQueryObject.getPage());
        Map<String,Object> condition = new HashMap<>();
        BeanUtil.copy(conditionMap,condition);
        return R.data(service.pageQueryVO(condition,query));
    }
    /**
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/feign/StatusClient.java
@@ -8,8 +8,10 @@
import com.vci.ubcs.starter.web.pagemodel.BaseQueryObject;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.web.bind.annotation.RestController;
@@ -44,7 +46,12 @@
        if (conditionMap == null) {
            conditionMap = new HashMap<>(16);
        }
        return R.data(service.listStatus(conditionMap,baseQueryObject.getPageHelper()));
        Map<String,Object> condition = new HashMap<>();
        BeanUtil.copy(conditionMap,condition);
        Query query = new Query();
        query.setCurrent(baseQueryObject.getPage());
        query.setSize(baseQueryObject.getLimit());
        return R.data(service.listStatus(condition,query));
    }
    /**
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/feign/WebSecretClient.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,111 @@
/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill åº„骞 (smallchill@163.com)
 */
package com.vci.ubcs.omd.feign;
import com.vci.ubcs.omd.service.IWebSecretService;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.system.user.vo.UserVO;
import lombok.AllArgsConstructor;
import org.springblade.core.tool.api.R;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;
/**
 * æžšä¸¾å®šä¹‰ Feign实现类
 *
 * @author yuxc
 * @since 2023-05-08
 */
@ApiIgnore()
@RestController
@AllArgsConstructor
public class WebSecretClient implements IWebSecretClient {
    IWebSecretService webSecretService;
    @Override
    public R<Integer> getMinUserSecret() throws VciBaseException {
        return R.data(webSecretService.getMinUserSecret());
    }
    @Override
    public R<Integer> getMinDataSecret() throws VciBaseException {
        return R.data(webSecretService.getMinDataSecret());
    }
    @Override
    public R<Integer> getMinIpSecret() throws VciBaseException {
        return R.data(webSecretService.getMinIpSecret());
    }
    @Override
    public R<Integer> getUserSecret(String userId) throws VciBaseException {
        return R.data(webSecretService.getUserSecret(userId));
    }
    @Override
    public R<Integer> getUserSecret(UserVO userVO) throws VciBaseException {
        return R.data(webSecretService.getUserSecret(userVO));
    }
    @Override
    public R<Boolean> checkDataSecret(int secret) {
        return R.data(webSecretService.checkDataSecret(secret));
    }
    @Override
    public R<Boolean> checkDataSecret(int secret, int userSecret) {
        return R.data(webSecretService.checkDataSecret(secret,userSecret));
    }
    @Override
    public R<Boolean> checkDataSecret(int secret, String userId) throws VciBaseException {
        return R.data(webSecretService.checkDataSecret(secret,userId));
    }
    @Override
    public R<Boolean> checkDataSecret(int secret, UserVO userVO) {
        return R.data(webSecretService.checkDataSecret(secret,userVO));
    }
    @Override
    public R<Integer> getIpSecret(String ip) throws VciBaseException {
        return R.data(webSecretService.getIpSecret(ip));
    }
    @Override
    public R<Boolean> checkIpSecret(int ipSecret, int userSecret) {
        return R.data(webSecretService.checkIpSecret(ipSecret,userSecret));
    }
    @Override
    public R<Boolean> checkIpSecret(int ipSecret) {
        return R.data(webSecretService.checkIpSecret(ipSecret));
    }
    @Override
    public R<Boolean> checkIpSecret(String ip, String userId) throws VciBaseException {
        return R.data(webSecretService.checkIpSecret(ip,userId));
    }
    @Override
    public R<Boolean> checkIpSecret(String ip, UserVO userVO) {
        return R.data(webSecretService.checkIpSecret(ip,userVO));
    }
}
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/mapper/RevisionRuleMapper.java
@@ -3,6 +3,9 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.vci.ubcs.omd.entity.RevisionRule;
import java.util.Collection;
import java.util.List;
/**
 * Description: ç‰ˆæœ¬è§„则数据层
 *
@@ -11,4 +14,10 @@
 */
public interface RevisionRuleMapper extends BaseMapper<RevisionRule> {
    /**
     * æŒ‰ç¼–号忽略大小写查询
     * @param records è®°å½•
     * @return
     */
    List<RevisionRule> selectByIdIgnoreCase(Collection<String> records);
}
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/mapper/StatusMapper.java
@@ -3,6 +3,9 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.vci.ubcs.omd.entity.Status;
import java.util.Collection;
import java.util.List;
/**
 * Description: çŠ¶æ€æ± æ•°æ®å±‚
 *
@@ -10,4 +13,10 @@
 * @date 2023/5/23
 */
public interface StatusMapper extends BaseMapper<Status> {
    /**
     * å¿½ç•¥å¤§å°å†™çš„æŸ¥è¯¢
     * @param records
     * @return
     */
    List<Status> selectByIdIgnoreCase(Collection<String> records);
}
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/IAttributeService.java
@@ -7,6 +7,7 @@
import com.vci.ubcs.omd.vo.BtmTypeVO;
import com.vci.ubcs.starter.exception.VciBaseException;
import org.springblade.core.mp.base.BaseService;
import org.springblade.core.tool.api.R;
import java.util.Collection;
import java.util.List;
@@ -84,4 +85,12 @@
     * @throws VciBaseException ä¸ç¬¦åˆæ—¶æŠ›å‡ºå¼‚常
     */
    boolean checkAttribute(BtmTypeLinkAttributesDTO attributesDTO) throws VciBaseException;
    /**
     * å•个删除
     *
     * @param oid ä¸»é”®
     * @return æ‰§è¡Œç»“æžœ
     */
    R remove(String oid);
}
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/IRevisionRuleService.java
@@ -182,11 +182,12 @@
    /**
     * åˆ†é¡µæŸ¥è¯¢
     * @param baseQueryObject æŸ¥è¯¢å¯¹è±¡
     * @param query åˆ†é¡µ
     * @param condition æŸ¥è¯¢æ¡ä»¶
     * @return æŸ¥è¯¢ç»“æžœ
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™æ—¶æŠ›å‡ºå¼‚常
     */
    IPage<RevisionRuleVO> pageQueryVO(BaseQueryObject baseQueryObject) throws VciBaseException;
    IPage<RevisionRuleVO> pageQueryVO(Map<String, Object> condition, Query query) throws VciBaseException;
    /**
     * æŸ¥çœ‹åº”用范围
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/IStatusService.java
@@ -5,7 +5,7 @@
import com.vci.ubcs.omd.entity.Status;
import com.vci.ubcs.omd.vo.StatusVO;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.web.pagemodel.PageHelper;
import org.springblade.core.mp.support.Query;
import java.util.Collection;
import java.util.List;
@@ -26,7 +26,7 @@
     * @return çŠ¶æ€å¯¹è±¡åˆ—è¡¨
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™æ—¶ä¼šæŠ›å‡ºå¼‚常
     */
    IPage<StatusVO> listStatus(Map<String,String> conditionMap, PageHelper pageHelper) throws VciBaseException;
    IPage<StatusVO> listStatus(Map<String, Object> conditionMap, Query pageHelper) throws VciBaseException;
    /**
     * èŽ·å–çŠ¶æ€åˆ—è¡¨
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/IWebSecretService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,120 @@
package com.vci.ubcs.omd.service;
import com.vci.ubcs.code.vo.pagemodel.SmUserVO;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.system.user.vo.UserVO;
/**
 * web端的密级服务
 */
public interface IWebSecretService {
    /**
     * èŽ·å–ç”¨æˆ·å¯†çº§çš„æœ€å°å€¼
     * @return å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    int getMinUserSecret() throws VciBaseException;
    /**
     * èŽ·å–æ•°æ®å¯†çº§çš„é»˜è®¤å€¼
     * @return å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    int getMinDataSecret() throws VciBaseException;
    /**
     * èŽ·å–IP密级的默认值
     * @return å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    int getMinIpSecret() throws VciBaseException;
    /**
     * èŽ·å–ç”¨æˆ·å¯†çº§
     * @param userId ç”¨æˆ·ä¸»é”®
     * @return ç”¨æˆ·çš„密级
     * @throws VciBaseException å‚数错误,用户不存在会抛出异常
     */
    int getUserSecret(String userId) throws VciBaseException ;
    /**
     * èŽ·å–ç”¨æˆ·å¯†çº§
     * @param userVO ç”¨æˆ·çš„æ˜¾ç¤ºå¯¹è±¡
     * @return ç”¨æˆ·çš„密级
     * @throws VciBaseException å‚数错误,用户不存在会抛出异常
     */
    int getUserSecret(UserVO userVO) throws VciBaseException;
    /**
     * æ ¡éªŒå½“前用户是否有权限访问数据
     * @param secret æ•°æ®çš„密级
     * @return true表示允许访问
     */
    boolean checkDataSecret(int secret);
    /**
     * æ ¡éªŒç”¨æˆ·çš„密级是否是否有权限访问数据
     * @param secret æ•°æ®çš„密级
     * @param userSecret ç”¨æˆ·å¯†çº§
     * @return true表示允许访问
     */
    boolean checkDataSecret(int secret, int userSecret) ;
    /**
     * æ ¹æ®ç”¨æˆ·åæ¥æ ¡éªŒæ•°æ®å¯†çº§
     * @param secret æ•°æ®çš„密级
     * @param userId ç”¨æˆ·å
     * @return true表示允许访问
     * @throws VciBaseException å‚数错误,用户不存在会抛出异常
     */
    boolean checkDataSecret(int secret, String userId) throws VciBaseException;
    /**
     * æ ¹æ®ç”¨æˆ·å¯¹è±¡æ¥æ ¡éªŒæ•°æ®å¯†çº§
     * @param secret  æ•°æ®çš„密级
     * @param userVO ç”¨æˆ·çš„æ˜¾ç¤ºå¯¹è±¡
     * @return true表示允许访问
     */
    boolean checkDataSecret(int secret, UserVO userVO) ;
    /**
     * èŽ·å–IP地址的密级
     * @param ip ip地址
     * @return å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™çš„æ—¶å€™ä¼šæŠ›å‡ºå¼‚常
     */
    int getIpSecret(String ip) throws VciBaseException;
    /**
     * æ£€æŸ¥æœºå™¨å¯†çº§
     * @param ipSecret æœºå™¨å¯†çº§
     * @param userSecret ç”¨æˆ·çš„密级
     * @return å¯†çº§çš„值
     */
    boolean checkIpSecret(int ipSecret, int userSecret);
    /**
     * æ£€æŸ¥å½“前用户是否符合机器密级
     * @param ipSecret æœºå™¨å¯†çº§
     * @return true表示允许访问
     */
    boolean checkIpSecret(int ipSecret) ;
    /**
     * æ ¡éªŒæŒ‡å®šip和用户是否符合机器密级
     * @param ip ip地址
     * @param userId ç”¨æˆ·å
     * @return true表示允许访问
     * @throws VciBaseException å‚数错误,用户不存在会抛出异常
     */
    boolean checkIpSecret(String ip, String userId) throws VciBaseException;
    /**
     * æ ¡éªŒæŒ‡å®šIP和用户对象符合机器密级
     * @param ip ip地址
     * @param userVO ç”¨æˆ·å¯¹è±¡
     * @return  true表示允许访问
     */
    boolean checkIpSecret(String ip, UserVO userVO) ;
}
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/impl/AttributeServiceImpl.java
@@ -4,15 +4,12 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.vci.ubcs.omd.constant.OmdCacheConstant;
import com.vci.ubcs.omd.dto.AttributeDTO;
import com.vci.ubcs.omd.dto.BtmTypeLinkAttributesDTO;
import com.vci.ubcs.omd.entity.Attribute;
import com.vci.ubcs.omd.entity.BtmType;
import com.vci.ubcs.omd.entity.BtmTypeAttribute;
import com.vci.ubcs.omd.mapper.AttributeMapper;
import com.vci.ubcs.omd.mapper.BtmTypeMapper;
import com.vci.ubcs.omd.service.IAttributeService;
import com.vci.ubcs.omd.vo.AttributeVO;
import com.vci.ubcs.omd.vo.BtmTypeVO;
@@ -24,14 +21,11 @@
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.Collection;
@@ -82,13 +76,14 @@
     */
    @Override
    public boolean submit(AttributeDTO dto) {
        VciBaseUtil.alertNotNull(dto.getId(),"属性编号",dto.getName(),"属性名称",dto.getTypeKey(),"属性类型",dto.getMaxLength(),"属性长度");
        if (!Pattern.compile(REGEXP).matcher(dto.getId()).matches()){
            throw new VciBaseException("属性名称{0}只能是英文",new Object[]{dto.getId()});
            throw new VciBaseException("属性编号{0}只能是英文",new Object[]{dto.getId()});
        }
        LambdaQueryWrapper<Attribute> wrapper = Wrappers.<Attribute>query().lambda().eq(Attribute::getId, dto.getId());
        Long count = baseMapper.selectCount((Func.isEmpty(dto.getOid())) ? wrapper : wrapper.notIn(Attribute::getOid, dto.getOid()));
        if (count > 0L) {
            throw new ServiceException("属性名已存在!");
            throw new ServiceException("属性编号已存在!");
        }
        Attribute attribute = AttributeWrapper.build().copyBeforeSave(dto);
        CacheUtil.clear(OmdCacheConstant.ATTR_CACHE);
@@ -98,13 +93,17 @@
    /**
     * åˆ é™¤
     *
     * @param ids ä¸»é”®é›†åˆ
     * @param oids ä¸»é”®é›†åˆ
     * @return æ‰§è¡Œç»“æžœ
     */
    @Override
    public boolean removeAttrs(String ids) {
        List<Long> idList = Func.toLongList(ids);
        return !deleteLogic(idList) && removeByIds(idList);
    public boolean removeAttrs(String oids) {
        List<String> oidList = Func.toStrList(",", oids);
        List<Attribute> list = list(Wrappers.<Attribute>query().lambda().in(Attribute::getOid, oidList));
        if (!CollectionUtils.isEmpty(list)){
            baseMapper.delete(Wrappers.<Attribute>query().lambda().in(Attribute::getOid,list.stream().map(Attribute::getOid).collect(Collectors.toList())));
        }
        return true;
    }
    /**
@@ -243,4 +242,20 @@
        }
        return pass;
    }
    /**
     * å•个删除
     *
     * @param oid ä¸»é”®
     * @return æ‰§è¡Œç»“æžœ
     */
    @Override
    public R remove(String oid) {
        List<BtmTypeVO> vos = applyRange(oid);
        if (CollectionUtils.isEmpty(vos)){
             return R.status(removeAttrs(oid));
        }else {
            return R.fail("该属性已被使用,不允许删除");
        }
    }
}
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/impl/RevisionRuleServiceImpl.java
@@ -148,8 +148,7 @@
    @Override
    public List<RevisionRuleVO> listRevisionRuleByIdCollection(Collection<String> revisionRuleIdCollection) throws VciBaseException {
        VciBaseUtil.alertNotNull(revisionRuleIdCollection,"英文名称集合");
//        return RevisionRuleWrapper.build().listVO(list(MybatisParameterUtil.cutInParameter(Wrappers.<RevisionRule>query().lambda(),RevisionRule::getId, Collections.singletonList(revisionRuleIdCollection))));
        List<RevisionRule> list = baseMapper.selectList(Wrappers.<RevisionRule>query().lambda().in(RevisionRule::getId, revisionRuleIdCollection));
        List<RevisionRule> list = baseMapper.selectByIdIgnoreCase(revisionRuleIdCollection);
        return RevisionRuleWrapper.build().listVO(list);
    }
@@ -545,20 +544,8 @@
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™æ—¶æŠ›å‡ºå¼‚常
     */
    @Override
    public IPage<RevisionRuleVO> pageQueryVO(BaseQueryObject baseQueryObject) throws VciBaseException {
        Map<String, String> conditionMap = baseQueryObject.getConditionMap();
        if (conditionMap == null){
            conditionMap = new HashMap<>();
        }
        PageHelper pageHelper = baseQueryObject.getPageHelper();
        Query query = new Query();
        query.setCurrent(pageHelper.getPage());
        query.setSize(pageHelper.getLimit());
        query.setAscs(pageHelper.getSort());
        RevisionRule queryConditionObj = new RevisionRule();
        BeanMap beanMap = BeanMap.create(queryConditionObj);
        beanMap.putAll(conditionMap);
        return RevisionRuleWrapper.build().pageVO(baseMapper.selectPage(Condition.getPage(query),Condition.getQueryWrapper(queryConditionObj).lambda().orderByAsc(RevisionRule::getId)));
    public IPage<RevisionRuleVO> pageQueryVO(Map<String, Object> condition, Query query) throws VciBaseException {
        return RevisionRuleWrapper.build().pageVO(baseMapper.selectPage(Condition.getPage(query),Condition.getQueryWrapper(condition,RevisionRule.class).lambda().orderByAsc(RevisionRule::getId)));
    }
    /**
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/impl/StatusServiceImpl.java
@@ -11,7 +11,6 @@
import com.vci.ubcs.omd.vo.StatusVO;
import com.vci.ubcs.omd.wrapper.StatusWrapper;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.web.pagemodel.PageHelper;
import com.vci.ubcs.starter.web.util.BeanUtil;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import org.springblade.core.mp.support.Condition;
@@ -46,14 +45,8 @@
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™æ—¶ä¼šæŠ›å‡ºå¼‚常
     */
    @Override
    public IPage<StatusVO> listStatus(Map<String, String> conditionMap, PageHelper pageHelper) throws VciBaseException {
        Query query = new Query();
        query.setCurrent(pageHelper.getPage());
        query.setSize(pageHelper.getLimit());
        query.setAscs("id");
        Status queryVO = new Status();
        BeanMap.create(queryVO).putAll(conditionMap);
        return StatusWrapper.build().pageVO(baseMapper.selectPage(Condition.getPage(query), Condition.getQueryWrapper(queryVO).lambda().orderByAsc(Status::getId)));
    public IPage<StatusVO> listStatus(Map<String, Object> conditionMap, Query pageHelper) throws VciBaseException {
        return StatusWrapper.build().pageVO(baseMapper.selectPage(Condition.getPage(pageHelper), Condition.getQueryWrapper(conditionMap,Status.class).lambda().orderByAsc(Status::getId)));
    }
    /**
@@ -203,7 +196,7 @@
        Collection<Collection<String>> idCollections = VciBaseUtil.switchCollectionForOracleIn(idCollection);
        if(!CollectionUtils.isEmpty(idCollections)) {
            idCollections.forEach(s -> {
                List<Status> queryResult = baseMapper.selectList(Wrappers.<Status>query().lambda().in(Status::getId,s));
                List<Status> queryResult = baseMapper.selectByIdIgnoreCase(s);
                if(!CollectionUtils.isEmpty(queryResult)){
                    statusDOList.addAll(queryResult);
                }
Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/impl/WebSecretServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,376 @@
package com.vci.ubcs.omd.service.impl;
import com.vci.ubcs.common.utils.CommonUtil;
import com.vci.ubcs.omd.cache.EnumCache;
import com.vci.ubcs.omd.service.IWebSecretService;
import com.vci.ubcs.omd.utils.VciOmdUtil;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.web.constant.EnumIdConstant;
import com.vci.ubcs.starter.web.enumpck.DataSecretEnum;
import com.vci.ubcs.starter.web.enumpck.UserSecretEnum;
import com.vci.ubcs.starter.web.pagemodel.KeyValue;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import com.vci.ubcs.starter.web.util.WebUtil;
import com.vci.ubcs.system.user.entity.User;
import com.vci.ubcs.system.user.feign.IUserClient;
import com.vci.ubcs.system.user.vo.UserVO;
import net.logstash.logback.encoder.org.apache.commons.lang3.StringUtils;
import org.springblade.core.tool.api.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.vci.ubcs.starter.web.constant.FrameWorkBusLangCodeConstant.DATA_ID_NOT_EXIST;
/**
 * å¯†çº§çš„æœåŠ¡
 * @author weidy
 * @date 2021-2-16
 */
@Service
public class WebSecretServiceImpl implements IWebSecretService {
    /**
     * ç”¨æˆ·æŸ¥è¯¢æœåŠ¡
     */
    @Autowired
    private IUserClient userClient;
    /**
     * ä¸šåŠ¡ç±»åž‹æœåŠ¡
     */
//    @Autowired
//    private WebBoServiceI boService;
    /**
     * å±žæ€§çš„对象
     */
//    @Autowired
//    private WebProperties properties;
    /**
     * èŽ·å–ç”¨æˆ·å¯†çº§çš„æœ€å°å€¼
     *
     * @return å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    @Override
    public int getMinUserSecret() throws VciBaseException {
        List<KeyValue> enumKeyValueList = VciOmdUtil.enumsToListKeyVale(EnumCache.getList(EnumIdConstant.USERSECRET_ENUMNAME));
//            enumService.getEnum(EnumIdConstant.USERSECRET_ENUMNAME);
        //重新设置枚举的值
        if(!CollectionUtils.isEmpty(enumKeyValueList)){
            List<KeyValue> keyValues = enumKeyValueList.stream().sorted((a, b) -> ((Integer) VciBaseUtil.getInt(a.getKey())).compareTo((Integer) VciBaseUtil.getInt(b.getKey()))).collect(Collectors.toList());
            for(int i = 0 ; i < keyValues.size() ; i++){
                KeyValue keyValue = keyValues.get(i);
                if(i ==0){
                    UserSecretEnum.NONE.setValue(VciBaseUtil.getInt(keyValue.getKey()));
                    UserSecretEnum.NONE.setText(keyValue.getValue());
                }else if(i ==1){
                    UserSecretEnum.SECRET.setValue(VciBaseUtil.getInt(keyValue.getKey()));
                    UserSecretEnum.SECRET.setText(keyValue.getValue());
                }else{
                    UserSecretEnum.PRIVACY.setValue(VciBaseUtil.getInt(keyValue.getKey()));
                    UserSecretEnum.PRIVACY.setText(keyValue.getValue());
                }
            }
        }
        return getMinValueInKeyValueList(enumKeyValueList,UserSecretEnum.NONE.getValue());
    }
    /**
     * èŽ·å–æžšä¸¾ä¸­çš„æœ€å°å€¼
     * @param enumKeyValueList æžšä¸¾K-V列表
     * @param minValue æœ€å°å€¼
     * @return æœ€å°å€¼
     */
    private int getMinValueInKeyValueList(  List<KeyValue> enumKeyValueList,int minValue){
        for(KeyValue ec : enumKeyValueList){
            int value = VciBaseUtil.getInt(ec.getKey());
            if(minValue> value){
                minValue = value;
            }
        }
        return minValue;
    }
    /**
     * èŽ·å–æ•°æ®å¯†çº§çš„é»˜è®¤å€¼
     *
     * @return æœ€å°å¯†çº§çš„值
     * @throws VciBaseException  æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    @Override
    public int getMinDataSecret() throws VciBaseException {
        List<KeyValue> enumKeyValueList = VciOmdUtil.enumsToListKeyVale(EnumCache.getList(EnumIdConstant.DATASECRET_ENUMNAME));
        //重新设置枚举的值
        if(!CollectionUtils.isEmpty(enumKeyValueList)){
            List<KeyValue> keyValues = enumKeyValueList.stream().sorted((a, b) -> ((Integer) VciBaseUtil.getInt(a.getKey())).compareTo((Integer) VciBaseUtil.getInt(b.getKey()))).collect(Collectors.toList());
            for(int i = 0 ; i < keyValues.size() ; i++){
                KeyValue keyValue = keyValues.get(i);
                if(i ==0){
                    DataSecretEnum.NONE.setValue(VciBaseUtil.getInt(keyValue.getKey()));
                    DataSecretEnum.NONE.setText(keyValue.getValue());
                }else if(i ==1){
                    DataSecretEnum.INNER.setValue(VciBaseUtil.getInt(keyValue.getKey()));
                    DataSecretEnum.INNER.setText(keyValue.getValue());
                }else if(i ==2){
                    DataSecretEnum.SECRET.setValue(VciBaseUtil.getInt(keyValue.getKey()));
                    DataSecretEnum.SECRET.setText(keyValue.getValue());
                }else{
                    DataSecretEnum.PRIVACY.setValue(VciBaseUtil.getInt(keyValue.getKey()));
                    DataSecretEnum.PRIVACY.setText(keyValue.getValue());
                }
            }
        }
        return getMinValueInKeyValueList(enumKeyValueList,DataSecretEnum.NONE.getValue());
    }
    /**
     * èŽ·å–IP密级的默认值
     *
     * @return æœ€å°å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    @Override
    public int getMinIpSecret() throws VciBaseException {
        List<KeyValue> enumKeyValueList = VciOmdUtil.enumsToListKeyVale(EnumCache.getList(EnumIdConstant.IPSECRET_ENUMNAME));
        return getMinValueInKeyValueList(enumKeyValueList,10);
    }
    /**
     * èŽ·å–ç”¨æˆ·å¯†çº§
     *
     * @param userId ç”¨æˆ·å
     * @return ç”¨æˆ·å¯†çº§çš„值,如果没有密级,默认为最小密级
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    @Override
    public int getUserSecret(String userId) throws VciBaseException {
        WebUtil.alertNotNull(userId,"用户名");
        R<User> userR = userClient.userInfoById(Long.valueOf(userId));
        if(userR.getData() == null){
            throw new VciBaseException(DATA_ID_NOT_EXIST,new String[]{userId});
        }
        return userR.getData().getSecretGrade()==null?getMinUserSecret():Integer.parseInt(userR.getData().getSecretGrade());
    }
    /**
     * èŽ·å–ç”¨æˆ·å¯†çº§
     *
     * @param userVO ç”¨æˆ·çš„对象
     * @return å¯†çº§ï¼Œä¸å­˜åœ¨çš„æ—¶å€™ä¸ºæœ€ä½Žå¯†çº§
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    @Override
    public int getUserSecret(UserVO userVO) throws VciBaseException {
        if(userVO == null){
            throw new VciBaseException(DATA_ID_NOT_EXIST,new String[0]);
        }
        return userVO.getSecretGrade()==null?getMinUserSecret(): Integer.valueOf(userVO.getSecretGrade());
    }
    /**
     * æ ¡éªŒå½“前用户是否有权限访问数据
     *
     * @param secret æ•°æ®çš„密级
     * @return true表示可以访问
     */
    @Override
    public boolean checkDataSecret(int secret) {
        return checkDataSecret(secret,WebUtil.getCurrentUserSecret()==null?getMinUserSecret():WebUtil.getCurrentUserSecret());
    }
    /**
     * èŽ·å–æ•°æ®æƒé™
     * @param secret æ•°æ®çš„密级的值
     * @return æ•°æ®å¯†çº§
     */
    private DataSecretEnum dataSecretForValue(int secret){
        for(DataSecretEnum de : DataSecretEnum.values()){
            if(de.getValue() == secret){
                return de;
            }
        }
        return null;
    }
    /**
     * ç”¨æˆ·çš„密级
     * @param userSecret ç”¨æˆ·çš„密级
     * @return å¯†çº§çš„对象
     */
    private UserSecretEnum userSecretForValue(int userSecret){
        for(UserSecretEnum ue : UserSecretEnum.values()){
            if(ue.getValue() == userSecret){
                return  ue;
            }
        }
        return null;
    }
    /**
     * æ ¡éªŒç”¨æˆ·çš„密级是否是否有权限访问数据
     *
     * @param secret     æ•°æ®çš„密级
     * @param userSecret ç”¨æˆ·å¯†çº§
     * @return true表示可以访问
     */
    @Override
    public boolean checkDataSecret(int secret, int userSecret){
        //可能被转换了下
        DataSecretEnum de = dataSecretForValue(secret);
        if(de == null){
            de = DataSecretEnum.NONE;
        }
        UserSecretEnum ue = userSecretForValue(userSecret);
        if(ue == null){
            ue = UserSecretEnum.NONE;
        }
        int reaySecret = 0;
        switch (de){
            case NONE:
                reaySecret=1;
                break;
            case INNER:
                reaySecret = 2;
                break;
            case SECRET:
                reaySecret = 3;
                break;
            default:
                reaySecret = 4;
                break;
        }
        int userReaySecret = 0;
        switch (ue){
            case NONE:
                userReaySecret = 1;
                break;
            case SECRET:
                userReaySecret = 3;
                break;
            default:
                userReaySecret = 4;
                break;
        }
        if(reaySecret> userReaySecret){
            return false;
        }else{
            return true;
        }
    }
    /**
     * æ ¹æ®ç”¨æˆ·åæ¥æ ¡éªŒæ•°æ®å¯†çº§
     *
     * @param secret æ•°æ®çš„密级
     * @param userId ç”¨æˆ·å
     * @return true表示可以访问
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    @Override
    public boolean checkDataSecret(int secret, String userId) throws VciBaseException {
        return checkDataSecret(secret,getUserSecret(userId));
    }
    /**
     * æ ¹æ®ç”¨æˆ·å¯¹è±¡æ¥æ ¡éªŒæ•°æ®å¯†çº§
     *
     * @param secret æ•°æ®å¯†çº§
     * @param userVO ç”¨æˆ·çš„对象
     * @return true表示可以访问
     */
    @Override
    public boolean checkDataSecret(int secret, UserVO userVO)  {
        return checkDataSecret(secret,getUserSecret(userVO));
    }
    /**
     * èŽ·å–IP地址的密级 æš‚时还未使用,数据库表也还未移植。
     *
     * @param ip ip地址
     * @return å¯†çº§çš„值
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™çš„æ—¶å€™ä¼šæŠ›å‡ºå¼‚常
     */
    @Override
    public int getIpSecret(String ip) throws VciBaseException {
        if(StringUtils.isBlank(ip)){
            return getMinIpSecret();
        }
        Map<String,String> conditionMap = new HashMap<String, String>();
        conditionMap.put("startip",ip.trim());
//        List<ClientBusinessObject> ipCbos = boService.queryCBO(EnumIdConstant.IPSECRET_BTMNAME,conditionMap,null, Arrays.asList(new String[]{"ipsecret"}));
        int ipSecret = 0;
//        if(ipCbos!=null&& ipCbos.size()>0){
//            ipSecret = WebUtil.getInt(ipCbos.get(0).getAttributeValue("ipsecret"));
//        }
        if(ipSecret == 0){
            ipSecret = getMinIpSecret();
        }
        return ipSecret;
    }
    /**
     * æ£€æŸ¥æœºå™¨å¯†çº§
     *
     * @param ipSecret   æœºå™¨å¯†çº§
     * @param userSecret ç”¨æˆ·çš„密级
     * @return true表示许可
     */
    @Override
    public boolean checkIpSecret(int ipSecret, int userSecret)  {
        if(ipSecret> userSecret){
            return false;
        }else{
            return true;
        }
    }
    /**
     * æ£€æŸ¥å½“前用户是否符合机器密级
     *
     * @param ipSecret æœºå™¨å¯†çº§
     * @return true表示许可
     */
    @Override
    public boolean checkIpSecret(int ipSecret) {
        return checkIpSecret(ipSecret,WebUtil.getCurrentUserSecret()==null?getMinUserSecret():WebUtil.getCurrentUserSecret());
    }
    /**
     * æ ¡éªŒæŒ‡å®šip和用户是否符合机器密级
     *
     * @param ip     ip地址
     * @param userId ç”¨æˆ·å
     * @return true表示许可
     * @throws VciBaseException æŸ¥è¯¢å‡ºé”™ä¼šæŠ›å‡ºå¼‚常
     */
    @Override
    public boolean checkIpSecret(String ip, String userId) throws VciBaseException {
        return checkIpSecret(getIpSecret(ip),getUserSecret(userId));
    }
    /**
     * æ ¡éªŒæŒ‡å®šIP和用户对象符合机器密级
     *
     * @param ip         ip地址
     * @param userVO ç”¨æˆ·å¯¹è±¡
     * @return true表示许可
     */
    @Override
    public boolean checkIpSecret(String ip, UserVO userVO) {
        return checkIpSecret(getIpSecret(ip),getUserSecret(userVO));
    }
}
Source/UBCS/ubcs-service/ubcs-omd/src/main/resources/mapper/RevisionRuleMapper.xml
@@ -29,4 +29,15 @@
        pl_omd_revision_rule
    </sql>
    <select id="selectByIdIgnoreCase" resultMap="BaseResultMap">
        select <include refid="base_query_column"/> from <include refid="tableName"/>
        where lower(id) in
        <foreach collection="records" item="item" index="arrayindex" open=" ( " close=")" >
            #{item,jdbcType=VARCHAR}
            <if test="(arrayindex != records.size() -1)">
                ,
            </if>
        </foreach>
    </select>
</mapper>
Source/UBCS/ubcs-service/ubcs-omd/src/main/resources/mapper/StatusMapper.xml
@@ -6,7 +6,7 @@
        <result column="id" jdbcType="VARCHAR" property="id" />
        <result column="name" jdbcType="VARCHAR" property="name" />
        <result column="description" jdbcType="VARCHAR" property="description" />
        <result column="btm_name" property="btmname" jdbcType="VARCHAR" />
        <result column="btm_name" property="btmName" jdbcType="VARCHAR" />
        <result column="owner" property="owner" jdbcType="VARCHAR" />
        <result column="creator" jdbcType="VARCHAR" property="creator" />
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
@@ -23,4 +23,15 @@
        pl_omd_status
    </sql>
    <select id="selectByIdIgnoreCase" resultMap="BaseResultMap">
        select <include refid="base_query_column"/> from <include refid="tableName"/>
                    where lower(id) in
        <foreach collection="records" item="item" index="arrayindex" open=" ( " close=")" >
            #{item,jdbcType=VARCHAR}
            <if test="(arrayindex != records.size() -1)">
                ,
            </if>
        </foreach>
    </select>
</mapper>
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/UserPwdstrategyController.java
@@ -13,6 +13,7 @@
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
/**
 * ç”¨æˆ·å¯†ç ç­–略关联(UserPwdstrategy)表控制层
Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/service/impl/UserServiceImpl.java
@@ -338,6 +338,7 @@
        boolean result = RegexUtil.find(regex, newPassword1);
        if(!result){
            throw new ServiceException("密码中只能存在【"+strategy.getCombinationNames()+"】中包含的字符!");
            //throw new ServiceException(resException);
        }
        //修改密码同时,改变用户信息中的密码修改状态字段,密码修改时间
        return this.update(Wrappers.<User>update().lambda()
Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/wrapper/UserWrapper.java
@@ -47,7 +47,7 @@
        List<String> roleName = SysCache.getRoleNames(user.getRoleId());
        List<String> deptName = SysCache.getDeptNames(user.getDeptId());
        List<String> postName = SysCache.getPostNames(user.getPostId());
        userVO.setTenantName(tenant.getTenantName());
        userVO.setTenantName(tenant==null?"":tenant.getTenantName());
        userVO.setRoleName(Func.join(roleName));
        userVO.setDeptName(Func.join(deptName));
        userVO.setPostName(Func.join(postName));