Compare commits

...

232 Commits
master ... 4.0

Author SHA1 Message Date
  yaoq 25afb4a7fa 优化 1 year ago
  yaoq 8700a70365 优化 1 year ago
  yaoq 23b89a4518 优化 1 year ago
  yaoq 6574e4b142 优化 1 year ago
  yaoq b708a30061 优化 1 year ago
  lip be1cac9b87 Merge remote-tracking branch 'origin/4.0' into 4.0 1 year ago
  FLYPHT 2c89970c44 修改 1 year ago
  FLYPHT 4a8a61c8a7 新增:开发手册 1 year ago
  yaoq a1af8a48a8 Merge remote-tracking branch 'origin/4.0' into 4.0 1 year ago
  yaoq 6e8c81bda4 优化 1 year ago
  lip d2c33685de 导出excel 2 years ago
  lip 7953f3dc42 模型方法独立 2 years ago
  FLYPHT bf06300da5 优化数据权限 2 years ago
  FLYPHT 4be822f190 优化功能权限 2 years ago
  郑根木 16a1f3f446 flowInstance增加getProcDef,findActivity 2 years ago
  yaoq 0710dffb07 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  yaoq 6bb095c6c3 平谷政协 2 years ago
  lip 3013e3f394 模板模型构建BUG 2 years ago
  lip 1f11cc6911 模型调整、Excel工具类 2 years ago
  FLYPHT 2d7cd82bca 修复bug:HttpUtil中map转SwMap失败 2 years ago
  FLYPHT fd74334925 优化映射登录 2 years ago
  FLYPHT 0025ab376f 移除 2 years ago
  FLYPHT b93a3aa04d bug:非法前置引用 2 years ago
  FLYPHT ebb8c874a1 bug:非法前置引用 2 years ago
  FLYPHT fd34868657 新增:支持数据权限 2 years ago
  yaoq fd02a965b3 区划 2 years ago
  yaoq 012cd6fb46 数据权限 2 years ago
  yaoq 0df91d874d 数据权限 2 years ago
  yaoq c0928eaf33 数据权限 2 years ago
  yaoq 3fcbd59f0d 数据权限 2 years ago
  yaoq 73d3becb83 canal集成、数据权限 2 years ago
  yaoq 3bbcdf6522 canal集成、数据权限 2 years ago
  FLYPHT 517fdd41b5 新增单位权限 2 years ago
  FLYPHT 4c20b66809 bpm新增common包 2 years ago
  FLYPHT 3676bdb07e "/" 请求免登录 2 years ago
  FLYPHT ad78298d41 优化映射登录 2 years ago
  yaoq 6dbb9240c3 canal集成 2 years ago
  yaoq b43475b09c Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  yaoq 12dc05d38b canal集成 2 years ago
  郑根木 2664e7582c listhandler.buildSumSql调整,允许不写 2 years ago
  FLYPHT 197dde622e 移除 2 years ago
  yaoq 6bc0034f48 canal集成 2 years ago
  FLYPHT 643278c426 数据集添加字段数据权限配置 2 years ago
  yaoq d5af00ca19 canal集成 2 years ago
  xiaxl 56a306c9ff 参数优化 2 years ago
  lip 131b60330a Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  lip 93ec115816 添加工作流模型 2 years ago
  郑根木 293be2fd8f jackson不能指定版本,否则和spring boot冲突,spring-starter-web依赖2.12.5 2 years ago
  FLYPHT 7412b917b6 优化:模型代码 2 years ago
  FLYPHT 07e1155201 新增:加载当前用户信息、修改用户信息、修改密码接口 2 years ago
  FLYPHT d254a9df68 优化:公众用户session不再失效 2 years ago
  FLYPHT 55a850e24e 优化:模型代码 2 years ago
  yaoq cbeefa22c0 canal集成 2 years ago
  yaoq bcdcf21c5a Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  yaoq 2b4931f8f4 canal集成 2 years ago
  xiaxl 72c1eca49b 工作流模板修改 2 years ago
  郑根木 a7be5a2de7 模型:单独列表handler 2 years ago
  yaoq a0c06b128b Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  yaoq 1ff14f8305 canal集成 2 years ago
  FLYPHT cf2e8080eb 优化:token延时 2 years ago
  FLYPHT 715a83dfee 新增:登录事件(用户映射,登录成功之后) 2 years ago
  yaoq adb8d248a4 canal集成 2 years ago
  yaoq d7aad13dcc canal 集成 2 years ago
  lip d093db1e65 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  lip 62395c0acc 自定义模型 2 years ago
  郑根木 c13412a3d4 系统:定时任务 2 years ago
  郑根木 713d022078 系统:定时任务 2 years ago
  郑根木 d00342ce9c 系统:定时任务 2 years ago
  FLYPHT f8e8274d4b 新增:登录事件(用户映射,登录成功之后) 2 years ago
  yaoq 91513c8676 线程池 2 years ago
  yaoq b15d5569c2 集成Canal 2 years ago
  yaoq 8ab1bde422 集成Canal 2 years ago
  lip 2282a5ef4f 模型调整 2 years ago
  FLYPHT b92bce66b1 优化:拦截器中实现跨域配置 2 years ago
  lip 6e4a29b132 模型: 左树+列表+编辑弹窗 2 years ago
  lip 3b58519b90 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  郑根木 62e650d600 系统:系统任务和一次性任务 2 years ago
  郑根木 f21f674a97 系统:系统任务和一次性任务 2 years ago
  郑根木 bd7cf4313f 系统:系统任务和一次性任务 2 years ago
  郑根木 93d5a73dba 系统:系统任务和一次性任务 2 years ago
  lip 59c0561f5e Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  郑根木 2ff242165d 系统:模型代码调整 2 years ago
  郑根木 7211a7b35b 系统:模型代码调整 2 years ago
  lip cacfd6482e Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  lip 2863ca08e9 工具类 2 years ago
  yaoq 29b034a272 重载缓存 2 years ago
  lip ad5b0b082e 静态资源不拦截 2 years ago
  lip f4fd27de1f Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  ht b148e4d35b 角色权限admin添加 2 years ago
  FLYPHT 29d76d56b5 优化:管理员的权限控制 2 years ago
  郑根木 7893a1fb6e 系统:自定义sql的表替换,[#tableName#] 2 years ago
  郑根木 1e916dc40d 系统:拦截器调整,统一异常处理,防重复提交指纹 2 years ago
  FLYPHT 01ba683554 优化:工作流模型配置 2 years ago
  郑根木 a258676c8d 系统:拦截器调整,统一异常处理,防重复提交指纹 2 years ago
  郑根木 159f1147f0 系统:拦截器调整,统一异常处理,防重复提交指纹 2 years ago
  郑根木 be8af8b963 系统:拦截器调整,统一异常处理,防重复提交指纹 2 years ago
  郑根木 1a96ce4654 系统:拦截器调整,统一异常处理,防重复提交指纹 2 years ago
  yaoq 68a383fa07 菜单权限保存问题 2 years ago
  yaoq 5f65d36c42 菜单权限保存问题 2 years ago
  yaoq 483c490b67 菜单权限保存问题 2 years ago
  FLYPHT 605c2c8fb7 新增:新增菜单权限 2 years ago
  lip dbb946ff49 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  ht 2b2be9f221 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  ht 921395d706 登录修改 2 years ago
  lip ba2673c9a6 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  zhangyulong 0591b28c6c 登录增加返回账号信息 2 years ago
  zhangyulong 270b7b0a3e 登录增加返回账号信息 2 years ago
  郑根木 a2786d2c39 流程:系列bug 2 years ago
  郑根木 3d778c8966 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  郑根木 5c10cefdfd 流程:系列bug 2 years ago
  xiaxl f17ac83135 优化点模板参数 2 years ago
  FLYPHT a9d9f53105 优化:工作流模型配置 2 years ago
  lip f1c803f3cc Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  郑根木 be57d46d8d 流程:增加selTaskId 2 years ago
  郑根木 e7332ac991 去掉指定字段的insert 2 years ago
  郑根木 8e0392548b 去掉指定字段的insert 2 years ago
  郑根木 d2f875f771 去掉指定字段的insert 2 years ago
  郑根木 5088a26c75 去掉指定字段的insert 2 years ago
  lip e9fa7ed868 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  郑根木 f6a3659aa9 流程:指定任务,不要切换 2 years ago
  郑根木 0397ca5b77 重构:去掉多余引用+格式化 2 years ago
  郑根木 4571518688 重构:删除部分Util,原PubUtil分散到CommUtil和StringUtil、NumberUtil 2 years ago
  郑根木 5bd9e23df5 重构:删除部分Util,原PubUtil分散到CommUtil和StringUtil、NumberUtil 2 years ago
  yaoq 133280bc63 菜单权限保存问题 2 years ago
  lip 1c990db0ce 默认非debug 2 years ago
  zhangyulong f04402d602 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  zhangyulong 82e77c670d 修改用户登录为直接查库、登录返回增加返回用户等级 2 years ago
  FLYPHT f65035be50 优化:工作流模型配置 2 years ago
  FLYPHT ec3e13a19b 优化:工作流模型配置 2 years ago
  FLYPHT 1dd0ec37d5 优化:工作流模板配置 2 years ago
  郑根木 145b88152a 流程:条件分支 2 years ago
  郑根木 a9c3ce1d19 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  郑根木 51e099b2d3 流程:条件分支 2 years ago
  FLYPHT 9af9d61535 新增:添加HttpUtil工具类 2 years ago
  郑根木 84d31f32c1 系统:启动监听,按order先执行init,再执行run; 2 years ago
  郑根木 a60b9e204f 系统:流程处理 2 years ago
  郑根木 41738f6438 系统:增加SwConsts.SysParam.RUN_PROJECTS,启动时只读取指定项目的表定义 2 years ago
  郑根木 9401b1c32b 系统:增加SwConsts.SysParam.RUN_PROJECTS,启动时只读取指定项目的表定义 2 years ago
  郑根木 73e780f9ae 系统:增加SwConsts.SysParam.RUN_PROJECTS,启动时只读取指定项目的表定义 2 years ago
  郑根木 d088c607fa Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  郑根木 94dccde30c 流程:按钮控制 2 years ago
  ht 8541bed84d Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  ht d295abe448 提交单点登录实体 2 years ago
  郑根木 692a122dca 流程:按钮控制 2 years ago
  郑根木 2024829f86 流程:按钮控制 2 years ago
  郑根木 54f07d25ef 流程:按钮控制 2 years ago
  xiaxl 67ebf7d5ec 调整参数 2 years ago
  郑根木 87d1c3e570 流程办理提交驳回取回作废终止 2 years ago
  xiaxl 29ee8316ed 补充一个参数 2 years ago
  xiaxl 8f0233f44d 优化模板参数 2 years ago
  郑根木 41535d1b81 废弃AbsDbWorker,增加IDbSimpleWorker,方便lambda表达式写法 2 years ago
  郑根木 0103df9754 废弃AbsDbWorker 2 years ago
  FLYPHT bc7153b47b bug:修改sql报错 2 years ago
  lip 502d3a7f97 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  lip 3df6834ffa 模型 2 years ago
  郑根木 f634fff6ae 流程引擎:extra返回 2 years ago
  郑根木 3ec303f413 流程引擎:load\save\submit;调整模型,以Bean方式处理 2 years ago
  郑根木 d7305800f8 流程引擎:load\save\submit;调整模型,以Bean方式处理 2 years ago
  郑根木 51a963700d 流程引擎:load\save\submit;调整模型,以Bean方式处理 2 years ago
  郑根木 a75c2638d2 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  郑根木 e6ddfb8fb6 流程引擎:load\save\submit;调整模型,以Bean方式处理 2 years ago
  xiaxl ad26db8fc8 模板调整参数 2 years ago
  xiaxl 56f0ba89fd 调点样式 2 years ago
  lip add833bc97 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  lip e5b83da5d7 添加两个模型 2 years ago
  郑根木 bcb6eb735e 流程引擎:load\save\submit 2 years ago
  FLYPHT 3a459ed545 新增:打包配置 2 years ago
  郑根木 32ad84350a 流程引擎:load\save\submit 2 years ago
  郑根木 ec49b3b8c3 bug:dynpage.save 2 years ago
  xiaxl 5110b06a67 调整点flow模板 2 years ago
  郑根木 2c6741804b 代码调整:add即返回id,根据_status判断是否新增 2 years ago
  郑根木 a852cbe539 代码调整:add即返回id,根据_status判断是否新增 2 years ago
  郑根木 0901fb476b 流程引擎-删除 2 years ago
  郑根木 4ec41104b3 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  郑根木 acfb4a1af5 流程引擎-保存 2 years ago
  xiaxl 3f9312dc51 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  xiaxl 2274898a67 模板部分修改 2 years ago
  lip af312ca3ee 下拉树控件名更改 2 years ago
  xiaxl 40812c2b20 提交普通卡片模板,主子表卡片模板 2 years ago
  FLYPHT 7310fabce0 apiController中 request.getRequestURI() 修改为request.getServletPath() 2 years ago
  郑根木 621ec86cdc 流程引擎-保存 2 years ago
  郑根木 27e80a8f71 流程引擎-新增 2 years ago
  郑根木 4bbc6e4f18 流程引擎-listhandler 2 years ago
  FLYPHT 3632d8876a 调整工作流模型的模板 2 years ago
  lip a118c2d925 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  lip e9926de544 修改模板和handler 2 years ago
  郑根木 950ca07324 流程引擎-listhandler 2 years ago
  郑根木 826f25276c 流程引擎-listhandler 2 years ago
  郑根木 7283600160 流程引擎 2 years ago
  lip 6e9a0b1a1c Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  lip d9c76a815c 模型 2 years ago
  FLYPHT 0c4918fbed 新增:工作流的模板实现 2 years ago
  郑根木 69d8e41b59 流程引擎 2 years ago
  郑根木 afbcf25d15 loadProcInstFields 2 years ago
  郑根木 575d3e4ca6 loadProcInstFields 2 years ago
  郑根木 69f9d6930c loadProcInstFields 2 years ago
  郑根木 3364f65348 loadProcInstFields 2 years ago
  郑根木 2d260a5940 loadProcInstFields 2 years ago
  郑根木 5d9fc400b0 页面+BillType,表定义加buildBean 2 years ago
  郑根木 038b02e7d8 页面+BillType,表定义加buildBean 2 years ago
  郑根木 5008555ef6 页面+BillType,表定义加buildBean 2 years ago
  lip c9a1811683 Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  lip bbdd0ebd45 树筛选 2 years ago
  郑根木 f40108341b 启动调整 2 years ago
  FLYPHT e82f445e4e 修改:model_list_card.ftl调整 2 years ago
  lip 538df033b9 2 years ago
  郑根木 543d02b88b 流程引擎 2 years ago
  郑根木 ae17aa5f11 流程引擎 2 years ago
  郑根木 d1d2dcc503 页面设计:返回带控件的字段信息 2 years ago
  lip 03e4ef16b3 枚举下拉框 2 years ago
  lip 03e81ca8c8 流程相关 2 years ago
  郑根木 5ad0bfb6c6 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2 years ago
  郑根木 aed2b1e379 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2 years ago
  郑根木 d736624007 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2 years ago
  郑根木 223bc9eb16 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2 years ago
  郑根木 01e12107aa 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2 years ago
  FLYPHT ef0ff750ad 修改:model_list_card.ftl调整 2 years ago
  郑根木 58feeeeeef 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2 years ago
  郑根木 a93e8d88e2 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2 years ago
  郑根木 407397fa1e 增加SWConsts.debug,是否调试模式,调试模式缓存从数据库加载 2 years ago
  郑根木 ea726b0069 增加:LC_SINGLE模型engine 2 years ago
  FLYPHT f92def87d8 修改:修改list_card.ftl模板 2 years ago
  郑根木 027bd3c9f6 增加:LC_SINGLE模型engine 2 years ago
  郑根木 10f2cb4cd2 增加:LC_SINGLE模型engine 2 years ago
  郑根木 d2fcac6845 增加:LC_SINGLE模型根据模板生成页面 2 years ago
  yaoq c10d065003 个人信息修改、密码修改、密码重置 2 years ago
  郑根木 27c588d0bf 增加:LC_SINGLE模型 2 years ago
  郑根木 cbcce3f28e Merge remote-tracking branch 'origin/4.0' into 4.0 2 years ago
  郑根木 705a80692a 增加:LC_SINGLE模型 2 years ago
  yaoq c4ee399bae 枚举combo 2 years ago
  郑根木 f1cae9d932 增加:LC_SINGLE模型 2 years ago
  郑根木 e62364c165 优化:form.load系列支持id、pageId、pageName 2 years ago
100 changed files with 3015 additions and 2738 deletions
Split View
  1. BIN
      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

BIN
smtweb-framework/bpm/doc/开发手册.doc View File


+ 6
- 2
smtweb-framework/bpm/pom.xml View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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 View File

@@ -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));


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save