コミットを比較

...

232 コミット
master ... 4.0

作成者 SHA1 メッセージ 日付
  yaoq 25afb4a7fa 优化 2年前
  yaoq 8700a70365 优化 2年前
  yaoq 23b89a4518 优化 2年前
  yaoq 6574e4b142 优化 2年前
  yaoq b708a30061 优化 2年前
  lip be1cac9b87 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  FLYPHT 2c89970c44 修改 2年前
  FLYPHT 4a8a61c8a7 新增:开发手册 2年前
  yaoq a1af8a48a8 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  yaoq 6e8c81bda4 优化 2年前
  lip d2c33685de 导出excel 2年前
  lip 7953f3dc42 模型方法独立 2年前
  FLYPHT bf06300da5 优化数据权限 2年前
  FLYPHT 4be822f190 优化功能权限 2年前
  郑根木 16a1f3f446 flowInstance增加getProcDef,findActivity 2年前
  yaoq 0710dffb07 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  yaoq 6bb095c6c3 平谷政协 2年前
  lip 3013e3f394 模板模型构建BUG 2年前
  lip 1f11cc6911 模型调整、Excel工具类 2年前
  FLYPHT 2d7cd82bca 修复bug:HttpUtil中map转SwMap失败 2年前
  FLYPHT fd74334925 优化映射登录 2年前
  FLYPHT 0025ab376f 移除 2年前
  FLYPHT b93a3aa04d bug:非法前置引用 2年前
  FLYPHT ebb8c874a1 bug:非法前置引用 2年前
  FLYPHT fd34868657 新增:支持数据权限 2年前
  yaoq fd02a965b3 区划 2年前
  yaoq 012cd6fb46 数据权限 2年前
  yaoq 0df91d874d 数据权限 2年前
  yaoq c0928eaf33 数据权限 2年前
  yaoq 3fcbd59f0d 数据权限 2年前
  yaoq 73d3becb83 canal集成、数据权限 2年前
  yaoq 3bbcdf6522 canal集成、数据权限 2年前
  FLYPHT 517fdd41b5 新增单位权限 2年前
  FLYPHT 4c20b66809 bpm新增common包 2年前
  FLYPHT 3676bdb07e "/" 请求免登录 2年前
  FLYPHT ad78298d41 优化映射登录 2年前
  yaoq 6dbb9240c3 canal集成 2年前
  yaoq b43475b09c Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  yaoq 12dc05d38b canal集成 2年前
  郑根木 2664e7582c listhandler.buildSumSql调整,允许不写 2年前
  FLYPHT 197dde622e 移除 2年前
  yaoq 6bc0034f48 canal集成 2年前
  FLYPHT 643278c426 数据集添加字段数据权限配置 2年前
  yaoq d5af00ca19 canal集成 2年前
  xiaxl 56a306c9ff 参数优化 2年前
  lip 131b60330a Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  lip 93ec115816 添加工作流模型 2年前
  郑根木 293be2fd8f jackson不能指定版本,否则和spring boot冲突,spring-starter-web依赖2.12.5 2年前
  FLYPHT 7412b917b6 优化:模型代码 2年前
  FLYPHT 07e1155201 新增:加载当前用户信息、修改用户信息、修改密码接口 2年前
  FLYPHT d254a9df68 优化:公众用户session不再失效 2年前
  FLYPHT 55a850e24e 优化:模型代码 2年前
  yaoq cbeefa22c0 canal集成 2年前
  yaoq bcdcf21c5a Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  yaoq 2b4931f8f4 canal集成 2年前
  xiaxl 72c1eca49b 工作流模板修改 2年前
  郑根木 a7be5a2de7 模型:单独列表handler 2年前
  yaoq a0c06b128b Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  yaoq 1ff14f8305 canal集成 2年前
  FLYPHT cf2e8080eb 优化:token延时 2年前
  FLYPHT 715a83dfee 新增:登录事件(用户映射,登录成功之后) 2年前
  yaoq adb8d248a4 canal集成 2年前
  yaoq d7aad13dcc canal 集成 2年前
  lip d093db1e65 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  lip 62395c0acc 自定义模型 2年前
  郑根木 c13412a3d4 系统:定时任务 2年前
  郑根木 713d022078 系统:定时任务 2年前
  郑根木 d00342ce9c 系统:定时任务 2年前
  FLYPHT f8e8274d4b 新增:登录事件(用户映射,登录成功之后) 2年前
  yaoq 91513c8676 线程池 2年前
  yaoq b15d5569c2 集成Canal 2年前
  yaoq 8ab1bde422 集成Canal 2年前
  lip 2282a5ef4f 模型调整 2年前
  FLYPHT b92bce66b1 优化:拦截器中实现跨域配置 2年前
  lip 6e4a29b132 模型: 左树+列表+编辑弹窗 2年前
  lip 3b58519b90 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  郑根木 62e650d600 系统:系统任务和一次性任务 2年前
  郑根木 f21f674a97 系统:系统任务和一次性任务 2年前
  郑根木 bd7cf4313f 系统:系统任务和一次性任务 2年前
  郑根木 93d5a73dba 系统:系统任务和一次性任务 2年前
  lip 59c0561f5e Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  郑根木 2ff242165d 系统:模型代码调整 2年前
  郑根木 7211a7b35b 系统:模型代码调整 2年前
  lip cacfd6482e Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  lip 2863ca08e9 工具类 2年前
  yaoq 29b034a272 重载缓存 2年前
  lip ad5b0b082e 静态资源不拦截 2年前
  lip f4fd27de1f Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  ht b148e4d35b 角色权限admin添加 2年前
  FLYPHT 29d76d56b5 优化:管理员的权限控制 2年前
  郑根木 7893a1fb6e 系统:自定义sql的表替换,[#tableName#] 2年前
  郑根木 1e916dc40d 系统:拦截器调整,统一异常处理,防重复提交指纹 2年前
  FLYPHT 01ba683554 优化:工作流模型配置 2年前
  郑根木 a258676c8d 系统:拦截器调整,统一异常处理,防重复提交指纹 2年前
  郑根木 159f1147f0 系统:拦截器调整,统一异常处理,防重复提交指纹 2年前
  郑根木 be8af8b963 系统:拦截器调整,统一异常处理,防重复提交指纹 2年前
  郑根木 1a96ce4654 系统:拦截器调整,统一异常处理,防重复提交指纹 2年前
  yaoq 68a383fa07 菜单权限保存问题 2年前
  yaoq 5f65d36c42 菜单权限保存问题 2年前
  yaoq 483c490b67 菜单权限保存问题 2年前
  FLYPHT 605c2c8fb7 新增:新增菜单权限 2年前
  lip dbb946ff49 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  ht 2b2be9f221 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  ht 921395d706 登录修改 2年前
  lip ba2673c9a6 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  zhangyulong 0591b28c6c 登录增加返回账号信息 2年前
  zhangyulong 270b7b0a3e 登录增加返回账号信息 2年前
  郑根木 a2786d2c39 流程:系列bug 2年前
  郑根木 3d778c8966 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  郑根木 5c10cefdfd 流程:系列bug 2年前
  xiaxl f17ac83135 优化点模板参数 2年前
  FLYPHT a9d9f53105 优化:工作流模型配置 2年前
  lip f1c803f3cc Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  郑根木 be57d46d8d 流程:增加selTaskId 2年前
  郑根木 e7332ac991 去掉指定字段的insert 2年前
  郑根木 8e0392548b 去掉指定字段的insert 2年前
  郑根木 d2f875f771 去掉指定字段的insert 2年前
  郑根木 5088a26c75 去掉指定字段的insert 2年前
  lip e9fa7ed868 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  郑根木 f6a3659aa9 流程:指定任务,不要切换 2年前
  郑根木 0397ca5b77 重构:去掉多余引用+格式化 2年前
  郑根木 4571518688 重构:删除部分Util,原PubUtil分散到CommUtil和StringUtil、NumberUtil 2年前
  郑根木 5bd9e23df5 重构:删除部分Util,原PubUtil分散到CommUtil和StringUtil、NumberUtil 2年前
  yaoq 133280bc63 菜单权限保存问题 2年前
  lip 1c990db0ce 默认非debug 2年前
  zhangyulong f04402d602 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  zhangyulong 82e77c670d 修改用户登录为直接查库、登录返回增加返回用户等级 2年前
  FLYPHT f65035be50 优化:工作流模型配置 2年前
  FLYPHT ec3e13a19b 优化:工作流模型配置 2年前
  FLYPHT 1dd0ec37d5 优化:工作流模板配置 2年前
  郑根木 145b88152a 流程:条件分支 2年前
  郑根木 a9c3ce1d19 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  郑根木 51e099b2d3 流程:条件分支 2年前
  FLYPHT 9af9d61535 新增:添加HttpUtil工具类 2年前
  郑根木 84d31f32c1 系统:启动监听,按order先执行init,再执行run; 2年前
  郑根木 a60b9e204f 系统:流程处理 2年前
  郑根木 41738f6438 系统:增加SwConsts.SysParam.RUN_PROJECTS,启动时只读取指定项目的表定义 2年前
  郑根木 9401b1c32b 系统:增加SwConsts.SysParam.RUN_PROJECTS,启动时只读取指定项目的表定义 2年前
  郑根木 73e780f9ae 系统:增加SwConsts.SysParam.RUN_PROJECTS,启动时只读取指定项目的表定义 2年前
  郑根木 d088c607fa Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  郑根木 94dccde30c 流程:按钮控制 2年前
  ht 8541bed84d Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  ht d295abe448 提交单点登录实体 2年前
  郑根木 692a122dca 流程:按钮控制 2年前
  郑根木 2024829f86 流程:按钮控制 2年前
  郑根木 54f07d25ef 流程:按钮控制 2年前
  xiaxl 67ebf7d5ec 调整参数 2年前
  郑根木 87d1c3e570 流程办理提交驳回取回作废终止 2年前
  xiaxl 29ee8316ed 补充一个参数 2年前
  xiaxl 8f0233f44d 优化模板参数 2年前
  郑根木 41535d1b81 废弃AbsDbWorker,增加IDbSimpleWorker,方便lambda表达式写法 2年前
  郑根木 0103df9754 废弃AbsDbWorker 2年前
  FLYPHT bc7153b47b bug:修改sql报错 2年前
  lip 502d3a7f97 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  lip 3df6834ffa 模型 2年前
  郑根木 f634fff6ae 流程引擎:extra返回 2年前
  郑根木 3ec303f413 流程引擎:load\save\submit;调整模型,以Bean方式处理 2年前
  郑根木 d7305800f8 流程引擎:load\save\submit;调整模型,以Bean方式处理 2年前
  郑根木 51a963700d 流程引擎:load\save\submit;调整模型,以Bean方式处理 2年前
  郑根木 a75c2638d2 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  郑根木 e6ddfb8fb6 流程引擎:load\save\submit;调整模型,以Bean方式处理 2年前
  xiaxl ad26db8fc8 模板调整参数 2年前
  xiaxl 56f0ba89fd 调点样式 2年前
  lip add833bc97 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  lip e5b83da5d7 添加两个模型 2年前
  郑根木 bcb6eb735e 流程引擎:load\save\submit 2年前
  FLYPHT 3a459ed545 新增:打包配置 2年前
  郑根木 32ad84350a 流程引擎:load\save\submit 2年前
  郑根木 ec49b3b8c3 bug:dynpage.save 2年前
  xiaxl 5110b06a67 调整点flow模板 2年前
  郑根木 2c6741804b 代码调整:add即返回id,根据_status判断是否新增 2年前
  郑根木 a852cbe539 代码调整:add即返回id,根据_status判断是否新增 2年前
  郑根木 0901fb476b 流程引擎-删除 2年前
  郑根木 4ec41104b3 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  郑根木 acfb4a1af5 流程引擎-保存 2年前
  xiaxl 3f9312dc51 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  xiaxl 2274898a67 模板部分修改 2年前
  lip af312ca3ee 下拉树控件名更改 2年前
  xiaxl 40812c2b20 提交普通卡片模板,主子表卡片模板 2年前
  FLYPHT 7310fabce0 apiController中 request.getRequestURI() 修改为request.getServletPath() 2年前
  郑根木 621ec86cdc 流程引擎-保存 2年前
  郑根木 27e80a8f71 流程引擎-新增 2年前
  郑根木 4bbc6e4f18 流程引擎-listhandler 2年前
  FLYPHT 3632d8876a 调整工作流模型的模板 2年前
  lip a118c2d925 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  lip e9926de544 修改模板和handler 2年前
  郑根木 950ca07324 流程引擎-listhandler 2年前
  郑根木 826f25276c 流程引擎-listhandler 2年前
  郑根木 7283600160 流程引擎 2年前
  lip 6e9a0b1a1c Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  lip d9c76a815c 模型 2年前
  FLYPHT 0c4918fbed 新增:工作流的模板实现 2年前
  郑根木 69d8e41b59 流程引擎 2年前
  郑根木 afbcf25d15 loadProcInstFields 2年前
  郑根木 575d3e4ca6 loadProcInstFields 2年前
  郑根木 69f9d6930c loadProcInstFields 2年前
  郑根木 3364f65348 loadProcInstFields 2年前
  郑根木 2d260a5940 loadProcInstFields 2年前
  郑根木 5d9fc400b0 页面+BillType,表定义加buildBean 2年前
  郑根木 038b02e7d8 页面+BillType,表定义加buildBean 2年前
  郑根木 5008555ef6 页面+BillType,表定义加buildBean 2年前
  lip c9a1811683 Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  lip bbdd0ebd45 树筛选 2年前
  郑根木 f40108341b 启动调整 2年前
  FLYPHT e82f445e4e 修改:model_list_card.ftl调整 2年前
  lip 538df033b9 2年前
  郑根木 543d02b88b 流程引擎 2年前
  郑根木 ae17aa5f11 流程引擎 2年前
  郑根木 d1d2dcc503 页面设计:返回带控件的字段信息 2年前
  lip 03e4ef16b3 枚举下拉框 2年前
  lip 03e81ca8c8 流程相关 2年前
  郑根木 5ad0bfb6c6 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2年前
  郑根木 aed2b1e379 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2年前
  郑根木 d736624007 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2年前
  郑根木 223bc9eb16 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2年前
  郑根木 01e12107aa 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2年前
  FLYPHT ef0ff750ad 修改:model_list_card.ftl调整 2年前
  郑根木 58feeeeeef 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2年前
  郑根木 a93e8d88e2 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2年前
  郑根木 407397fa1e 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2年前
  郑根木 ea726b0069 增加:LC_SINGLE模型engine 2年前
  FLYPHT f92def87d8 修改:修改list_card.ftl模板 2年前
  郑根木 027bd3c9f6 增加:LC_SINGLE模型engine 2年前
  郑根木 10f2cb4cd2 增加:LC_SINGLE模型engine 2年前
  郑根木 d2fcac6845 增加:LC_SINGLE模型根据模板生成页面 2年前
  yaoq c10d065003 个人信息修改、密码修改、密码重置 2年前
  郑根木 27c588d0bf 增加:LC_SINGLE模型 2年前
  郑根木 cbcce3f28e Merge remote-tracking branch 'origin/4.0' into 4.0 2年前
  郑根木 705a80692a 增加:LC_SINGLE模型 2年前
  yaoq c4ee399bae 枚举combo 2年前
  郑根木 f1cae9d932 增加:LC_SINGLE模型 2年前
  郑根木 e62364c165 优化:form.load系列支持id、pageId、pageName 2年前
100個のファイルの変更3015行の追加2738行の削除
分割表示
  1. バイナリ
      smtweb-framework/bpm/doc/开发手册.doc
  2. +6
    -2
      smtweb-framework/bpm/pom.xml
  3. +1
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmApplication.java
  4. +7
    -5
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmAutoConfiguration.java
  5. +2
    -4
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmConfigBean.java
  6. +0
    -30
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmStartedListener.java
  7. +1
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfig.java
  8. +1
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfigProperties.java
  9. +61
    -64
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/AttachController.java
  10. +148
    -142
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileDownloadController.java
  11. +109
    -119
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileUploadController.java
  12. +44
    -44
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/ImageAttachDao.java
  13. +71
    -71
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/SysAttachDao.java
  14. +11
    -11
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dataCacheInit/AttachFolderEntityBuffer.java
  15. +6
    -6
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/AttachPathPO.java
  16. +1
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/FileDataVO.java
  17. +8
    -8
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/UploadDataVO.java
  18. +6
    -5
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachFileWork.java
  19. +4
    -3
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachFtpWork.java
  20. +49
    -46
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachHelper.java
  21. +17
    -16
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachUtil.java
  22. +4
    -6
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/IAttachWorkIntf.java
  23. +1
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/initPlugin/RunDataInit.java
  24. +81
    -81
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/BeanUtil.java
  25. +27
    -85
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenerator.java
  26. +1
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FileDynPath.java
  27. +63
    -62
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathGenerator.java
  28. +32
    -32
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathInfo.java
  29. +37
    -29
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataHandler.java
  30. +3
    -2
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataLevelHandler.java
  31. +4
    -7
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/IdeaUtil.java
  32. +56
    -56
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/MemMultipartFile.java
  33. +88
    -87
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ThumbImage.java
  34. +166
    -164
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/TreeDataUtil.java
  35. +8
    -6
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilFile.java
  36. +3
    -3
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilLogger.java
  37. +0
    -465
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilMath.java
  38. +0
    -504
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilString.java
  39. +59
    -58
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/XmlUtil.java
  40. +79
    -79
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/YamlUtil.java
  41. +9
    -8
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/FtpTaskManager.java
  42. +2
    -2
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/FtpUtil.java
  43. +1
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/IFtpServerConfig.java
  44. +5
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/IFtpUtil.java
  45. +5
    -4
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/SFtpUtil.java
  46. +50
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/BpmStartedListener.java
  47. +22
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/canal/FilePathConfig.java
  48. +22
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/common/BpmConst.java
  49. +49
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/common/BpmEnum.java
  50. +1
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogCache.java
  51. +18
    -8
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java
  52. +4
    -4
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHelper.java
  53. +9
    -6
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectCache.java
  54. +14
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableService.java
  55. +9
    -3
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java
  56. +5
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProc.java
  57. +3
    -3
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java
  58. +5
    -3
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcHelper.java
  59. +2
    -4
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcLoadHandler.java
  60. +4
    -3
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcSaveHandler.java
  61. +44
    -2
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java
  62. +20
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ProcInfo.java
  63. +1
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/Sign.java
  64. +1
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/Trans.java
  65. +54
    -7
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/CodeBuildHandler.java
  66. +8
    -2
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelForm.java
  67. +20
    -19
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormCache.java
  68. +58
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormDelHandler.java
  69. +129
    -48
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java
  70. +27
    -40
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormLoadHandler.java
  71. +24
    -76
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormSaveHandler.java
  72. +56
    -18
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormService.java
  73. +1
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/BaseDatasetField.java
  74. +6
    -2
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDataset.java
  75. +2
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetFilter.java
  76. +16
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetLinkClob.java
  77. +4
    -1
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasets.java
  78. +88
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/BaseModelWorker.java
  79. +69
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/EmptyWorker.java
  80. +18
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcLc1Worker.java
  81. +18
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcLc2Worker.java
  82. +17
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcLt2Worker.java
  83. +26
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcLtMsWorker.java
  84. +26
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcLtWorker.java
  85. +46
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcMsWorker.java
  86. +81
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcNormalWorker.java
  87. +57
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcSingleWorker.java
  88. +67
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/ModelFactory.java
  89. +27
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowLcLc1Worker.java
  90. +27
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowLcLc2Worker.java
  91. +27
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowLcLtWorker.java
  92. +27
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowLcMsWorker.java
  93. +27
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowLtMsWorker.java
  94. +74
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowSingleWorker.java
  95. +42
    -42
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/MenuVO.java
  96. +54
    -13
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/PreviewMenuTreeService.java
  97. +31
    -6
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/AbstractDynPageHandler.java
  98. +3
    -3
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageDelHandler.java
  99. +162
    -93
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java
  100. +26
    -6
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageListHandler.java

バイナリ
smtweb-framework/bpm/doc/开发手册.doc ファイルの表示


+ 6
- 2
smtweb-framework/bpm/pom.xml ファイルの表示

@@ -35,6 +35,10 @@
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>[0.4, 0.5)</version>
@@ -47,12 +51,12 @@
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.11.0</version>
<!-- 不能指定版本,否则和spring boot冲突,spring-starter-web依赖2.12.5 <version>2.13.4</version>-->
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.11.0</version>
<!-- <version>2.13.4</version>-->
</dependency>
<!-- https://mvnrepository.com/artifact/net.jodah/typetools -->
<!-- <dependency>-->


+ 1
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmApplication.java ファイルの表示

@@ -9,6 +9,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BpmApplication {
public static void main(String[] args) {
SpringApplication.run(BpmApplication.class, args);
SpringApplication.run(BpmApplication.class, args);
}
}

+ 7
- 5
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmAutoConfiguration.java ファイルの表示

@@ -11,9 +11,11 @@ import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class BpmAutoConfiguration {
/** 配置自定义service扫描路径 {module}/{service}/{method} */
@Bean
public ControllerConfig bpmControllerConfig() {
return new ControllerConfig("bpm", "cc.smtweb.system.bpm.web", null);
}
/**
* 配置自定义service扫描路径 {module}/{service}/{method}
*/
@Bean
public ControllerConfig bpmControllerConfig() {
return new ControllerConfig("bpm", "cc.smtweb.system.bpm.web", null);
}
}

+ 2
- 4
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmConfigBean.java ファイルの表示

@@ -8,8 +8,6 @@ import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "smtweb.bpm")
@Data
public class BpmConfigBean {
// 是否debug模式
private boolean debug;
private String codeJavaPath;
private int mode;
private String codeJavaPath;
private int mode;
}

+ 0
- 30
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/BpmStartedListener.java ファイルの表示

@@ -1,30 +0,0 @@
package cc.smtweb.system.bpm.spring;

import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.cache.CacheManager;
import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.impl.DatabaseUtil;
import cc.smtweb.framework.core.systask.TaskStartEvent;
import cc.smtweb.framework.core.systask.WebStartedEvent;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
* Created by Akmm at 2022/7/8 19:57
*/
@Component
@Order(SwConsts.DEFAULT_ORDER + 1)
public class BpmStartedListener implements ApplicationListener<ApplicationStartedEvent> {

@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
//初始化数据库
new DatabaseUtil(true, false).checkDb();
//初始化缓存
CacheManager.getIntance().init();
}
}

+ 1
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfig.java ファイルの表示

@@ -1,10 +1,10 @@
package cc.smtweb.system.bpm.spring.config;

import cc.smtweb.framework.core.db.jdbc.IdGenerator;
import cc.smtweb.system.bpm.util.FilePathGenerator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import cc.smtweb.framework.core.db.jdbc.IdGenerator;

/**
* 微服务框架封装自动配置类


+ 1
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfigProperties.java ファイルの表示

@@ -13,7 +13,7 @@ public class FileConfigProperties {
/**
* 系统底层附件保存路径和访问路径
*/
private String localPath;
private String localPath;
private String url;

/**


+ 61
- 64
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/AttachController.java ファイルの表示

@@ -4,14 +4,14 @@ import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.util.Consts;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.NumberUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.spring.config.FileConfigProperties;
import cc.smtweb.system.bpm.spring.file.attach.AttachHelper;
import cc.smtweb.system.bpm.spring.file.attach.AttachUtil;
import cc.smtweb.system.bpm.util.UtilDownloadFile;
import cc.smtweb.system.bpm.util.UtilFile;
import cc.smtweb.system.bpm.util.UtilLogger;
import cc.smtweb.system.bpm.util.UtilMath;
import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
@@ -48,7 +48,7 @@ import java.util.Map;
@RestController
@RequestMapping("/api/attach")
public class AttachController {
private static Logger logger = LoggerFactory.getLogger(AttachController.class);
private static Logger logger = LoggerFactory.getLogger(AttachController.class);
@Autowired
private FileConfigProperties properties;
@Autowired
@@ -60,14 +60,13 @@ public class AttachController {
private BASE64Decoder decoder = new BASE64Decoder();

/**
*
* @param request
* @param type 类型,如idcard:身份证、headImg:头像
* @param ownerId 拥有者ID
* @param path 存储目录路径名,如:idcard
* @param type 类型,如idcard:身份证、headImg:头像
* @param ownerId 拥有者ID
* @param path 存储目录路径名,如:idcard
* @param attachIsTemp 是否临时文件:true/false 字符串
* @param attachName 附件名称,如:XXXXX.jpg
* @param savePath 保存路径,指定文件保存目录,可为空
* @param attachName 附件名称,如:XXXXX.jpg
* @param savePath 保存路径,指定文件保存目录,可为空
* @return
* @throws Exception
*/
@@ -91,23 +90,22 @@ public class AttachController {
AttachInfo attach = new AttachInfo();
attach.setId(dbEngine.nextId());
attach.setType(type);//附件类别
if(null !=ownerId) {
if (null != ownerId) {
attach.setOwnerId(ownerId);//附件拥有者id
}
attach.setPath(path);//附件路径
attach.setPartyId(-1l);
attach.setTime(PubUtil.getLastTime());
attach.setTime(DateUtil.nowDateTimeLong());
attach.setUserId(-1l);
attach.setIsTemp("true".equals(attachIsTemp) ? 1 : 0);//暂时没有有效拥有者标记 方便定时任务清除垃圾附件
attach.setIsTemp("true".equals(attachIsTemp) ? 1: 0);//暂时没有有效拥有者标记 方便定时任务清除垃圾附件
// 上传文件名
final int i = file.getOriginalFilename().lastIndexOf(".");
if (i >= 0) {
attach.setSuffix(file.getOriginalFilename().substring(i));
}
if (PubUtil.isEmptyStr(attachName)) {
if (StringUtil.isEmpty(attachName)) {
attachName = file.getOriginalFilename();
}
else {
} else {
attachName = attachName + attach.getSuffix();
}
attach.setName(attachName);
@@ -116,7 +114,7 @@ public class AttachController {
// 上传文件域对象
File upload = new File(attachHelper.getAttachTmpPath() + attach.getId() + attach.getSuffix());
attach.setSize((long) FileCopyUtils.copy(file.getInputStream(), new BufferedOutputStream(new FileOutputStream(upload))));
if (PubUtil.isEmpty(savePath)) {
if (StringUtil.isEmpty(savePath)) {
localSaveAttach(attach, upload);
} else {//复制到指定目录
String filePath;
@@ -138,18 +136,17 @@ public class AttachController {
}

/**
*
* @param request
* @param response
* @param base64File 文件base64编码
* @param attachId 附件ID,可为空,如果有,则替换此附件ID对应数据
* @param type 类型,如idcard:身份证、headImg:头像
* @param ownerId 拥有者ID
* @param path 存储目录路径名,如:idcard
* @param base64File 文件base64编码
* @param attachId 附件ID,可为空,如果有,则替换此附件ID对应数据
* @param type 类型,如idcard:身份证、headImg:头像
* @param ownerId 拥有者ID
* @param path 存储目录路径名,如:idcard
* @param attachIsTemp 是否临时文件:true/false 字符串
* @param attachName 附件名称,如:XXXXX.jpg
* @param savePath 保存路径,指定文件保存目录,可为空
* @param suffix 文件后缀,如.jpg
* @param attachName 附件名称,如:XXXXX.jpg
* @param savePath 保存路径,指定文件保存目录,可为空
* @param suffix 文件后缀,如.jpg
* @return
* @throws Exception
*/
@@ -164,23 +161,22 @@ public class AttachController {
@RequestParam(value = "attachName", required = false) String attachName,
@RequestParam(value = "savePath", required = false) String savePath,
@RequestParam(value = "suffix", required = false) String suffix
) throws Exception {
) throws Exception {
// UtilLogger.error("上传文件接收base64", base64File);
if (null == base64File || "".equals(base64File)){
if (null == base64File || "".equals(base64File)) {
return R.error("文件不能为空");
}
String str[]=base64File.split(",");
if(str.length>1){
base64File=str[1];
String str[] = base64File.split(",");
if (str.length > 1) {
base64File = str[1];
}
// 上传文件类型
//String uploadContentType = file.getContentType();
AttachInfo attach = null;
boolean isNew = PubUtil.isEmpty(attachId+"");
boolean isNew = StringUtil.isEmpty(attachId + "");
if (isNew) {
attach = new AttachInfo();
}
else {
} else {
attach = dbEngine.findDao(AttachInfo.class).queryEntity(attachId);
if (attach == null) {
attach = new AttachInfo();
@@ -188,19 +184,19 @@ public class AttachController {
} else isNew = attach.isNew();
}
attach.setId(attachId);
if (PubUtil.isEmpty(attachId+"")) attach.setId(dbEngine.nextId());
if (StringUtil.isEmpty(attachId + "")) attach.setId(dbEngine.nextId());

attach.setType(type);//附件类别
if(null !=ownerId) {
if (null != ownerId) {
attach.setOwnerId(ownerId);//附件拥有者id
}
attach.setPath(path);//附件路径
attach.setPartyId(-1l);
attach.setTime(PubUtil.getLastTime());
attach.setTime(DateUtil.nowDateTimeLong());
attach.setUserId(-1l);
attach.setIsTemp("true".equals(attachIsTemp) ? 1 : 0);//暂时没有有效拥有者标记 方便定时任务清除垃圾附件
attach.setIsTemp("true".equals(attachIsTemp) ? 1: 0);//暂时没有有效拥有者标记 方便定时任务清除垃圾附件
attach.setTime(DateUtil.nowDateTimeLong());
attach.setIsTemp("true".equals(attachIsTemp) ? 1 : 0);//暂时没有有效拥有者标记 方便定时任务清除垃圾附件
attach.setIsTemp("true".equals(attachIsTemp) ? 1: 0);//暂时没有有效拥有者标记 方便定时任务清除垃圾附件
// 上传文件名
attach.setSuffix(suffix);
attach.setName(attachName);
@@ -219,7 +215,7 @@ public class AttachController {
File upload = new File(attachHelper.getAttachTmpPath() + attach.getId() + attach.getSuffix());
FileUtils.writeByteArrayToFile(upload, byt);
attach.setSize(upload.length());
if (PubUtil.isEmpty(savePath)) {
if (StringUtil.isEmpty(savePath)) {
localSaveAttach(attach, upload);
} else {//复制到指定目录
String filePath;
@@ -235,42 +231,43 @@ public class AttachController {
}
return R.success(attach.getId());
}

@PostMapping({"/copyupload"})
public R copyupload(HttpServletRequest request) throws Exception {
String type=request.getParameter("type");
String attachId=request.getParameter("attachId");
if(PubUtil.isEmpty(attachId)){
String type = request.getParameter("type");
String attachId = request.getParameter("attachId");
if (StringUtil.isEmpty(attachId)) {
return R.success("");
}
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, Long.valueOf(attachId));
if(null ==attach){
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, Long.valueOf(attachId));
if (null == attach) {
return R.success("");
}
String remoteName =attach.getId()+attach.getName().substring(attach.getName().lastIndexOf("."));
String remoteName = attach.getId() + attach.getName().substring(attach.getName().lastIndexOf("."));
String remotePath = attach.getPath();
String filePath =attachHelper.getAttachTmpPath()+"tempFiles/";
String filePath = attachHelper.getAttachTmpPath() + "tempFiles/";
UtilFile.makeDir(filePath);
Map<String, String> map = null;
try {
attachUtil.downloadAttach(remotePath, remoteName, filePath);
String filePaths=filePath+remoteName;
String filePaths = filePath + remoteName;

attach.setId(dbEngine.nextId());
attach.setType(type);//附件类别
attach.setOwnerId(-1l);//附件拥有者id
attach.setPartyId(-1l);
attach.setTime(PubUtil.getLastTime());
attach.setTime(DateUtil.nowDateTimeLong());
attach.setUserId(-1l);
attach.setName(attach.getId()+attach.getSuffix());
attach.setName(attach.getId() + attach.getSuffix());
// 上传文件域对象
File upload = new File(filePaths);
// attach.setSize((long) FileCopyUtils.copy(file.getInputStream(), new BufferedOutputStream(new FileOutputStream(upload))));
localSaveAttach(attach, upload);
}catch (Exception e){
} catch (Exception e) {
logger.error("上传文件失败", e);
return R.error("上传文件失败");
}
return R.success(attach.getId());
return R.success(attach.getId());
}


@@ -291,7 +288,7 @@ public class AttachController {
//附件下载
@RequestMapping(value = "/download", method = {RequestMethod.GET, RequestMethod.POST})
public R down(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "attachId", required = false) Long attachId) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class,attachId);
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, attachId);
if (null == attach) {
return R.error("附件不存在");
}
@@ -302,9 +299,9 @@ public class AttachController {
try {
attachUtil.downloadAttach(remotePath, remoteFileName, fileName, response);
attach.setCount(attach.getCount() + 1);
dbEngine.updateEntity(attach,"attach_count");
dbEngine.updateEntity(attach, "attach_count");
} catch (Exception e) {
logger.error("附件下载失败",e);
logger.error("附件下载失败", e);
R.error("附件下载失败");

}
@@ -314,21 +311,21 @@ public class AttachController {
//图片附件显示路径
@GetMapping(value = "/showImg")
public R showImg(HttpServletResponse response, @RequestParam(value = "attachId", required = false) Long attachId) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class,attachId);
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, attachId);
if (null == attach) {
return R.error("附件不存在");
}
// attachUtil.showImg(attach.getPath(),attach.getName(),response);
attachUtil.downloadAttach(attach.getPath(),attach.getName(),attach.getName(),response);
attachUtil.downloadAttach(attach.getPath(), attach.getName(), attach.getName(), response);
return null;
}

//图片附件显示路径
@RequestMapping(value = "/showImgThumb", method = {RequestMethod.GET, RequestMethod.POST})
public R showImgThumb(HttpServletResponse response, @RequestParam(value = "attachId", required = false) Long attachId,
@RequestParam(value = "width", required = false,defaultValue = "200") String width,
@RequestParam(value = "height", required = false,defaultValue = "120") String height) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class,attachId);
@RequestParam(value = "width", required = false, defaultValue = "200") String width,
@RequestParam(value = "height", required = false, defaultValue = "120") String height) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, attachId);
if (null == attach) {
return R.error("附件不存在");
}
@@ -339,8 +336,8 @@ public class AttachController {
String lfo = tempPath + "/" + remoteFileName;
String lfd = tempPath + "/thumb_" + attach.getId() + attach.getSuffix();
attachUtil.downloadAttach(remotePath, remoteFileName, tempPath);
int w=Integer.valueOf(width);
int h=Integer.valueOf(height);
int w = Integer.valueOf(width);
int h = Integer.valueOf(height);
if (w <= 0) w = 100;
if (h <= 0) h = 100;
getImgThumb(lfo, lfd, w, h);
@@ -350,7 +347,7 @@ public class AttachController {
UtilDownloadFile.downfileEx(response, lfo, attach.getName());
}
} catch (Exception e) {
logger.error("附件下载失败",e);
logger.error("附件下载失败", e);
R.error("附件下载失败");
}
return null;
@@ -372,7 +369,7 @@ public class AttachController {
if (h > height) {
r = Math.min(1.0 * height / h, r);
}
if (!UtilMath.isEqualsZero(r - 1)) {
if (!NumberUtil.isEqualsZero(r - 1)) {
w = (int) Math.round(w * r);
h = (int) Math.round(h * r);
}
@@ -419,7 +416,7 @@ public class AttachController {
//图片附件显示路径
@GetMapping(value = "/loadAttachBean")
public R loadAttachBean(@RequestParam(value = "attachIds") String attachIds) throws Exception {
List<AttachInfo> beans = dbEngine.queryWhere(AttachInfo.class, "attach_id in ("+attachIds+")");
List<AttachInfo> beans = dbEngine.queryWhere(AttachInfo.class, "attach_id in (" + attachIds + ")");
return R.success(beans);
}
}

+ 148
- 142
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileDownloadController.java ファイルの表示

@@ -9,7 +9,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
@@ -22,164 +25,167 @@ import java.util.concurrent.TimeUnit;

@RestController
public class FileDownloadController {
private static final MediaType APPLICATION_JAVASCRIPT = new MediaType("application", "javascript");
@Value("${smtweb.static.local-path:}")
private String staticLocalPath;

@Autowired
private FilePathGenerator filePathGenerator;

@Autowired
private RedisManager redisManager;

/** path方式下载文件 */
@GetMapping("/fs/files/**")
public ResponseEntity<InputStreamResource> files(@RequestParam(value="name", required=false) String name,
@RequestParam(value="noCache", required=false) Boolean noCache,
HttpServletRequest request
) throws FileNotFoundException {
String filePath = request.getRequestURI().substring(10);
return download(filePath, name, noCache, request);
}

/** 参数方式下载文件 */
@GetMapping("/fs/download")
public ResponseEntity<InputStreamResource> download(@RequestParam(value="path") String path,
@RequestParam(value="name", required=false) String name,
@RequestParam(value="noCache", required=false) Boolean noCache,
HttpServletRequest request
) throws FileNotFoundException {
SessionUtil.checkSession(request, redisManager);

File file = new File(filePathGenerator.getFileDiskPath(path));

if (!file.exists()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
private static final MediaType APPLICATION_JAVASCRIPT = new MediaType("application", "javascript");
@Value("${smtweb.static.local-path:}")
private String staticLocalPath;

@Autowired
private FilePathGenerator filePathGenerator;

/**
* path方式下载文件
*/
@GetMapping("/fs/files/**")
public ResponseEntity<InputStreamResource> files(@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "noCache", required = false) Boolean noCache,
@RequestParam(value = "absolutePath", required = false) Boolean absolutePath,
HttpServletRequest request
) throws FileNotFoundException {
String filePath = request.getServletPath().substring(10);
return download(filePath, name, noCache,absolutePath, request);
}

if (StringUtils.isBlank(name)) {
name = file.getName();
}

HttpHeaders headers = new HttpHeaders();
if (Boolean.TRUE.equals(noCache)) {
headers.setCacheControl("no-cache, no-store, must-revalidate");
headers.setPragma("no-cache");
headers.setExpires(0);
}

headers.setLastModified(file.lastModified());
headers.add("Content-Disposition",
String.format("attachment; filename=\"%s\"", new String(name.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1)));

return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(new InputStreamResource(new FileInputStream(file)));
}

/** path方式读取静态目录文件 */
@GetMapping("/fs/static/**")
public ResponseEntity<InputStreamResource> resource(@RequestParam(value="default", required=false) String defaultPath,
@RequestParam(value="noCache", required=false) Boolean noCache,
@RequestHeader(value="If-Modified-Since", required = false) String ifModifiedSince,
HttpServletRequest request) throws FileNotFoundException {
String filePath = request.getRequestURI().substring(11);

HttpHeaders headers = new HttpHeaders();

if (Boolean.TRUE.equals(noCache)) {
headers.setCacheControl("no-cache, no-store, must-revalidate");
headers.setPragma("no-cache");
headers.setExpires(0);
} else {
// 暂时缓存1天
headers.setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS));
headers.setExpires(Instant.ofEpochMilli(System.currentTimeMillis() + DateUtils.MILLIS_PER_DAY));
}

String name = getFileName(filePath);
headers.add("Content-Disposition",
String.format("attachment; filename=\"%s\"", new String(name.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1)));

MediaType contentType = getContentType(filePath);
// 先找文件
if (StringUtils.isNotBlank(staticLocalPath)) {
File file = new File(staticLocalPath + filePath);
/**
* 参数方式下载文件
*/
@GetMapping("/fs/download")
public ResponseEntity<InputStreamResource> download(@RequestParam(value = "path") String path,
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "noCache", required = false) Boolean noCache,
@RequestParam(value = "absolutePath", required = false) Boolean absolutePath,
HttpServletRequest request
) throws FileNotFoundException {
File file = new File(absolutePath? path:filePathGenerator.getFileDiskPath(path));

if (!file.exists()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}

if (StringUtils.isBlank(name)) {
name = file.getName();
}

HttpHeaders headers = new HttpHeaders();
if (Boolean.TRUE.equals(noCache)) {
headers.setCacheControl("no-cache, no-store, must-revalidate");
headers.setPragma("no-cache");
headers.setExpires(0);
}

if (file.exists()) {
headers.setLastModified(file.lastModified());
headers.add("Content-Disposition",
String.format("attachment; filename=\"%s\"", new String(name.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)));

return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(contentType)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(new InputStreamResource(new FileInputStream(file)));
}
}

// 再找资源目录
InputStream inputStream = getClass().getResourceAsStream("/static/" + filePath);
if (inputStream != null) {
return buildResource(inputStream, contentType, headers);
} else if (StringUtils.isNotBlank(defaultPath)) {
inputStream = getClass().getResourceAsStream("/static/" + defaultPath);
if (inputStream != null) {
return buildResource(inputStream, contentType, headers);
}
/**
* path方式读取静态目录文件
*/
@GetMapping("/fs/static/**")
public ResponseEntity<InputStreamResource> resource(@RequestParam(value = "default", required = false) String defaultPath,
@RequestParam(value = "noCache", required = false) Boolean noCache,
@RequestHeader(value = "If-Modified-Since", required = false) String ifModifiedSince,
HttpServletRequest request) throws FileNotFoundException {
String filePath = request.getServletPath().substring(11);

HttpHeaders headers = new HttpHeaders();

if (Boolean.TRUE.equals(noCache)) {
headers.setCacheControl("no-cache, no-store, must-revalidate");
headers.setPragma("no-cache");
headers.setExpires(0);
} else {
// 暂时缓存1天
headers.setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS));
headers.setExpires(Instant.ofEpochMilli(System.currentTimeMillis() + DateUtils.MILLIS_PER_DAY));
}

String name = getFileName(filePath);
headers.add("Content-Disposition",
String.format("attachment; filename=\"%s\"", new String(name.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)));

MediaType contentType = getContentType(filePath);
// 先找文件
if (StringUtils.isNotBlank(staticLocalPath)) {
File file = new File(staticLocalPath + filePath);

if (file.exists()) {
headers.setLastModified(file.lastModified());

return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(contentType)
.body(new InputStreamResource(new FileInputStream(file)));
}
}

// 再找资源目录
InputStream inputStream = getClass().getResourceAsStream("/static/" + filePath);
if (inputStream != null) {
return buildResource(inputStream, contentType, headers);
} else if (StringUtils.isNotBlank(defaultPath)) {
inputStream = getClass().getResourceAsStream("/static/" + defaultPath);
if (inputStream != null) {
return buildResource(inputStream, contentType, headers);
}
}

return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}

return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
private String getFileName(String filePath) {
int pos = filePath.lastIndexOf("/");
if (pos >= 0) {
return filePath.substring(pos + 1);
}

private String getFileName(String filePath) {
int pos = filePath.lastIndexOf("/");
if (pos >= 0) {
return filePath.substring(pos + 1);
return filePath;
}

return filePath;
}

private ResponseEntity<InputStreamResource> buildResource(InputStream inputStream, MediaType contentType, HttpHeaders headers) {
return ResponseEntity.ok()
.headers(headers)
private ResponseEntity<InputStreamResource> buildResource(InputStream inputStream, MediaType contentType, HttpHeaders headers) {
return ResponseEntity.ok()
.headers(headers)
// .contentLength(file.length())
.contentType(contentType)
.body(new InputStreamResource(inputStream));
}

private static MediaType getContentType(String filePath) {
int pos = filePath.lastIndexOf(".");

if (pos >= 0) {
String fileExt = filePath.substring(pos + 1).toLowerCase();
switch (fileExt) {
case "htm":
case "html":
case "css":
return MediaType.TEXT_HTML;
case "js":
return APPLICATION_JAVASCRIPT;
case "txt":
return MediaType.TEXT_PLAIN;
case "pdf":
return MediaType.APPLICATION_PDF;
case "xml":
return MediaType.TEXT_XML;
case "gif":
return MediaType.IMAGE_GIF;
case "jpeg":
case "jpg":
return MediaType.IMAGE_JPEG;
case "png":
return MediaType.IMAGE_PNG;
default:
return MediaType.APPLICATION_OCTET_STREAM;
}
.contentType(contentType)
.body(new InputStreamResource(inputStream));
}

return MediaType.APPLICATION_OCTET_STREAM;
}
private static MediaType getContentType(String filePath) {
int pos = filePath.lastIndexOf(".");

if (pos >= 0) {
String fileExt = filePath.substring(pos + 1).toLowerCase();
switch (fileExt) {
case "htm":
case "html":
case "css":
return MediaType.TEXT_HTML;
case "js":
return APPLICATION_JAVASCRIPT;
case "txt":
return MediaType.TEXT_PLAIN;
case "pdf":
return MediaType.APPLICATION_PDF;
case "xml":
return MediaType.TEXT_XML;
case "gif":
return MediaType.IMAGE_GIF;
case "jpeg":
case "jpg":
return MediaType.IMAGE_JPEG;
case "png":
return MediaType.IMAGE_PNG;
default:
return MediaType.APPLICATION_OCTET_STREAM;
}
}

return MediaType.APPLICATION_OCTET_STREAM;
}
}

+ 109
- 119
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/FileUploadController.java ファイルの表示

@@ -1,10 +1,12 @@
package cc.smtweb.system.bpm.spring.controller;

import cc.smtweb.framework.core.cache.redis.RedisManager;
import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.cache.redis.RedisManager;
import cc.smtweb.framework.core.session.SessionUtil;
import cc.smtweb.system.bpm.spring.dao.ImageAttachDao;
import cc.smtweb.system.bpm.spring.entity.FileDataVO;
import cc.smtweb.system.bpm.spring.entity.UploadDataVO;
import cc.smtweb.system.bpm.util.FilePathGenerator;
import cc.smtweb.system.bpm.util.FilePathInfo;
import cc.smtweb.system.bpm.util.MemMultipartFile;
@@ -13,8 +15,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import cc.smtweb.system.bpm.spring.entity.FileDataVO;
import cc.smtweb.system.bpm.spring.entity.UploadDataVO;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
@@ -23,135 +23,125 @@ import java.text.SimpleDateFormat;

@RestController
public class FileUploadController {
@Autowired
private FilePathGenerator filePathGenerator;

@Autowired
private DbEngine dbEngine;

@Autowired
private RedisManager redisManager;

@Autowired
private ImageAttachDao imageAttachDao;

// TODO: 权限处理,临时文件处理
@PostMapping("/fs/upload/{path}")
public R upload(@RequestParam("file") MultipartFile file, @PathVariable("path") String path,
@RequestParam(value="thumb", required=false) String thumb,
@RequestParam(value="thumbHeight", required=false) Integer thumbHeight,
@RequestParam(value="commit", required=false) Boolean insert,
@RequestParam(value="keepName", required=false) Boolean keepName,
HttpServletRequest request
) {
SessionUtil.checkSession(request, redisManager);
return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, insert, keepName);
}

@PostMapping("/fs/uploadImage/{path}")
public R upload(@RequestBody FileDataVO data, @PathVariable("path") String path,
@RequestParam(value="thumb", required=false) String thumb,
@RequestParam(value="thumbHeight", required=false) Integer thumbHeight,
@RequestParam(value="commit", required=false) Boolean insert,
HttpServletRequest request) {
SessionUtil.checkSession(request, redisManager);

MultipartFile file = MemMultipartFile.build(data.getData());
if (file == null) {
return R.error("数据内容格式有错");
@Autowired
private FilePathGenerator filePathGenerator;

@Autowired
private DbEngine dbEngine;

@Autowired
private ImageAttachDao imageAttachDao;

// TODO: 权限处理,临时文件处理
@PostMapping("/fs/upload/{path}")
public R upload(@RequestParam("file") MultipartFile file, @PathVariable("path") String path,
@RequestParam(value = "thumb", required = false) String thumb,
@RequestParam(value = "thumbHeight", required = false) Integer thumbHeight,
@RequestParam(value = "commit", required = false) Boolean insert,
@RequestParam(value = "keepName", required = false) Boolean keepName,
HttpServletRequest request
) {
return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, insert, keepName);
}

return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, insert, false);
}

@PostMapping("/fs/uploadAvatar/{path}")
public R uploadAvatar(@RequestParam("file") MultipartFile file, @PathVariable("path") String path,
@RequestParam(value="size", required=false) Integer size,
@RequestParam(value="commit", required=false) Boolean insert,
@RequestParam(value="keepName", required=false) Boolean keepName,
HttpServletRequest request) {
SessionUtil.checkSession(request, redisManager);
return uploadFile(path, file, ThumbImage.TYPE_AVATAR, size, insert, keepName);
}

// 保存文件和插入数据库数据
@PostMapping("/fs/commit/{path}")
public R commit(@RequestParam("file") MultipartFile file, @PathVariable("path") String path,
@RequestParam(value="thumb", required=false) String thumb,
@RequestParam(value="thumbHeight", required=false) Integer thumbHeight,
@RequestParam(value="keepName", required=false) Boolean keepName,
HttpServletRequest request) {
SessionUtil.checkSession(request, redisManager);
return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, true, keepName);
}

private R uploadFile(String path, MultipartFile file, int type, Integer size, Boolean insert, Boolean keepName) {
//获取上传时的文件名
String fileName = file.getOriginalFilename();

//判断文件是否为空
if(file.isEmpty() && fileName != null){
return R.error("文件为空");
@PostMapping("/fs/uploadImage/{path}")
public R upload(@RequestBody FileDataVO data, @PathVariable("path") String path,
@RequestParam(value = "thumb", required = false) String thumb,
@RequestParam(value = "thumbHeight", required = false) Integer thumbHeight,
@RequestParam(value = "commit", required = false) Boolean insert,
HttpServletRequest request) {
MultipartFile file = MemMultipartFile.build(data.getData());
if (file == null) {
return R.error("数据内容格式有错");
}

return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, insert, false);
}

// 判断保持文件名不变
FilePathInfo fileInfo = filePathGenerator.make(path, fileName, Boolean.TRUE.equals(keepName));

// 注意是路径+文件名
File targetFile = new File(fileInfo.getFullFileName());

try(InputStream inputStream = file.getInputStream(); OutputStream outputStream = new FileOutputStream(targetFile)) {
// 最后使用资源访问器FileCopyUtils的copy方法拷贝文件
FileCopyUtils.copy(inputStream, outputStream);
} catch (IOException e) {
//出现异常,则告诉页面失败
return R.error("上传失败", e);
@PostMapping("/fs/uploadAvatar/{path}")
public R uploadAvatar(@RequestParam("file") MultipartFile file, @PathVariable("path") String path,
@RequestParam(value = "size", required = false) Integer size,
@RequestParam(value = "commit", required = false) Boolean insert,
@RequestParam(value = "keepName", required = false) Boolean keepName,
HttpServletRequest request) {
return uploadFile(path, file, ThumbImage.TYPE_AVATAR, size, insert, keepName);
}

// 生成缩略图
// String contentType = file.getContentType();
UploadDataVO data = new UploadDataVO();

data.setPath(fileInfo.getMysqlFilePath());
data.setName(fileName);
data.setSize(file.getSize());
data.setContentType(file.getContentType());
data.setUrl(filePathGenerator.getFileUrl(fileInfo.getMysqlFilePath()));

if (type == ThumbImage.TYPE_THUMB || type == ThumbImage.TYPE_AVATAR) {
try {
imageAttachDao.makeThumb(data, type == ThumbImage.TYPE_THUMB, targetFile, size);
} catch (IOException e) {
return R.error("生成缩略图失败", e);
}
// 保存文件和插入数据库数据
@PostMapping("/fs/commit/{path}")
public R commit(@RequestParam("file") MultipartFile file, @PathVariable("path") String path,
@RequestParam(value = "thumb", required = false) String thumb,
@RequestParam(value = "thumbHeight", required = false) Integer thumbHeight,
@RequestParam(value = "keepName", required = false) Boolean keepName,
HttpServletRequest request) {
return uploadFile(path, file, ThumbImage.type(thumb), thumbHeight, true, keepName);
}

if (Boolean.TRUE.equals(insert)) {
Long id = dbEngine.nextId();
Timestamp now = new Timestamp(System.currentTimeMillis());
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
private R uploadFile(String path, MultipartFile file, int type, Integer size, Boolean insert, Boolean keepName) {
//获取上传时的文件名
String fileName = file.getOriginalFilename();

dbEngine.update("insert into sw_user.sys_attach(attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time) values(?, ?, ?, ?, ?, ?)",
id, data.getName(), data.getPath(), data.getContentType(), data.getSize(), sdf.format(now));
//判断文件是否为空
if (file.isEmpty() && fileName != null) {
return R.error("文件为空");
}

data.setId(id);
}
// 判断保持文件名不变
FilePathInfo fileInfo = filePathGenerator.make(path, fileName, Boolean.TRUE.equals(keepName));

return R.success(data);
}
// 注意是路径+文件名
File targetFile = new File(fileInfo.getFullFileName());

// TODO: 修改为安全的后台删除方式
@PostMapping("/fs/remove")
public R remove(@RequestParam(value="filePath") String filePath, HttpServletRequest request) {
SessionUtil.checkSession(request, redisManager);
try (InputStream inputStream = file.getInputStream(); OutputStream outputStream = new FileOutputStream(targetFile)) {
// 最后使用资源访问器FileCopyUtils的copy方法拷贝文件
FileCopyUtils.copy(inputStream, outputStream);
} catch (IOException e) {
//出现异常,则告诉页面失败
return R.error("上传失败", e);
}

File file = new File(filePathGenerator.getFileDiskPath(filePath));
if (file.exists() && file.isFile()) {
if (file.delete()) {
R.success(filePath);
}
// 生成缩略图
// String contentType = file.getContentType();
UploadDataVO data = new UploadDataVO();

data.setPath(fileInfo.getMysqlFilePath());
data.setName(fileName);
data.setSize(file.getSize());
data.setContentType(file.getContentType());
data.setUrl(filePathGenerator.getFileUrl(fileInfo.getMysqlFilePath()));

if (type == ThumbImage.TYPE_THUMB || type == ThumbImage.TYPE_AVATAR) {
try {
imageAttachDao.makeThumb(data, type == ThumbImage.TYPE_THUMB, targetFile, size);
} catch (IOException e) {
return R.error("生成缩略图失败", e);
}
}

if (Boolean.TRUE.equals(insert)) {
Long id = dbEngine.nextId();
Timestamp now = new Timestamp(System.currentTimeMillis());
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");

dbEngine.update("insert into sw_user.sys_attach(attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time) values(?, ?, ?, ?, ?, ?)",
id, data.getName(), data.getPath(), data.getContentType(), data.getSize(), sdf.format(now));

data.setId(id);
}

return R.success(data);
}

return R.success();
}
// TODO: 修改为安全的后台删除方式
@PostMapping("/fs/remove")
public R remove(@RequestParam(value = "filePath") String filePath, HttpServletRequest request) {
File file = new File(filePathGenerator.getFileDiskPath(filePath));
if (file.exists() && file.isFile()) {
if (file.delete()) {
R.success(filePath);
}
}

return R.success();
}
}

+ 44
- 44
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/ImageAttachDao.java ファイルの表示

@@ -1,63 +1,63 @@
package cc.smtweb.system.bpm.spring.dao;

import cc.smtweb.system.bpm.spring.entity.UploadDataVO;
import cc.smtweb.system.bpm.util.ThumbImage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import cc.smtweb.system.bpm.spring.entity.UploadDataVO;

import java.io.File;
import java.io.IOException;

@Service
public class ImageAttachDao {
public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";

public void makeThumb(UploadDataVO data, boolean isThumb, File targetFile, Integer size) throws IOException {
boolean imageType = false;
String fileName = data.getName();
String contentType = data.getContentType();

if (contentType.startsWith("image/")) {
imageType = true;
} else if (contentType.equals(APPLICATION_OCTET_STREAM)) {
String fileExt = fileName.substring(fileName.lastIndexOf("."));

if (StringUtils.isNotEmpty(fileExt)) {
switch (fileExt.toLowerCase()) {
case ".jpg":
case ".jpeg":
contentType = "image/jpg";
imageType = true;
break;
case ".gif":
contentType = "image/gif";
imageType = true;
break;
case ".png":
contentType = "image/png";
public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";

public void makeThumb(UploadDataVO data, boolean isThumb, File targetFile, Integer size) throws IOException {
boolean imageType = false;
String fileName = data.getName();
String contentType = data.getContentType();

if (contentType.startsWith("image/")) {
imageType = true;
break;
default:
break;
} else if (contentType.equals(APPLICATION_OCTET_STREAM)) {
String fileExt = fileName.substring(fileName.lastIndexOf("."));

if (StringUtils.isNotEmpty(fileExt)) {
switch (fileExt.toLowerCase()) {
case ".jpg":
case ".jpeg":
contentType = "image/jpg";
imageType = true;
break;
case ".gif":
contentType = "image/gif";
imageType = true;
break;
case ".png":
contentType = "image/png";
imageType = true;
break;
default:
break;
}

if (imageType) {
data.setContentType(contentType);
}
}
}

if (imageType) {
data.setContentType(contentType);
}
}
}
int thumbHeight = 80;
if (size != null) {
thumbHeight = (size > 500) ? 500: size;
}

if (imageType) {
int thumbHeight = 80;
if (size != null) {
thumbHeight = (size > 500) ? 500 : size;
}
ThumbImage thumbImage = new ThumbImage();

ThumbImage thumbImage = new ThumbImage();

thumbImage.makeThumb(isThumb, targetFile, thumbHeight);
data.setWidth(thumbImage.getImageWidth());
data.setHeight(thumbImage.getImageHeight());
thumbImage.makeThumb(isThumb, targetFile, thumbHeight);
data.setWidth(thumbImage.getImageWidth());
data.setHeight(thumbImage.getImageHeight());
}
}
}
}

+ 71
- 71
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dao/SysAttachDao.java ファイルの表示

@@ -14,101 +14,101 @@ import java.util.Map;

@Service
public class SysAttachDao {
@Autowired
private FilePathGenerator filePathGenerator;

@Autowired
private DbEngine dbEngine;

/**
* 获取文件本地文件路径
*
* @param filePath 相对路径
* @return 本地文件全路径
*/
public String getDiskPath(String filePath) {
return filePathGenerator.getFileDiskPath(filePath);
}

/**
* 获取访问文件的URL地址
*
* @param filePath 文件相对路径
* @return 文件URL地址
*/
public String getFileUrl(String filePath) {
return filePathGenerator.getFileUrl(filePath);
}

/**
* 获取访问文件的URL地址
*
* @param filePath 文件相对路径
* @param filePath 文件名
* @return 文件URL地址
*/
public String getFileUrl(String filePath, String fileName) {
return "/fs/download?path=" + UriEncoder.encode(filePath) + "&name=" + UriEncoder.encode(fileName);
}

public AttachPathPO get(Long id) {
if (id != null) {
return dbEngine.queryEntity("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id=?",
AttachPathPO.class, id);
@Autowired
private FilePathGenerator filePathGenerator;

@Autowired
private DbEngine dbEngine;

/**
* 获取文件本地文件路径
*
* @param filePath 相对路径
* @return 本地文件全路径
*/
public String getDiskPath(String filePath) {
return filePathGenerator.getFileDiskPath(filePath);
}

return null;
}
/**
* 获取访问文件的URL地址
*
* @param filePath 文件相对路径
* @return 文件URL地址
*/
public String getFileUrl(String filePath) {
return filePathGenerator.getFileUrl(filePath);
}

/**
* 获取访问文件的URL地址
*
* @param filePath 文件相对路径
* @param filePath 文件名
* @return 文件URL地址
*/
public String getFileUrl(String filePath, String fileName) {
return "/fs/download?path=" + UriEncoder.encode(filePath) + "&name=" + UriEncoder.encode(fileName);
}

public AttachPathPO get(Long id) {
if (id != null) {
return dbEngine.queryEntity("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id=?",
AttachPathPO.class, id);
}

return null;
}

// 删除文件记录和文件
public void remove(Long fileId) {
// 删除文件记录和文件
public void remove(Long fileId) {
// if (id != null) {
// return dbEngine.queryEntity("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id=?",
// AttachPathPO.class, id);
// }
//
// return null;
}
}

// 删除文件
public void remove(String filePath) {
// 删除文件
public void remove(String filePath) {
// if (id != null) {
// return dbEngine.queryEntity("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id=?",
// AttachPathPO.class, id);
// }
//
// return null;
}
}

public List<AttachPathPO> list(Long[] ids) {
if (ids != null && ids.length > 0) {
return dbEngine.query("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id in( "
+ StringUtils.join(ids, ",") + ")",
AttachPathPO.class);
}

public List<AttachPathPO> list(Long[] ids) {
if (ids != null && ids.length > 0) {
return dbEngine.query("select attach_id, attach_name, attach_path, attach_content_type, attach_size, attach_create_time from sw_user.sys_attach where attach_id in( "
+ StringUtils.join(ids, ",") + ")",
AttachPathPO.class);
return null;
}

return null;
}
public Map<Long, AttachPathPO> map(Long[] ids) {
List<AttachPathPO> list = list(ids);
if (list != null && !list.isEmpty()) {
Map<Long, AttachPathPO> map = new HashMap<>(list.size());
list.forEach((item) -> map.put(item.getAttachId(), item));

public Map<Long, AttachPathPO> map(Long[] ids) {
List<AttachPathPO> list = list(ids);
if (list != null && !list.isEmpty()) {
Map<Long, AttachPathPO> map = new HashMap<>(list.size());
list.forEach((item) -> map.put(item.getAttachId(), item));
return map;
}

return map;
return null;
}

return null;
}
// 保持文件,删除临时文件记录,避免被定时删除
public void retain(String filePath) {

// 保持文件,删除临时文件记录,避免被定时删除
public void retain(String filePath) {

}
}

// 保持文件,删除临时文件记录,避免被定时删除
public void retain(Long fileId) {
// 保持文件,删除临时文件记录,避免被定时删除
public void retain(Long fileId) {

}
}
}

+ 11
- 11
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dataCacheInit/AttachFolderEntityBuffer.java ファイルの表示

@@ -20,13 +20,13 @@ public final class AttachFolderEntityBuffer {
@Autowired
private DbEngine dbEngine;

public static final String cacheKey="attach_folder_";
public static final String cacheKey = "attach_folder_";


//根据附件路径和期间获取对象
public AttachFolderPojo getByPath(String attachPath, String period) {

return redisManager.get(cacheKey+attachPath + "_" + period, AttachFolderPojo.class);
return redisManager.get(cacheKey + attachPath + "_" + period, AttachFolderPojo.class);

}

@@ -45,27 +45,27 @@ public final class AttachFolderEntityBuffer {
}

//初始化数据
public void initData(){
public void initData() {
//查询所有数据
String sql="select folder_id,folder_path,folder_period,folder_max_seq,folder_file_count from "+ AttachFolder.ENTITY_NAME;
List<AttachFolder> returnList = dbEngine.query(sql,AttachFolder.class);
if(null !=returnList && returnList.size()>0){
for(AttachFolder pojo:returnList){
AttachFolderPojo p=new AttachFolderPojo();
String sql = "select folder_id,folder_path,folder_period,folder_max_seq,folder_file_count from " + AttachFolder.ENTITY_NAME;
List<AttachFolder> returnList = dbEngine.query(sql, AttachFolder.class);
if (null != returnList && returnList.size() > 0) {
for (AttachFolder pojo : returnList) {
AttachFolderPojo p = new AttachFolderPojo();
p.setFolderId(pojo.getId());
p.setFolderAttachPath(pojo.getPath());
p.setFolderFileCount(pojo.getFileCount());
p.setFolderPeriod(pojo.getPeriod());
p.setFolderMaxSeq(pojo.getMaxSeq());
redisManager.set(cacheKey+pojo.getPath()+"_"+pojo.getPeriod(),p,0);
redisManager.set(cacheKey + pojo.getPath() + "_" + pojo.getPeriod(), p, 0);
}
}
}

//写入一个数据
public void putOneData(AttachFolderPojo pojo){
public void putOneData(AttachFolderPojo pojo) {
//查询所有数据
redisManager.set(cacheKey+pojo.getFolderAttachPath()+"_"+pojo.getFolderPeriod(),pojo,0);
redisManager.set(cacheKey + pojo.getFolderAttachPath() + "_" + pojo.getFolderPeriod(), pojo, 0);
}

}

+ 6
- 6
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/AttachPathPO.java ファイルの表示

@@ -4,10 +4,10 @@ import lombok.Data;

@Data
public class AttachPathPO {
private Long attachId;
private String attachName;
private String attachPath;
private String attachContentType;
private Long attachSize;
private Long attachCreate;
private Long attachId;
private String attachName;
private String attachPath;
private String attachContentType;
private Long attachSize;
private Long attachCreate;
}

+ 1
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/FileDataVO.java ファイルの表示

@@ -4,5 +4,5 @@ import lombok.Data;

@Data
public class FileDataVO {
private String data;
private String data;
}

+ 8
- 8
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/entity/UploadDataVO.java ファイルの表示

@@ -4,12 +4,12 @@ import lombok.Data;

@Data
public class UploadDataVO {
private Long id;
private Integer height;
private Integer width;
private long size;
private String path;
private String name;
private String contentType;
private String url;
private Long id;
private Integer height;
private Integer width;
private long size;
private String path;
private String name;
private String contentType;
private String url;
}

+ 6
- 5
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachFileWork.java ファイルの表示

@@ -1,6 +1,6 @@
package cc.smtweb.system.bpm.spring.file.attach;

import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.spring.config.FileConfigProperties;
import cc.smtweb.system.bpm.util.UtilDownloadFile;
import cc.smtweb.system.bpm.util.UtilFile;
@@ -19,12 +19,13 @@ import java.util.List;
public final class AttachFileWork implements IAttachWorkIntf {
@Autowired
private FileConfigProperties properties;

private String getPath(String remoteFolderPath) {
String path =properties.getAttachPath();
if (PubUtil.isNotEmpty(remoteFolderPath) && !path.endsWith("/") && !remoteFolderPath.startsWith("/"))
String path = properties.getAttachPath();
if (StringUtil.isNotEmpty(remoteFolderPath) && !path.endsWith("/") && !remoteFolderPath.startsWith("/"))
path = path + "/" + remoteFolderPath;
else path = path + remoteFolderPath;
path = path.replaceAll("-","");
path = path.replaceAll("-", "");
UtilFile.makeDir(path);
if (!path.endsWith("/")) path = path + "/";
return path;
@@ -37,7 +38,7 @@ public final class AttachFileWork implements IAttachWorkIntf {
public void saveAttach(String remoteAttachName, String remoteFolderPath, String localAttach, boolean isDelLocal) throws Exception {
String dstFile = getFileName(remoteFolderPath, remoteAttachName);
if (isDelLocal) UtilFile.renameTo(localAttach, dstFile);
else UtilFile.copy(localAttach,dstFile);
else UtilFile.copy(localAttach, dstFile);
}

@Override


+ 4
- 3
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachFtpWork.java ファイルの表示

@@ -1,6 +1,6 @@
package cc.smtweb.system.bpm.spring.file.attach;

import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.spring.config.FileConfigProperties;
import cc.smtweb.system.bpm.util.UtilDownloadFile;
import cc.smtweb.system.bpm.util.UtilFile;
@@ -31,9 +31,10 @@ public final class AttachFtpWork implements IAttachWorkIntf {
Logger logger = LoggerFactory.getLogger(AttachFtpWork.class);
@Autowired
private FileConfigProperties properties;

private String getPath(String remoteFolderPath) {
String path = properties.getAttachPath();
if (PubUtil.isNotEmpty(remoteFolderPath) && !path.endsWith("/") && !remoteFolderPath.startsWith("/"))
if (StringUtil.isNotEmpty(remoteFolderPath) && !path.endsWith("/") && !remoteFolderPath.startsWith("/"))
path = path + "/" + remoteFolderPath;
else path = path + remoteFolderPath;
path = path.replaceAll("-", "");
@@ -169,7 +170,7 @@ public final class AttachFtpWork implements IAttachWorkIntf {
getFtpManager().execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
try {
ftp.downloadFileEx(getPath(remotePath), remoteName,localPath + File.separator + localName );
ftp.downloadFileEx(getPath(remotePath), remoteName, localPath + File.separator + localName);
} catch (Exception e) {
e.printStackTrace();
}


+ 49
- 46
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachHelper.java ファイルの表示

@@ -1,10 +1,12 @@
package cc.smtweb.system.bpm.spring.file.attach;

import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.NumberUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.spring.config.FileConfigProperties;
import cc.smtweb.system.bpm.util.UtilFile;
import cc.smtweb.system.bpm.util.UtilMath;
import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,8 +31,9 @@ public final class AttachHelper {
private DbEngine dbEngine;
@Autowired
private AttachUtil attachUtil;

//得到附件临时目录
public String getAttachTmpPath() {
public String getAttachTmpPath() {
String tmp_attach = properties.getAttachTempPath();
if (!tmp_attach.endsWith("/")) tmp_attach += "/";
File file = new File(tmp_attach);
@@ -41,10 +44,10 @@ public final class AttachHelper {
}

//删除ftp服务器的文件
public boolean deleteOneAttach(String attachId) throws Exception {
if (PubUtil.isEmpty(attachId)) return true;
public boolean deleteOneAttach(String attachId) throws Exception {
if (StringUtil.isEmpty(attachId)) return true;
AttachInfo attachInfo = dbEngine.queryEntity(AttachInfo.class, Long.valueOf(attachId));
if(null == attachInfo){
if (null == attachInfo) {
return true;
}
boolean deleteSuccess = deleteAttachInFtpServer(attachInfo.getPath(), attachInfo.getName());
@@ -55,7 +58,7 @@ public final class AttachHelper {
}

//删除ftp服务器的文件
public boolean deleteOneAttach(AttachInfo bean) {
public boolean deleteOneAttach(AttachInfo bean) {
boolean deleteSuccess = deleteAttachInFtpServer(bean.getPath(), bean.getName());
if (deleteSuccess) {
dbEngine.deleteEntity(bean);
@@ -64,41 +67,41 @@ public final class AttachHelper {
}

//删除ftp服务器的文件夹
public void deleteFolder(final String remotePath) throws Exception {
public void deleteFolder(final String remotePath) throws Exception {
attachUtil.deletePath(remotePath);
}

public List<AttachInfo> getAttachListByOwnerId(String ownerId) throws Exception {
return dbEngine.query("select * from "+AttachInfo.ENTITY_NAME+" where attach_owner_id=? ",AttachInfo.class,ownerId);
public List<AttachInfo> getAttachListByOwnerId(String ownerId) throws Exception {
return dbEngine.query("select * from " + AttachInfo.ENTITY_NAME + " where attach_owner_id=? ", AttachInfo.class, ownerId);
}

public List<AttachInfo> listAttachListByOwnerIdAndType(String ownerId, String attach_type) throws Exception {
return dbEngine.query("select * from "+AttachInfo.ENTITY_NAME+" where attach_owner_id=? and attach_type=? ",AttachInfo.class,ownerId,attach_type);
public List<AttachInfo> listAttachListByOwnerIdAndType(String ownerId, String attach_type) throws Exception {
return dbEngine.query("select * from " + AttachInfo.ENTITY_NAME + " where attach_owner_id=? and attach_type=? ", AttachInfo.class, ownerId, attach_type);
}

public int getAttachCountByOwnerId(String ownerId) throws Exception {
return dbEngine.queryInt("select count(0) from "+AttachInfo.ENTITY_NAME+" where attach_owner_id=? ",ownerId);
public int getAttachCountByOwnerId(String ownerId) throws Exception {
return dbEngine.queryInt("select count(0) from " + AttachInfo.ENTITY_NAME + " where attach_owner_id=? ", ownerId);
}

//根据附件拥有者和附件类型删除
public boolean deleteAttachByOwnerIdAndType(String ownerId, String attachType) throws Exception {
public boolean deleteAttachByOwnerIdAndType(String ownerId, String attachType) throws Exception {
final List<AttachInfo> list = listAttachListByOwnerIdAndType(ownerId, attachType);
return deleteAttachListEx(list);
}

public boolean deleteAttachByOwnerId(String ownerId) throws Exception {
public boolean deleteAttachByOwnerId(String ownerId) throws Exception {
final List<AttachInfo> list = getAttachListByOwnerId(ownerId);
return deleteAttachListEx(list);
}

//批量删除
public boolean deleteAttachList(List<String> attachIdList) throws Exception {
if (PubUtil.isEmpty(attachIdList)) return false;
dbEngine.update("delete from "+AttachInfo.ENTITY_NAME+" where attach_id in(" + PubUtil.getSqlInIds(attachIdList) + ")");
public boolean deleteAttachList(List<String> attachIdList) throws Exception {
if (CommUtil.isEmpty(attachIdList)) return false;
dbEngine.update("delete from " + AttachInfo.ENTITY_NAME + " where attach_id in(" + StringUtil.join(attachIdList,",") + ")");
return true;
}

public boolean deleteAttachListEx(List<AttachInfo> list) throws Exception {
public boolean deleteAttachListEx(List<AttachInfo> list) throws Exception {
boolean result = true;
for (AttachInfo bean : list) {
if (!deleteAttachInFtpServer(bean.getPath(), bean.getName())) {
@@ -115,7 +118,7 @@ public final class AttachHelper {
}

//删除在ftp服务器上的附件
public boolean deleteAttachInFtpServer(String remotePath, String remoteName) {
public boolean deleteAttachInFtpServer(String remotePath, String remoteName) {
try {
attachUtil.deleteAttach(remotePath, remoteName);
} catch (Exception e) {
@@ -133,7 +136,7 @@ public final class AttachHelper {
* @return 返回文件名
* @throws Exception
*/
public String getAttachFromFtp(final String attachId, final String localPath) throws Exception {
public String getAttachFromFtp(final String attachId, final String localPath) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, Long.valueOf(attachId));
if (null == attach) throw new Exception("附件不存在!");

@@ -153,7 +156,7 @@ public final class AttachHelper {
* @return 返回文件名
* @throws Exception
*/
public String getAttachFromFtp(final String attachId, final String localPath, String localName) throws Exception {
public String getAttachFromFtp(final String attachId, final String localPath, String localName) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, Long.valueOf(attachId));
if (null == attach) throw new Exception("附件不存在!");
final String remoteFileName = attach.getName();
@@ -172,7 +175,7 @@ public final class AttachHelper {
* @return 返回文件名列表,本地有此文件将不再下载
* @throws Exception
*/
private List<String> getAttachListFromFtp(final List<AttachInfo> attachlist, final String ownerType) throws Exception {
private List<String> getAttachListFromFtp(final List<AttachInfo> attachlist, final String ownerType) throws Exception {
return attachUtil.getAttachListFromFtp(attachlist, ownerType, getAttachTmpPath());
}

@@ -184,7 +187,7 @@ public final class AttachHelper {
* @return 返回文件名列表,本地有此文件将不再下载
* @throws Exception
*/
public List<String> getAttachsFromFtp(final String ownerId, final String ownerType) throws Exception {
public List<String> getAttachsFromFtp(final String ownerId, final String ownerType) throws Exception {
final List<AttachInfo> attachlist = getAttachListByOwnerId(ownerId);

return getAttachListFromFtp(attachlist, ownerType);
@@ -199,20 +202,20 @@ public final class AttachHelper {
* @return 返回文件名列表,本地有此文件将不再下载
* @throws Exception
*/
public List<String> getAttachsFromFtp(final List<String> attachIds, final String ownerType) throws Exception {
public List<String> getAttachsFromFtp(final List<String> attachIds, final String ownerType) throws Exception {
List<Object> paras = new ArrayList<Object>();
if (PubUtil.isNotEmpty(attachIds)) {
if (!CommUtil.isEmpty(attachIds)) {
StringBuilder sb = new StringBuilder(128);
for(int i=0;i<attachIds.size();i++){
if(i==0){
for (int i = 0; i < attachIds.size(); i++) {
if (i == 0) {
sb.append(" attach_id=? ");
}else{
} else {
sb.append(" or attach_id=? ");
}
paras.add(attachIds.get(i));
}
final List<AttachInfo> attachlist =dbEngine.queryWhere(AttachInfo.class,sb.toString(),paras.toArray());
if (null == attachlist || attachlist.size()<1) throw new Exception("附件不存在!");
final List<AttachInfo> attachlist = dbEngine.queryWhere(AttachInfo.class, sb.toString(), paras.toArray());
if (null == attachlist || attachlist.size() < 1) throw new Exception("附件不存在!");
return getAttachListFromFtp(attachlist, ownerType);
}
return new ArrayList<>();
@@ -223,12 +226,12 @@ public final class AttachHelper {
*
* @return
*/
public String getSizeStr(long fileSize) {
public String getSizeStr(long fileSize) {
if (fileSize < 1024) return fileSize + "B";
double n = fileSize * 1.0 / 1024;
if (UtilMath.compare(n, 1024) < 0) return UtilMath.toStdNumberString(n, 0) + "KB";
if (NumberUtil.compare(n, 1024) < 0) return NumberUtil.toStdNumberString(n, 0) + "KB";
n = n / 1024;
return UtilMath.toStdNumberString(n) + "MB";
return NumberUtil.toStdNumberString(n) + "MB";
}

/**
@@ -237,31 +240,31 @@ public final class AttachHelper {
* @param attach_owner_id 拥有者
* @throws Exception
*/
public void removeTempTag(String attach_owner_id) throws Exception {
dbEngine.update("update "+AttachInfo.ENTITY_NAME+" set attach_is_temp=0 WHERE attach_owner_id=? AND attach_is_temp=1 ",attach_owner_id);
public void removeTempTag(String attach_owner_id) throws Exception {
dbEngine.update("update " + AttachInfo.ENTITY_NAME + " set attach_is_temp=0 WHERE attach_owner_id=? AND attach_is_temp=1 ", attach_owner_id);
}

public String copyupload(String type,Long attachId) {
public String copyupload(String type, Long attachId) {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, attachId);
if(attach==null){
if (attach == null) {
return "";
}
String remoteName =attach.getId()+attach.getName().substring(attach.getName().lastIndexOf("."));
String remoteName = attach.getId() + attach.getName().substring(attach.getName().lastIndexOf("."));
String remotePath = attach.getPath();
String filePath =getAttachTmpPath()+"tempFiles/";
String filePath = getAttachTmpPath() + "tempFiles/";
UtilFile.makeDir(filePath);
Map<String, String> map = null;
try {
attachUtil.downloadAttach(remotePath, remoteName, filePath);
String filePaths=filePath+remoteName;
String filePaths = filePath + remoteName;

attach.setId(dbEngine.nextId());
attach.setType(type);//附件类别
attach.setOwnerId(-1l);//附件拥有者id
attach.setPartyId(-1l);
attach.setTime(PubUtil.getLastTime());
attach.setTime(DateUtil.nowDateTimeLong());
attach.setUserId(-1l);
attach.setName(attach.getId()+attach.getSuffix());
attach.setName(attach.getId() + attach.getSuffix());
// 上传文件域对象
File upload = new File(filePaths);
// attach.setAttachSize((long) FileCopyUtils.copy(file.getInputStream(), new BufferedOutputStream(new FileOutputStream(upload))));
@@ -274,10 +277,10 @@ public final class AttachHelper {
} finally {
UtilFile.delFile(upload.getAbsolutePath());
}
}catch (Exception e){
} catch (Exception e) {
logger.error("复制文件失败", e);
return "";
}
return attach.getId()+"";
return attach.getId() + "";
}
}

+ 17
- 16
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachUtil.java ファイルの表示

@@ -3,7 +3,7 @@ package cc.smtweb.system.bpm.spring.file.attach;

import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.spring.config.FileConfigProperties;
import cc.smtweb.system.bpm.spring.dataCacheInit.AttachFolderEntityBuffer;
import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;
@@ -24,7 +24,7 @@ import java.util.List;
public final class AttachUtil {
//一个文件夹下最多允许多少文件
private final static int MAX_FILE_COUNT = 1000;
private static IAttachWorkIntf worker;
private static IAttachWorkIntf worker;
@Autowired
private FileConfigProperties properties;
@Autowired
@@ -35,22 +35,23 @@ public final class AttachUtil {
private AttachFtpWork attachFtpWork;
@Autowired
private AttachFileWork attachFileWork;

static {
// init();
}

public void init() {
final String at = PubUtil.checkNull(properties.getAttachType()).toLowerCase();
public void init() {
final String at = StringUtil.checkNull(properties.getAttachType()).toLowerCase();
if ("ftp".equals(at) || "sftp".equals(at))
worker = attachFtpWork;
else worker = attachFileWork;
}

private void checkAttachFolder(final AttachInfo attach) throws Exception {
private void checkAttachFolder(final AttachInfo attach) throws Exception {
final String period = DateUtil.getNowYm();
AttachFolderPojo folder = attachFolderEntityBuffer.getByPath(attach.getPath(), period);

AttachFolder entity=new AttachFolder();
AttachFolder entity = new AttachFolder();
boolean isNew = false;
if (folder == null) {
isNew = true;
@@ -92,43 +93,43 @@ public final class AttachUtil {
}
}

public void saveAttach(String remoteAttachName, String remoteFolderPath, String localAttach, boolean isDelLocal) throws Exception {
public void saveAttach(String remoteAttachName, String remoteFolderPath, String localAttach, boolean isDelLocal) throws Exception {
worker.saveAttach(remoteAttachName, remoteFolderPath, localAttach, isDelLocal);
}

public void copyAttach(String srcFileName, String desFileName, String remoteFolderPath, boolean isDelSrc) throws Exception {
public void copyAttach(String srcFileName, String desFileName, String remoteFolderPath, boolean isDelSrc) throws Exception {
worker.copyAttach(srcFileName, desFileName, remoteFolderPath, isDelSrc);
}

public void deletePath(String remotePath) throws Exception {
public void deletePath(String remotePath) throws Exception {
worker.deletePath(remotePath);
}

public void deleteAttach(String remotePath, String remoteName) throws Exception {
public void deleteAttach(String remotePath, String remoteName) throws Exception {
worker.deleteAttach(remotePath, remoteName);
}

public void downloadAttach(String remotePath, String remoteName, String fileName, HttpServletResponse response) throws Exception {
public void downloadAttach(String remotePath, String remoteName, String fileName, HttpServletResponse response) throws Exception {
worker.downloadAttach(remotePath, remoteName, fileName, response);
}

public void downloadAttach(String remotePath, String remoteName, String localPath) throws Exception {
public void downloadAttach(String remotePath, String remoteName, String localPath) throws Exception {
worker.downloadAttach(remotePath, remoteName, localPath);
}

public void downloadAttach(String remotePath, String remoteName, String localPath, String localName) throws Exception {
public void downloadAttach(String remotePath, String remoteName, String localPath, String localName) throws Exception {
worker.downloadAttach(remotePath, remoteName, localPath, localName);
}

public List<String> getAttachListFromFtp(final List<AttachInfo> attachlist, final String ownerType, final String localRoot) throws Exception {
public List<String> getAttachListFromFtp(final List<AttachInfo> attachlist, final String ownerType, final String localRoot) throws Exception {
return worker.getAttachListFromFtp(attachlist, ownerType, localRoot);
}

public void makeRemoteDir(String path) throws Exception {
public void makeRemoteDir(String path) throws Exception {
worker.makeRemoteDir(path);
}

public Path getAttachPath(String remotePath, String remoteName) throws Exception {
public Path getAttachPath(String remotePath, String remoteName) throws Exception {
return worker.getAttachPath(remotePath, remoteName);
}



+ 4
- 6
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/IAttachWorkIntf.java ファイルの表示

@@ -1,7 +1,6 @@
package cc.smtweb.system.bpm.spring.file.attach;



import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;

import javax.servlet.http.HttpServletResponse;
@@ -28,10 +27,10 @@ public interface IAttachWorkIntf {
/**
* 复制附件
*
* @param srcFileName 源文件
* @param desFileName 新文件
* @param remoteFolderPath 文件路径
* @param isDelSrc 保存后是否删除源文件
* @param srcFileName 源文件
* @param desFileName 新文件
* @param remoteFolderPath 文件路径
* @param isDelSrc 保存后是否删除源文件
* @throws Exception
*/
void copyAttach(String srcFileName, String desFileName, String remoteFolderPath, boolean isDelSrc) throws Exception;
@@ -109,7 +108,6 @@ public interface IAttachWorkIntf {

/**
* 获取文件路径
*
*/
Path getAttachPath(String remotePath, String remoteName);
}

+ 1
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/initPlugin/RunDataInit.java ファイルの表示

@@ -18,6 +18,7 @@ public class RunDataInit implements ApplicationRunner {
private AttachFolderEntityBuffer attachFolderEntityBuffer;
@Autowired
private AttachUtil attachUtil;

@Override
public void run(ApplicationArguments args) throws Exception {
attachFolderEntityBuffer.initData();//附件目录缓存


+ 81
- 81
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/BeanUtil.java ファイルの表示

@@ -1,7 +1,7 @@
package cc.smtweb.system.bpm.util;

import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.exception.SwException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
@@ -17,104 +17,104 @@ import java.util.Arrays;
import java.util.List;

public class BeanUtil {
private BeanUtil() {}
private BeanUtil() {
}

public static void mapToBean(SwMap source, Object target) {
mapToBean(source, target, null);
}
public static void mapToBean(SwMap source, Object target) {
mapToBean(source, target, null);
}

private static void mapToBean(SwMap source, Object target, @Nullable Class<?> editable,
@Nullable String... ignoreProperties) throws BeansException {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
private static void mapToBean(SwMap source, Object target, @Nullable Class<?> editable,
@Nullable String... ignoreProperties) throws BeansException {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");

Class<?> actualEditable = target.getClass();
if (editable != null) {
if (!editable.isInstance(target)) {
throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
"] not assignable to Editable class [" + editable.getName() + "]");
}
actualEditable = editable;
}
PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
Class<?> actualEditable = target.getClass();
if (editable != null) {
if (!editable.isInstance(target)) {
throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
"] not assignable to Editable class [" + editable.getName() + "]");
}
actualEditable = editable;
}
PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties): null);

for (PropertyDescriptor targetPd : targetPds) {
Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
Object value = source.get(targetPd.getName());
for (PropertyDescriptor targetPd : targetPds) {
Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
Object value = source.get(targetPd.getName());

if (value == null || ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], value.getClass())) {
try {
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
if (value == null || ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], value.getClass())) {
try {
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(target, value);
} catch (Throwable ex) {
throw new FatalBeanException(
"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
}
}
}
writeMethod.invoke(target, value);
} catch (Throwable ex) {
throw new FatalBeanException(
"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
}
}
}
}
}

public static void beanToMap(Object source, SwMap target, @Nullable String... ignoreProperties) throws BeansException {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
public static void beanToMap(Object source, SwMap target, @Nullable String... ignoreProperties) throws BeansException {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");

List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties): null);

PropertyDescriptor[] sourcePds = BeanUtils.getPropertyDescriptors(source.getClass());
PropertyDescriptor[] sourcePds = BeanUtils.getPropertyDescriptors(source.getClass());

for (PropertyDescriptor sourcePd: sourcePds) {
if (ignoreList == null || !ignoreList.contains(sourcePd.getName())) {
for (PropertyDescriptor sourcePd : sourcePds) {
if (ignoreList == null || !ignoreList.contains(sourcePd.getName())) {
// PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getKey());
// if (sourcePd != null) {
Method readMethod = sourcePd.getReadMethod();
if (readMethod != null) {
try {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source);
target.put(sourcePd.getName(), value);
}
catch (Throwable ex) {
throw new FatalBeanException(
"Could not copy property '" + sourcePd.getName() + "' from source to target", ex);
}
}
Method readMethod = sourcePd.getReadMethod();
if (readMethod != null) {
try {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source);
target.put(sourcePd.getName(), value);
} catch (Throwable ex) {
throw new FatalBeanException(
"Could not copy property '" + sourcePd.getName() + "' from source to target", ex);
}
}
// }
}
}
}
}
}

public static List<?> toBeanList(List<SwMap> bodyList, Class<?> clazz) {
List<Object> beans = new ArrayList<>(bodyList.size());
try {
for (SwMap body: bodyList) {
Object bean = clazz.newInstance();
BeanUtil.mapToBean(body, bean);
beans.add(bean);
}
} catch (InstantiationException | IllegalAccessException e) {
throw new SwException(e);
public static List<?> toBeanList(List<SwMap> bodyList, Class<?> clazz) {
List<Object> beans = new ArrayList<>(bodyList.size());
try {
for (SwMap body : bodyList) {
Object bean = clazz.newInstance();
BeanUtil.mapToBean(body, bean);
beans.add(bean);
}
} catch (InstantiationException | IllegalAccessException e) {
throw new SwException(e);
}
return beans;
}
return beans;
}

public static List<SwMap> toMapList(List<?> beans) {
List<SwMap> bodyList = null;
if (beans != null) {
bodyList = new ArrayList<>(beans.size());
for (Object bean: beans) {
SwMap body = new SwMap();
beanToMap(bean, body);
bodyList.add(body);
}
}
public static List<SwMap> toMapList(List<?> beans) {
List<SwMap> bodyList = null;
if (beans != null) {
bodyList = new ArrayList<>(beans.size());
for (Object bean : beans) {
SwMap body = new SwMap();
beanToMap(bean, body);
bodyList.add(body);
}
}

return bodyList;
}
return bodyList;
}
}

+ 27
- 85
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/CodeGenerator.java ファイルの表示

@@ -1,9 +1,9 @@
package cc.smtweb.system.bpm.util;

import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.exception.SwException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateMethodModelEx;
@@ -12,13 +12,12 @@ import org.apache.commons.io.IOUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Created by Akmm at 2022/6/8 15:36
* 模板生成代码
* Created by Akmm at 2022/6/8 15:36
* 模板生成代码
*/
public class CodeGenerator {
private final static String KEY_MODEL = "model";
@@ -28,7 +27,8 @@ public class CodeGenerator {
private final static String TEMPLATE_JS_EVENT = "js_event";
private static CodeGenerator instance = null;

private Configuration configuration = null;
private Configuration modelConfiguration = null;
private Configuration codeConfiguration = null;

private final String encode = org.apache.commons.codec.CharEncoding.UTF_8;
//模板文件所在目录
@@ -40,32 +40,33 @@ public class CodeGenerator {
protected CodeGenerator() {
// templatesDir = this.getClass().getResource("/static/template").getPath();
mapTemplate = YamlUtil.readValue(this.getClass().getResourceAsStream("/static/template/" + SwConsts.modelPath + "/index.yaml"), SwMap.class);
configuration = new Configuration(Configuration.VERSION_2_3_31);
try {
configuration.setClassForTemplateLoading(this.getClass(), "/static/template/");
modelConfiguration = buildConfig("/static/template/" + SwConsts.modelPath);
codeConfiguration = buildConfig("/static/template/");
}

private Configuration buildConfig(String path) {
Configuration config = new Configuration(Configuration.VERSION_2_3_31);
config.setClassForTemplateLoading(this.getClass(), path);
// configuration.setDirectoryForTemplateLoading(new File(templatesDir));
configuration.setClassicCompatible(true);
configuration.setDefaultEncoding(encode);
configuration.setOutputEncoding(encode);
} catch (Exception e) {
e.printStackTrace();
throw new SwException(e);
}
config.setClassicCompatible(true);
config.setDefaultEncoding(encode);
config.setOutputEncoding(encode);
return config;
}

//页面设计的模板信息
public List<Map<String, Object>> getModelTemplates() {
return (List<Map<String, Object>>)mapTemplate.get(KEY_MODEL);
return (List<Map<String, Object>>) mapTemplate.get(KEY_MODEL);
}

private void initModel(Map<String, Object> model) {
model.put("newId", new PKGenerator());
}

public void generate(Map<String, Object> model, String templateName, Writer writer) {
public void generate(Configuration config, Map<String, Object> model, String templateName, Writer writer) {
try {
initModel(model);
Template template = configuration.getTemplate(templateName, encode);
Template template = config.getTemplate(templateName, encode);
template.setOutputEncoding(encode);
template.process(model, writer);
writer.close();
@@ -76,7 +77,7 @@ public class CodeGenerator {
}


public void generate(Map<String, Object> model, String templateName, String fileName) {
public void generate(Configuration config, Map<String, Object> model, String templateName, String fileName) {
File file = new File(fileName);
if (file.exists()) file.delete();
FileOutputStream out = null;
@@ -85,7 +86,7 @@ public class CodeGenerator {
out = new FileOutputStream(fileName);

initModel(model);
Template template = configuration.getTemplate(templateName + ".ftl", StandardCharsets.UTF_8.toString());
Template template = config.getTemplate(templateName + ".ftl", StandardCharsets.UTF_8.toString());
template.setOutputEncoding(encode);
template.process(model, new OutputStreamWriter(out, encode));
out.flush();
@@ -96,26 +97,26 @@ public class CodeGenerator {
}
}

public String generate(Map<String, Object> model, String templateName) {
public String generatePage(Map<String, Object> model, String templateName) {
StringWriter out = new StringWriter();
generate(model, SwConsts.modelPath + "/" + templateName + ".ftl", out);
generate(modelConfiguration, model, templateName + ".ftl", out);
return out.getBuffer().toString();
}

public void generateBean(Map<String, Object> model, String fileName) {
generate(model, TEMPLATE_JAVA_BEAN, fileName);
generate(codeConfiguration, model, TEMPLATE_JAVA_BEAN, fileName);
}

public void generateCache(Map<String, Object> model, String fileName) {
generate(model, TEMPLATE_JAVA_CACHE, fileName);
generate(codeConfiguration, model, TEMPLATE_JAVA_CACHE, fileName);
}

public void generateService(Map<String, Object> model, String fileName) {
generate(model, TEMPLATE_JAVA_SERVICE, fileName);
generate(codeConfiguration, model, TEMPLATE_JAVA_SERVICE, fileName);
}

public void generateJsEvent(Map<String, Object> model, String fileName) {
generate(model, TEMPLATE_JS_EVENT, fileName);
generate(codeConfiguration, model, TEMPLATE_JS_EVENT, fileName);
}


@@ -140,63 +141,4 @@ public class CodeGenerator {
// return DbEngine.getInstance().nextId();
}
}


/*
{param:{pa:"aaa"},
layout:{
c1:[{type:"list", dataset:"ds123", fields:[{field:"", dataset:""}], cfilters:[{}]}]
}
*/
public static void main(String[] args) {
StringWriter out = new StringWriter();
SwMap map = new SwMap();
SwMap param = new SwMap();
param.put("pa", "aaaaa");
map.put("param", param);

SwMap layout = new SwMap();
map.put("layout", layout);
List<SwMap> groups = new ArrayList<>();
layout.put("c1", groups);

SwMap area = new SwMap();
groups.add(area);
area.put("type", "list");
area.put("dataset", "ds123");

List<SwMap> fields = new ArrayList<>();
area.put("fields", fields);
SwMap field = new SwMap();
field.put("field", "f123");
field.put("dataset", "ds123");
field.put("label", "字段123");
fields.add(field);

field = new SwMap();
field.put("field", "f121");
field.put("label", "字段121");
field.put("dataset", "ds123");
fields.add(field);

field = new SwMap();
field.put("field", "f122");
field.put("label", "字段122");
field.put("dataset", "ds123");
fields.add(field);

List<SwMap> filters = new ArrayList<>();
area.put("cfilters", filters);
field = new SwMap();
field.put("field", "f122");
field.put("dataset", "ds123");
field.put("label", "字段122");
field.put("maxlength", 20);
filters.add(field);

map.put("title", "thisIsATest!");
map.put("newId", new PKGenerator());
CodeGenerator.getInstance().generate(map, SwConsts.modelPath + "/model_card.ftl", out);
System.out.println(out.getBuffer().toString());
}
}

+ 1
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FileDynPath.java ファイルの表示

@@ -53,7 +53,7 @@ public class FileDynPath extends FileFixPath {
// 如果文件数量太大就需要创建新子目录
while (this.fileCount >= MAX_FILE_COUNT) {
this.pathIndex++;
if(this.pathIndex > MAX_DIR_COUNT) {
if (this.pathIndex > MAX_DIR_COUNT) {
throw new RuntimeException("dir is two many");
}



+ 63
- 62
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathGenerator.java ファイルの表示

@@ -1,16 +1,16 @@
package cc.smtweb.system.bpm.util;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

import cc.smtweb.framework.core.db.jdbc.IdGenerator;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.tika.mime.MimeType;
import org.apache.tika.mime.MimeTypeException;
import org.apache.tika.mime.MimeTypes;
import org.springframework.web.multipart.MultipartFile;
import cc.smtweb.framework.core.db.jdbc.IdGenerator;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

/**
* 文件名生成规则 subDir/[yyyymm]/[d]/[hex(fileid)]_[hex(rand)].[fileExt] 如果文件是图片格式,会生成缩略图,文件名会直接添加.thumb.jpg后缀 规则参数 yyyymm:
@@ -19,50 +19,51 @@ import cc.smtweb.framework.core.db.jdbc.IdGenerator;
@Slf4j
public class FilePathGenerator {

public static final String THUMB_FILE_EXT = ".thumb.jpg";
// 文件时间是否作为PK
private SimpleDateFormat sdf;
@Getter
private String rootPath;
private Map<String, FileFixPath> fileFxPathMap = new HashMap<>();
private Map<String, FileDynPath> fileDynPathMap = new HashMap<>();
private String fileUrl;
private IdGenerator idGenerator;

public FilePathGenerator(String rootPath, String fileUrl, IdGenerator idGenerator) {
this.fileUrl = fixEnd(fileUrl);
this.idGenerator = idGenerator;
this.rootPath = fixEnd(rootPath);

sdf = new SimpleDateFormat("yyyyMM/dd/");
}

private static String fixEnd(String path) {
if (path.endsWith("/") || path.endsWith("\\")) {
return path;
} else {
return path + "/";
}
}

/**
* 生成文件路径,根据日期分目录存储
*
* @param subPath 子目录,区分不同应用的文件
* @param originalFileName 原始的文件名,用于提取扩展名用
* @return 文件路径信息类
*/
public FilePathInfo make(String subPath, String originalFileName) {
return make(subPath, originalFileName, null, false);
}

public FilePathInfo make(String subPath, String originalFileName, boolean keepName) {
return make(subPath, originalFileName, null, keepName);
}
public static final String THUMB_FILE_EXT = ".thumb.jpg";
// 文件时间是否作为PK
private SimpleDateFormat sdf;
@Getter
private String rootPath;
private Map<String, FileFixPath> fileFxPathMap = new HashMap<>();
private Map<String, FileDynPath> fileDynPathMap = new HashMap<>();
private String fileUrl;
private IdGenerator idGenerator;

public FilePathGenerator(String rootPath, String fileUrl, IdGenerator idGenerator) {
this.fileUrl = fixEnd(fileUrl);
this.idGenerator = idGenerator;
this.rootPath = fixEnd(rootPath);

sdf = new SimpleDateFormat("yyyyMM/dd/");
}

private static String fixEnd(String path) {
if (path.endsWith("/") || path.endsWith("\\")) {
return path;
} else {
return path + "/";
}
}

/**
* 生成文件路径,根据日期分目录存储
*
* @param subPath 子目录,区分不同应用的文件
* @param subPath 子目录,区分不同应用的文件
* @param originalFileName 原始的文件名,用于提取扩展名用
* @return 文件路径信息类
*/
public FilePathInfo make(String subPath, String originalFileName) {
return make(subPath, originalFileName, null, false);
}

public FilePathInfo make(String subPath, String originalFileName, boolean keepName) {
return make(subPath, originalFileName, null, keepName);
}

/**
* 生成文件路径,根据日期分目录存储
*
* @param subPath 子目录,区分不同应用的文件
* @param multipartFile 上传文件流,用于提取扩展名用
* @return 文件路径信息类
*/
@@ -71,23 +72,23 @@ public class FilePathGenerator {
}

private synchronized FilePathInfo make(String subPath, String originFileName, String contentType, boolean keepName) {
if (keepName) {
FileFixPath filePathSub = fileFxPathMap.get(subPath);
if (filePathSub == null) {
filePathSub = new FileFixPath(this.rootPath, subPath);
fileFxPathMap.put(subPath, filePathSub);
}
if (keepName) {
FileFixPath filePathSub = fileFxPathMap.get(subPath);
if (filePathSub == null) {
filePathSub = new FileFixPath(this.rootPath, subPath);
fileFxPathMap.put(subPath, filePathSub);
}

return filePathSub.makeDatePath(this.idGenerator.nextId(), originFileName);
} else {
FileDynPath filePathSub = fileDynPathMap.get(subPath);
if (filePathSub == null) {
filePathSub = new FileDynPath(this.rootPath, subPath, sdf);
fileDynPathMap.put(subPath, filePathSub);
}
return filePathSub.makeDatePath(this.idGenerator.nextId(), originFileName);
} else {
FileDynPath filePathSub = fileDynPathMap.get(subPath);
if (filePathSub == null) {
filePathSub = new FileDynPath(this.rootPath, subPath, sdf);
fileDynPathMap.put(subPath, filePathSub);
}

return filePathSub.makeDatePath(this.idGenerator.nextId(), ext(originFileName, contentType));
}
return filePathSub.makeDatePath(this.idGenerator.nextId(), ext(originFileName, contentType));
}
}

private static String ext(String filename, String contentType) {
@@ -127,6 +128,6 @@ public class FilePathGenerator {

// 获取下载路径前缀
public String getDownloadUrl() {
return this.fileUrl;
return this.fileUrl;
}
}

+ 32
- 32
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/FilePathInfo.java ファイルの表示

@@ -9,40 +9,40 @@ import lombok.Getter;
*/
@Getter
public class FilePathInfo {
// 文件ID
private long fileId;
// 文件创建时间,数据库需要存储
private long fileTime;
// 文件子路径
private String subPath;
// 文件名
private String fileName;
// 本地根路径
private String rootPath;
// 文件ID
private long fileId;
// 文件创建时间,数据库需要存储
private long fileTime;
// 文件子路径
private String subPath;
// 文件名
private String fileName;
// 本地根路径
private String rootPath;

public FilePathInfo(String rootPath, String subPath, long fileTime, String fileName, long fileId) {
this.rootPath = rootPath;
this.subPath = subPath;
this.fileTime = fileTime;
this.fileName = fileName;
this.fileId = fileId;
}
public FilePathInfo(String rootPath, String subPath, long fileTime, String fileName, long fileId) {
this.rootPath = rootPath;
this.subPath = subPath;
this.fileTime = fileTime;
this.fileName = fileName;
this.fileId = fileId;
}

/**
* 获取本地需要存储的文件全路径
*/
public String getFullFileName() {
return getDiskFilePath();
}
/**
* 获取本地需要存储的文件全路径
*/
public String getFullFileName() {
return getDiskFilePath();
}

public String getDiskFilePath() {
return this.rootPath + subPath + fileName;
}
public String getDiskFilePath() {
return this.rootPath + subPath + fileName;
}

/**
* 获取数据库存储需要的文件全路径
*/
public String getMysqlFilePath() {
return subPath + fileName;
}
/**
* 获取数据库存储需要的文件全路径
*/
public String getMysqlFilePath() {
return subPath + fileName;
}
}

+ 37
- 29
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataHandler.java ファイルの表示

@@ -4,42 +4,50 @@ import java.util.List;

/**
* 树型节点句柄
*
* @author xkliu
*/
public interface ITreeDataHandler<T> {
/**
* 获取ID
* @param node 节点
* @return 节点ID
*/
Long getId(T node);
/**
* 获取ID
*
* @param node 节点
* @return 节点ID
*/
Long getId(T node);

/**
* 获取上级ID
* @param node 当前节点
* @return 上级ID
*/
Long getParentId(T node);
/**
* 获取上级ID
*
* @param node 当前节点
* @return 上级ID
*/
Long getParentId(T node);

// void addChild(IWebTreeVO item);

/**
* 获取下级对象列表
* @param node 当前节点
* @return 下级对象列表
*/
List<T> getChildren(T node);
/**
* 获取下级对象列表
*
* @param node 当前节点
* @return 下级对象列表
*/
List<T> getChildren(T node);

/**
* 设置下级对象列表
* @param children 下级对象列表
*/
void setChildren(T node, List<T> children);
/**
* 设置下级对象列表
*
* @param children 下级对象列表
*/
void setChildren(T node, List<T> children);

/**
* 是否强行添加未找到上级的错误节点到顶级
* @param node 通过node有parentId值,但未找到对应上级节点
* @return 是否强行添加错误节点到顶级
*/
default boolean forceAdd(T node) { return false; }
/**
* 是否强行添加未找到上级的错误节点到顶级
*
* @param node 通过node有parentId值,但未找到对应上级节点
* @return 是否强行添加错误节点到顶级
*/
default boolean forceAdd(T node) {
return false;
}
}

+ 3
- 2
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ITreeDataLevelHandler.java ファイルの表示

@@ -1,6 +1,7 @@
package cc.smtweb.system.bpm.util;

public interface ITreeDataLevelHandler<T> extends ITreeDataHandler<T> {
int getLevel(T t);
void setLevel(T t, int level);
int getLevel(T t);

void setLevel(T t, int level);
}

+ 4
- 7
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/IdeaUtil.java ファイルの表示

@@ -1,18 +1,13 @@
package cc.smtweb.system.bpm.util;


import cc.smtweb.framework.core.common.SwMap;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -23,6 +18,7 @@ import java.util.Map;
*/
public class IdeaUtil {
private final static int MODE_POM = 1;

//获取工程中的Module文件
public static Map<String, String> getModules(String ideaPath, int mode) {
if (mode == MODE_POM) {
@@ -41,7 +37,7 @@ public class IdeaUtil {
Map<String, String> map = new HashMap<>();
PomProject project = XmlUtil.readValue(file, PomProject.class);
if (project == null || project.modules == null) return map;
for (String module: project.modules) {
for (String module : project.modules) {
File f = new File(ideaPath + "/" + module);
String s = f.getName();
int i = s.lastIndexOf(".");
@@ -50,11 +46,12 @@ public class IdeaUtil {
}
return map;
}

public static Map<String, String> getModulesFromModule(String ideaPath, File file) {
Map<String, String> map = new HashMap<>();
IdeaProject project = XmlUtil.readValue(file, IdeaProject.class);
if (project == null || project.component == null || project.component.modules == null) return map;
for (Module module: project.component.modules) {
for (Module module : project.component.modules) {
String s = module.filepath.replace("$PROJECT_DIR$", ideaPath);
File f = new File(s);
s = f.getName();


+ 56
- 56
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/MemMultipartFile.java ファイルの表示

@@ -6,74 +6,74 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.*;

public class MemMultipartFile implements MultipartFile {
private static final String DATA_IMAGE = "data:image/";
private byte[] data;
private String contentType;
private String filename;
private static final String DATA_IMAGE = "data:image/";
private byte[] data;
private String contentType;
private String filename;

public static MemMultipartFile build(String dataUrl) {
if (dataUrl != null && dataUrl.startsWith(DATA_IMAGE)) {
// data:image/png;base64,
int pos1 = dataUrl.indexOf(';', DATA_IMAGE.length());
int pos2 = dataUrl.indexOf(',', DATA_IMAGE.length());
if (pos1 > 0 && pos2 > pos1) {
byte[] data = Base64.decodeBase64(dataUrl.substring(pos2));
public static MemMultipartFile build(String dataUrl) {
if (dataUrl != null && dataUrl.startsWith(DATA_IMAGE)) {
// data:image/png;base64,
int pos1 = dataUrl.indexOf(';', DATA_IMAGE.length());
int pos2 = dataUrl.indexOf(',', DATA_IMAGE.length());
if (pos1 > 0 && pos2 > pos1) {
byte[] data = Base64.decodeBase64(dataUrl.substring(pos2));

if (data != null) {
String contentType = dataUrl.substring(5, pos1);
return new MemMultipartFile(contentType.replace('/', '.'), contentType, data);
if (data != null) {
String contentType = dataUrl.substring(5, pos1);
return new MemMultipartFile(contentType.replace('/', '.'), contentType, data);
}
}
}
}
}

return null;
}
return null;
}

private MemMultipartFile(String filename, String contentType, byte[] data) {
this.data = data;
this.contentType = contentType;
this.filename = filename;
}
private MemMultipartFile(String filename, String contentType, byte[] data) {
this.data = data;
this.contentType = contentType;
this.filename = filename;
}

@Override
public String getName() {
return "data";
}
@Override
public String getName() {
return "data";
}

@Override
public String getOriginalFilename() {
return filename;
}
@Override
public String getOriginalFilename() {
return filename;
}

@Override
public String getContentType() {
return contentType;
}
@Override
public String getContentType() {
return contentType;
}

@Override
public boolean isEmpty() {
return data.length == 0;
}
@Override
public boolean isEmpty() {
return data.length == 0;
}

@Override
public long getSize() {
return data.length;
}
@Override
public long getSize() {
return data.length;
}

@Override
public byte[] getBytes() throws IOException {
return data;
}
@Override
public byte[] getBytes() throws IOException {
return data;
}

@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(data);
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(data);
}

@Override
public void transferTo(File file) throws IOException, IllegalStateException {
try(FileOutputStream os = new FileOutputStream(file)) {
os.write(data);
@Override
public void transferTo(File file) throws IOException, IllegalStateException {
try (FileOutputStream os = new FileOutputStream(file)) {
os.write(data);
}
}
}
}

+ 88
- 87
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ThumbImage.java ファイルの表示

@@ -1,13 +1,5 @@
package cc.smtweb.system.bpm.util;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.imageio.ImageIO;

import lombok.Getter;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
@@ -15,95 +7,104 @@ import net.coobird.thumbnailator.resizers.configurations.Antialiasing;
import net.sf.image4j.codec.ico.ICODecoder;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
* 缩略图生成工具
*
* @author xkliu
*/
@Getter
public class ThumbImage {
// 图片处理方式
public static final int TYPE_DEFAULT = 1;
public static final int TYPE_THUMB = 2;
public static final int TYPE_AVATAR = 3;

private int imageWidth;
private int imageHeight;

public static int type(String thumb) {
// 解决历史遗留boolean类型
if (StringUtils.isBlank(thumb) || "false".equalsIgnoreCase(thumb)) {
return TYPE_DEFAULT;
}

if ("true".equalsIgnoreCase(thumb)) {
return TYPE_THUMB;
}

return Integer.parseInt(thumb);
}

public void makeThumb(boolean isThumb, File file, int size) throws IOException {
makeThumb(file, size, size, isThumb);
}
// 后台等比压缩后大小最好控制在20k以内
public void makeThumb(File file, int w, int h, boolean keepAspectRatio) throws IOException {
String fileName = file.getName().toLowerCase();

BufferedImage image;

if (fileName.endsWith(".ico")) {
List<BufferedImage> images = ICODecoder.read(file);
image = images.get(images.size() - 1);
} else {
image = ImageIO.read(file);
}

imageWidth = image.getWidth();
imageHeight = image.getHeight();

if (fileName.endsWith(".png") || fileName.endsWith(".gif")) {
// 把透明的图填充白色背景
BufferedImage newBufferedImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
newBufferedImage.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
image = newBufferedImage;
}

Thumbnails.Builder<BufferedImage> builder = Thumbnails.of(image);

if (keepAspectRatio) {
if (h > 0) {
// 高度为基准调整宽度到达原图缩放比例
int imageR = imageWidth * 1000 / imageHeight;
w = h * imageR / 1000;
} else {
// 宽度为基准调整宽度到达原图缩放比例
int imageR = imageHeight * 1000 / imageWidth;
h = w * imageR / 1000;
}
// 图片处理方式
public static final int TYPE_DEFAULT = 1;
public static final int TYPE_THUMB = 2;
public static final int TYPE_AVATAR = 3;

private int imageWidth;
private int imageHeight;

public static int type(String thumb) {
// 解决历史遗留boolean类型
if (StringUtils.isBlank(thumb) || "false".equalsIgnoreCase(thumb)) {
return TYPE_DEFAULT;
}

if ("true".equalsIgnoreCase(thumb)) {
return TYPE_THUMB;
}

return Integer.parseInt(thumb);
}

public void makeThumb(boolean isThumb, File file, int size) throws IOException {
makeThumb(file, size, size, isThumb);
}

// 后台等比压缩后大小最好控制在20k以内
public void makeThumb(File file, int w, int h, boolean keepAspectRatio) throws IOException {
String fileName = file.getName().toLowerCase();

BufferedImage image;

if (fileName.endsWith(".ico")) {
List<BufferedImage> images = ICODecoder.read(file);
image = images.get(images.size() - 1);
} else {
image = ImageIO.read(file);
}

imageWidth = image.getWidth();
imageHeight = image.getHeight();

if (fileName.endsWith(".png") || fileName.endsWith(".gif")) {
// 把透明的图填充白色背景
BufferedImage newBufferedImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
newBufferedImage.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
image = newBufferedImage;
}

Thumbnails.Builder<BufferedImage> builder = Thumbnails.of(image);

if (keepAspectRatio) {
if (h > 0) {
// 高度为基准调整宽度到达原图缩放比例
int imageR = imageWidth * 1000 / imageHeight;
w = h * imageR / 1000;
} else {
// 宽度为基准调整宽度到达原图缩放比例
int imageR = imageHeight * 1000 / imageWidth;
h = w * imageR / 1000;
}

// int r = w * 1000 / h;
// int imageR = imageWidth * 1000 / imageHeight;
// if (r != imageR) {
// w = imageHeight * r / 1000;
// }
} else {
int r = w * 1000 / h;
int imageR = imageWidth * 1000 / imageHeight;
if (r != imageR) {
int width = imageWidth;
int height = imageHeight;
if (r > imageR) {
width = imageHeight * r / 1000;
} else {
height = imageWidth * 1000 / r;
}
builder.sourceRegion(Positions.CENTER, width, height);
}
}
builder.size(w, h).antialiasing(Antialiasing.ON).outputFormat("jpg").outputQuality(0.9)
.toFile(file.getAbsolutePath() + FilePathGenerator.THUMB_FILE_EXT);
}
} else {
int r = w * 1000 / h;
int imageR = imageWidth * 1000 / imageHeight;
if (r != imageR) {
int width = imageWidth;
int height = imageHeight;
if (r > imageR) {
width = imageHeight * r / 1000;
} else {
height = imageWidth * 1000 / r;
}
builder.sourceRegion(Positions.CENTER, width, height);
}
}
builder.size(w, h).antialiasing(Antialiasing.ON).outputFormat("jpg").outputQuality(0.9)
.toFile(file.getAbsolutePath() + FilePathGenerator.THUMB_FILE_EXT);
}
}

+ 166
- 164
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/TreeDataUtil.java ファイルの表示

@@ -6,212 +6,214 @@ import java.util.function.Consumer;

/**
* 树结构数据创建器
*
* @author xkliu
*/
public class TreeDataUtil {
private TreeDataUtil(){}

public static boolean longEquals(Long l1, Long l2) {
if (l1 != null) {
return l1.equals(l2);
private TreeDataUtil() {
}

return l2 == null;
}
public static boolean longEquals(Long l1, Long l2) {
if (l1 != null) {
return l1.equals(l2);
}

private static <T> boolean findAndAdd(T parent, T item, ITreeDataHandler<T> handler) {
if (longEquals(handler.getId(parent), handler.getParentId(item))) {
addChild(parent, item, handler);
return true;
} else {
List<T> children = handler.getChildren(parent);
return l2 == null;
}

if (children != null) {
for (T child : children) {
if (findAndAdd(child, item, handler)) {
private static <T> boolean findAndAdd(T parent, T item, ITreeDataHandler<T> handler) {
if (longEquals(handler.getId(parent), handler.getParentId(item))) {
addChild(parent, item, handler);
return true;
}
} else {
List<T> children = handler.getChildren(parent);

if (children != null) {
for (T child : children) {
if (findAndAdd(child, item, handler)) {
return true;
}
}
}
}
}
}

return false;
}

private static <T> boolean findAndAddLevel(T parent, T item, ITreeDataLevelHandler<T> handler) {
if (longEquals(handler.getId(parent), handler.getParentId(item))) {
addChildLevel(parent, item, handler);
return true;
} else {
List<T> children = handler.getChildren(parent);
return false;
}

if (children != null) {
for (T child : children) {
if (findAndAddLevel(child, item, handler)) {
private static <T> boolean findAndAddLevel(T parent, T item, ITreeDataLevelHandler<T> handler) {
if (longEquals(handler.getId(parent), handler.getParentId(item))) {
addChildLevel(parent, item, handler);
return true;
}
} else {
List<T> children = handler.getChildren(parent);

if (children != null) {
for (T child : children) {
if (findAndAddLevel(child, item, handler)) {
return true;
}
}
}
}
}

return false;
}

return false;
}
private static <T> void addChild(T parent, T item, ITreeDataHandler<T> handler) {
List<T> children = handler.getChildren(parent);
if (children == null) {
children = new ArrayList<>();
handler.setChildren(parent, children);
}

private static <T> void addChild(T parent, T item, ITreeDataHandler<T> handler) {
List<T> children = handler.getChildren(parent);
if (children == null) {
children = new ArrayList<>();
handler.setChildren(parent, children);
children.add(item);
}

children.add(item);
}
private static <T> void addChildLevel(T parent, T item, ITreeDataLevelHandler<T> handler) {
List<T> children = handler.getChildren(parent);
if (children == null) {
children = new ArrayList<>();
handler.setChildren(parent, children);
}

private static <T> void addChildLevel(T parent, T item, ITreeDataLevelHandler<T> handler) {
List<T> children = handler.getChildren(parent);
if (children == null) {
children = new ArrayList<>();
handler.setChildren(parent, children);
updateLevel(item, handler.getLevel(parent) + 1, handler);
children.add(item);
}

updateLevel(item, handler.getLevel(parent) + 1, handler);
children.add(item);
}

private static <T> void updateLevel(T parent, int parentLevel, ITreeDataLevelHandler<T> handler) {
handler.setLevel(parent, parentLevel);
List<T> children = handler.getChildren(parent);
if (children != null) {
int level = parentLevel + 1;
for (T t: children) {
handler.setLevel(t, level);
updateLevel(t, level, handler);
}
}
}

// 读取树结构
public static <T> List<T> buildTree(T root, List<T> list, ITreeDataHandler<T> handler) {
if (list != null) {
for (T item: list) {
if (!findAndAdd(root, item, handler)) {
for (T it: list) {
if (longEquals(handler.getId(it), handler.getParentId(item))) {
addChild(it, item, handler);
item = null;
break;
private static <T> void updateLevel(T parent, int parentLevel, ITreeDataLevelHandler<T> handler) {
handler.setLevel(parent, parentLevel);
List<T> children = handler.getChildren(parent);
if (children != null) {
int level = parentLevel + 1;
for (T t : children) {
handler.setLevel(t, level);
updateLevel(t, level, handler);
}
}

// not find item parent
if (item != null && handler.forceAdd(item)) {
addChild(root, item, handler);
}
}
}
}

return handler.getChildren(root);
}

// 读取树结构
public static <T> List<T> buildLevelTree(T root, List<T> list, ITreeDataLevelHandler<T> handler) {
if (list != null) {
handler.setLevel(root, 0);
for (T item: list) {
if (!findAndAddLevel(root, item, handler)) {
for (T it: list) {
if (longEquals(handler.getId(it), handler.getParentId(item))) {
addChildLevel(it, item, handler);
item = null;
break;
// 读取树结构
public static <T> List<T> buildTree(T root, List<T> list, ITreeDataHandler<T> handler) {
if (list != null) {
for (T item : list) {
if (!findAndAdd(root, item, handler)) {
for (T it : list) {
if (longEquals(handler.getId(it), handler.getParentId(item))) {
addChild(it, item, handler);
item = null;
break;
}
}

// not find item parent
if (item != null && handler.forceAdd(item)) {
addChild(root, item, handler);
}
}
}
}

// not find item parent
if (item != null && handler.forceAdd(item)) {
addChildLevel(root, item, handler);
}
}
}

return handler.getChildren(root);
}

return handler.getChildren(root);
}
// 读取树结构
public static <T> List<T> buildLevelTree(T root, List<T> list, ITreeDataLevelHandler<T> handler) {
if (list != null) {
handler.setLevel(root, 0);
for (T item : list) {
if (!findAndAddLevel(root, item, handler)) {
for (T it : list) {
if (longEquals(handler.getId(it), handler.getParentId(item))) {
addChildLevel(it, item, handler);
item = null;
break;
}
}

// not find item parent
if (item != null && handler.forceAdd(item)) {
addChildLevel(root, item, handler);
}
}
}
}

public static <T> T findParent(T root, Long id, int treeLevel, ITreeDataLevelHandler<T> handler) {
T result = findParentInLevel(root, id, treeLevel, handler);
if (result != null && handler.getLevel(result) != treeLevel) {
result = null;
return handler.getChildren(root);
}

return result;
}
public static <T> T findParent(T root, Long id, int treeLevel, ITreeDataLevelHandler<T> handler) {
T result = findParentInLevel(root, id, treeLevel, handler);
if (result != null && handler.getLevel(result) != treeLevel) {
result = null;
}

private static <T> T findParentInLevel(T parent, Long id, int treeLevel, ITreeDataLevelHandler<T> handler) {
List<T> children = handler.getChildren(parent);
if (children != null) {
for (T child: children) {
if (id.equals(handler.getId(child))) {
return parent;
} else {
T find = findParentInLevel(child, id, treeLevel - 1, handler);
if (find != null) {
if (treeLevel > 0) {
return find;
} else {
return parent;
return result;
}

private static <T> T findParentInLevel(T parent, Long id, int treeLevel, ITreeDataLevelHandler<T> handler) {
List<T> children = handler.getChildren(parent);
if (children != null) {
for (T child : children) {
if (id.equals(handler.getId(child))) {
return parent;
} else {
T find = findParentInLevel(child, id, treeLevel - 1, handler);
if (find != null) {
if (treeLevel > 0) {
return find;
} else {
return parent;
}
}
}
}
}
}
}
}

return null;
}
return null;
}

public static <T> T findParent(T root, Long id,ITreeDataHandler<T> handler) {
List<T> children = handler.getChildren(root);
if (children != null) {
for (T child: children) {
if (id.equals(handler.getId(child))) {
return root;
} else {
T find = findParent(child, id, handler);
if (find != null) {
return find;
}
public static <T> T findParent(T root, Long id, ITreeDataHandler<T> handler) {
List<T> children = handler.getChildren(root);
if (children != null) {
for (T child : children) {
if (id.equals(handler.getId(child))) {
return root;
} else {
T find = findParent(child, id, handler);
if (find != null) {
return find;
}
}
}
}
}
}

return null;
}
return null;
}

public static <T> T find(T root, Long id, ITreeDataHandler<T> handler) {
List<T> children = handler.getChildren(root);
if (children != null) {
for (T child: children) {
if (id.equals(handler.getId(child))) {
return child;
} else {
T find = find(child, id, handler);
if (find != null) {
return find;
}
public static <T> T find(T root, Long id, ITreeDataHandler<T> handler) {
List<T> children = handler.getChildren(root);
if (children != null) {
for (T child : children) {
if (id.equals(handler.getId(child))) {
return child;
} else {
T find = find(child, id, handler);
if (find != null) {
return find;
}
}
}
}
}
}

return null;
}
return null;
}

public static <T> void forEach(T node, ITreeDataHandler<T> handler, Consumer<T> action) {
List<T> children = handler.getChildren(node);
if (children != null) {
for (T child: children) {
action.accept(child);
}
public static <T> void forEach(T node, ITreeDataHandler<T> handler, Consumer<T> action) {
List<T> children = handler.getChildren(node);
if (children != null) {
for (T child : children) {
action.accept(child);
}
}
}
}
}

+ 8
- 6
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilFile.java ファイルの表示

@@ -1,6 +1,6 @@
package cc.smtweb.system.bpm.util;

import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.StringUtil;
import com.aliyuncs.utils.IOUtils;
import org.springframework.util.FileCopyUtils;
import sun.misc.BASE64Decoder;
@@ -149,7 +149,7 @@ public class UtilFile {
write.flush();
write.close();
} catch (IOException e) {
UtilLogger.error(e.getMessage( ), e);
UtilLogger.error(e.getMessage(), e);
}
}

@@ -341,8 +341,8 @@ public class UtilFile {
/**
* 查找所有的文件 *
*
* @param sSearchStr 要搜索的字符串
* return 文件名list
* @param sSearchStr 要搜索的字符串
* return 文件名list
*/
public static List<String> searchFiles(String sSearchStr, String sFilePath) {
List<String> list = new ArrayList<>();
@@ -898,7 +898,7 @@ public class UtilFile {
} else {
//String filePath = child.getAbsolutePath();
String filePath = child.getName();
if (PubUtil.isEmpty(suffix)) {
if (StringUtil.isEmpty(suffix)) {
//后缀名为null则为所有文件
fileList.add(filePath);
} else {
@@ -951,7 +951,7 @@ public class UtilFile {
getFiles(fileList, child, suffix, level + 1, max_level);
} else {
String filePath = child.getName();
if (PubUtil.isEmpty(suffix)) {
if (StringUtil.isEmpty(suffix)) {
//后缀名为null则为所有文件
fileList.add(child);
} else {
@@ -1069,6 +1069,7 @@ public class UtilFile {

/**
* 读取txt文件类型
*
* @param fileName
* @return
*/
@@ -1097,6 +1098,7 @@ public class UtilFile {
}
return sbf.toString();
}

/**
* 解压文件到指定目录
*


+ 3
- 3
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilLogger.java ファイルの表示

@@ -1,6 +1,6 @@
package cc.smtweb.system.bpm.util;

import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.CommUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@@ -12,7 +12,7 @@ public class UtilLogger {

private static String getOrigMsg(String message, Throwable e) {
if (message != null) return message;
return PubUtil.getOrigMsg(e);
return CommUtil.getOrigMsg(e);
}

public static void debug(String message) {
@@ -60,7 +60,7 @@ public class UtilLogger {
}

public static void error(String message, Throwable e) {
if (e instanceof Exception) logger.info(message + PubUtil.getOrigMsg(e));
if (e instanceof Exception) logger.info(message + CommUtil.getOrigMsg(e));
else logger.error(getOrigMsg(message, e), e);
}
}

+ 0
- 465
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilMath.java ファイルの表示

@@ -1,465 +0,0 @@
package cc.smtweb.system.bpm.util;

import cc.smtweb.framework.core.util.PubUtil;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;

/**
* Created with IntelliJ IDEA.
* User: AKhh
* Date: 12-12-25 下午1:02
* To change this template use File | Settings | File Templates.
*/
public class UtilMath {
//整数
private static DecimalFormat dfLng = new DecimalFormat("##############0");
private static DecimalFormat dfLong = new DecimalFormat("###,###,###,###,##0");
//一位小数
private static DecimalFormat df1 = new DecimalFormat("##############0.0");
private static DecimalFormat df1Format = new DecimalFormat("###,###,###,###,##0.0");
//两位小数
private static DecimalFormat df2 = new DecimalFormat("##############0.00");
private static DecimalFormat df2Format = new DecimalFormat("###,###,###,###,##0.00");
//四位小数
private static DecimalFormat df4 = new DecimalFormat("###,###,###,###,##0.0000");
//六位小数
private static DecimalFormat df6Number = new DecimalFormat("#######################0.000000");
private static DecimalFormat df6NumberF = new DecimalFormat("#,###,###,###,###,###,##0.000000");

public final static DecimalFormat stdAmountFormat = new DecimalFormat("###,###,###,###,##0.00");
public final static DecimalFormat stdNumberFormat = new DecimalFormat("#0.00");
public final static String DEF_NUM_TEN_THOUSAND = "10000";//万
public static final double MAX_VALUE = 9999999999999.99D;
public static final double MIN_VALUE = -9999999999999.99D;

private final static BigDecimal ONE_BIG = new BigDecimal(1.00D);
private static final String UNIT = "万仟佰拾亿仟佰拾万仟佰拾元角分";
private static final String DIGIT = "零壹贰叁肆伍陆柒捌玖";

/**
* 4舍5入double,2位小数
*/
public static double roundDouble(double src) {
return roundDouble(src, 2);
}

/**
* 4舍5入double,N 位小数
* @param src
* @param scale 小数位数
* @return
*/
public static double roundDouble(Object src, int scale) {
if (src == null) return 0.0;
String v = src.toString();
if (PubUtil.isEmpty(v)) return 0.0;
if (scale < 0) scale = 2;

BigDecimal src_b = new BigDecimal(v);
BigDecimal src_v = src_b.divide(ONE_BIG, scale + 2, BigDecimal.ROUND_HALF_UP);// 4舍5入
src_v = src_v.divide(ONE_BIG, scale, BigDecimal.ROUND_HALF_UP);// 4舍5入
return src_v.doubleValue();
}

/**
* 舍位处理,原生floor有坑,部分浮点数记录为.99999999999形式,导致floor结果错误
* @param d
* @return
*/
public static double floor(double d) {
return Math.floor(UtilMath.roundDouble(d, 2));
}

/**
* 比较两Double是否相等,将会吧他们专程BigDecimal进行比较;
*
* @param src double1
* @param tag double2
* @return src > tag 返回1, src < tag 返回-1, 否则返回0
*/
public static int compare(double src, double tag) {
BigDecimal src_b = new BigDecimal(src);
BigDecimal src_v = src_b.divide(ONE_BIG, 2, BigDecimal.ROUND_HALF_UP);// 4舍5入

BigDecimal tag_b = new BigDecimal(tag);
BigDecimal tag_v = tag_b.divide(ONE_BIG, 2, BigDecimal.ROUND_HALF_UP);// 4舍5入

return src_v.compareTo(tag_v);
}

/**
* 自动过滤金额中的逗号转换为double,如果出错,则返回0
*
* @param s 源串,可能为带逗号的金额串;
* @return double
*/
public static Double toDouble(String s) {
return todouble(s);
}

/**
* 自动过滤金额中的逗号转换为double,如果出错,则返回0
*
* @param s 源串,可能为带逗号的金额串;
* @return double
*/
public static double todouble(String s) {
try {
return Double.parseDouble(s.replaceAll(",", ""));
} catch (Exception e) {
return 0.00;
}
}

/**
* 获取double,主要过滤d为null的情况;
*
* @param d Double对象;
* @return double
*/
public static double todouble(Double d) {
if (d == null) return 0.0d;
return d.doubleValue();
}

/**
* 自动过滤金额中的逗号转换为float,如果出错,则返回0
*
* @param s 源串,可能为带逗号的金额串;
* @return Float
*/
public static Float toFloat(String s) {
return tofloat(s);
}

/**
* 自动过滤金额中的逗号转换为float,如果出错,则返回0
*
* @param s 源串,可能为带逗号的金额串;
* @return Float
*/
public static float tofloat(String s) {
try {
return Float.parseFloat(s.replaceAll(",", ""));
} catch (Exception e) {
return 0.0f;
}
}

public static long tolong(String src, long defaultvalue) {
try {
return Long.parseLong(src);
} catch (Exception e) {
return defaultvalue;
}
}

public static int toint(String src, int defaultvalue) {
try {
return Integer.parseInt(src);
} catch (Exception e) {
return defaultvalue;
}
}

/**
* 考虑使用中的精度,判断一个Value是否>0,实际是>0.00001
*
* @param value double类型
* @return boolean
*/
public static boolean isBigThanZero(double value) {
return (value > 0.00001);
}

/**
* 考虑使用中的精度,判断一个Value是否>0,实际是>0.00001
*
* @param value String类型
* @return boolean
*/
public static boolean isBigThanZero(String value) {
return !PubUtil.isEmpty(value) && isBigThanZero(toDouble(value));
}

/**
* 考虑使用中的精度,判断一个Value是否=0,实际是给出一个值范围。
*
* @param value double类型
* @return boolean
*/
public static boolean isEqualsZero(double value) {
return (-0.00001 < value && value < 0.00001);
}

/**
* 考虑使用中的精度,判断一个Value是否=0,实际是给出一个值范围。
*
* @param value String类型
* @return boolean
*/
public static boolean isEqualsZero(String value) {
return PubUtil.isEmpty(value) || isEqualsZero(toDouble(value));
}

/**
* 是否是负数
*
* @param db_val 要判断的double
* @return 负数则返回true;
*/
public static boolean isNegative(double db_val) {
return (compare(db_val, 0.00D) == -1);
}

/**
* 是否是正数
*
* @param db_val 要判断的double
* @return 正数则返回true;
*/
public static boolean isPlus(double db_val) {
return (compare(db_val, 0.00D) == 1);
}

/**
* 得到金额字符串,保持小数点2位
*
* @param db 将double转换为金额字符串;
* @return 金额字符串#0.00;
*/
public static String toStdNumberString(double db) {
try {
return stdNumberFormat.format(db);
} catch (Exception e) {
return "0.00";
}
}

public static String toStdNumberStringEx(double db) {
try {
if (compare(db, -1d) == 0) return "-";
return stdNumberFormat.format(db);
} catch (Exception e) {
return "0.00";
}
}

/**
* 将金额格式字符串,如23,333,093.01 去掉逗号
*
* @param s 金额串
* @return String 去掉逗号后的串,如果amount为空,则返回0.00
*/
public static String toStdNumberString(String s) {
if (PubUtil.isEmpty(s))
return "0.00";
return stdNumberFormat.format(UtilMath.todouble(s));
}

/**
* 将数据转换为两位小数的数字格式;
*
* @param d 数据
* @param isZeroToEmpty 如果未0,是否返回“”;
* @return 两位小数的字符串;
*/
public static String toStdNumberString(double d, boolean isZeroToEmpty) {
if (isEqualsZero(d)) {
return isZeroToEmpty ? "": "0.00";
}
return stdNumberFormat.format(d);
}

public static String toStdNumberString(String s, boolean isZeroToEmpty) {
return toStdNumberString(UtilMath.todouble(s), isZeroToEmpty);
}

public static String toStdNumberString(double d, int scale) {
DecimalFormat dfn = null;
if (scale == 1) dfn = df1Format;
if (scale == 2) dfn = df2Format;
else if (scale == 4) dfn = df4;
else if (scale == 6) dfn = df6NumberF;
else if (scale <= 0) dfn = dfLong;
else {
StringBuilder sb = new StringBuilder("###,###,###,###,##0.");
for (int i = 0; i < scale; i++) sb.append("0");
dfn = new DecimalFormat(sb.toString());
}
return dfn.format(d);
}

/**
* 将数字乘100,保留小数点后两位, 然后后面添加%
*
* @param d 值
* @param isZeroToEmpty,如果值为0,是否返回空;
* @return 字符串;
*/
public static String toStdPercentNumberStr(double d, boolean isZeroToEmpty) {
if (d > -0.00000000001 && d < 0.00000000001) {
return isZeroToEmpty ? "": "0.00%";
}
return toStdNumberString(d * 100) + "%";
}


public static String toStdAmountString(double d) {
return toStdAmountString(d, false);
}

/**
* 将数据转换为两位小数的金额格式,带逗号;
*
* @param d 数据
* @param isZeroToEmpty 如果未0,是否返回“”;
* @return 金额格式的字符串;
*/
public static String toStdAmountString(double d, boolean isZeroToEmpty) {
if (isEqualsZero(d)) {
return isZeroToEmpty ? "": "0.00";
}
return stdAmountFormat.format(d);
}

public static String toStdAmountString(String s) {
return toStdAmountString(UtilMath.todouble(s), false);
}

public static String toStdAmountString(String s, boolean isZeroToEmpty) {
return toStdAmountString(UtilMath.todouble(s), isZeroToEmpty);
}


/**
* 将小写金额转换为人民币大写金额
*
* @param s 金额格式的串
* @return String 转换结果
*/
public static String toCapsAmountString(String s) {
if (PubUtil.isEmpty(s)) return "";
return toCapsAmountString(todouble(s));
}

/**
* 将小写金额转换为人民币大写金额
*
* @param v double
* @return String 转换结果
*/
public static String toCapsAmountString(double v) {
if (v < MIN_VALUE || v > MAX_VALUE) return "参数非法!";

boolean negative = isNegative(v);

if (negative) v = Math.abs(v);
long l = Math.round(v * 100);
if (l == 0) return "零元整";

String strValue = String.valueOf(l);
// i用来控制数
int i = 0;
// j用来控制单位
int j = UNIT.length() - strValue.length();
StringBuilder rs = new StringBuilder(32);
boolean isZero = false;
for (; i < strValue.length(); i++, j++) {
char ch = strValue.charAt(i);
if (ch == '0') {
isZero = true;
if (UNIT.charAt(j) == '亿' || UNIT.charAt(j) == '万' || UNIT.charAt(j) == '元') {
rs.append(UNIT.charAt(j));
isZero = false;
}
} else {
if (isZero) {
rs.append('零');
isZero = false;
}
rs.append(DIGIT.charAt(ch - '0')).append(UNIT.charAt(j));
}
}
if (rs.charAt(rs.length() - 1) != '分')
rs.append('整');

i = rs.indexOf("亿万");
if (i > 0) rs.delete(i + 1, i + 2); // i+1 ->万

if (negative)
return rs.insert(0, '负').toString();
else
return rs.toString();
}

/**
* 返回0 到 maxvalue的随机数
*
* @param maxvalue 随机数的最大值
* @return int
*/
public static int rnd(int maxvalue) {
return (int) (Math.random() * (maxvalue + 1));
}


public static double chkDbNull(Double v) {
return v == null ? 0: v;
}

public static double max(double d1, double d2) {
return compare(d1, d2) < 0 ? d2 : d1;
}

public static double min(double d1, double d2) {
return compare(d1, d2) < 0 ? d1 : d2;
}


public static void main(String[] args) {
double aa=123456789.345678900005;
System.out.println("args0 = " + upDouble(aa,0));
System.out.println("args1 = " + upDouble(aa,1));
System.out.println("args2 = " + upDouble(aa,2));
System.out.println("args3 = " + upDouble(aa,3));
System.out.println("args4 = " + upDouble(aa,4));
System.out.println("args5 = " + upDouble(aa,5));
System.out.println("args5 = " + upDouble(aa,6));
System.out.println("args5 = " + upDouble(aa,7));
System.out.println("args5 = " + upDouble(aa,8));

}

/**
* double 去尾法
* @param src 待处理数据
* @param scale 保留小数位数
* @return
*/
public static double cutDouble(double src, int scale){
String v = toStdNumberString(src, 6);//先到6位小数,再去计算,否则容易出错,如8.3成8.29999999999,舍位就成了8.29了
DecimalFormat formater = new DecimalFormat();
formater.setMaximumFractionDigits(scale);
formater.setGroupingSize(0);
formater.setRoundingMode(RoundingMode.FLOOR);
return new BigDecimal(formater.format(toDouble(v))).doubleValue();
}

/**
* double 进位法
* @param src 待处理数据
* @param scale 保留小数位数
* @return
*/
public static double upDouble(double src, int scale){
String v = toStdNumberString(src, 6);//先到6位小数,再去计算
DecimalFormat formater = new DecimalFormat();
formater.setMaximumFractionDigits(scale);
formater.setGroupingSize(0);
formater.setRoundingMode(RoundingMode.UP);
return new BigDecimal(formater.format(toDouble(v))).doubleValue();
}
}

+ 0
- 504
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilString.java ファイルの表示

@@ -1,504 +0,0 @@
package cc.smtweb.system.bpm.util;


import cc.smtweb.framework.core.util.PubUtil;

import java.text.Collator;
import java.util.*;

/**
* Created with IntelliJ IDEA.
* User: AKhh
* Date: 12-12-24 下午5:09
* To change this template use File | Settings | File Templates.
*/
@SuppressWarnings("UnusedDeclaration")
public class UtilString {
private static Collator chineseCollator = Collator.getInstance(Locale.CHINA);

/**
* strSrc中寻找第一个strSe并且返回以其分隔的Left部分,汉字长度也为1
*
* @param strSrc 源字符串
* @param strSe 分割字符
* @return String 返回
*/
public static String getLeft(String strSrc, String strSe) {
if (PubUtil.isEmpty(strSrc))
return "";
if (PubUtil.isEmpty(strSe))
strSe = " ";

String result = "";
int pos = strSrc.indexOf(strSe);
if (pos >= 0)
result = strSrc.substring(0, pos);
return result;
}

/**
* 返回字符串的左边部分,汉字长度也为1
*
* @param strSrc 源串,如果为空,则返回“”;
* @param count 要获取的右边字符串长度,负数将返回“”,如果count>字符串长度,则返回整个字符串;
* @return String return
*/
public static String getLeft(String strSrc, int count) {
if (PubUtil.isEmpty(strSrc) || count <= 0) {
return "";
}
if (strSrc.length() < count) {
return strSrc;
} else {
return strSrc.substring(0, count);
}
}

/**
* strSrc中寻找第一个strSe并且返回以其分隔的Right部分,汉字长度也为1
*
* @param strSrc 源串
* @param strSe 分隔符,一个字符
* @return String right部分
*/
public static String getRight(String strSrc, String strSe) {
if (PubUtil.isEmpty(strSrc))
return "";
if (PubUtil.isEmpty(strSe))
strSe = " ";

String result = strSrc;
int pos = strSrc.indexOf(strSe);
if (pos >= 0)
result = strSrc.substring(pos + strSe.length());
return result;
}

/**
* 返回字符串的右边部分,汉字长度也为1
*
* @param strSrc 源串
* @param count 要获取的右边字符串长度,负数将返回“”,如果count>字符串长度,则返回整个字符串;
* @return String return
*/
public static String getRight(String strSrc, int count) {
if (PubUtil.isEmpty(strSrc) || count <= 0) {
return "";
}
int l = strSrc.length();
if (l <= count) {
return strSrc;
}
return strSrc.substring(l - count);
}

/**
* 左边补齐字符
*
* @param src 源串
* @param pad 补齐字符
* @param length 最终长度
* @return 补齐后的字符串
*/
public static String padLeft(String src, String pad, int length) {
StringBuilder sb = new StringBuilder(repeatString(pad, length));
sb.append(src);
return sb.substring(sb.length() - length);
}

public static String padLeft(long src, String pad, int length) {
StringBuilder sb = new StringBuilder(repeatString(pad, length));
sb.append(src);
return sb.substring(sb.length() - length);
}

public static String padRight(String src, String pad, int length) {
StringBuilder sb = new StringBuilder(length * pad.length() + src.length());
sb.append(src).append(repeatString(pad, length));
return sb.substring(0, length);
}

public static String padRight(long src, String pad, int length) {
StringBuilder sb = new StringBuilder(length * pad.length());
sb.append(src).append(repeatString(pad, length));
return sb.substring(0, length);
}

/**
* 由于jdk1.3提供的replace函数不能满足替换要求,自己写一个
*
* @param src 源串
* @param oldS 将...
* @param newS 替换成...
* @return 替换后的字符串
*/
public static String replaceString(String src, String oldS, String newS) {
StringBuilder ret = new StringBuilder(64);
int pos = src.indexOf(oldS);
while (pos >= 0) {
ret.append(src, 0, pos).append(newS);
src = src.substring(pos + oldS.length());
pos = src.indexOf(oldS);
}
ret.append(src);
return ret.toString();
}

/**
* 取得指定字符串左边的有效数字,首先去掉两边空格
*
* @param s 源串
* @return 串左边的有效数字
*/
public static String getStringLeftNumber(String s) {
String ret = "";
int dotCount = 0;
s = s.trim();
char[] carr = s.toCharArray();
for (char aCarr : carr) {
if (Character.isDigit(aCarr)) {
ret += aCarr;
} else if (aCarr == '.' && dotCount == 0) {
ret += aCarr;
dotCount++;
} else {
break;
}
}
if (ret.endsWith(".")) {
ret = ret.substring(0, ret.length() - 1);
}
return ret;
}

/**
* 取得重复字串
*
* @param repeatString 重复字串
* @param count 重复次数
* @return String
*/
public static String repeatString(String repeatString, int count) {
if (count <= 0) return "";
StringBuilder ret = new StringBuilder(repeatString.length() * count);
for (int i = 1; i <= count; i++) {
ret.append(repeatString);
}
return ret.toString();
}

/**
* 去除字符串左边的指定字符串
*
* @param src 源字符串
* @param cut 要去掉的字符串;
* @return 处理结果
*/
public static String cutStringLeft(String src, String cut) {
if (PubUtil.isEmpty(src) || PubUtil.isEmpty(cut)) {
return "";
}
if (src.startsWith(cut)) {
return cutStringLeft(src.substring(cut.length()), cut);
} else {
return src;
}
}

public static String cutStringRight(String src, String cut) {
if (PubUtil.isEmpty(src) || PubUtil.isEmpty(cut)) {
return "";
}
while (src.endsWith(cut))
src = src.substring(0, src.length() - cut.length());

return src;
}

/**
* Removes all spaces from a string
* 可以替换大部分空白字符, 不限于空格,\s 可以匹配空格、制表符、换页符等空白字符的其中任意一个
*/
public static String removeSpaces(String str) {
return str.replaceAll("\\s*", "");
}

/**
* Creates a single string from a List of strings seperated by a delimiter.
*
* @param list a list of strings to join
* @param delim the delimiter character(s) to use. (null value will join with no delimiter)
* @return a String of all values in the list seperated by the delimiter
*/
public static String join(List<String> list, String delim) {
if (list == null || list.size() < 1)
return null;
StringBuffer buf = new StringBuffer();
Iterator i = list.iterator();

while (i.hasNext()) {
buf.append((String) i.next());
if (i.hasNext())
buf.append(delim);
}
return buf.toString();
}

/**
* Splits a String on a delimiter into a List of Strings.
*
* @param str the String to split
* @param delim the delimiter character(s) to join on (null will split on whitespace)
* @return a list of Strings
*/
public static List<String> split(String str, String delim) {
List<String> splitList = new ArrayList<>();
StringTokenizer st;
if (str == null)
return splitList;

if (delim != null)
st = new StringTokenizer(str, delim);
else
st = new StringTokenizer(str);

while (st.hasMoreTokens()) {
splitList.add(st.nextToken());
}
return splitList;
}

//是否为true,(1,y,true,yes)
public static boolean toBoolean(String v) {
return "1".equals(v) || "y".equalsIgnoreCase(v) || "true".equalsIgnoreCase(v) || "yes".equalsIgnoreCase(v);
}

public static int chineseCompare(String s1, String s2) {
return chineseCollator.compare(s1, s2);
}

/**
* 按照编码级次,得到类型的真实编码,主要用于like 'parentCode%'
* getSplitTypeCode('GF82000',2, 2, 1) == GF82
* getSplitTypeCode('GF82100',3, 2, 1) == GF821
* getSplitTypeCode('82100' ,3, 0, 1) == 821
*
* @param curLevel 当前编码的所在层次
* @param startIndex 数字编码的开始选项
* @param perSize 每层的数字编码长度
*/
public static String getRealCode(String code, int curLevel, int startIndex, int perSize) {
StringBuilder sb = new StringBuilder(code.length());
if (startIndex > 0) sb.append(code, 0, startIndex);
for (int i = startIndex, l = 0; i < code.length(); i += perSize) {
if (l < curLevel) {
sb.append(code, i, i + perSize);
++l;
} else {
break;
}
}
return sb.toString();
}

//函数功能: 正整数
public static boolean isPureNumber(String inputString) {
return inputString.matches("^[1-9]\\d*$");
}

//函数功能: 整数
public static boolean isNumber(String inputString) {
return inputString.matches("^[-+][0-9]\\d*$");
}

//函数功能: 浮点数
public static boolean isAmount(String inputString) {
return inputString.matches("^[-+]?[\\d,]+(\\.\\d+)?$");
}

//函数功能: 带千分号的整数
public static boolean isFormatNumber(String inputString) {
return inputString.matches("^[-+]?[\\d,]+(\\d+)?$");
}


//首字母大写
public static String upFirst(String s) {
return s.substring(0, 1).toUpperCase() + s.substring(1);
}

public static String padRightBytes(String src, String pad, int length) {
length -= src.replaceAll("[^\\x00-\\xff]", "**").length();
return src + repeatString(pad, length);
}

//按字节数取子串,begin不是按字节的
public static String substrByte(String src, int begin, int len) {
StringBuilder sb = new StringBuilder(32);
char c;
int tl = src.length();
for (int i = begin; i < len + begin && i < tl; i++) {

c = src.charAt(i);
sb.append(c);
if (String.valueOf(c).replaceAll("[^\\x00-\\xff]", "**").length() > 1) {
// 遇到中文汉字,截取字节总数减1
--len;
}
}
return sb.toString();
}

/**
* 通配符算法。 可以匹配"*"和"?"
* 如a*b?d可以匹配aAAAbcd
*
* @param pattern 匹配表达式
* @param str 匹配的字符串
* @return
*/
public static boolean match(String pattern, String str) {
if (pattern == null || str == null)
return false;

boolean result = false;
char c; // 当前要匹配的字符串
boolean beforeStar = false; // 是否遇到通配符*
int back_i = 0;// 回溯,当遇到通配符时,匹配不成功则回溯
int back_j = 0;
int i, j;
for (i = 0, j = 0; i < str.length(); ) {
if (pattern.length() <= j) {
if (back_i != 0) {// 有通配符,但是匹配未成功,回溯
beforeStar = true;
i = back_i;
j = back_j;
back_i = 0;
back_j = 0;
continue;
}
break;
}

if ((c = pattern.charAt(j)) == '*') {
if (j == pattern.length() - 1) {// 通配符已经在末尾,返回true
result = true;
break;
}
beforeStar = true;
j++;
continue;
}

if (beforeStar) {
if (str.charAt(i) == c) {
beforeStar = false;
back_i = i + 1;
back_j = j;
j++;
}
} else {
if (c != '?' && c != str.charAt(i)) {
result = false;
if (back_i != 0) {// 有通配符,但是匹配未成功,回溯
beforeStar = true;
i = back_i;
j = back_j;
back_i = 0;
back_j = 0;
continue;
}
break;
}
j++;
}
i++;
}

if (i == str.length() && j == pattern.length())// 全部遍历完毕
result = true;
return result;
}

//填充变量
public static String myReplaceStrEx(String express, String b, String e, IStrHanlder hanlder) {
if (null == express) return express;
int keyBegin = 0, keyEnd = 0;
int lb = b.length(), le = e.length();
String fn;
while (true) {
keyBegin = express.indexOf(b, keyBegin);
if (keyBegin < 0) break;
keyEnd = express.indexOf(e, keyBegin);
if (keyEnd <= keyBegin) break;
keyBegin++;
fn = express.substring(keyBegin + lb - 1, keyEnd);
fn = hanlder.work(fn);
if (fn != null) {
express = express.substring(0, keyBegin - 1) + fn + express.substring(keyEnd + le);
}
}
return express;
}

//填充变量
public static String myReplaceStrEx(String express, String b, String e, final Map<String, String> mapVals) {
return myReplaceStrEx(express, b, e, new IStrHanlder() {
@Override
public String work(String src) {
return PubUtil.checkNull(mapVals.get(src));
}
});
}

/*Blob转String*/
// public static String blob2Str(Blob blob) {
// if (blob == null) return "";
// ByteArrayOutputStream outStream = null;
// try {
// long len = blob.length();
// if (len == 0L) return "";
// byte[] bytes;
// long i = 1L;
// outStream = new ByteArrayOutputStream();
// while (i < len) {
// bytes = blob.getBytes(i, 1024);
// i += 1024L;
// outStream.write(bytes);
// }
//
// return UtilEncode.base64EncodeB(outStream.toByteArray());
// } catch (Exception e) {
// e.printStackTrace();
// return "";
// } finally {
// IOUtils.closeQuietly(outStream);
// }
// }


public interface IStrHanlder {
String work(String src);
}

public static int[] splitStr(String src, String ch) {
String[] ss = src.split(ch);
int[] ret = new int[ss.length];
for (int i = 0, len = ss.length; i < len; i++) {
ret[i] = PubUtil.getIntIgnoreErr(ss[i]);
}
return ret;
}

public static void main(String[] args) {
String s = "a[#[#123#]bcde[aaa]bcd";
s = UtilString.myReplaceStrEx(s, "[#", "#]", new UtilString.IStrHanlder() {
@Override
public String work(String src) {
if (src.equals("123")) return "1";
return null;
}
});
System.out.println(s);
}
}

+ 59
- 58
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/XmlUtil.java ファイルの表示

@@ -13,76 +13,77 @@ import java.io.InputStream;
import java.io.OutputStream;

public class XmlUtil {
private static final XmlMapper OBJECT_MAPPER = new XmlMapper();
private static final XmlMapper OBJECT_MAPPER = new XmlMapper();

static {
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
OBJECT_MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
}
static {
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
OBJECT_MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
}

private XmlUtil() {}
private XmlUtil() {
}

public static <T> T readValue(String str, Class<T> clazz) {
try {
if (StringUtils.isBlank(str)) {
return null;
} else {
return OBJECT_MAPPER.readValue(str, clazz);
}
} catch (Exception e) {
throw new JsonParseException("can't convert this json to " + clazz + " type", e);
public static <T> T readValue(String str, Class<T> clazz) {
try {
if (StringUtils.isBlank(str)) {
return null;
} else {
return OBJECT_MAPPER.readValue(str, clazz);
}
} catch (Exception e) {
throw new JsonParseException("can't convert this json to " + clazz + " type", e);
}
}
}

public static <T> T readValue(File file, Class<T> clazz) {
try {
if (file == null || !file.exists()) {
return null;
} else {
return OBJECT_MAPPER.readValue(file, clazz);
}
} catch (Exception e) {
throw new JsonParseException("can't convert this json to " + clazz + " type", e);
public static <T> T readValue(File file, Class<T> clazz) {
try {
if (file == null || !file.exists()) {
return null;
} else {
return OBJECT_MAPPER.readValue(file, clazz);
}
} catch (Exception e) {
throw new JsonParseException("can't convert this json to " + clazz + " type", e);
}
}
}

public static <T> T readValue(InputStream is, Class<T> clazz) {
try {
if (is == null) {
return null;
} else {
return OBJECT_MAPPER.readValue(is, clazz);
}
} catch (Exception e) {
throw new JsonParseException("can't convert this xml to " + clazz + " type", e);
public static <T> T readValue(InputStream is, Class<T> clazz) {
try {
if (is == null) {
return null;
} else {
return OBJECT_MAPPER.readValue(is, clazz);
}
} catch (Exception e) {
throw new JsonParseException("can't convert this xml to " + clazz + " type", e);
}
}
}

public static String writeValue(Object obj) {
try {
return OBJECT_MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e);
public static String writeValue(Object obj) {
try {
return OBJECT_MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e);
}
}
}

public static void writeValue(OutputStream outputStream, Object obj) {
try {
OBJECT_MAPPER.writeValue(outputStream, obj);
} catch (JsonProcessingException e) {
throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e);
} catch (IOException e) {
throw new JsonParseException(e.getMessage(), e);
public static void writeValue(OutputStream outputStream, Object obj) {
try {
OBJECT_MAPPER.writeValue(outputStream, obj);
} catch (JsonProcessingException e) {
throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e);
} catch (IOException e) {
throw new JsonParseException(e.getMessage(), e);
}
}
}

public static void writeValue(File file, Object obj) {
try {
OBJECT_MAPPER.writeValue(file, obj);
} catch (JsonProcessingException e) {
throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e);
} catch (IOException e) {
throw new JsonParseException(e.getMessage(), e);
public static void writeValue(File file, Object obj) {
try {
OBJECT_MAPPER.writeValue(file, obj);
} catch (JsonProcessingException e) {
throw new JsonParseException("can't convert type " + obj.getClass() + " to json string", e);
} catch (IOException e) {
throw new JsonParseException(e.getMessage(), e);
}
}
}
}

+ 79
- 79
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/YamlUtil.java ファイルの表示

@@ -16,97 +16,97 @@ import java.io.*;
import java.nio.charset.StandardCharsets;

public class YamlUtil {
private static final ObjectMapper OBJECT_MAPPER;
private static final Representer representer;
private static final ObjectMapper OBJECT_MAPPER;
private static final Representer representer;

static {
YAMLFactory yamlFactory = new YAMLFactory();
static {
YAMLFactory yamlFactory = new YAMLFactory();

// yamlFactory.enable(YAMLGenerator.Feature.CANONICAL_OUTPUT);
yamlFactory.disable(YAMLGenerator.Feature.SPLIT_LINES);
yamlFactory.enable(YAMLGenerator.Feature.MINIMIZE_QUOTES);

OBJECT_MAPPER = new ObjectMapper(yamlFactory);
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);

// 生成yaml时忽略null属性
representer = new Representer() {
@Override
protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
// if value of property is null, ignore it.
if (propertyValue == null) {
return null;
yamlFactory.disable(YAMLGenerator.Feature.SPLIT_LINES);
yamlFactory.enable(YAMLGenerator.Feature.MINIMIZE_QUOTES);

OBJECT_MAPPER = new ObjectMapper(yamlFactory);
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);

// 生成yaml时忽略null属性
representer = new Representer() {
@Override
protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
// if value of property is null, ignore it.
if (propertyValue == null) {
return null;
} else {
return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
}
}
};
}

private YamlUtil() {
}

public static <T> T readValue(String str, Class<T> clazz) {
try {
if (StringUtils.isBlank(str)) {
return null;
} else {
return OBJECT_MAPPER.readValue(str, clazz);
}
} catch (Exception e) {
throw new JsonParseException("can't convert this json to " + clazz + " type", e);
}
else {
return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
}

public static <T> T readValue(File file, Class<T> clazz) {
try {
return OBJECT_MAPPER.readValue(file, clazz);
} catch (Exception e) {
throw new JsonParseException("can't convert this json to " + clazz + " type", e);
}
}
};
}

private YamlUtil() {}

public static <T> T readValue(String str, Class<T> clazz) {
try {
if (StringUtils.isBlank(str)) {
return null;
} else {
return OBJECT_MAPPER.readValue(str, clazz);
}
} catch (Exception e) {
throw new JsonParseException("can't convert this json to " + clazz + " type", e);
}
}

public static <T> T readValue(File file, Class<T> clazz) {
try {
return OBJECT_MAPPER.readValue(file, clazz);
} catch (Exception e) {
throw new JsonParseException("can't convert this json to " + clazz + " type", e);
public static <T> T readValue(InputStream is, Class<T> clazz) {
try {
if (is == null) {
return null;
} else {
return OBJECT_MAPPER.readValue(is, clazz);
}
} catch (Exception e) {
throw new JsonParseException("can't convert this yaml to " + clazz + " type", e);
}
}
}

public static <T> T readValue(InputStream is, Class<T> clazz) {
try {
if (is == null) {
return null;
} else {
return OBJECT_MAPPER.readValue(is, clazz);
}
} catch (Exception e) {
throw new JsonParseException("can't convert this yaml to " + clazz + " type", e);

public static String writeValue(Object obj) {
Yaml yaml = buildYaml();
StringWriter sw = new StringWriter();
yaml.dump(obj, sw);
return sw.toString();
}
}

public static String writeValue(Object obj) {
Yaml yaml = buildYaml();
StringWriter sw = new StringWriter();
yaml.dump(obj, sw);
return sw.toString();
}

private static Yaml buildYaml() {
Yaml result = new Yaml(representer);

return result;
}

public static void writeValue(OutputStream outputStream, Object obj) {
Yaml yaml = buildYaml();
yaml.dump(obj, new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
}

public static void writeValue(File file, Object obj) {
Yaml yaml = buildYaml();
try(OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) {
yaml.dump(obj, out);
// OBJECT_MAPPER.writeValue(file, obj);
} catch (IOException e) {
throw new JsonParseException(e.getMessage(), e);

private static Yaml buildYaml() {
Yaml result = new Yaml(representer);

return result;
}

public static void writeValue(OutputStream outputStream, Object obj) {
Yaml yaml = buildYaml();
yaml.dump(obj, new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
}

public static void writeValue(File file, Object obj) {
Yaml yaml = buildYaml();
try (OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) {
yaml.dump(obj, out);
// OBJECT_MAPPER.writeValue(file, obj);
} catch (IOException e) {
throw new JsonParseException(e.getMessage(), e);
}


// StringWriter sw = new StringWriter();
// System.out.println(sw.toString());
}
}
}

+ 9
- 8
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/FtpTaskManager.java ファイルの表示

@@ -1,9 +1,8 @@
package cc.smtweb.system.bpm.util.ftp;



import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.util.UtilLogger;

import java.io.File;
@@ -24,7 +23,7 @@ public class FtpTaskManager {
private Map<Thread, IFtpUtil> mapThreadFtp = new HashMap<>();

public static FtpTaskManager getInstance(String key, IFtpServerConfig ftpConfig) {
key = key + "_" + (ftpConfig.isSFTP() ? 1 : 0) + ftpConfig.getServerIp() + "_" + ftpConfig.getPort() + "_" + ftpConfig.getUserName();
key = key + "_" + (ftpConfig.isSFTP() ? 1: 0) + ftpConfig.getServerIp() + "_" + ftpConfig.getPort() + "_" + ftpConfig.getUserName();
FtpTaskManager instance = mapInstance.get(key);
if (instance == null) {
synchronized (FtpTaskManager.class) {
@@ -55,7 +54,7 @@ public class FtpTaskManager {
IFtpUtil ftp = mapThreadFtp.get(Thread.currentThread());
if (ftp != null) return ftp;

ftp = ftpConfig.isSFTP() ? new SFtpUtil() : new FtpUtil();
ftp = ftpConfig.isSFTP() ? new SFtpUtil(): new FtpUtil();
boolean isConnect = ftp.login(ftpConfig);
if (isConnect) {
UtilLogger.info("FTP连接成功!");
@@ -87,7 +86,7 @@ public class FtpTaskManager {
public Object execute(FtpTask ftpTask) throws Exception {
IFtpUtil ftp = getFtpUtil();
if (!ftp.isConnected())
throw new Exception("FTP连接失败(" + ftpConfig.getServerIp() + "/" + ftpConfig.getUserName() + "/" + (ftpConfig.isSFTP() ? "sftp" : "ftp") + ")。");
throw new Exception("FTP连接失败(" + ftpConfig.getServerIp() + "/" + ftpConfig.getUserName() + "/" + (ftpConfig.isSFTP() ? "sftp": "ftp") + ")。");
try {
return ftpTask.execute(ftp);
} finally {
@@ -118,7 +117,7 @@ public class FtpTaskManager {
}

private String getBakPath(String path) {
path = PubUtil.isEmpty(path) ? DateUtil.getNowYm() : path;
path = StringUtil.isEmpty(path) ? DateUtil.getNowYm(): path;
return "bak/" + path + "/";
}

@@ -161,15 +160,17 @@ public class FtpTaskManager {
}
});
}

public void delFile(String delPath, String fileName) throws Exception {
this.execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
if (!ftp.existsFile(delPath, fileName)) return null;
ftp.deleteFile(delPath,fileName );
ftp.deleteFile(delPath, fileName);
return null;
}
});
}

//从服务器下载文件到本地。传完后,根据设置删除远程目录文件
public String[] listFileNames(final String remotePath) throws Exception {
IFtpUtil ftp = getFtpUtil();
@@ -190,7 +191,7 @@ public class FtpTaskManager {
public Object execute(IFtpUtil ftp) throws Exception {
for (String file : files) {
if (worker != null && !worker.isDownload(file, fileNamePrefix)) continue;
if (PubUtil.isNotEmptyId(fileNamePrefix) && !file.startsWith(fileNamePrefix)) continue;
if (StringUtil.isNotEmpty(fileNamePrefix) && !file.startsWith(fileNamePrefix)) continue;
ftp.downloadFileEx(remotePath, file, localPath + "/" + file);
if (isDelLocal) {
ftp.setRemoteDir("/");


+ 2
- 2
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/FtpUtil.java ファイルの表示

@@ -1,6 +1,6 @@
package cc.smtweb.system.bpm.util.ftp;

import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.system.bpm.util.UtilFile;
import cc.smtweb.system.bpm.util.UtilLogger;
import org.apache.commons.net.ftp.FTPClient;
@@ -243,7 +243,7 @@ public class FtpUtil implements IFtpUtil {
ftpClient.enterLocalPassiveMode();//设置被动模式
setRemoteDir(path);
String[] files = ftpClient.listNames(gbktoiso8859(filename));
return PubUtil.isNotEmpty(files);
return !CommUtil.isEmpty(files);
} catch (IOException e) {
logError("判断文件是否存在失败", e);
return false;


+ 1
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/IFtpServerConfig.java ファイルの表示

@@ -6,6 +6,7 @@ package cc.smtweb.system.bpm.util.ftp;
*/
public interface IFtpServerConfig {
boolean isSFTP();

String getServerIp();

Integer getPort();


+ 5
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/IFtpUtil.java ファイルの表示

@@ -9,10 +9,13 @@ import java.io.InputStream;
public interface IFtpUtil {
//是否自动删除
boolean isAutoFree();

//设置自动删除
void setAutoFree(boolean autoFree);

//登录ftp
boolean login(IFtpServerConfig ftpConf);

//退出ftp
void logout();

@@ -21,6 +24,7 @@ public interface IFtpUtil {

//设置远程目录
boolean setRemoteDir(String path);

void mkdir(String dirName);

//删除远程路径
@@ -37,6 +41,7 @@ public interface IFtpUtil {
boolean uploadFile(String path, String filename, File localFile) throws Exception;

void deleteFile(String path, String filename);

//判断文件是否存在
boolean existsFile(String path, String filename);



+ 5
- 4
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/SFtpUtil.java ファイルの表示

@@ -1,6 +1,7 @@
package cc.smtweb.system.bpm.util.ftp;

import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.util.UtilFile;
import cc.smtweb.system.bpm.util.UtilLogger;
import com.jcraft.jsch.*;
@@ -63,7 +64,7 @@ public class SFtpUtil implements IFtpUtil {
UtilLogger.debug("已连接到 " + ftpConf.getServerIp() + ";");
return true;
} catch (Exception e) {
UtilLogger.debug("connect fail[" + count + "/3]:" + PubUtil.getOrigMsg(e));
UtilLogger.debug("connect fail[" + count + "/3]:" + CommUtil.getOrigMsg(e));
}
}
UtilLogger.debug("sftp登录失败:3次连接超时...");
@@ -135,7 +136,7 @@ public class SFtpUtil implements IFtpUtil {
try {
String now = sftp.pwd();
for (int i = 0; i < dirs.length; i++) {
if (PubUtil.isEmpty(dirs[i])) continue;
if (StringUtil.isEmpty(dirs[i])) continue;
boolean dirExists = openRemoteDir(dirs[i]);
if (!dirExists) {
sftp.mkdir(dirs[i]);
@@ -387,7 +388,7 @@ public class SFtpUtil implements IFtpUtil {
setRemoteDir(path);
Vector<ChannelSftp.LsEntry> files = sftp.ls(filename);
sftp.cd(now);
return PubUtil.isNotEmpty(files);
return !CommUtil.isEmpty(files);
} catch (SftpException e) {
logError("判断文件是否存在失败", e);
return false;


+ 50
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/BpmStartedListener.java ファイルの表示

@@ -0,0 +1,50 @@
package cc.smtweb.system.bpm.web;

import cc.smtweb.framework.core.annotation.SwStartListener;
import cc.smtweb.framework.core.cache.CacheManager;
import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.db.impl.DatabaseUtil;
import cc.smtweb.framework.core.db.vo.ModelCatalog;
import cc.smtweb.framework.core.mvc.controller.IStartListener;
import cc.smtweb.framework.core.mvc.service.TreeHelper;
import cc.smtweb.framework.core.systask.SysServiceFactory;
import cc.smtweb.framework.core.systask.SysThreadPool;
import cc.smtweb.system.bpm.web.design.db.ModelCatalogTreeHelper;
import cc.smtweb.system.bpm.web.sys.base.job.JobUtils;
import cc.smtweb.system.bpm.web.sys.oneTimeService.OneTimeServiceFactory;
import cc.smtweb.system.bpm.web.sys.oneTimeService.OneTimeTaskCleanService;

/**
* Created by Akmm at 2022/7/8 19:57
*/
@SwStartListener()
public class BpmStartedListener implements IStartListener {
public int order() {
return SwConsts.DEFAULT_ORDER + 1;
}

@Override
public void init() {
SwConsts.SysParam.RUN_PROJECTS = "bpm";
SysServiceFactory.getInstance().reg(new OneTimeTaskCleanService());
TreeHelper.regTreeHelper(ModelCatalog.ENTITY_NAME, ModelCatalogTreeHelper.class);

}

@Override
public void run() {
//初始化数据库
new DatabaseUtil(true, false).checkDb();
//初始化缓存
CacheManager.getIntance().init();
OneTimeServiceFactory.getInstance().start();
JobUtils.getInstance().start();
}

@Override
public void close() {
OneTimeServiceFactory.getInstance().stop();
JobUtils.getInstance().stop();
SysThreadPool.getInstance().stop();
}
}

+ 22
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/canal/FilePathConfig.java ファイルの表示

@@ -0,0 +1,22 @@
package cc.smtweb.system.bpm.web.canal;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**
* @Author yaoq
* @Date 2022年07月20日 10:38
* @Description
*/
@Configuration
public class FilePathConfig {

@Value("${canal.file.path}")
private String path;

public String getPath() {
return path;
}
}



+ 22
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/common/BpmConst.java ファイルの表示

@@ -0,0 +1,22 @@
package cc.smtweb.system.bpm.web.common;

/**
* @Author: tanghp
* @Date: 2022-09-22 13:33
* @Desc: bpm模块的常量
*/
public interface BpmConst {

String DEF_PWD = "abc@123456"; //初始密码
String MENU_KEY = "__menuId";// 菜单ID key
String KEY_HEADER_MENU = "hmk"; // header中的菜单ID

interface DataRight {
public final static Long CUR_VALUE = 999L;//本机构,本部门
public final static Long ALL_DEPT = 998L;//全部门权限
public final static int V_SELF = 0;//本级
public final static int V_INCLUDE_CHILDREN = 1;//含下级
public final static int V_INCLUDE = 0;//包含
public final static int V_EXCEPT = 1;//排除
}
}

+ 49
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/common/BpmEnum.java ファイルの表示

@@ -0,0 +1,49 @@
package cc.smtweb.system.bpm.web.common;

import cc.smtweb.framework.core.common.IntEnum;
import cc.smtweb.framework.core.common.StrEnum;

/**
* Created by Akmm at 2022/3/23 9:39
* 系统的一些枚举变量
*/
public interface BpmEnum {

// 权限类型
class MenuRightType extends StrEnum {
public static MenuFuncRight instance = new MenuFuncRight();
public static StrEnumBean DATA = instance.addEnum("data", "数据权限");
public static StrEnumBean FUNC = instance.addEnum("func", "功能权限");
public static StrEnumBean FIELD = instance.addEnum("field", "字段权限");
}

class MenuType extends IntEnum {
public static MenuType instance = new MenuType();
public static IntEnumBean DESIGN = instance.addEnum(0, "设计器页面");
public static IntEnumBean CUSTOM = instance.addEnum(1, "自定义页面");
public static IntEnumBean LINK = instance.addEnum(2, "外部链接");
}

// 功能权限枚举
class MenuFuncRight extends StrEnum {
public static MenuFuncRight instance = new MenuFuncRight();
public static StrEnumBean READ = instance.addEnum("read", "查看");
public static StrEnumBean WRITE = instance.addEnum("write", "修改");
public static StrEnumBean EXPORT = instance.addEnum("export", "导出");
public static StrEnumBean AUDIT = instance.addEnum("audit", "审核");
}

class UserStatu extends IntEnum {
public static UserStatu instance = new UserStatu();
public static IntEnumBean NOACT = instance.addEnum(0, "未激活");
public static IntEnumBean NORMAL = instance.addEnum(1, "已激活");
public static IntEnumBean LOCK = instance.addEnum(2, "已锁定");
public static IntEnumBean STOP = instance.addEnum(9, "已停用");
}

class DataRightType extends StrEnum {
public static DataRightType instance = new DataRightType();
public static StrEnumBean PARTY = instance.addEnum("party", "机构权限");
public static StrEnumBean DEPT = instance.addEnum("dept", "部门权限");
}
}

+ 1
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogCache.java ファイルの表示

@@ -40,7 +40,7 @@ public class ModelCatalogCache extends AbstractCache<ModelCatalog> {

public String getName(long id) {
ModelCatalog bean = get(id);
return bean != null ? bean.getName() : "";
return bean != null ? bean.getName(): "";
}

public String getFullName(long id) {


+ 18
- 8
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHandler.java ファイルの表示

@@ -12,6 +12,7 @@ import cc.smtweb.framework.core.mvc.service.AbstractTreeHandler;
import cc.smtweb.framework.core.mvc.service.TreeHelper;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.flow.ModelProc;
import cc.smtweb.system.bpm.web.design.flow.ModelProcCache;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
@@ -35,6 +36,7 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
private int type;//查询类型:0-目录;1-表定义;2-页面定义
private boolean exc_empty;//排除空目录,type非目录时有效
private boolean exc_depend;//排除依赖项目的目录
private boolean only_bill;//仅限单据页面(billType>0)
private ModelCatalogTreeHelper mcTreeHelper = null;

//模块子页面,暂存
@@ -47,7 +49,9 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
prj_id = params.readLong("prj_id");
exc_empty = params.readBool("exc_empty");
exc_depend = params.readBool("exc_depend");
mcTreeHelper = (ModelCatalogTreeHelper) TreeHelper.getTreeHelper(ModelCatalog.ENTITY_NAME, ModelCatalogTreeHelper.class);
only_bill = params.readBool("only_bill");
if (only_bill) exc_empty = true;
mcTreeHelper = (ModelCatalogTreeHelper) TreeHelper.getTreeHelper(ModelCatalog.ENTITY_NAME);
}

@Override
@@ -60,7 +64,7 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>

@Override
protected List<DefaultEntity> filterData() {
Set<Long> setId =exc_depend ? new HashSet<>(Arrays.asList(prj_id)) : ModelProjectCache.getInstance().getDependsPrjIds(prj_id);
Set<Long> setId = exc_depend ? new HashSet<>(Arrays.asList(prj_id)): ModelProjectCache.getInstance().getDependsPrjIds(prj_id);
if (setId.isEmpty()) return new ArrayList<>();
String sqlPrjId = CommUtil.getSqlInIds(setId);

@@ -102,7 +106,7 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>

@Override
protected List<DefaultEntity> getChildren(long id) {
List<ModelCatalog> list = mcTreeHelper.getChildren(id, prj_id,exc_depend, (o1, o2) -> CommUtil.chineseCompare(o1.getName(), o2.getName()));
List<ModelCatalog> list = mcTreeHelper.getChildren(id, prj_id, exc_depend, (o1, o2) -> StringUtil.chineseCompare(o1.getName(), o2.getName()));
List<DefaultEntity> listRet;
if (type != TYPE_CATALOG && exc_empty) {//排除空目录
listRet = cleanEmpty(list);
@@ -156,7 +160,7 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
addPageChildren(listRet, mc.getId(), type);
}
if (!listRet.isEmpty()) return true;
List<ModelCatalog> list = mcTreeHelper.getChildren(mc.getId(), prj_id,exc_depend,null);
List<ModelCatalog> list = mcTreeHelper.getChildren(mc.getId(), prj_id, exc_depend, null);
if (list == null || list.isEmpty()) return false;
for (ModelCatalog c : list) {
if (hasChildren(c)) return true;
@@ -166,7 +170,7 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>

//增加表
private void addTableChildren(List<DefaultEntity> listRet, long mcid) {
Collection<ModelTable> set = ModelTableCache.getInstance().getTablesByMc(mcid, (o1, o2) -> CommUtil.chineseCompare(o1.getName(), o2.getName()));
Collection<ModelTable> set = ModelTableCache.getInstance().getTablesByMc(mcid, (o1, o2) -> StringUtil.chineseCompare(o1.getName(), o2.getName()));
if (set == null || set.isEmpty()) return;

listRet.addAll(set);
@@ -174,7 +178,7 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>

//增加工作流
private void addProcChildren(List<DefaultEntity> listRet, long mcid) {
Collection<ModelProc> set = ModelProcCache.getInstance().getProcByMc(mcid, (o1, o2) -> CommUtil.chineseCompare(o1.getName(), o2.getName()));
Collection<ModelProc> set = ModelProcCache.getInstance().getProcByMc(mcid, (o1, o2) -> StringUtil.chineseCompare(o1.getName(), o2.getName()));
if (set == null || set.isEmpty()) return;

listRet.addAll(set);
@@ -184,6 +188,9 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
private void addForm(List<DefaultEntity> listRet, List<ModelForm> lf, boolean exc_widget) {
for (ModelForm mf : lf) {
if (exc_widget && mf.getType() == SwEnum.FormType.WIDGET.value) continue;
if (only_bill && mf.getBillType() <= 0L) {//清除非单据页面
continue;
}
if (mf.getParent() > 0) {
List<DefaultEntity> ch = mapFormChild.computeIfAbsent(mf.getParent(), k -> new ArrayList<>());
ch.add(mf);
@@ -197,7 +204,7 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
private void addPageChildren(List<DefaultEntity> listRet, long mcid, int type) {
List<ModelForm> set = ModelFormCache.getInstance().getFormsByMc(mcid, (o1, o2) -> {
if (o1.getType() != o2.getType()) return o1.getType() - o2.getType();
return CommUtil.chineseCompare(o1.getTitle(), o2.getTitle());
return StringUtil.chineseCompare(o1.getTitle(), o2.getTitle());
});
if (set == null || set.isEmpty()) return;
switch (type) {
@@ -233,6 +240,9 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
if (bean instanceof ModelForm) {
return ((ModelForm) bean).getTitle();
}
if (bean instanceof ModelProc) {
return ((ModelProc) bean).getName();
}
return null;
}

@@ -249,7 +259,7 @@ public class ModelCatalogTreeHandler extends AbstractTreeHandler<DefaultEntity>
final ModelForm form = (ModelForm) bean;
node.put("type", form.getType() + 2);
// 返回页面名称
bean.put("pageName",ModelProjectCache.getInstance().getModule(((ModelForm) bean).getPrjId())+"."+((ModelForm) bean).getName());
bean.put("pageName", ModelProjectCache.getInstance().getModule(((ModelForm) bean).getPrjId()) + "." + ((ModelForm) bean).getName());
//是模块,需要加子页面
if (form.getType() == SwEnum.FormType.MODULE.value) {
List<DefaultEntity> lf = mapFormChild.get(form.getEntityId());


+ 4
- 4
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelCatalogTreeHelper.java ファイルの表示

@@ -17,15 +17,15 @@ public class ModelCatalogTreeHelper extends TreeHelper<ModelCatalog> {
super(ModelCatalog.ENTITY_NAME);
}

public List<ModelCatalog> getChildren(long id, long prj_id,boolean exc_depend, Comparator<ModelCatalog> comparator) {
if (id > 0) {
public List<ModelCatalog> getChildren(long id, long prj_id, boolean exc_depend, Comparator<ModelCatalog> comparator) {
if (id > 0L) {
return getChildren(id, comparator);
}
Set<Long> setId = exc_depend ? new HashSet<>(Arrays.asList(prj_id)) : ModelProjectCache.getInstance().getDependsPrjIds(prj_id);
Set<Long> setId = exc_depend ? new HashSet<>(Arrays.asList(prj_id)): ModelProjectCache.getInstance().getDependsPrjIds(prj_id);
if (setId.isEmpty()) return new ArrayList<>();
Set<ModelCatalog> set = new HashSet<>();

for (long prjId: setId) {
for (long prjId : setId) {
Collection<ModelCatalog> st = cache.getListByKey(CACHE_KEY, prjId + SwConsts.SPLIT_CHAR + SwConsts.DEF_ROOT_ID);
if (st != null) set.addAll(st);
}


+ 9
- 6
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelProjectCache.java ファイルの表示

@@ -19,12 +19,13 @@ import java.util.Set;
@SwCache(ident = "ASP_MODEL_PROJECT", title = "项目定义")
public class ModelProjectCache extends AbstractCache<ModelProject> {
private final static String mm = "m";

public static ModelProjectCache getInstance() {
return CacheManager.getIntance().getCache(ModelProjectCache.class);
}

public ModelProjectCache() {
regMap(mm, k-> String.valueOf(k.getModule()));
regMap(mm, k -> String.valueOf(k.getModule()));
}

@Override
@@ -40,14 +41,16 @@ public class ModelProjectCache extends AbstractCache<ModelProject> {

public String getModule(long id) {
ModelProject bean = get(id);
return bean != null ? bean.getModule() : "";
return bean != null ? bean.getModule(): "";
}
public ModelProject getByModule(String module){
return getByKey(mm,module);

public ModelProject getByModule(String module) {
return getByKey(mm, module);
}

public String getIdByModule(String module) {
ModelProject bean = getByModule(module);
return bean !=null ? String.valueOf(bean.getId()): "";
return bean != null ? String.valueOf(bean.getId()): "";
}

//找当前项目及其依赖项目的id集合,递归
@@ -65,7 +68,7 @@ public class ModelProjectCache extends AbstractCache<ModelProject> {
set.add(id);
if (StringUtils.isEmpty(bean.getDepends())) return;
String[] dps = bean.getDepends().split(",");
for (String s: dps) {
for (String s : dps) {
s = s.trim();
if (StringUtils.isEmpty(s)) return;
addPrjId(set, NumberUtil.getLongIgnoreErr(s));


+ 14
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/ModelTableService.java ファイルの表示

@@ -8,6 +8,7 @@ import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.mvc.service.*;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.system.bpm.web.design.form.CodeBuildHandler;

/**
* Created by Akmm at 2022/3/22 9:12
@@ -44,4 +45,17 @@ public class ModelTableService extends AbstractCompService {
return R.error("操作失败!", e);
}
}

//生成bean
public R buildBean(@SwBody SwMap params, UserSession us) {
CodeBuildHandler handler = new CodeBuildHandler();
if (params == null) params = new SwMap();
if (us == null) us = UserSession.createSys();
handler.init(params, us);
try {
return handler.buildBeanByTable();
} catch (Exception e) {
return R.error("操作失败!", e);
}
}
}

+ 9
- 3
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/FlowConst.java ファイルの表示

@@ -14,7 +14,7 @@ public interface FlowConst {
public static final int NEW = 1;//新增
public static final int EDIT = 2;//编辑
}
//流程按钮
class Button extends StrEnum {
public static Button instance = new Button();
@@ -28,10 +28,11 @@ public interface FlowConst {
public static StrEnumBean RETAKE = instance.addEnum("retake", "取回");
//驳回
public static StrEnumBean REJECT = instance.addEnum("reject", "驳回");
public static StrEnumBean INTERRUPT = instance.addEnum("interrupt", "终止");
//新增
public static StrEnumBean ADD = instance.addEnum("add", "新增");
//删除
public static StrEnumBean DEL = instance.addEnum("del", "删除");
public static StrEnumBean DEL = instance.addEnum("remove", "删除");
//保存
public static StrEnumBean SAVE = instance.addEnum("save", "保存");

@@ -43,6 +44,7 @@ public interface FlowConst {
public static StrEnumBean LOG = instance.addEnum("log", "流程历史");

}

/**
* 活动类型 1-开始任务 2-用户任务 3-条件分支 4-并行开始 5-并行结束 6-脚本任务 9-结束任务
*/
@@ -65,8 +67,12 @@ public interface FlowConst {
public static IntEnumBean WAIT = instance.addEnum(0, "待办");
public static IntEnumBean HANDLE = instance.addEnum(1, "办理中");
public static IntEnumBean SUBMIT = instance.addEnum(2, "已提交");
//审批不通过
public static IntEnumBean INTERRUPT = instance.addEnum(7, "已中止");
public static IntEnumBean DISUSE = instance.addEnum(8, "已作废");
public static IntEnumBean REJECT = instance.addEnum(9, "已驳回");
//并发流程中,因其他任务被驳回,导致该任务的停止
public static IntEnumBean STOP = instance.addEnum(6, "已停止");
}

/**
@@ -77,7 +83,7 @@ public interface FlowConst {
public static IntEnumBean BEGIN = instance.addEnum(1, "制单");
public static IntEnumBean RUNING = instance.addEnum(2, "审批中");
public static IntEnumBean FINISH = instance.addEnum(99, "生效");
public static IntEnumBean ABORTED = instance.addEnum(98, "中止");
public static IntEnumBean INTERRUPT = instance.addEnum(98, "中止");
public static IntEnumBean DISUSE = instance.addEnum(89, "作废");
}



+ 5
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProc.java ファイルの表示

@@ -21,11 +21,15 @@ public class ModelProc extends DefaultEntity {
super(ENTITY_NAME);
}

public void clear() {
procInfo = null;
}

public ProcInfo getProcInfo() {
if (procInfo == null) {
synchronized ("ModelProc_" + getId()) {
if (procInfo == null) {
procInfo = JsonUtil.parse(getContent(), ProcInfo.class);
procInfo = JsonUtil.parse(getContent(), "model", ProcInfo.class);
}
}
}


+ 3
- 3
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcCache.java ファイルの表示

@@ -25,9 +25,9 @@ public class ModelProcCache extends AbstractCache<ModelProc> {
}

public ModelProcCache() {
regMap(mk, k-> k.getName().toUpperCase());
regList(mp, k-> String.valueOf(k.getPrjId()));
regList(mc, k-> String.valueOf(k.getMcId()));
regMap(mk, k -> k.getName().toUpperCase());
regList(mp, k -> String.valueOf(k.getPrjId()));
regList(mc, k -> String.valueOf(k.getMcId()));
}

@Override


+ 5
- 3
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcHelper.java ファイルの表示

@@ -22,11 +22,13 @@ public class ModelProcHelper {
public static ModelProc getFromCache(long proc_id) {
return ModelProcCache.getInstance().get(proc_id);
}

public static ProcInfo getProcFromCache(long proc_id) {
ModelProc proc = getFromCache(proc_id);
if (proc == null) return null;
return proc.getProcInfo();
}

/**
* 获取配置的工作流程定义
*
@@ -34,9 +36,9 @@ public class ModelProcHelper {
* @param user_id
* @return
*/
public static ModelProc getBillProc(int bill_type, long user_id) {
public static ModelProc getBillProc(long bill_type, long user_id) {
Set<BillFlow> list = BillFlowCache.getInstance().getByBillType(bill_type);
if (CommUtil.isEmpty(list)) {
return null;
}
@@ -101,7 +103,7 @@ public class ModelProcHelper {
return act;
}
}
return null;
}



+ 2
- 4
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcLoadHandler.java ファイルの表示

@@ -13,17 +13,15 @@ public class ModelProcLoadHandler extends DefaultLoadHandler<ModelProc> {
}

@Override
protected ModelProc loadComp(long id) {
ModelProc bean = super.loadComp(id);
protected void afterLoad(ModelProc bean) {
bean.getData().remove("prc_content");
return bean;
}


//页面设计 - 加载页面model定义
public R loadModel() {
long id = params.readLong("id");
ModelProc bean = super.loadComp(id);
ModelProc bean = ModelProcCache.getInstance().get(id);
if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id);
return R.success(bean.getContent());
}


+ 4
- 3
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcSaveHandler.java ファイルの表示

@@ -5,7 +5,7 @@ import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.jdbc.AbsDbWorker;
import cc.smtweb.framework.core.db.jdbc.IDbWorker;
import cc.smtweb.framework.core.db.vo.ModelField;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.exception.BizException;
@@ -60,12 +60,12 @@ public class ModelProcSaveHandler extends DefaultSaveHandler<ModelProc> {
public R saveModel() {
long id = params.readLong("id");
String data = params.readString("data");
bean = loadComp(id);
bean = ModelProcCache.getInstance().get(id);
if (StringUtils.isEmpty(data)) {
throw new BizException("没有待保存的数据!");
}
bean.setContent(data);
DbEngine.getInstance().doTrans(new AbsDbWorker() {
DbEngine.getInstance().doTrans(new IDbWorker() {
@Override
public void work() {
EntityDao<ModelProc> dao = DbEngine.getInstance().findDao(tableName);
@@ -73,6 +73,7 @@ public class ModelProcSaveHandler extends DefaultSaveHandler<ModelProc> {
ModelTable table = ModelTableCache.getInstance().getByName(tableName);
ModelField field = table.findFieldByType(SwEnum.FieldType.UPDATE_USER.value);
if (field != null) bean.put(field.getName(), us.getUserId());
bean.clear();
dao.updateEntity(bean, "prc_content");
}



+ 44
- 2
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/ModelProcService.java ファイルの表示

@@ -3,12 +3,22 @@ package cc.smtweb.system.bpm.web.design.flow;
import cc.smtweb.framework.core.annotation.SwBody;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.vo.ModelField;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.mvc.service.AbstractCompService;
import cc.smtweb.framework.core.mvc.service.AbstractHandler;
import cc.smtweb.framework.core.mvc.service.DefaultDelHandler;
import cc.smtweb.framework.core.mvc.service.DefaultListHandler;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.system.bpm.web.design.form.ModelFormHelper;
import cc.smtweb.system.bpm.web.engine.flow.entity.Comment;
import cc.smtweb.system.bpm.web.engine.flow.entity.ProcInst;

import java.util.ArrayList;
import java.util.List;

/**
* Created by Akmm at 2022/3/22 9:12
@@ -33,12 +43,44 @@ public class ModelProcService extends AbstractCompService {

//保存页面模型
public R saveModel(@SwBody SwMap params, UserSession us) {
return pageHandler(params, us, TYPE_SAVE, handler -> ((ModelProcSaveHandler)handler).saveModel());
return pageHandler(params, us, TYPE_SAVE, handler -> ((ModelProcSaveHandler) handler).saveModel());
}

//加载页面模型
public R loadModel(@SwBody SwMap params, UserSession us) {
return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelProcLoadHandler)handler).loadModel());
return pageHandler(params, us, TYPE_LOAD, handler -> ((ModelProcLoadHandler) handler).loadModel());
}

//加载工作流的列表字段
public R loadFlowListFields (@SwBody SwMap params, UserSession us) {
List<SwMap> ret = new ArrayList<>();
ModelFormHelper.buildTableFields(ret, ProcInst.ENTITY_NAME);
return R.success(ret);
}
public R loadFlowCardFields(@SwBody SwMap params, UserSession us) {
List<SwMap> ret = new ArrayList<>();
ModelFormHelper.buildTableFields(ret, ProcInst.ENTITY_NAME);
ret.add(buildField("selTaskId", SwEnum.DataType.ID.value, "选中任务"));

return R.success(ret);
}

//加载审批意见的列表字段
public R loadCommentFields(@SwBody SwMap params, UserSession us) {
List<SwMap> ret = new ArrayList<>();
ModelFormHelper.buildTableFields(ret, Comment.ENTITY_NAME);
ret.add(buildField("cmt_act_code", SwEnum.DataType.CODE.value, "活动编号"));
ret.add(buildField("cmt_act_text", SwEnum.DataType.NAME.value, "活动名称"));
return R.success(ret);
}

private SwMap buildField(String name, String dataType, String title) {
SwMap col = new SwMap();
col.put("name", name);
col.put("dataType", dataType);
col.put("title", title);
col.put("editor", SwEnum.EditorType.INPUT.value);
return col;
}
}

+ 20
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/ProcInfo.java ファイルの表示

@@ -1,8 +1,10 @@
package cc.smtweb.system.bpm.web.design.flow.define;

import cc.smtweb.system.bpm.web.design.flow.FlowConst;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
@@ -24,11 +26,28 @@ public class ProcInfo {

public Activity findActivity(String id) {
if (StringUtils.isEmpty(id)) return null;
for (Activity act: activities) {
for (Activity act : activities) {
if (id.equalsIgnoreCase(act.getId())) {
return act;
}
}
return null;
}

//获取任务名称
public String getActNameById(String id) {
Activity act = findActivity(id);
return act != null ? act.getLabel(): "";
}

//获取结束节点
public List<Activity> findEndActivity() {
List<Activity> list = new ArrayList<>();
for (Activity act : activities) {
if (act.getType() == FlowConst.ActivityType.END.value) {
list.add(act);
}
}
return list;
}
}

+ 1
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/Sign.java ファイルの表示

@@ -14,5 +14,5 @@ public class Sign extends Handler {
private int minAgree;
//最少会签同意人数单位:0-人数 1-会签同意占比
private int minAgreeUnit;
}

+ 1
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/flow/define/Trans.java ファイルの表示

@@ -13,7 +13,7 @@ public class Trans {
//序号
private int seq;
//条件表达式
private String expr;
private String filter;
//源活动
private String src;
//目标活动


+ 54
- 7
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/CodeBuildHandler.java ファイルの表示

@@ -1,6 +1,8 @@
package cc.smtweb.system.bpm.web.design.form;

import cc.smtweb.framework.core.common.*;
import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.vo.ModelCache;
import cc.smtweb.framework.core.db.vo.ModelField;
@@ -57,14 +59,53 @@ public class CodeBuildHandler extends AbstractHandler {
buildJavaTable(tableId, needBean, needCache);
}
if (needBuildService) buildJavaService(pageId);
System.out.println("JAVA代码路径:" + codePath);
return R.success();
}

public R buildBeanByTable() {
userName = String.valueOf(us.getUserId());

//页面id
long tableId = params.readLong("tableId");
ModelTable table = ModelTableCache.getInstance().get(tableId);
if (table == null) throw new BizException("未找到指定的表定义(" + table + ")!");

String moduleName = ModelProjectCache.getInstance().getModule(table.getPrjId());
if (StringUtils.isEmpty(moduleName)) throw new BizException("此项目未定义Module!");
if (moduleName.equals("bpm")) {
packageName = "cc.smtweb.system.bpm.web";
} else {
packageName = "cc.smtweb.biz." + moduleName + ".web";
}
BpmConfigBean bpmConfigBean = SpringUtil.getBean(BpmConfigBean.class);
Map<String, String> mapIdeaModules = IdeaUtil.getModules(bpmConfigBean.getCodeJavaPath(), bpmConfigBean.getMode());
if (mapIdeaModules == null || mapIdeaModules.isEmpty())
throw new BizException("没有定义idea项目的路径(smtweb.bpm.codeJavaPath)!");
codePath = mapIdeaModules.get(moduleName);
if (StringUtils.isEmpty(codePath)) {
throw new BizException("没有找到对应项目在idea中Module的路径(" + moduleName + ")!");
}
codePath += "/src/main/java/";
//加上目录
String cn = ModelCatalogCache.getInstance().getFullName(table.getMcId());
if (StringUtils.isNotEmpty(cn)) {
packageName += "." + cn;
}

codePath += packageName.replaceAll("\\.", "/");
new File(codePath).mkdirs();

buildJavaTable(tableId, true, table.isNeedCache());
System.out.println("JAVA代码路径:" + codePath);
return R.success();
}

public R buildJsCode() {
userName = String.valueOf(us.getUserId());
//页面id
long pageId = params.readLong("pageId");
ModelForm form = ModelFormCache.getInstance().get(pageId);
String pageId = params.readString("pageId");
ModelForm form = ModelFormHelper.getFromCache(pageId);
if (form == null) throw new BizException("未找到指定的页面定义(" + pageId + ")!");
String moduleName = ModelProjectCache.getInstance().getModule(form.getPrjId());
if (StringUtils.isEmpty(moduleName)) throw new BizException("此项目未定义Module!");
@@ -79,6 +120,7 @@ public class CodeBuildHandler extends AbstractHandler {
model.put("title", form.getTitle());
model.put("eventPath", eventPath + "." + form.getName());
CodeGenerator.getInstance().generateJsEvent(model, codePath + "/" + form.getName() + ".js");
System.out.println("JS代码路径:" + codePath);
return R.success();
}

@@ -100,7 +142,8 @@ public class CodeBuildHandler extends AbstractHandler {
}
BpmConfigBean bpmConfigBean = SpringUtil.getBean(BpmConfigBean.class);
Map<String, String> mapIdeaModules = IdeaUtil.getModules(bpmConfigBean.getCodeJavaPath(), bpmConfigBean.getMode());
if (mapIdeaModules == null || mapIdeaModules.isEmpty()) throw new BizException("没有定义idea项目的路径(smtweb.bpm.codeJavaPath)!");
if (mapIdeaModules == null || mapIdeaModules.isEmpty())
throw new BizException("没有定义idea项目的路径(smtweb.bpm.codeJavaPath)!");
codePath = mapIdeaModules.get(moduleName);
if (StringUtils.isEmpty(codePath)) {
throw new BizException("没有找到对应项目在idea中Module的路径(" + moduleName + ")!");
@@ -143,7 +186,11 @@ public class CodeBuildHandler extends AbstractHandler {
fields.add(fn);
fn.put("name", field.getName());
fn.put("title", field.getTitle());
fn.put("javaName", CodeGenUtil.getBeanName(field.getName()));
String javaName = CodeGenUtil.getBeanName(field.getName());
if (SwEnum.DataType.BOOL.value.equals(field.getDataType()) && javaName.startsWith("Is")) {
javaName = javaName.substring(2);
}
fn.put("javaName", javaName);
SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(field.getDataType());
fn.put("javaType", dtb.javaType);
fn.put("shortJavaType", dtb.shortJavaType);
@@ -177,11 +224,11 @@ public class CodeBuildHandler extends AbstractHandler {
if (StringUtils.isEmpty(sName)) {
//模块名称
form = ModelFormCache.getInstance().get(form.getParent());
if(form == null){
if (form == null) {
throw new BizException("页面设置未定义服务名!" + form.getTitle());
}
sName = form.getService();
if(StringUtils.isEmpty(sName)){
if (StringUtils.isEmpty(sName)) {
throw new BizException("模块设置未定义服务名!" + form.getTitle());
}
}


+ 8
- 2
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelForm.java ファイルの表示

@@ -3,10 +3,13 @@ package cc.smtweb.system.bpm.web.design.form;
import cc.smtweb.framework.core.annotation.SwTable;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.impl.DefaultEntity;
import cc.smtweb.framework.core.util.JsonUtil;
import cc.smtweb.system.bpm.web.design.form.define.PageDataset;
import cc.smtweb.system.bpm.web.design.form.define.PageDatasetField;
import cc.smtweb.system.bpm.web.design.form.define.PageDatasets;

import java.util.Map;

/**
* Created by Akmm at 2022/4/15 17:26
*/
@@ -150,7 +153,9 @@ public class ModelForm extends DefaultEntity {
}

public void setContent(String mfContent) {
put("mf_content", mfContent);
String temStr = mfContent == null ? "{}" : mfContent;
Map map = JsonUtil.parseMap(temStr);
put("mf_content", JsonUtil.encodeString(map));
}

public String getOption() {
@@ -230,6 +235,7 @@ public class ModelForm extends DefaultEntity {

//返回单据类型id
public long getBillType() {
return getOpts().readLong("billType");
SwMap opts = getOpts();
return opts != null ? opts.readLong(ModelFormHelper.KEY_BILL_TYPE): 0L;
}
}

+ 20
- 19
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormCache.java ファイルの表示

@@ -1,19 +1,13 @@
package cc.smtweb.system.bpm.web.design.form;

import cc.smtweb.framework.core.annotation.SwCache;
import cc.smtweb.framework.core.cache.AbstractCache;
import cc.smtweb.framework.core.cache.AbstractEntityCache;
import cc.smtweb.framework.core.cache.CacheManager;
import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.system.bpm.web.design.db.ModelProjectCache;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.*;

/**
* Created by Akmm at 2022/1/12 18:34
@@ -26,17 +20,18 @@ public class ModelFormCache extends AbstractEntityCache<ModelForm> {
private final static String mt = "t";
private final static String ms = "s";
private final static String mn = "mn";

public static ModelFormCache getInstance() {
return CacheManager.getIntance().getCache(ModelFormCache.class);
}

public ModelFormCache() {
regMap(mk, k-> k.getName().toUpperCase());
regMap(mn, k-> ModelProjectCache.getInstance().getModule(k.getPrjId())+"-"+k.getName().toUpperCase());
regList(mp, k-> String.valueOf(k.getPrjId()));
regList(mc, k-> String.valueOf(k.getMcId()));
regList(ms, k-> String.valueOf(k.getParent()));
regList(mt, k-> k.getMasterTableId() + SwConsts.SPLIT_CHAR + k.getType());
regMap(mk, k -> k.getName().toUpperCase());
regMap(mn, k -> ModelFormHelper.getPageName(k).toUpperCase());
regList(mp, k -> String.valueOf(k.getPrjId()));
regList(mc, k -> String.valueOf(k.getMcId()));
regList(ms, k -> String.valueOf(k.getParent()));
regList(mt, k -> k.getMasterTableId() + SwConsts.SPLIT_CHAR + k.getType());
// regList(mf, k-> k.get);
}

@@ -86,24 +81,30 @@ public class ModelFormCache extends AbstractEntityCache<ModelForm> {

//根据模块id,找对应的页面设计
public Set<ModelForm> getListByModule(long parent) {
return getListByKey(mt, String.valueOf(parent));
return getListByKey(ms, String.valueOf(parent));
}

public String getText(long id) {
ModelForm form = get(id);
return form != null ? form.getTitle() : String.valueOf(id);
return form != null ? form.getTitle(): String.valueOf(id);
}

/**
* 根据末模块名称和页面名称获取 页面模型
*
* @param module
* @param pageName
* @return ModelForm
*/
public ModelForm getByName(String module,String pageName){
if(PubUtil.isEmptyStr(module)||PubUtil.isEmptyStr(pageName)){
return null;
public ModelForm getByPageName(String pageName) {
return getByKey(mn, pageName.toUpperCase());
}
// 获取包含本页面的模块下的所有页面
public Set<ModelForm> getIncPage(long pageId){
ModelForm form = get(pageId);
if(form==null || form.getParent()<=0L){
return null;
}
return getByKey(mn,module+"-"+pageName.toUpperCase());
return getListByModule(form.getParent());
}
}

+ 58
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormDelHandler.java ファイルの表示

@@ -0,0 +1,58 @@
package cc.smtweb.system.bpm.web.design.form;

import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.mvc.service.DefaultDelHandler;
import cc.smtweb.framework.core.util.CommUtil;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* Created by Akmm at 2022-08-15 15:00
*/
public class ModelFormDelHandler extends DefaultDelHandler<ModelForm> {
//被删除的id
private Set<ModelForm> listDeled = new HashSet<>();

public ModelFormDelHandler() {
super(ModelForm.ENTITY_NAME);
}

@Override
protected void checkValid() {
// super.checkValid();
}

@Override
protected void delDb() {
EntityDao<ModelForm> dao = DbEngine.getInstance().findDao(ModelForm.class);
Set<ModelForm> l1 = ModelFormCache.getInstance().getListByModule(id);
Set<ModelForm> list = l1 != null ? new HashSet<>(l1): null;
if (CommUtil.isEmpty(list)) {
listDeled = null;
dao.deleteEntity(id);
} else {
listDeled = new HashSet<>(list);
List<Long> ids = new ArrayList<>();
ids.add(id);
for (ModelForm form : list) {
ids.add(form.getId());
}
dao.deleteEntity(ids);
}
}

@Override
protected void saveSuccess() {
ModelFormCache cache = ModelFormCache.getInstance();
if (!CommUtil.isEmpty(listDeled)) {
for (ModelForm form : listDeled) {
cache.remove(form.getId());
}
}
cache.remove(id);
}
}

+ 129
- 48
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java ファイルの表示

@@ -1,24 +1,28 @@
package cc.smtweb.system.bpm.web.design.form;

import cc.smtweb.framework.core.cache.AbstractCache;
import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.vo.ModelField;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.framework.core.mvc.variable.SwVariableFactory;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.JsonUtil;
import cc.smtweb.framework.core.util.MapUtil;
import cc.smtweb.framework.core.util.SpringUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.spring.BpmConfigBean;
import cc.smtweb.system.bpm.util.CodeGenerator;
import cc.smtweb.system.bpm.util.IdeaUtil;
import cc.smtweb.system.bpm.web.design.db.ModelCatalogCache;
import cc.smtweb.system.bpm.web.design.db.ModelProjectCache;
import cc.smtweb.system.bpm.web.design.form.define.*;
import cc.smtweb.system.bpm.web.engine.flow.entity.Comment;
import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanHelper;
import cc.smtweb.system.bpm.web.sys.user.role.RoleHelper;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.lang3.StringUtils;

@@ -30,12 +34,38 @@ import java.util.*;
*/
public class ModelFormHelper {
public static final String KEY_EVENT_PATH = "eventPath";
public static final String KEY_BILL_TYPE = "billType";
//分组类别-list
public static final String PAGE_TYPE_LIST = "list";
//分组类别-card
public static final String PAGE_TYPE_CARD = "card";
//分组类别-view
public static final String PAGE_TYPE_VIEW = "view";
//opts里面的配置关键字
public static final String OPT_CONFIG = "config";
public static final String OPT_MODEL = "model";
public static final String OPT_PAGE_TYPE = "pageType";
public static final String OPT_PAGE = "page";


/**
* 获取页面的pageName,格式:module.name
*
* @param form
* @return
*/
public static String getPageName(ModelForm form) {
return ModelProjectCache.getInstance().getModule(form.getPrjId()) + "." + form.getName();
}

//获取form的模型
public static String getFormModel(ModelForm form) {
SwMap opts = form.getOpts();
if (opts == null) return null;
SwMap config = opts.readMap(OPT_CONFIG);
if (config == null) return null;
return config.readString(OPT_MODEL);
}

/**
* 从缓存获取Form对象
@@ -43,10 +73,11 @@ public class ModelFormHelper {
* @param formId
* @return
*/
public static ModelForm getFromCache(long formId) {
AbstractCache<ModelForm> cache = ModelFormCache.getInstance();
public static ModelForm getFromCache(String formId) {
ModelFormCache cache = ModelFormCache.getInstance();
if (cache == null) return null;
return cache.get(formId);
ModelForm form = cache.get(formId);
return form != null ? form: cache.getByPageName(formId);
}

/*public static PageDatasets parsePageDataset(long formId) {
@@ -103,16 +134,16 @@ public class ModelFormHelper {
//没有配置db,配置有误,不处理
if (StringUtils.isEmpty(db)) throw new BizException("model未配置数据集db,无法解析!");
PageDataset pds = datasets.findById(db);
String key = isField ? "fields" : "filters";
String key = isField ? "fields": "filters";
List<Map<String, Object>> fields = (List<Map<String, Object>>) model.get(key);
if (fields == null || fields.isEmpty()) return;
for (Map<String, Object> field : fields) {
String fn = (String) field.get("field");
if (StringUtils.isEmpty(fn)) throw new BizException("model[" + db + "]." + key + "未配置字段名field,无法解析!");
BaseDatasetField pdf = isField ? pds.findFieldByName(fn) : pds.findFilterByName(fn);
BaseDatasetField pdf = isField ? pds.findFieldByName(fn): pds.findFilterByName(fn);
if (pdf == null) throw new BizException("model[" + db + "]." + key + "未找到定义的数据集字段(" + fn + "),无法解析!");

if (CommUtil.isStrEquals(MapUtil.readString(field, "label"), pdf.label)) {
if (StringUtil.isStrEquals(MapUtil.readString(field, "label"), pdf.label)) {
field.remove("label");
}

@@ -161,10 +192,10 @@ public class ModelFormHelper {
ModelField tf = table.findFieldByName(field.field);
if (tf == null) continue;
field.table_text = null;
if (CommUtil.isStrEquals(tf.getTitle(), field.label)) field.label = null;
if (CommUtil.isStrEquals(tf.getDataType(), field.dataType)) field.dataType = null;
if (CommUtil.isStrEquals(tf.getRemark(), field.remark)) field.remark = null;
if (CommUtil.isStrEquals(tf.getEditor(), field.editor)) field.editor = null;
if (StringUtil.isStrEquals(tf.getTitle(), field.label)) field.label = null;
if (StringUtil.isStrEquals(tf.getDataType(), field.dataType)) field.dataType = null;
if (StringUtil.isStrEquals(tf.getRemark(), field.remark)) field.remark = null;
if (StringUtil.isStrEquals(tf.getEditor(), field.editor)) field.editor = null;
}
}

@@ -189,7 +220,7 @@ public class ModelFormHelper {
public static String buildReqModel(ModelForm form) {
PageDatasets datasets = form.getDatasets();
PageModel pageInfo = parsePageInfo(form.getContent());
if (pageInfo == null) return "";
if (pageInfo == null || pageInfo.model == null) return "";
for (Map<String, Object> model : pageInfo.model) {
String db = (String) model.get("dataset");
//没有配置db,配置有误,不处理
@@ -204,13 +235,13 @@ public class ModelFormHelper {

//处理model的fields和filters
private static void buildReqModelFields(PageDataset dataSet, Map<String, Object> model, boolean isField) {
String key = isField ? "fields" : "filters";
String key = isField ? "fields": "filters";
List<Map<String, Object>> fields = (List<Map<String, Object>>) model.get(key);
if (fields == null || fields.isEmpty()) return;
for (Map<String, Object> field : fields) {
String fn = (String) field.get("field");
if (StringUtils.isEmpty(fn)) continue;
BaseDatasetField pdf = isField ? dataSet.findFieldByName(fn) : dataSet.findFilterByName(fn);
BaseDatasetField pdf = isField ? dataSet.findFieldByName(fn): dataSet.findFilterByName(fn);
if (pdf == null) continue;
if (!field.containsKey("label")) {
field.put("label", pdf.label);
@@ -253,16 +284,24 @@ public class ModelFormHelper {
PageDatasets datasets = form.getDatasets();
if (datasets == null || datasets.list == null) return "";
String service = form.getService();
if (StringUtils.isEmpty(service) && form.getParent() > 0) {
if (StringUtils.isEmpty(service) && form.getParent() > 0L) {
service = ModelFormCache.getInstance().get(form.getParent()).getService();
}
SwMap ret = new SwMap();
PageModel pageInfo = parsePageInfo(form.getContent());
if (pageInfo == null) return "";
ret.put("pageId", form.getEntityId());
ret.put("pageName", getPageName(form));
ret.put("label", form.getTitle());
ret.put("service", service);
ret.put("module", ModelProjectCache.getInstance().getModule(form.getPrjId()));
// 加载权限
long menuId = params.readLong("menuId");
String fullPath = params.readString("fullPath");
long findMenuId = MenuPlanHelper.findMenuId(menuId,form.getId(),fullPath);
Map<String,Object> permission = RoleHelper.getFuncAndFieldRight(us.getUserId(),us.getPartyId(),findMenuId);
ret.put("menuId",findMenuId>0L? findMenuId: menuId);
ret.put("permission",permission);
buildOptsEx(form, ret);
//form不用管
if (pageInfo.form != null) ret.put("form", pageInfo.form);
@@ -293,7 +332,8 @@ public class ModelFormHelper {
ret.put("idField", dataSet.idField);
ret.put("lazy", dataSet.lazy);
ret.put("canEdit", dataSet.canEdit);

ret.put("virtual", dataSet.virtual);
ret.put("linkClob", model.get("linkClob"));
ret.put("fields", model.get("fields"));
ret.put("filters", model.get("filters"));

@@ -313,21 +353,14 @@ public class ModelFormHelper {

List widgetIds = (List) option.get("widgetRef");
for (Object v : widgetIds) {
long id;
if (v instanceof String) {
id = Long.parseLong((String) v);
} else if (v instanceof Integer) {
id = (Integer) v;
} else if (v instanceof Long) {
id = (Long) v;
} else throw new BizException("不能识别的控件Id:" + v);
String id = v.toString();
ModelForm widgetForm = getFromCache(id);
if (widgetForm == null) throw new BizException("没有找到指定的控件定义!id=" + id);
SwMap w = new SwMap();
widget.put("w" + id, w);
SwMap widgetOpts = widgetForm.getOpts();
String service = widgetForm.getService();
if (StringUtils.isEmpty(service) && widgetForm.getParent() > 0) {
if (StringUtils.isEmpty(service) && widgetForm.getParent() > 0L) {
service = ModelFormCache.getInstance().get(widgetForm.getParent()).getService();
}
w.put("service", service);
@@ -359,7 +392,7 @@ public class ModelFormHelper {
}
}
}
listRet.sort((o1, o2) -> CommUtil.chineseCompare(o1.readString("label"), o2.readString("label")));
listRet.sort((o1, o2) -> StringUtil.chineseCompare(o1.readString("label"), o2.readString("label")));
return listRet;
}

@@ -373,6 +406,9 @@ public class ModelFormHelper {
if (StringUtils.isNotEmpty(eventPath)) {
opts.put(KEY_EVENT_PATH, eventPath + "." + bean.getName());
}
SwMap formOpts = bean.getOpts();
opts.put(OPT_CONFIG, formOpts.get(OPT_CONFIG));
opts.put(OPT_PAGE_TYPE, formOpts.readString(OPT_PAGE_TYPE));
}

public static String getCodePath(ModelForm bean) {
@@ -406,15 +442,27 @@ public class ModelFormHelper {
}

/**
* 根据向导生成model
*
* @param form
* @param tmplId
*/
public static void buildSaveModelByTmpl(ModelForm form, String tmplId) {
buildSaveModelByTmplExt(form, new SwMap(), tmplId);
}

/**
* 根据向导生成model
*
* @param form
* @param tmplId
* @param modelExt 额外的属性配置
*/
public static void buildSaveModelByTmplExt(ModelForm form,SwMap modelExt, String tmplId) {
PageDatasets datasets = form.getDatasets();
SwMap tmplModel = JsonUtil.parse(form.getTmpl(), SwMap.class);
tmplModel.putAll(modelExt);
tmplModel.put("title", form.getTitle());
tmplModel.put("name", form.getName());
tmplModel.put("datasets", JsonUtil.bean2MapList(form.getDatasets().list));
SwMap layout = tmplModel.readMap("layout");
//用到的自定义控件
@@ -444,7 +492,7 @@ public class ModelFormHelper {
}
tmplModel.put("widgetRef", widgetRef);
tmplModel.put("tmplType", tmplId);
final String model = CodeGenerator.getInstance().generate(tmplModel, tmplId);
final String model = CodeGenerator.getInstance().generatePage(tmplModel, tmplId);
form.setContent(model);
// form.setContent(buildSaveModel(form));
}
@@ -470,39 +518,72 @@ public class ModelFormHelper {
field.put("id", pdf.id);
field.put("field", pdf.field);
field.put("name", pdf.name);
field.put("label", pdf.label);
String label = (String) field.get("field_label");
field.put("label", StringUtils.isEmpty(label) ? pdf.label: label);
field.put("required", pdf.isFieldNotNull());
field.put("widget", 0);
final SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(pdf.dataType);
if (dtb != null) {
field.put("maxlength", dtb.dataLength);
field.put("editor", dtb.editor);
if (pdf.link > 0) {
long widget = getFieldCtrl(pdf.link);
if (widget > 0) {
setWidget.add(widget);
field.put("widget", widget);
field.put("widgetText", ModelFormCache.getInstance().getText(widget));
}
}
} else {
field.put("maxlength", 0);
field.put("editor", SwEnum.EditorType.INPUT.value);
}
Map lookup = (Map) field.get("lookup");
if (lookup != null) {
long widgetId = MapUtil.readLong(lookup, "widgetId", -1L);
if (widgetId > 0) {
setWidget.add(widgetId);
}
}
}
}

public static void buildTableFields(List<SwMap> ret, String tableName) {
ModelTable table = ModelTableCache.getInstance().getByName(tableName);
if (table == null) throw new SwException("没有找到表定义信息(table=" + tableName + ")!");

for (ModelField field : table.getFields()) {
SwMap col = new SwMap(2);
ModelFormHelper.buildFieldInfo(table, field, col);
ret.add(col);
}
}

/**
* 计算字段适用控件
* 页面设计时,返回的字段信息,带控件
*
* @param tableId
* @return
* @param table
* @param field
* @param col
*/
public static long getFieldCtrl(long tableId) {
Set<ModelForm> set = ModelFormCache.getInstance().getListByTable(tableId, SwEnum.FormType.WIDGET.value);
if (set == null || set.isEmpty()) return 0L;
public static void buildFieldInfo(ModelTable table, ModelField field, SwMap col) {
col.put("name", field.getName());
col.put("dataType", field.getDataType());
col.put("fieldType", field.getFieldType());
col.put("null", field.getNotNull());
col.put("default", field.getDefaultValue());
col.put("title", field.getTitle());
col.put("link", field.getLink());
col.put("table", table.getId());
col.put("table_text", table.getTitle());

SwEnum.DataTypeBean dtb = SwEnum.DataType.instance.getByValue(field.getDataType());
col.put("editor", dtb != null ? dtb.editor: SwEnum.EditorType.INPUT.value);

if (field.getLink() == 0L) return;

Set<ModelForm> set = ModelFormCache.getInstance().getListByTable(field.getLink(), SwEnum.FormType.WIDGET.value);
if (set == null || set.isEmpty()) return;
ModelForm form = set.iterator().next();
return (form != null) ? form.getEntityId() : 0L;
if (form == null) return;
SwMap widget = new SwMap();
col.put("widget", widget);

widget.put("widgetId", form.getId());
widget.put("widgetId_text", form.getTitle());
SwMap opts = form.getOpts();
if (opts != null) {
col.put("editor", SwEnum.WidgetType.getEditor(opts.readString("widgetType")));
}
}

/*//js文件的路径


+ 27
- 40
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormLoadHandler.java ファイルの表示

@@ -1,22 +1,17 @@
package cc.smtweb.system.bpm.web.design.form;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.mvc.service.DefaultLoadHandler;
import cc.smtweb.framework.core.util.FileUtil;
import cc.smtweb.framework.core.util.JsonUtil;
import cc.smtweb.framework.core.util.SpringUtil;
import cc.smtweb.system.bpm.spring.BpmConfigBean;
import cc.smtweb.system.bpm.util.IdeaUtil;
import cc.smtweb.system.bpm.web.design.db.ModelProjectCache;
import cc.smtweb.system.bpm.web.sys.base.billType.BillTypeCache;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
* Created by Akmm at 2022/5/9 16:17
@@ -26,62 +21,54 @@ public class ModelFormLoadHandler extends DefaultLoadHandler<ModelForm> {
super(ModelForm.ENTITY_NAME);
}

@Override
protected ModelForm loadComp(long id) {
ModelForm bean = super.loadComp(id);
SwMap opts = bean.getOpts();
if (opts != null) {
ModelFormHelper.buildOptsEx(bean, opts);
protected ModelForm localLoadForm() {
String id = params.readString("id");
if (StringUtils.isEmpty(id)) id = params.readString("pageId");
if (StringUtils.isEmpty(id)) id = params.readString("pageName");
ModelForm bean = ModelFormHelper.getFromCache(id);
if (bean == null) throw new BizException("没有找到指定的页面定义信息!id=" + id);
long billType = bean.getBillType();
if (billType > 0L) {
SwMap opts = bean.getOpts();
opts.put(ModelFormHelper.KEY_BILL_TYPE + SwConsts.TEXT_SUFFIX, BillTypeCache.getInstance().getName(billType));
bean.setOption(JsonUtil.encodeString(opts));
}
//去掉content和dataset
bean.getData().remove("mf_content");
bean.getData().remove("mf_dataset");

return bean;
}

@Override
public R load() {
return R.success(localLoadForm());
}

//页面设计-加载数据集定义
public R loadDataset() {
long id = params.readLong("id");
ModelForm bean = super.loadComp(id);
if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id);
ModelForm bean = localLoadForm();
return R.success(ModelFormHelper.buildReqDataset(bean.getDatasets()));
}

//页面设计 - 加载页面model定义
public R loadModel() {
long id = params.readLong("id");
ModelForm bean = super.loadComp(id);
if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id);
ModelForm bean = localLoadForm();
return R.success(ModelFormHelper.buildReqModel(bean));
}

//页面引擎-获取页面模型
public R loadForm() {
long id = params.readLong("id");
ModelForm bean = super.loadComp(id);
if (bean == null) throw new BizException("没有找到指定定义信息!id=" + id);
return R.success(ModelFormHelper.buildEngineModel(bean, params, us));
}
// 页面引擎-获取页面模型
public R loadForm(String module, String pageName) {
ModelForm bean = ModelFormCache.getInstance().getByName(module,pageName);
if (bean == null) throw new BizException("没有找到指定定义信息!module=" + module+",pageName="+pageName);
ModelForm bean = localLoadForm();
return R.success(ModelFormHelper.buildEngineModel(bean, params, us));
}

//获取页面使用的控件的filter信息
public R loadWidgetFilter() {
long id = params.readLong("id");
ModelForm bean = super.loadComp(id);
if (bean == null) throw new BizException("没有找到指定控件定义!id=" + id);
ModelForm bean = localLoadForm();
return R.success(ModelFormHelper.buildWidgetFilter(bean));
}

//加载页面js方法
public R loadJsFuncs() {
long pageId = params.readLong("pageId");
ModelForm form = ModelFormCache.getInstance().get(pageId);
if (form == null) throw new BizException("未找到指定的页面定义(" + pageId + ")!");
ModelForm form = localLoadForm();

List<String> listRet = new ArrayList<>();
R r = R.success(listRet);
@@ -90,7 +77,7 @@ public class ModelFormLoadHandler extends DefaultLoadHandler<ModelForm> {
if (StringUtils.isEmpty(codeJavaPath)) {
return r;
}
String path = ModelFormHelper.getCodePath(form) + "/src/main/resources/static/event/" + ModelFormHelper.getEventPath(form).replaceAll("\\.", "/") + "/" + form.getName() + ".js";
String path = ModelFormHelper.getCodePath(form) + "/src/main/resources/static/event/" + ModelFormHelper.getEventPath(form).replaceAll("\\.", "/") + "/" + form.getName() + ".js";
String js = FileUtil.readFileStr(path);
if (StringUtils.isEmpty(js)) {
return r;
@@ -103,7 +90,7 @@ public class ModelFormLoadHandler extends DefaultLoadHandler<ModelForm> {
index = js.indexOf("{", index);
js = js.substring(index + 1, js.indexOf("}", index)).trim();
String[] fs = js.split(",");
for (String s: fs) {
for (String s : fs) {
if (StringUtils.isNotBlank(s)) {
listRet.add(s.trim());
}


+ 24
- 76
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormSaveHandler.java ファイルの表示

@@ -2,22 +2,19 @@ package cc.smtweb.system.bpm.web.design.form;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.jdbc.AbsDbWorker;
import cc.smtweb.framework.core.db.jdbc.IDbWorker;
import cc.smtweb.framework.core.db.vo.ModelField;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.mvc.service.DefaultSaveHandler;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.JsonUtil;
import cc.smtweb.system.bpm.web.design.form.model.ModelFactory;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
* Created by Akmm at 2022/5/9 17:05
@@ -25,7 +22,7 @@ import java.util.Set;
*/
public class ModelFormSaveHandler extends DefaultSaveHandler<ModelForm> {
//自动生成的模块子页面,暂存,便于维护缓存
private List<ModelForm> listFormChild;
private List<ModelForm> listFormChild = null;

public ModelFormSaveHandler() {
super(ModelForm.ENTITY_NAME);
@@ -33,63 +30,22 @@ public class ModelFormSaveHandler extends DefaultSaveHandler<ModelForm> {

@Override
protected void updateBean(EntityDao<ModelForm> dao) {
updateFormChild(dao);
listFormChild = new ArrayList<>();
ModelFactory.getInstance().saveForm(bean, listFormChild);
dao.updateEntityEx(bean, "mf_content", "mf_dataset", "mf_tmpl");
}

@Override
protected void insertBean(EntityDao<ModelForm> dao) {
listFormChild = new ArrayList<>();
ModelFactory.getInstance().saveForm(bean, listFormChild);
super.insertBean(dao);
updateFormChild(dao);
}

private void updateFormChild(EntityDao<ModelForm> dao) {
SwMap opts = bean.getOpts();
if (opts != null) {
opts.remove(ModelFormHelper.KEY_EVENT_PATH);
bean.setOption(JsonUtil.encodeString(opts));
}
if (bean.getType() == SwEnum.FormType.MODULE.value) {
addChildPage(dao, opts);
}
}

//自动增加子页面
private void addChildPage(EntityDao<ModelForm> dao, SwMap opts) {
listFormChild = new ArrayList<>();
Set<ModelForm> setExists = ModelFormCache.getInstance().getListByModule(bean.getEntityId());
//维护已有的子页面
if(setExists!=null){
for (ModelForm mf: setExists) {
if (!CommUtil.isStrEquals(mf.getService(), bean.getService())) {
mf.setService(bean.getService());
dao.updateEntityEx(bean, "mf_content", "mf_dataset", "mf_tmpl");
listFormChild.add(mf);
}
}
}
if (opts == null) return;
List<String> incPage = (List<String>) opts.get("incPage");
if (incPage == null || incPage.isEmpty()) return;

//增加新的子页面
for (String type : incPage) {
String name = bean.getName() + "_" + type;
if (existsPage(setExists, name)) continue;
ModelForm page = new ModelForm();
page.getData().putAll(bean.getData());
page.setId(DbEngine.getInstance().nextId());
page.setOption("{}");
page.setDataset(null);
page.setContent(null);
page.setTmpl(null);
page.setType(SwEnum.FormType.PAGE.value);
page.setName(name);
page.setParent(bean.getId());
page.setTitle(bean.getTitle() + "_" + SwEnum.PageType.instance.getName(type));
listFormChild.add(page);
dao.insertEntity(page);
}
@Override
protected void checkValid() {
super.checkValid();
DbEngine.getInstance().findDao(ModelForm.class).checkUnique(bean, "mf_prj_id", "mf_name");
}

@Override
@@ -97,6 +53,7 @@ public class ModelFormSaveHandler extends DefaultSaveHandler<ModelForm> {
ModelFormCache.getInstance().put(bean);
if (listFormChild != null) {
for (ModelForm page : listFormChild) {
page.removeStatus();
ModelFormCache.getInstance().put(page);
}
}
@@ -112,26 +69,15 @@ public class ModelFormSaveHandler extends DefaultSaveHandler<ModelForm> {
}
}

//已经存在的,不管了
private boolean existsPage(Set<ModelForm> setExists, String name) {
if (setExists == null){
return false;
}
for (ModelForm form : setExists) {
if (name.equalsIgnoreCase(form.getName())) return true;
}
return false;
}

public R saveDataset() {
long id = params.readLong("id");
String data = params.readString("data");
bean = loadComp(id);
bean = ModelFormCache.getInstance().get(id);
if (StringUtils.isEmpty(data)) {
throw new BizException("没有待保存的数据!");
}
bean.setDataset(ModelFormHelper.buildSaveDataset(data));
DbEngine.getInstance().doTrans(new AbsDbWorker() {
DbEngine.getInstance().doTrans(new IDbWorker() {
@Override
public void work() {
EntityDao<ModelForm> dao = DbEngine.getInstance().findDao(tableName);
@@ -158,12 +104,12 @@ public class ModelFormSaveHandler extends DefaultSaveHandler<ModelForm> {
public R saveModel() {
long id = params.readLong("id");
String data = params.readString("data");
bean = loadComp(id);
bean = ModelFormCache.getInstance().get(id);
if (StringUtils.isEmpty(data)) {
throw new BizException("没有待保存的数据!");
}
bean.setContent(ModelFormHelper.buildSaveModel(bean, data));
DbEngine.getInstance().doTrans(new AbsDbWorker() {
DbEngine.getInstance().doTrans(new IDbWorker() {
@Override
public void work() {
EntityDao<ModelForm> dao = DbEngine.getInstance().findDao(tableName);
@@ -188,16 +134,18 @@ public class ModelFormSaveHandler extends DefaultSaveHandler<ModelForm> {
}

public R saveModelByTmpl() {
long id = params.readLong("pageId");
String templateId = params.readString("templateId");
String id = params.readString("pageId");
String data = params.readString("data");
bean = loadComp(id);
bean = ModelFormHelper.getFromCache(id);
if (StringUtils.isEmpty(data)) {
throw new BizException("没有待保存的数据!");
}
bean.setTmpl(data);
ModelFormHelper.buildSaveModelByTmpl(bean, templateId);
DbEngine.getInstance().doTrans(new AbsDbWorker() {
ModelFactory.getInstance().buildSaveModel(bean);
//先构建一次,防止有错
String ret = ModelFormHelper.buildReqModel(bean);
// ModelFormHelper.buildSaveModelByTmpl(bean, templateId);
DbEngine.getInstance().doTrans(new IDbWorker() {
@Override
public void work() {
EntityDao<ModelForm> dao = DbEngine.getInstance().findDao(tableName);
@@ -218,6 +166,6 @@ public class ModelFormSaveHandler extends DefaultSaveHandler<ModelForm> {
saveFailed();
}
});
return R.success(ModelFormHelper.buildReqModel(bean));
return R.success(ret);
}
}

+ 56
- 18
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormService.java ファイルの表示

@@ -11,16 +11,20 @@ import cc.smtweb.framework.core.db.vo.ModelField;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.mvc.service.AbstractCompService;
import cc.smtweb.framework.core.mvc.service.AbstractHandler;
import cc.smtweb.framework.core.mvc.service.DefaultDelHandler;
import cc.smtweb.framework.core.mvc.service.DefaultListHandler;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.SqlUtil;
import cc.smtweb.system.bpm.util.CodeGenerator;
import cc.smtweb.system.bpm.web.design.db.ModelProjectCache;
import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefine;
import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefineCache;
import org.apache.commons.lang3.StringUtils;

import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
* Created by Akmm at 2022/3/22 9:12
@@ -28,6 +32,7 @@ import java.util.List;
@SwService
public class ModelFormService extends AbstractCompService {
private final static String TYPE_CODE = "type_code";

@Override
protected AbstractHandler createHandler(String type) {
switch (type) {
@@ -36,7 +41,7 @@ public class ModelFormService extends AbstractCompService {
case TYPE_SAVE:
return new ModelFormSaveHandler();
case TYPE_DEL:
return new DefaultDelHandler<ModelForm>(ModelForm.ENTITY_NAME);
return new ModelFormDelHandler();
case TYPE_LIST:
return new DefaultListHandler<ModelForm>(ModelForm.ENTITY_NAME);
case TYPE_CODE:
@@ -109,15 +114,7 @@ public class ModelFormService extends AbstractCompService {
public R model(@SwBody SwMap params, UserSession us) {
try {
ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD);
String page = params.readString("id","");
String [] array = page.split("\\.");
String module = "";
String pageName = "";
if(array.length==2){
module = array[0];
pageName = array[1];
}
return handler.loadForm(module,pageName);
return handler.loadForm();
} catch (Exception e) {
return R.error("操作失败!", e);
}
@@ -157,16 +154,11 @@ public class ModelFormService extends AbstractCompService {
col.put("name", colName);
ModelField field = table.findField(colName);
if (field != null) {
col.put("dataType", field.getDataType());
col.put("null", field.getNotNull());
col.put("default", field.getDefaultValue());
col.put("title", field.getTitle());
col.put("link", field.getLink());
col.put("table", table.getId());
col.put("table_text", table.getTitle());
ModelFormHelper.buildFieldInfo(table, field, col);
} else {
SwEnum.DataTypeBean dtb = SwEnum.DataType.getBySqlType(metaData.getColumnType(i), metaData.getPrecision(i), metaData.getScale(i));
col.put("dataType", dtb.value);
col.put("editor", dtb.editor);
}
fields.add(col);
}
@@ -178,6 +170,21 @@ public class ModelFormService extends AbstractCompService {
}
}

public R loadFieldCfg(@SwBody SwMap params, UserSession us) {
long tableId = params.readLong("tableId");
if (tableId <= 0L) return R.error("没有传入的Table!");
ModelTable table = ModelTableCache.getInstance().get(tableId);
if (table == null) return R.error("没有找到表定义信息(table=" + tableId + ")!");

List<SwMap> ret = new ArrayList<>();
for (ModelField field : table.getFields()) {
SwMap col = new SwMap(2);
ModelFormHelper.buildFieldInfo(table, field, col);
ret.add(col);
}
return R.success(ret);
}

//加载模板定义
public R loadTmpls(@SwBody SwMap params, UserSession us) {
return R.success(CodeGenerator.getInstance().getModelTemplates());
@@ -202,4 +209,35 @@ public class ModelFormService extends AbstractCompService {
return R.error("操作失败!", e);
}
}
// 获取数据权限类型
public R loadDataRightType(@SwBody SwMap params, UserSession us) {
try {
long prj_id = params.readLong("prj_id");
List<SwMap> rtData = new ArrayList<>();
if(prj_id<=0){
return R.success(rtData);
}
// 查项目所依赖的项目
Set<Long> ids = ModelProjectCache.getInstance().getDependsPrjIds(prj_id);
if(CommUtil.isEmpty(ids)){
return R.success(rtData);
}
ids.forEach(id -> {
// 取数据权限定义
Set<DataRightDefine> dfs = DataRightDefineCache.getInstance().getByMp(id.toString());
if(!CommUtil.isEmpty(dfs)){
dfs.forEach(bean -> {
SwMap map = new SwMap();
map.put("value",bean.getId());
map.put("label",bean.getName());
map.put("bean",bean);
rtData.add(map);
});
}
});
return R.success(rtData);
} catch (Exception e) {
return R.error("操作失败!", e);
}
}
}

+ 1
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/BaseDatasetField.java ファイルの表示

@@ -42,6 +42,7 @@ public class BaseDatasetField {
public String defValue;
// type为depend时, 表达式
public String dependExpr;

@JsonIgnore
public boolean isFieldNotNull() {
return notNull == 1;


+ 6
- 2
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDataset.java ファイルの表示

@@ -34,6 +34,10 @@ public class PageDataset {
public boolean lazy;
//是否可编辑
public boolean canEdit;
//是否虚拟数据集
public boolean virtual;
//关联大字段信息
public PageDatasetLinkClob linkClob;
//select的字段
public List<PageDatasetField> fields;
public List<PageDatasetFilter> filters;
@@ -73,11 +77,11 @@ public class PageDataset {
}


public ModelTable getModelTable() {
public ModelTable _getModelTable() {
return ModelTableCache.getInstance().get(masterTable);
}

public boolean isCurDataSet(String dataset) {
public boolean _isCurDataSet(String dataset) {
return this.name.equals(dataset);
}



+ 2
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetFilter.java ファイルの表示

@@ -10,4 +10,6 @@ public class PageDatasetFilter extends BaseDatasetField {
// 触发类型 click按钮触发;change监听触发
public String trigger;
public boolean required = false;
// 数据权限类型ID
public long dataRightType;
}

+ 16
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasetLinkClob.java ファイルの表示

@@ -0,0 +1,16 @@
package cc.smtweb.system.bpm.web.design.form.define;

/**
* Created by Akmm at 2022-08-13 14:55
* 数据集关联到大字段的设置信息
*/
public class PageDatasetLinkClob {
//关联的数据集
public String linkDs;
//关联的字段
public String linkField;
//字段内容格式,暂时只支持JSON
public String linkType;
//节点
public String node;
}

+ 4
- 1
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/define/PageDatasets.java ファイルの表示

@@ -3,7 +3,10 @@ package cc.smtweb.system.bpm.web.design.form.define;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import com.fasterxml.jackson.annotation.JsonIgnore;

import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Created by Akmm at 2022/5/25 15:53


+ 88
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/BaseModelWorker.java ファイルの表示

@@ -0,0 +1,88 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.framework.core.util.JsonUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormHelper;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

/**
* Created by Akmm at 2022-08-14 10:37
* 抽象类的页面保存,供各模板继承使用
*/
public class BaseModelWorker {
/**
* 模块/页面保存:opts根据模型做些个性化处理,如果是模块,需要添加子页面
*
* @param bean
* @param listFormChild
*/
public void saveForm(ModelForm bean, List<ModelForm> listFormChild) {
SwMap opts = bean.getOpts();
if (opts != null) {
opts.remove(ModelFormHelper.KEY_EVENT_PATH);
opts.remove(ModelFormHelper.KEY_BILL_TYPE + SwConsts.TEXT_SUFFIX);
bean.setOption(JsonUtil.encodeString(opts));
}
if (bean.getType() == SwEnum.FormType.MODULE.value) {
saveModule(bean, listFormChild);
} else {
savePage(bean);
}
}

//保存模块
protected void saveModule(ModelForm bean, List<ModelForm> listFormChild) {

}

//保存页面,备用
protected void savePage(ModelForm bean) {

}

//构建一个子页面
protected ModelForm createPage(ModelForm bean, String type) {
ModelForm page = new ModelForm();
page.getData().putAll(bean.getData());
page.setId(DbEngine.getInstance().nextId());
page.setName(bean.getName() + StringUtil.upFirst(type));

page.setDataset(null);
page.setContent(null);
page.setTmpl(null);
page.setType(SwEnum.FormType.PAGE.value);
page.setParent(bean.getId());
page.setTitle(bean.getTitle() + SwEnum.PageType.instance.getName(type));

SwMap opts = new SwMap();
opts.putAll(bean.getOpts());
opts.put("pageType", type);
page.setOption(JsonUtil.encodeString(opts));

return page;
}

/**
* 根据模型生成页面
*
* @param bean
*/
public void buildSaveModel(ModelForm bean) {
String tmplId = getTmplId(bean);
if (StringUtils.isEmpty(tmplId)) throw new SwException("此类型页面没有找到对应的模板文件!");
ModelFormHelper.buildSaveModelByTmpl(bean, tmplId);
}

//获取模板名
protected String getTmplId(ModelForm bean) {
return null;
}
}

+ 69
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/EmptyWorker.java ファイルの表示

@@ -0,0 +1,69 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.framework.core.common.AbstractEnum;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.util.JsonUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormHelper;
import org.springframework.util.Assert;

import java.util.List;

/**
* @Author:lip
* @Date : 2022/9/14 11:27
* 自定义模型-生成一个空白页面
*/
public class EmptyWorker extends BaseModelWorker{
private final static String template = "model_empty";

@Override
protected void saveModule(ModelForm bean, List<ModelForm> listFormChild) {
EntityDao<ModelForm> dao = DbEngine.getInstance().findDao(ModelForm.class);

SwMap opts = bean.getOpts();
SwMap cfg = opts.readMap(ModelFormHelper.OPT_CONFIG);
//
String pageType = cfg.readMap("props").readString("pageType");
AbstractEnum.StrEnumBean type = SwEnum.PageType.instance.getByValue(pageType);
Assert.notNull(type, "无效页面类型: " + pageType);
String pageName = ModelFormHelper.getPageName(bean) + StringUtil.upFirst(pageType);
//
SwMap cfgPage = new SwMap();
cfg.put(ModelFormHelper.OPT_PAGE, cfgPage);
//
cfgPage.put(pageType, pageName);
bean.setOption(JsonUtil.encodeString(opts));
//
ModelForm page;
if (bean.isNew()) {
//新增
page = createPage(bean, pageType);
listFormChild.add(page);
dao.insertEntity(page);
} else {
//修改,先不考虑修改模型的情况 todo
page = ModelFormHelper.getFromCache(pageName);
Assert.isTrue(page != null, "获取页面失败");
listFormChild.add(page);
boolean modified = false;
//服务名发生变化
if (!StringUtil.isStrEquals(page.getService(), bean.getService())) {
page.setService(bean.getService());
modified = true;
}
if (modified) {
dao.updateEntity(page, "mf_content,mf_dataset,mf_tmpl");
}
}
}

@Override
protected String getTmplId(ModelForm bean) {
return template;
}
}

+ 18
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcLc1Worker.java ファイルの表示

@@ -0,0 +1,18 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.system.bpm.web.design.form.ModelForm;

/**
* @Author:lip
* @Date : 2022/9/1 16:05
* 左列表-右列表(含编辑弹窗、左列表可编辑)
*/
public class LcLc1Worker extends LcSingleWorker {
private final static String tmpl = "model_list_list_1";

@Override
protected String getTmplId(ModelForm bean) {
return tmpl;
}

}

+ 18
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcLc2Worker.java ファイルの表示

@@ -0,0 +1,18 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.system.bpm.web.design.form.ModelForm;

/**
* @Author:lip
* @Date : 2022/9/1 16:05
* 左列表-右列表(含编辑弹窗、左列表不可编辑)
*/
public class LcLc2Worker extends LcSingleWorker {
private final static String tmpl = "model_list_list_2";

@Override
protected String getTmplId(ModelForm bean) {
return tmpl;
}

}

+ 17
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcLt2Worker.java ファイルの表示

@@ -0,0 +1,17 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.system.bpm.web.design.form.ModelForm;

/**
* @Author:lip
* @Date : 2022/9/13 10:06
* 左树-列表(含编辑弹窗)
*/
public class LcLt2Worker extends LcSingleWorker {
private final static String template = "model_tree_list_dialog";

@Override
protected String getTmplId(ModelForm bean) {
return template;
}
}

+ 26
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcLtMsWorker.java ファイルの表示

@@ -0,0 +1,26 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;

/**
* @Author:lip
* @Date : 2022/8/28 22:57
* 左树-主子列表(含编辑卡片)
*/
public class LcLtMsWorker extends LcMsWorker {
private final static String templateList = "model_tree_list";
private final static String templateCard = "model_card_ms";

@Override
protected String getTmplId(ModelForm bean) {
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.LIST.value))) {
return templateList;
}
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.CARD.value))) {
return templateCard;
}
return super.getTmplId(bean);
}
}

+ 26
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcLtWorker.java ファイルの表示

@@ -0,0 +1,26 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;

/**
* @Author:lip
* @Date : 2022/8/26 10:20
* 左树-列表(含编辑卡片)
*/
public class LcLtWorker extends LcNormalWorker {
private final static String templateList = "model_tree_list";
private final static String templateCard = "model_card_normal";

@Override
protected String getTmplId(ModelForm bean) {
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.LIST.value))) {
return templateList;
}
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.CARD.value))) {
return templateCard;
}
return super.getTmplId(bean);
}
}

+ 46
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcMsWorker.java ファイルの表示

@@ -0,0 +1,46 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormHelper;
import org.apache.commons.lang3.StringUtils;

/**
* @Author:lip
* @Date : 2022/8/28 12:11
*/
public class LcMsWorker extends LcNormalWorker {
private final static String templateList = "model_list_normal";
private final static String templateCard = "model_card_ms";

@Override
protected String getTmplId(ModelForm bean) {
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.LIST.value))) {
return templateList;
}
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.CARD.value))) {
return templateCard;
}
return super.getTmplId(bean);
}

/**
* 根据模型生成页面
*
* @param bean
*/
public void buildSaveModel(ModelForm bean) {
String tmplId = getTmplId(bean);
if (StringUtils.isEmpty(tmplId)) throw new SwException("此类型页面没有找到对应的模板文件!");
SwMap model = new SwMap();
SwMap opts = bean.getOpts();
SwMap cfg = opts.readMap(ModelFormHelper.OPT_CONFIG);
//
model.put("subIndSave",cfg.readMap("props").readBool("subIndSave"));

ModelFormHelper.buildSaveModelByTmplExt(bean, model, tmplId);
}
}

+ 81
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcNormalWorker.java ファイルの表示

@@ -0,0 +1,81 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.util.JsonUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormHelper;
import org.springframework.util.Assert;

import java.util.List;

/**
* @Author:lip
* @Date : 2022/8/26 10:20
* 普通列表(含编辑卡片)
*/
public class LcNormalWorker extends BaseModelWorker {
private final static String templateList = "model_list_normal";
private final static String templateCard = "model_card_normal";

@Override
protected void saveModule(ModelForm bean, List<ModelForm> listFormChild) {
EntityDao<ModelForm> dao = DbEngine.getInstance().findDao(ModelForm.class);

String baseName = ModelFormHelper.getPageName(bean);
String listName = baseName + StringUtil.upFirst(SwEnum.PageType.LIST.value);
String cardName = baseName + StringUtil.upFirst(SwEnum.PageType.CARD.value);
//
SwMap opts = bean.getOpts();
SwMap cfg = opts.readMap(ModelFormHelper.OPT_CONFIG);
//
SwMap cfgPage = new SwMap();
cfg.put(ModelFormHelper.OPT_PAGE, cfgPage);
//
cfgPage.put(SwEnum.PageType.LIST.value, listName);
cfgPage.put(SwEnum.PageType.CARD.value, cardName);
bean.setOption(JsonUtil.encodeString(opts));
//
ModelForm listPage;
ModelForm cardPage;
if (bean.isNew()) {
//新增
listPage = createPage(bean, SwEnum.PageType.LIST.value);
cardPage = createPage(bean, SwEnum.PageType.CARD.value);
listFormChild.add(listPage);
listFormChild.add(cardPage);
dao.batchInsertEntity(listFormChild);
} else {
//修改,先不考虑修改模型的情况 todo
listPage = ModelFormHelper.getFromCache(listName);
cardPage = ModelFormHelper.getFromCache(cardName);
Assert.isTrue(listPage != null && cardPage != null, "获取页面失败");
listFormChild.add(listPage);
listFormChild.add(cardPage);
boolean modified = false;
//服务名发生变化
if (!StringUtil.isStrEquals(listPage.getService(), bean.getService())) {
listPage.setService(bean.getService());
cardPage.setService(bean.getService());
modified = true;
}
if (modified) {
dao.batchUpdateEntity(listFormChild, "mf_content,mf_dataset,mf_tmpl");
}
}
}

@Override
protected String getTmplId(ModelForm bean) {
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.LIST.value))) {
return templateList;
}
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.CARD.value))) {
return templateCard;
}
return super.getTmplId(bean);
}
}

+ 57
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/LcSingleWorker.java ファイルの表示

@@ -0,0 +1,57 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.util.JsonUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormHelper;

import java.util.List;

/**
* Created by Akmm at 2022-08-14 12:17
* 简单列表(含编辑弹窗)
*/
public class LcSingleWorker extends BaseModelWorker {
private final static String tmpl = "model_list_card";

@Override
protected void saveModule(ModelForm bean, List<ModelForm> listFormChild) {
EntityDao<ModelForm> dao = DbEngine.getInstance().findDao(ModelForm.class);

SwMap opts = bean.getOpts();
SwMap cfg = opts.readMap(ModelFormHelper.OPT_CONFIG);
SwMap cfgPage = new SwMap();
cfg.put(ModelFormHelper.OPT_PAGE, cfgPage);
String formName = ModelFormHelper.getPageName(bean) + StringUtil.upFirst(SwEnum.PageType.LIST.value);
cfgPage.put(SwEnum.PageType.LIST.value, formName);
bean.setOption(JsonUtil.encodeString(opts));

ModelForm page;
if (bean.isNew()) {//新增
page = createPage(bean, SwEnum.PageType.LIST.value);
listFormChild.add(page);
dao.insertEntity(page);
} else {//修改,先不考虑修改模型的情况 todo
page = ModelFormHelper.getFromCache(formName);
boolean modified = false;
//服务名发生变化
if (!StringUtil.isStrEquals(page.getService(), bean.getService())) {
page.setService(bean.getService());
modified = true;
}
if (modified) {
dao.updateEntityEx(bean, "mf_content", "mf_dataset", "mf_tmpl");
listFormChild.add(page);
}
}
}

@Override
protected String getTmplId(ModelForm bean) {
return tmpl;
}
}

+ 67
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/ModelFactory.java ファイルの表示

@@ -0,0 +1,67 @@
package cc.smtweb.system.bpm.web.design.form.model;

import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormHelper;
import cc.smtweb.system.bpm.web.design.form.model.flow.*;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Created by Akmm at 2022-08-14 10:02
* 不同模型,在保存时候的个性处理
*/
public class ModelFactory {
private static ModelFactory instance;
private static Map<String, BaseModelWorker> mapWorker;

static {
instance = new ModelFactory();
mapWorker = new HashMap<>();
mapWorker.put(SwConsts.DEF_ROOT_ID, new BaseModelWorker());
mapWorker.put(SwEnum.ModelType.LC_SINGLE.value, new LcSingleWorker());
mapWorker.put(SwEnum.ModelType.LC_NORMAL.value, new LcNormalWorker());
mapWorker.put(SwEnum.ModelType.LC_LT.value, new LcLtWorker());
mapWorker.put(SwEnum.ModelType.LC_LT_2.value, new LcLt2Worker());
mapWorker.put(SwEnum.ModelType.LC_MS.value, new LcMsWorker());
mapWorker.put(SwEnum.ModelType.LC_LT_MS.value, new LcLtMsWorker());
mapWorker.put(SwEnum.ModelType.LC_LC_1.value, new LcLc1Worker());
mapWorker.put(SwEnum.ModelType.LC_LC_2.value, new LcLc2Worker());
mapWorker.put(SwEnum.ModelType.FLOW_SINGLE.value, new FlowSingleWorker());
mapWorker.put(SwEnum.ModelType.FLOW_LC_LC_1.value, new FlowLcLc1Worker());
mapWorker.put(SwEnum.ModelType.FLOW_LC_LC_2.value, new FlowLcLc2Worker());
mapWorker.put(SwEnum.ModelType.FLOW_LC_LT.value, new FlowLcLtWorker());
mapWorker.put(SwEnum.ModelType.FLOW_LC_MS.value, new FlowLcMsWorker());
mapWorker.put(SwEnum.ModelType.FLOW_LT_MS.value, new FlowLtMsWorker());
mapWorker.put(SwEnum.ModelType.EMPTY.value, new EmptyWorker());
}

public static ModelFactory getInstance() {
return instance;
}

private BaseModelWorker getWorker(ModelForm bean) {
String model = ModelFormHelper.getFormModel(bean);
if (StringUtils.isEmpty(model)) return mapWorker.get(SwConsts.DEF_ROOT_ID);
BaseModelWorker worker = mapWorker.get(model);
if (worker == null) throw new SwException("该模型暂无接口实现!");
return worker;
}

//各模型的个性化保存实现
public void saveForm(ModelForm bean, List<ModelForm> listFormChild) {
BaseModelWorker worker = getWorker(bean);
worker.saveForm(bean, listFormChild);
}

//构建模板
public void buildSaveModel(ModelForm bean) {
BaseModelWorker worker = getWorker(bean);
worker.buildSaveModel(bean);
}
}

+ 27
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowLcLc1Worker.java ファイルの表示

@@ -0,0 +1,27 @@
package cc.smtweb.system.bpm.web.design.form.model.flow;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.model.LcNormalWorker;

/**
* @Author:lip
* @Date : 2022/9/15 16:49
* 左列表-右列表(含编辑卡片、工作流、左列表可编辑)
*/
public class FlowLcLc1Worker extends LcNormalWorker {
private final static String templateList = "model_list_flow_ll1";
private final static String templateCard = "model_card_flow_ll";

@Override
protected String getTmplId(ModelForm bean) {
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.LIST.value))) {
return templateList;
}
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.CARD.value))) {
return templateCard;
}
return super.getTmplId(bean);
}
}

+ 27
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowLcLc2Worker.java ファイルの表示

@@ -0,0 +1,27 @@
package cc.smtweb.system.bpm.web.design.form.model.flow;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.model.LcNormalWorker;

/**
* @Author:lip
* @Date : 2022/9/15 16:49
* 左列表-右列表(含编辑卡片、工作流、左列表不可编辑)
*/
public class FlowLcLc2Worker extends LcNormalWorker {
private final static String templateList = "model_list_flow_ll2";
private final static String templateCard = "model_card_flow_ll";

@Override
protected String getTmplId(ModelForm bean) {
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.LIST.value))) {
return templateList;
}
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.CARD.value))) {
return templateCard;
}
return super.getTmplId(bean);
}
}

+ 27
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowLcLtWorker.java ファイルの表示

@@ -0,0 +1,27 @@
package cc.smtweb.system.bpm.web.design.form.model.flow;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.model.LcNormalWorker;

/**
* @Author:lip
* @Date : 2022/9/15 16:45
* 左树-列表(含编辑卡片、工作流)
*/
public class FlowLcLtWorker extends LcNormalWorker {
private final static String templateList = "model_tree_list";
private final static String templateCard = "model_card_flow";

@Override
protected String getTmplId(ModelForm bean) {
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.LIST.value))) {
return templateList;
}
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.CARD.value))) {
return templateCard;
}
return super.getTmplId(bean);
}
}

+ 27
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowLcMsWorker.java ファイルの表示

@@ -0,0 +1,27 @@
package cc.smtweb.system.bpm.web.design.form.model.flow;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.model.LcMsWorker;

/**
* @Author:lip
* @Date : 2022/9/15 16:49
* 普通主子列表(含编辑卡片、工作流)
*/
public class FlowLcMsWorker extends LcMsWorker {
private final static String templateList = "model_list_normal";
private final static String templateCard = "model_card_flow_lms";

@Override
protected String getTmplId(ModelForm bean) {
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.LIST.value))) {
return templateList;
}
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.CARD.value))) {
return templateCard;
}
return super.getTmplId(bean);
}
}

+ 27
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowLtMsWorker.java ファイルの表示

@@ -0,0 +1,27 @@
package cc.smtweb.system.bpm.web.design.form.model.flow;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.model.LcMsWorker;

/**
* @Author:lip
* @Date : 2022/9/15 16:49
* 左树-主子列表(含编辑卡片、工作流)
*/
public class FlowLtMsWorker extends LcMsWorker {
private final static String templateList = "model_tree_list";
private final static String templateCard = "model_card_flow_lms";

@Override
protected String getTmplId(ModelForm bean) {
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.LIST.value))) {
return templateList;
}
if (bean.getName().endsWith(StringUtil.upFirst(SwEnum.PageType.CARD.value))) {
return templateCard;
}
return super.getTmplId(bean);
}
}

+ 74
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/model/flow/FlowSingleWorker.java ファイルの表示

@@ -0,0 +1,74 @@
package cc.smtweb.system.bpm.web.design.form.model.flow;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.util.JsonUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormCache;
import cc.smtweb.system.bpm.web.design.form.ModelFormHelper;
import cc.smtweb.system.bpm.web.design.form.model.BaseModelWorker;

import java.util.ArrayList;
import java.util.List;

/**
* @Author: tanghp
* @Date: 2022-08-26 9:48
* @Desc: 普通列表(含编辑卡片、工作流)
*/
public class FlowSingleWorker extends BaseModelWorker {
private final static String listTmpl = "model_list_flow";
private final static String cardTmpl = "model_card_flow";

@Override
protected void saveModule(ModelForm bean, List<ModelForm> listFormChild) {
EntityDao<ModelForm> dao = DbEngine.getInstance().findDao(ModelForm.class);

SwMap opts = bean.getOpts();
SwMap cfg = opts.readMap(ModelFormHelper.OPT_CONFIG);
SwMap cfgPage = new SwMap();
cfg.put(ModelFormHelper.OPT_PAGE, cfgPage);
// 添加列表页面名称
String listFormName = ModelFormHelper.getPageName(bean) + StringUtil.upFirst(SwEnum.PageType.LIST.value);
cfgPage.put(SwEnum.PageType.LIST.value, listFormName);
// 添加卡片页面名称
String cardFormName = ModelFormHelper.getPageName(bean) + StringUtil.upFirst(SwEnum.PageType.CARD.value);
cfgPage.put(SwEnum.PageType.CARD.value, cardFormName);
bean.setOption(JsonUtil.encodeString(opts));

if (bean.isNew()) {//新增
List<ModelForm> insertList = new ArrayList<>();

ModelForm listPage = createPage(bean, SwEnum.PageType.LIST.value);
listFormChild.add(listPage);
insertList.add(listPage);

ModelForm cardPage = createPage(bean, SwEnum.PageType.CARD.value);
listFormChild.add(cardPage);
insertList.add(cardPage);

dao.batchInsertEntity(insertList);
} else {//修改,先不考虑修改模型的情况 todo

}
}

@Override
public void buildSaveModel(ModelForm bean) {
ModelForm parent = ModelFormCache.getInstance().get(bean.getParent());
if (parent == null) {
return;
}
String listFormName = parent.getName() + StringUtil.upFirst(SwEnum.PageType.LIST.value);
String cardFormName = parent.getName() + StringUtil.upFirst(SwEnum.PageType.CARD.value);
if (listFormName.equals(bean.getName())) {
ModelFormHelper.buildSaveModelByTmpl(bean, listTmpl);
} else if (cardFormName.equals(bean.getName())) {
ModelFormHelper.buildSaveModelByTmpl(bean, cardTmpl);
}
}

}

+ 42
- 42
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/MenuVO.java ファイルの表示

@@ -7,46 +7,46 @@ import java.util.List;

@Data
public class MenuVO {
private Long id;
private Long parentId;
private int level;
private String name;
private String path;
private String icon;
private List<MenuVO> children;
// 树结构数据句柄
public static ITreeDataLevelHandler<MenuVO> createTreeHandler() {
return new ITreeDataLevelHandler<MenuVO> () {
@Override
public Long getId (MenuVO node){
return node.getId();
}
@Override
public Long getParentId (MenuVO node){
return node.getParentId();
}
@Override
public List<MenuVO> getChildren (MenuVO node){
return node.children;
}
@Override
public void setChildren (MenuVO node, List <MenuVO> children){
node.children = children;
}
@Override
public int getLevel (MenuVO node){
return node.level;
}
@Override
public void setLevel (MenuVO node, int level){
node.level = level;
}
} ;
}
private Long id;
private Long parentId;
private int level;
private String name;
private String path;
private String icon;
private List<MenuVO> children;
// 树结构数据句柄
public static ITreeDataLevelHandler<MenuVO> createTreeHandler() {
return new ITreeDataLevelHandler<MenuVO>() {
@Override
public Long getId(MenuVO node) {
return node.getId();
}
@Override
public Long getParentId(MenuVO node) {
return node.getParentId();
}
@Override
public List<MenuVO> getChildren(MenuVO node) {
return node.children;
}
@Override
public void setChildren(MenuVO node, List<MenuVO> children) {
node.children = children;
}
@Override
public int getLevel(MenuVO node) {
return node.level;
}
@Override
public void setLevel(MenuVO node, int level) {
node.level = level;
}
};
}
}

+ 54
- 13
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/design/preview/PreviewMenuTreeService.java ファイルの表示

@@ -3,13 +3,14 @@ package cc.smtweb.system.bpm.web.design.preview;
import cc.smtweb.framework.core.annotation.SwParam;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.vo.ModelCatalog;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.util.TreeDataUtil;
import cc.smtweb.system.bpm.web.design.db.ModelCatalogCache;
import cc.smtweb.system.bpm.web.design.db.ModelProjectCache;
@@ -20,6 +21,7 @@ import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlan;
import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanCache;
import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanContent;
import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanItem;
import cc.smtweb.system.bpm.web.sys.user.role.RoleHelper;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
@@ -31,9 +33,18 @@ public class PreviewMenuTreeService {

public R treeAll(@SwParam("module") String module, UserSession us) {
String prj_id = ModelProjectCache.getInstance().getIdByModule(module);
List<MenuVO> menuVOList = buildMenu(prj_id, module, us);
if (PubUtil.isNotEmpty(menuVOList)) {
return R.success(menuVOList);
if (!SwConsts.SysParam.SYS_DEBUG) {
MenuVO home = new MenuVO();
List<MenuVO> menuVOList = buildMenu(prj_id, module, us,home);
if (!CommUtil.isEmpty(menuVOList)) {
R r = R.success(menuVOList);
if(home.getId()!=null&&home.getId()>0){
r.put("home",home);
}
return r;
}else {
return R.success(new ArrayList<>());
}
}
List<ModelForm> listForm;
if (StringUtils.isNotEmpty(prj_id)) {
@@ -41,7 +52,7 @@ public class PreviewMenuTreeService {
} else {
listForm = new ArrayList<>(ModelFormCache.getInstance().getAll());
}
listForm.sort((o1, o2) -> CommUtil.chineseCompare(o1.getTitle(), o2.getTitle()));
listForm.sort((o1, o2) -> StringUtil.chineseCompare(o1.getTitle(), o2.getTitle()));
if (listForm.isEmpty()) throw new BizException("此项目无页面设计!");

List<MenuVO> list = new ArrayList<>();
@@ -70,20 +81,30 @@ public class PreviewMenuTreeService {
root.setPath(module);
root.setId(-1L);
List<MenuVO> data = TreeDataUtil.buildTree(root, list, MenuVO.createTreeHandler());

return R.success(data);
return R.success(data);
}

public List<MenuVO> buildMenu(String prj_id, String module, UserSession us) {
Set<MenuPlan> set = MenuPlanCache.getInstance().getByP(prj_id);
if (PubUtil.isEmpty(set)) {
public List<MenuVO> buildMenu(String prj_id, String module, UserSession us,MenuVO home) {
Set<MenuPlan> set = RoleHelper.isAdmin(us.getUserId()) ? MenuPlanCache.getInstance().getByP(prj_id):RoleHelper.getMenuPlans(us.getUserId(),us.getPartyId());
if (CommUtil.isEmpty(set)) {
return new ArrayList<>();
}
MenuPlan menuPlan = set.iterator().next();
MenuPlanContent mpc = new MenuPlanContent(menuPlan.getContent());
List<MenuVO> list = new ArrayList<>();
Set<Long> rightMenuIds = RoleHelper.getRoleMenuIds(us.getUserId() , us.getPartyId(),menuPlan.getId(), true);
for(MenuPlanItem item : mpc.getHomeList()){
long id = item.getId();
if(rightMenuIds.contains(id)){
home.setId(item.getId());
home.setName(item.getLabel());
home.setIcon(item.getIcon());
home.setPath(MenuCache.getInstance().getPath(item.getMenu()));
break;
}
}
for (MenuPlanItem mp : mpc.getChildren(0)) {
List<MenuVO> menuVOList = buildMenu(-1, mp);
List<MenuVO> menuVOList = RoleHelper.isAdmin(us.getUserId())? buildMenu(-1,mp):buildMenuWithRight(-1, mp,rightMenuIds);
if (menuVOList == null) continue;
list.addAll(menuVOList);
}
@@ -104,7 +125,7 @@ public class PreviewMenuTreeService {
menu.setPath(MenuCache.getInstance().getPath(mp.getMenu()));
menu.setParentId(parent_id);
List<MenuVO> child = new ArrayList<>();
if (PubUtil.isNotEmpty(mp.getChildren())) {
if (!CommUtil.isEmpty(mp.getChildren())) {
for (MenuPlanItem cmp : mp.getChildren()) {
List<MenuVO> m = buildMenu(menu.getId(), cmp);
if (m == null) continue;
@@ -115,7 +136,27 @@ public class PreviewMenuTreeService {
list.add(menu);
return list;
}

private List<MenuVO> buildMenuWithRight(long parent_id, MenuPlanItem mp,Set<Long> rightMenuIds) {
if (mp == null || !rightMenuIds.contains(mp.getId())) return null;
List<MenuVO> list = new ArrayList<>();
MenuVO menu = new MenuVO();
menu.setId(mp.getId());
menu.setName(mp.getLabel());
menu.setIcon(mp.getIcon());
menu.setPath(MenuCache.getInstance().getPath(mp.getMenu()));
menu.setParentId(parent_id);
List<MenuVO> child = new ArrayList<>();
if (!CommUtil.isEmpty(mp.getChildren())) {
for (MenuPlanItem cmp : mp.getChildren()) {
List<MenuVO> m = buildMenuWithRight(menu.getId(), cmp,rightMenuIds);
if (m == null) continue;
child.addAll(m);
}
}
menu.setChildren(child);
list.add(menu);
return list;
}
private MenuVO setMenuParent(Long parent_id, Map<Long, MenuVO> map, List<MenuVO> list) {
MenuVO parent = map.get(parent_id);
if (parent != null) return parent;


+ 31
- 6
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/AbstractDynPageHandler.java ファイルの表示

@@ -1,8 +1,9 @@
package cc.smtweb.system.bpm.web.engine.dynPage;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.mvc.service.AbstractHandler;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
@@ -14,31 +15,55 @@ import cc.smtweb.system.bpm.web.design.form.define.PageDatasets;
* Created by Akmm at 2022/4/21 17:53
*/
public abstract class AbstractDynPageHandler extends AbstractHandler {
//页面定义id
protected long pageId;
//页面定义id或页面pageName
protected String pageId;
protected ModelForm form;
protected PageDatasets datasets;

protected DynPageProvider provider = getProvider();

public DynPageProvider getProvider() {
return new DynPageProvider();
}

@Override
public void init(SwMap params, UserSession us) {
super.init(params, us);
pageId = params.readLong("pageId");
ModelForm form = ModelFormHelper.getFromCache(pageId);
pageId = params.readString("pageId");
form = ModelFormHelper.getFromCache(pageId);
if (form == null) throw new BizException("没有找到页面定义数据(" + pageId + ")!");
datasets = form.getDatasets();
if (datasets == null || datasets.list == null) throw new BizException("没有找到页面定义的数据集数据(" + pageId + ")!");

provider.pageId = pageId;
provider.pageId = form.getId();
provider.datasets = datasets;
provider.us = us;
}

protected PageDataset findDataset(String name) {
return datasets.findByName(name);
}

//找可编辑卡片数据集
protected PageDataset findCardDataset(String dsName) {
PageDataset cardDataset = datasets.findByName(dsName);
if (cardDataset == null) throw new SwException("没有找到卡片数据集(" + dsName + ")!");
if (!SwEnum.DatasetType.FORM.value.equals(cardDataset.type)) {//单表
throw new SwException("卡片数据集定义错误(" + dsName + ")!");
}
return cardDataset;
}

//找列表数据集
protected PageDataset findListDataset(String dsName) {
PageDataset listDataset = datasets.findByName(dsName);
if (listDataset == null) throw new SwException("没有找到列表数据集(" + dsName + ")!");
if (!SwEnum.DatasetType.LIST.value.equals(listDataset.type)) {//列表
throw new SwException("列表数据集定义错误(" + dsName + ")!");
}
return listDataset;
}

//获取第一个,主数据集
protected PageDataset findMasterDataset() {
return datasets.findMasterDataset();


+ 3
- 3
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageDelHandler.java ファイルの表示

@@ -9,7 +9,7 @@ import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.db.EntityHelper;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.impl.DefaultEntity;
import cc.smtweb.framework.core.db.jdbc.AbsDbWorker;
import cc.smtweb.framework.core.db.jdbc.IDbWorker;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.system.bpm.web.design.form.define.PageDataset;
@@ -39,7 +39,7 @@ public class DynPageDelHandler extends AbstractDynPageHandler {

checkBean(pageDataSet, id);

DbEngine.getInstance().doTrans(new AbsDbWorker() {
DbEngine.getInstance().doTrans(new IDbWorker() {
@Override
public void work() {
ModelTable table = ModelTableCache.getInstance().get(pageDataSet.masterTable);
@@ -107,7 +107,7 @@ public class DynPageDelHandler extends AbstractDynPageHandler {
info.ids.addAll(list);
}
}
DbEngine.getInstance().doTrans(new AbsDbWorker() {
DbEngine.getInstance().doTrans(new IDbWorker() {
@Override
public void work() {
for (RemovableInfo info : mapRemovableInfo.values()) {


+ 162
- 93
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java ファイルの表示

@@ -12,11 +12,20 @@ import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.framework.core.mvc.service.SqlNamedPara;
import cc.smtweb.framework.core.mvc.service.TreeHelper;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.MapUtil;
import cc.smtweb.framework.core.util.NumberUtil;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.framework.core.util.SqlUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.design.form.define.*;
import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefine;
import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefineCache;
import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.IDataRightHandler;
import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.IDataRightTreeFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.NonNull;

import java.util.HashMap;
import java.util.HashSet;
@@ -29,6 +38,7 @@ import static cc.smtweb.framework.core.common.SwConsts.TOTAL_KEY;
* Created by Akmm at 2022/4/23 10:01
* 动态页面辅助类
*/
@Slf4j
public class DynPageHelper {
/**
* 新建bean
@@ -37,31 +47,20 @@ public class DynPageHelper {
* @return
*/
public static SwMap createBean(PageDataset dataSet) {
if (dataSet.masterTable <= 0) {
if (dataSet.masterTable <= 0L) {
return new SwMap();
}
//主表
ModelTable masterTable = ModelTableCache.getInstance().get(dataSet.masterTable);
EntityDao<DefaultEntity> dao = DbEngine.getInstance().findDao(masterTable.getName());
DefaultEntity bean = dao.createBean();
bean.setEntityId(DbEngine.getInstance().nextId());
return bean.getData();
}

/**
* 构建select fields from table
*
* @param dataSet
* @return
*/
public static SqlNamedPara buildSelectSql(PageDataset dataSet, Map<String, Object> params) {
SqlNamedPara sqlNamedPara = buildWhereSql(dataSet, params);
buildSelectSql(dataSet, params, sqlNamedPara);
return sqlNamedPara;
}

public static void buildSelectSql(PageDataset dataSet, Map<String, Object> params, SqlNamedPara sqlNamedPara) {
private static void buildSelectSql(PageDataset dataSet, Map<String, Object> params, SqlNamedPara sqlNamedPara, IBuildSqlListener listener) {
StringBuilder sql = new StringBuilder(512);
sql.append(buildSelFieldsSql(dataSet, sqlNamedPara));
sql.append(buildSelFieldsSql(dataSet, sqlNamedPara, listener));
if (StringUtils.isNotEmpty(sqlNamedPara.sql)) {
sql.append(" where ").append(sqlNamedPara.sql);
}
@@ -79,11 +78,27 @@ public class DynPageHelper {
sqlNamedPara.rows = MapUtil.readInt(params, SwConsts.PARAM_ROWS);
}

/**
* 构建select fields from table
*
* @param dataSet
* @return
*/
public static SqlNamedPara buildSelectSql(PageDataset dataSet, SwMap params,UserSession us) {
return buildSelectSqlEx(dataSet, params,us,null);
}

public static SqlNamedPara buildSelectSqlEx(PageDataset dataSet,SwMap params,UserSession us, IBuildSqlListener listener) {
SqlNamedPara sqlNamedPara = buildWhereSql(dataSet, params,us, listener);
buildSelectSql(dataSet, params, sqlNamedPara, listener);
return sqlNamedPara;
}

//构建树型查询语句,插入parent_id=?
public static SqlNamedPara buildTreeSelectSql(PageDataset dataSet, SwMap params, long parentId) {
public static SqlNamedPara buildTreeSelectSql(PageDataset dataSet, SwMap params,UserSession us, long parentId) {
ModelTable table = ModelTableCache.getInstance().get(dataSet.masterTable);
if (table == null) throw new SwException("没有找到指定的表:" + dataSet.masterTable);
SqlNamedPara sqlNamedPara = buildWhereSql(dataSet, params);
SqlNamedPara sqlNamedPara = buildWhereSql(dataSet, params,us, null);
if (table.getType() == SwEnum.TableType.TYPE_TREE.value) {//是树型结构,才做处理
ModelField field = table.findFieldByType(SwEnum.FieldType.PARENT_ID.value);
if (field == null) throw new SwException("树型表(" + table.getName() + ")未定义上级id字段!");
@@ -96,15 +111,15 @@ public class DynPageHelper {
sqlNamedPara.addParas("parent_id", parentId);
}

buildSelectSql(dataSet, params, sqlNamedPara);
buildSelectSql(dataSet, params, sqlNamedPara, null);
return sqlNamedPara;
}

//构建过滤查询语句
public static SqlNamedPara buildFilterSelectSql(PageDataset dataSet, SwMap params, String text) {
public static SqlNamedPara buildFilterSelectSql(PageDataset dataSet, SwMap params,UserSession us, String text) {
ModelTable table = ModelTableCache.getInstance().get(dataSet.masterTable);
if (table == null) throw new SwException("没有找到指定的表:" + dataSet.masterTable);
SqlNamedPara sqlNamedPara = buildWhereSql(dataSet, params);
SqlNamedPara sqlNamedPara = buildWhereSql(dataSet, params,us, null);
if (StringUtils.isNotEmpty(text)) {//有文本信息
StringBuilder sql = new StringBuilder(128);
ModelField field = table.findFieldByType(SwEnum.FieldType.CODE.value);
@@ -127,36 +142,56 @@ public class DynPageHelper {
}
}

buildSelectSql(dataSet, params, sqlNamedPara);
buildSelectSql(dataSet, params, sqlNamedPara, null);
return sqlNamedPara;
}
private static Map<String, IBuilderExpr> mapBuilder;
private static IBuilderExpr baseBuilder;
static {
baseBuilder = (opt, field, name, value, args, filter) -> {
args.put(name, value);
return field + " " + opt + " :" + name;
};
mapBuilder = new HashMap<>();
mapBuilder.put(SwEnum.OptType.LIKE.value, (opt, field, name, value, args, filter) -> {
args.put(name, "%" + value + "%");
return field + " like :" + name;
});

/**
* 构建合计栏sql
*
* @param dataSet
* @param params
* @return
*/
public static SqlNamedPara buildSumSql(PageDataset dataSet, Map<String, Object> params) {
SqlNamedPara sqlNamedPara = buildSelectSql(dataSet, params);
StringBuilder sql = new StringBuilder(256);
sql.append("select count(1) " + TOTAL_KEY);
for (PageDatasetField field : dataSet.fields) {
if (StringUtils.isEmpty(field.summary)) continue;
if (field.fieldIsCalc()) continue;
sql.append(",");
if (!SwEnum.SummaryType.instance.isText(field.summary)) {
sql.append(field.summary).append("(").append(field.name).append(") ").append(field.name);
} else {
sql.append("'").append(field.summary).append("' ").append(field.name);
mapBuilder.put(SwEnum.OptType.PLIKE.value, (opt, field, name, value, args, filter) -> {
args.put(name, value + "%");
return field + " like :" + name;
});

mapBuilder.put(SwEnum.OptType.BT.value, (opt, field, name, value, args, filter) -> {
String[] ss = value.toString().split(",");
if (ss.length != 2) throw new BizException("介于条件,参数值个数错误!");
args.put(name + "_1", ss[0]);
args.put(name + "_2", ss[1]);
return "(" + field + ">=:" + name + "_1 and " + field + "<=:" + name + "_2)";
});

mapBuilder.put(SwEnum.OptType.IN.value, (opt, field, name, value, args, filter) -> {
if (StringUtil.isEmpty(value.toString())) return "";
args.put(name, value);
return field + " in (:" + name + ") ";
});

mapBuilder.put(SwEnum.OptType.NOT_IN.value, (opt, field, name, value, args, filter) -> {
if (StringUtil.isEmpty(value.toString())) return "";
args.put(name, value);
return field + " not in (:" + name + ") ";
});
mapBuilder.put(SwEnum.OptType.IN_CHILD.value, (opt, field, name, value, args, filter) -> {
ModelTable table = ModelTableCache.getInstance().get(filter.link);
if(table==null){
return "";
}
}
sqlNamedPara.sql = sql.toString() + " from (" + sqlNamedPara.sql + ") xxxxa";
return sqlNamedPara;
return TreeHelper.getTreeHelper(table.getName()).buildLikeFrSql(Long.parseLong(value.toString()),field);
});
}

private static String buildSelFieldsSql(PageDataset dataSet, SqlNamedPara sqlNamedPara) {
private static String buildSelFieldsSql(PageDataset dataSet, SqlNamedPara sqlNamedPara, IBuildSqlListener listener) {
StringBuilder sql = new StringBuilder(512);
//主表
ModelTable masterTable = ModelTableCache.getInstance().get(dataSet.masterTable);
@@ -175,20 +210,45 @@ public class DynPageHelper {
}
sql.setCharAt(sql.length() - 1, ' ');
sql.append(" from ").append(masterTable.getSchemaTableName());
if (listener != null) listener.buildSelect(dataSet, sql);
return sql.toString();
} else {
return dataSet.sql;
return SqlUtil.replaceTable(dataSet.sql);
}
}

/**
* 构建合计栏sql
*
* @param dataSet
* @param sqlNamedPara
* @return
*/
public static SqlNamedPara buildSumSql(PageDataset dataSet, @NonNull SqlNamedPara sqlNamedPara) {
StringBuilder sql = new StringBuilder(256);
sql.append("select count(1) " + TOTAL_KEY);
for (PageDatasetField field : dataSet.fields) {
if (StringUtils.isEmpty(field.summary)) continue;
if (field.fieldIsCalc()) continue;
sql.append(",");
if (!SwEnum.SummaryType.instance.isText(field.summary)) {
sql.append(field.summary).append("(").append(field.name).append(") ").append(field.name);
} else {
sql.append("'").append(field.summary).append("' ").append(field.name);
}
}
sqlNamedPara.sql = sql.toString() + " from (" + sqlNamedPara.sql + ") xxxxa";
return sqlNamedPara;
}

/**
* 构建where条件:组合固定和动态条件
*
* @param dataSet
* @param params
* @return
*/
public static SqlNamedPara buildWhereSql(PageDataset dataSet, Map<String, Object> params) {
private static SqlNamedPara buildWhereSql(PageDataset dataSet, SwMap params,UserSession us, IBuildSqlListener listener) {
StringBuilder sql = new StringBuilder(512);
SwMap args = new SwMap();

@@ -201,7 +261,7 @@ public class DynPageHelper {
setFixedFilter.add(filter.name);
}
if (!dataSet.dynCond.isEmpty()) {
String s = buildDynCondSql(dataSet, dataSet.dynCond, params, args, setFixedFilter);
String s = buildDynCondSql(dataSet, dataSet.dynCond, params,us, args, setFixedFilter);
if (StringUtils.isNotEmpty(s)) {
if (sql.length() > 0) sql.append(" and ");
sql.append(s);
@@ -210,6 +270,14 @@ public class DynPageHelper {
for (String s : setFixedFilter) {
args.put(s, MapUtil.readString(params, s, ""));
}
if (listener != null) listener.buildWhere(dataSet, sql, args);
// 设置固定条件数据权限
for (PageDatasetFilter filter : dataSet.filters) {
if(!setFixedFilter.contains(filter.name))break;
if(filter.dataRightType<=0L)break;
if (sql.length() > 0) sql.append(" and ");
buildDataRight(filter.dataRightType,filter.sqlName,MapUtil.readString(params, filter.name, ""),sql,args,params,us);
}
return new SqlNamedPara(sql.toString(), args);
}

@@ -219,18 +287,19 @@ public class DynPageHelper {
* @param dataSet
* @param dynCond
* @param params
* @param us
* @param args
* @param setFixedFilter
* @return
*/
private static String buildDynCondSql(PageDataset dataSet, PageDatasetDynCond dynCond, Map<String, Object> params, SwMap args, Set<String> setFixedFilter) {
private static String buildDynCondSql(PageDataset dataSet, PageDatasetDynCond dynCond, SwMap params,UserSession us, SwMap args, Set<String> setFixedFilter) {
if (dynCond.isCondOpt()) {//是and/or
if (dynCond.children == null || dynCond.children.isEmpty()) return "";
StringBuilder sql = new StringBuilder(256);
boolean b = false;
//递归调用
for (PageDatasetDynCond dc : dynCond.children) {
String s = buildDynCondSql(dataSet, dc, params, args, setFixedFilter);
String s = buildDynCondSql(dataSet, dc, params,us, args, setFixedFilter);
if (StringUtils.isEmpty(s)) continue;

if (b) sql.append(" ").append(dynCond.opt).append(" ");
@@ -257,16 +326,33 @@ public class DynPageHelper {
value = params.get(filter.name);
}
if (value == null || StringUtils.isEmpty(value.toString())) {
if(filter.dataRightType>0L){
StringBuilder frSql = new StringBuilder();
buildDataRight(filter.dataRightType,filter.sqlName,"",frSql,args,params,us);
return frSql.toString();
}
if (filter.required) {
throw new BizException("过滤条件不能为空(" + filter.name + ")!");
}
return null;
}
IBuilderExpr builder = getBuilder(dynCond.opt);
String ns = isNameSelf ? filter.name : filter.name + "_" + dynCond.hashCode();
return builder.build(dynCond.opt, filter.sqlName, ns, value, args);
String ns = isNameSelf ? filter.name: filter.name + "_" + dynCond.hashCode();
String optWhere = builder.build(dynCond.opt, filter.sqlName, ns, value, args,filter);
// 添加数据权限
if(filter.dataRightType>0L){
StringBuilder frSql = new StringBuilder();
buildDataRight(filter.dataRightType,filter.sqlName,value.toString(),frSql,args,params,us);
if(frSql.length()>0){
if(StringUtil.isEmpty(optWhere)){
optWhere = frSql.toString();
}else {
optWhere+= " and "+ frSql.toString();
}
}
}
return optWhere;
}

/**
* 处理计算字段
*
@@ -281,53 +367,36 @@ public class DynPageHelper {
}
}

private static Map<String, IBuilderExpr> mapBuilder;
private static IBuilderExpr baseBuilder;

static {
baseBuilder = (opt, field, name, value, args) -> {
args.put(name, value);
return field + " " + opt + " :" + name;
};
mapBuilder = new HashMap<>();
mapBuilder.put(SwEnum.OptType.LIKE.value, (opt, field, name, value, args) -> {
args.put(name, "%" + value + "%");
return field + " like :" + name;
});

mapBuilder.put(SwEnum.OptType.PLIKE.value, (opt, field, name, value, args) -> {
args.put(name, value + "%");
return field + " like :" + name;
});

mapBuilder.put(SwEnum.OptType.BT.value, (opt, field, name, value, args) -> {
String[] ss = value.toString().split(",");
if (ss.length != 2) throw new BizException("介于条件,参数值个数错误!");
args.put(name + "_1", ss[0]);
args.put(name + "_2", ss[1]);
return "(" + field + ">=:" + name + "_1 and " + field + "<=:" + name + "_2)";
});

mapBuilder.put(SwEnum.OptType.IN.value, (opt, field, name, value, args) -> {
if (PubUtil.isEmpty(value.toString())) return "";
args.put(name, value);
return field + " in (:" + name + ") ";
});

mapBuilder.put(SwEnum.OptType.NOT_IN.value, (opt, field, name, value, args) -> {
if (PubUtil.isEmpty(value.toString())) return "";
args.put(name, value);
return field + " not in (:" + name + ") ";
});
/**
* 构建数据权限
* @param dsType 数据权限定义ID
* @param sqlField sql字段名
* @param value 值
* @param sql sql语句
* @param args 参数
* @param params 参数
* @param us 用户session
*/
private static void buildDataRight(long dsType,String sqlField,String value,StringBuilder sql,SwMap args,SwMap params,UserSession us){
DataRightDefine drd = DataRightDefineCache.getInstance().get(dsType);
if(drd==null){return;}
try{
IDataRightHandler dataRightHandler = IDataRightTreeFactory.getInstance().getHandler(drd.getCode());
dataRightHandler.init(us,params);
dataRightHandler.buildSqlWhere(sqlField,value,sql,args);
}catch (Exception e){
log.error("加载数据权限失败:",e);
throw new SwException(e);
}
}

private static IBuilderExpr getBuilder(String opt) {
IBuilderExpr builder = mapBuilder.get(opt);
return builder != null ? builder : baseBuilder;
return builder != null ? builder: baseBuilder;
}

interface IBuilderExpr {
String build(String opt, String field, String name, Object value, Map<String, Object> args);
String build(String opt, String field, String name, Object value, Map<String, Object> args,PageDatasetFilter filter);
}

}

+ 26
- 6
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageListHandler.java ファイルの表示

@@ -6,12 +6,14 @@ import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityHelper;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.exception.SwException;
import cc.smtweb.framework.core.mvc.service.AbstractListHandler;
import cc.smtweb.framework.core.mvc.service.SqlNamedPara;
import cc.smtweb.framework.core.mvc.service.SqlPara;
import cc.smtweb.system.bpm.web.design.form.define.PageDataset;

import java.util.List;
import java.util.Map;

import static cc.smtweb.framework.core.common.SwConsts.TOTAL_KEY;

@@ -27,6 +29,9 @@ public class DynPageListHandler extends AbstractListHandler {
//对应的数据集定义
protected PageDataset pageDataSet;

public DynPageListHandler() {
}

public DynPageListHandler(long pageId, SwMap filter, PageDataset pageDataSet) {
this.pageId = pageId;
this.filter = filter;
@@ -45,34 +50,49 @@ public class DynPageListHandler extends AbstractListHandler {

@Override
protected SqlPara buildSqlPara() {
return DynPageHelper.buildSelectSql(pageDataSet, filter);
return DynPageHelper.buildSelectSql(pageDataSet, filter,us);
}

@Override
protected List<SwMap> queryData(String sql, SqlPara sqlPara) {
List<SwMap> list;
SqlNamedPara sp = (SqlNamedPara)sqlPara;
SqlNamedPara sp = (SqlNamedPara) sqlPara;
if (sqlPara.page > 0 && sqlPara.rows > 0) {
list = DbEngine.getInstance().pagedQueryN(sql, SwMap.class, (sqlPara.page - 1) * sqlPara.rows, sqlPara.rows, sp.mapParas);
} else {
list = DbEngine.getInstance().queryN(sql, sp.mapParas, SwMap.class);
}
if(pageDataSet.masterTable != 0 && pageDataSet.masterTable != -1){
if (pageDataSet.masterTable > 0L) {
ModelTable masterTable = ModelTableCache.getInstance().get(pageDataSet.masterTable);
EntityHelper.loadBeanText(masterTable.getName(), list, sp.mapFieldAlias);
}

for (SwMap map: list) {
for (SwMap map : list) {
DynPageHelper.setCalcFields(map, pageDataSet);
}
return list;
}


@Override
protected SqlNamedPara buildSumSqlPara() {
SqlNamedPara sqlPara = getCache(KEY_SQLPARA);
if (sqlPara == null) sqlPara = buildDataSql();
return DynPageHelper.buildSumSql(pageDataSet, sqlPara);
}

@Override
public R getTotal() {
SqlNamedPara sqlPara = DynPageHelper.buildSumSql(pageDataSet, filter);
SqlNamedPara sqlParaSum = getCache(KEY_SQLPARA_SUM);
if (sqlParaSum == null) {
Map<String, Object> map = getCache(KEY_PARAMS);
if (map != null) params.putAll(map);
sqlParaSum = buildSumSqlPara();
}
if (sqlParaSum == null) return R.success();
setCache(KEY_SQLPARA_SUM, sqlParaSum);

SwMap mapFooter = DbEngine.getInstance().queryEntityN(sqlPara.sql, sqlPara.mapParas, SwMap.class);
SwMap mapFooter = DbEngine.getInstance().queryEntityN(sqlParaSum.sql, sqlParaSum.mapParas, SwMap.class);

SwMap r = new SwMap();
r.put("total", mapFooter.get(TOTAL_KEY));


変更されたファイルが多すぎるため、一部のファイルは表示されません

読み込み中…
キャンセル
保存