From 29014d089141f1084ae0fa59c0b2b5fec1c8ff3f Mon Sep 17 00:00:00 2001 From: lixin Date: Thu, 4 Mar 2021 09:41:32 +0800 Subject: [PATCH] =?UTF-8?q?=E7=97=85=E6=A1=88=E7=94=B3=E8=AF=B7=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=90=8E=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 9 + ruoyi-admin/pom.xml | 62 +- .../src/main/resources/application-druid.yml | 5 - .../src/main/resources/application-local.yml | 14 + .../src/main/resources/application-prod.yml | 15 + .../src/main/resources/application.yml | 27 +- .../main/resources/ehcache/ehcache-shiro.xml | 15 +- .../src/main/resources/static/favicon.ico | Bin 16958 -> 90022 bytes .../src/main/resources/templates/index.html | 7 +- .../src/main/resources/templates/login.html | 19 +- .../src/main/resources/templates/main.html | 1456 ++++------------- .../main/resources/templates/main_readme.html | 1222 ++++++++++++++ .../src/main/resources/templates/main_v1.html | 336 ---- ruoyi-common/pom.xml | 9 +- .../ruoyi/common/core/domain/AjaxResult.java | 6 + .../exception/wx/NotLoginException.java | 8 + .../exception/wx/WxBusinessException.java | 9 + ruoyi-framework/pom.xml | 6 + .../framework/config/ResourcesConfig.java | 14 +- .../ruoyi/framework/config/ShiroConfig.java | 4 + .../web/exception/GlobalExceptionHandler.java | 70 +- wx-record-order/doc/docus.cn.csr | 0 wx-record-order/doc/docus.cn.key | 0 wx-record-order/doc/docus.cn.pem | 0 wx-record-order/doc/wx.docus.cn.csr | 0 wx-record-order/doc/wx.docus.cn.key | 0 wx-record-order/doc/wx.docus.cn.pem | 0 wx-record-order/doc/小程序表设计.xlsx | Bin 0 -> 11638 bytes wx-record-order/doc/病案室审核.xmind | Bin 0 -> 36850 bytes wx-record-order/doc/病案调用.xmind | Bin 0 -> 41378 bytes wx-record-order/doc/短信通知模板.txt | 6 + wx-record-order/pom.xml | 44 + .../wx/controller/ApiRestController.java | 63 + .../controller/MrRecordOrderController.java | 151 ++ .../wx/controller/ShortUrlController.java | 30 + .../ruoyi/wx/controller/WxUserController.java | 141 ++ .../com/ruoyi/wx/domain/MrRecordOrder.java | 216 +++ .../main/java/com/ruoyi/wx/domain/WxUser.java | 196 +++ .../java/com/ruoyi/wx/dto/RecordOrderDTO.java | 129 ++ .../main/java/com/ruoyi/wx/dto/WxUserDTO.java | 112 ++ .../com/ruoyi/wx/dto/req/OrderListReqDTO.java | 31 + .../com/ruoyi/wx/dto/req/UserSignInfo.java | 58 + .../ruoyi/wx/mapper/MrRecordOrderMapper.java | 71 + .../com/ruoyi/wx/mapper/WxUserMapper.java | 70 + .../wx/service/IMrRecordOrderService.java | 75 + .../com/ruoyi/wx/service/IWxUserService.java | 82 + .../impl/MrRecordOrderServiceImpl.java | 218 +++ .../wx/service/impl/WxUserServiceImpl.java | 207 +++ .../java/com/ruoyi/wx/util/ShortUrlUtils.java | 22 + .../main/java/com/ruoyi/wx/util/SmsUtils.java | 119 ++ .../com/ruoyi/wx/util/WxServiceUtils.java | 76 + .../java/com/ruoyi/wx/util/WxUserUtils.java | 48 + .../mapper/wx/MrRecordOrderMapper.xml | 149 ++ .../main/resources/mapper/wx/WxUserMapper.xml | 124 ++ .../resources/templates/wx/order/add.html | 135 ++ .../resources/templates/wx/order/edit.html | 81 + .../resources/templates/wx/order/order.html | 171 ++ .../templates/wx/order/sendView.html | 69 + .../main/resources/templates/wx/user/add.html | 76 + .../resources/templates/wx/user/edit.html | 44 + .../resources/templates/wx/user/user.html | 159 ++ 61 files changed, 4900 insertions(+), 1586 deletions(-) create mode 100644 ruoyi-admin/src/main/resources/application-local.yml create mode 100644 ruoyi-admin/src/main/resources/application-prod.yml create mode 100644 ruoyi-admin/src/main/resources/templates/main_readme.html delete mode 100644 ruoyi-admin/src/main/resources/templates/main_v1.html create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/wx/NotLoginException.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/exception/wx/WxBusinessException.java create mode 100644 wx-record-order/doc/docus.cn.csr create mode 100644 wx-record-order/doc/docus.cn.key create mode 100644 wx-record-order/doc/docus.cn.pem create mode 100644 wx-record-order/doc/wx.docus.cn.csr create mode 100644 wx-record-order/doc/wx.docus.cn.key create mode 100644 wx-record-order/doc/wx.docus.cn.pem create mode 100644 wx-record-order/doc/小程序表设计.xlsx create mode 100644 wx-record-order/doc/病案室审核.xmind create mode 100644 wx-record-order/doc/病案调用.xmind create mode 100644 wx-record-order/doc/短信通知模板.txt create mode 100644 wx-record-order/pom.xml create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/controller/ApiRestController.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/controller/MrRecordOrderController.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/controller/ShortUrlController.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/controller/WxUserController.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/domain/MrRecordOrder.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/domain/WxUser.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/dto/RecordOrderDTO.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/dto/WxUserDTO.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/dto/req/OrderListReqDTO.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/dto/req/UserSignInfo.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/mapper/MrRecordOrderMapper.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/mapper/WxUserMapper.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/service/IMrRecordOrderService.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/service/IWxUserService.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/service/impl/MrRecordOrderServiceImpl.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/service/impl/WxUserServiceImpl.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/util/ShortUrlUtils.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/util/SmsUtils.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/util/WxServiceUtils.java create mode 100644 wx-record-order/src/main/java/com/ruoyi/wx/util/WxUserUtils.java create mode 100644 wx-record-order/src/main/resources/mapper/wx/MrRecordOrderMapper.xml create mode 100644 wx-record-order/src/main/resources/mapper/wx/WxUserMapper.xml create mode 100644 wx-record-order/src/main/resources/templates/wx/order/add.html create mode 100644 wx-record-order/src/main/resources/templates/wx/order/edit.html create mode 100644 wx-record-order/src/main/resources/templates/wx/order/order.html create mode 100644 wx-record-order/src/main/resources/templates/wx/order/sendView.html create mode 100644 wx-record-order/src/main/resources/templates/wx/user/add.html create mode 100644 wx-record-order/src/main/resources/templates/wx/user/edit.html create mode 100644 wx-record-order/src/main/resources/templates/wx/user/user.html diff --git a/pom.xml b/pom.xml index 54012613..725c4c86 100644 --- a/pom.xml +++ b/pom.xml @@ -208,6 +208,14 @@ ${ruoyi.version} + + + com.ruoyi + wx-record-order + ${ruoyi.version} + + + com.ruoyi @@ -225,6 +233,7 @@ ruoyi-quartz ruoyi-generator ruoyi-common + wx-record-order pom diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 58df34fc..4e38444a 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -80,6 +80,25 @@ + + + + local + + local + + + true + + + + + prod + + prod + + + @@ -98,17 +117,48 @@ - - org.apache.maven.plugins - maven-war-plugin - 3.0.0 + + org.apache.maven.plugins + maven-war-plugin + 3.0.0 false ${project.artifactId} - - + + ${project.artifactId} + + src/main/resources/application.yml + + + + src/main/resources + true + + application-*.* + META-INF/** + static/** + template/** + + + + src/main/resources + false + + application-druid.yml + META-INF/** + static/** + template/** + + + + src/main/resources + + application-${active.env}.* + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml index d69c66d2..174ff482 100644 --- a/ruoyi-admin/src/main/resources/application-druid.yml +++ b/ruoyi-admin/src/main/resources/application-druid.yml @@ -4,11 +4,6 @@ spring: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver druid: - # 主库数据源 - master: - url: jdbc:mysql://localhost:3306/ry?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 - username: root - password: password # 从库数据源 slave: # 从数据源开关/默认关闭 diff --git a/ruoyi-admin/src/main/resources/application-local.yml b/ruoyi-admin/src/main/resources/application-local.yml new file mode 100644 index 00000000..ca540a09 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-local.yml @@ -0,0 +1,14 @@ +# 项目相关配置 +ruoyi: + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: D:/ruoyi/uploadPath +spring: + datasource: + druid: + # 主库数据源 + master: + url: jdbc:mysql://localhost:3306/ry?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: root + password: docus702 \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml new file mode 100644 index 00000000..9cd3ea71 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -0,0 +1,15 @@ +# 项目相关配置 +ruoyi: + # 实例演示开关 + demoEnabled: false + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: C:/wwwroot/wx.docus.cn/uploadPath + +spring: + datasource: + druid: + # 主库数据源 + master: + url: jdbc:mysql://localhost:3306/wx_docus_cn?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: wx_docus_cn + password: Bj87yZBAxECG5kTG \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index d013a3f1..797330d0 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -1,13 +1,11 @@ # 项目相关配置 ruoyi: # 名称 - name: RuoYi + name: Docus # 版本 version: 4.6.0 # 版权年份 copyrightYear: 2021 - # 实例演示开关 - demoEnabled: true # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) profile: D:/ruoyi/uploadPath # 获取ip地址开关 @@ -16,10 +14,11 @@ ruoyi: # 开发环境配置 server: # 服务器的HTTP端口,默认为80 - port: 80 + port: 8080 servlet: # 应用的访问路径 context-path: / + domain: https://wx.docus.cn tomcat: # tomcat的URI编码 uri-encoding: UTF-8 @@ -40,6 +39,16 @@ user: # 密码错误{maxRetryCount}次锁定10分钟 maxRetryCount: 5 +wx: + appid: wxa35fbc494f55cdd1 + appsecret: 81c02b2758b9e9b7c0b41aa01f336353 + +aliyun: + accesskey-id: LTAIANCnxPby45Y8 + accesskey-secret: tMmutQW2J1TkNmmEMXeltepnmr47jh + sms: + sign-name: 嘉时软件 + # Spring配置 spring: # 模板引擎 @@ -56,14 +65,14 @@ spring: time-zone: GMT+8 date-format: yyyy-MM-dd HH:mm:ss profiles: - active: druid + active: druid,@active.env@ # 文件上传 servlet: multipart: # 单个文件大小 - max-file-size: 10MB + max-file-size: 1GB # 设置总上传的文件大小 - max-request-size: 20MB + max-request-size: 20GB # 服务模块 devtools: restart: @@ -127,11 +136,11 @@ xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) - excludes: /system/notice/* + excludes: /system/notice/*,/wx/api/* # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* # Swagger配置 swagger: # 是否开启swagger - enabled: true + enabled: false diff --git a/ruoyi-admin/src/main/resources/ehcache/ehcache-shiro.xml b/ruoyi-admin/src/main/resources/ehcache/ehcache-shiro.xml index 8ffd5ed0..2ff7ae4c 100644 --- a/ruoyi-admin/src/main/resources/ehcache/ehcache-shiro.xml +++ b/ruoyi-admin/src/main/resources/ehcache/ehcache-shiro.xml @@ -86,6 +86,19 @@ timeToLiveSeconds="0" timeToIdleSeconds="0" statistics="false"/> - + + + + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/favicon.ico b/ruoyi-admin/src/main/resources/static/favicon.ico index 6f07782abfc7881a73d3f47a00b761c183e06ff9..0408ffe16a4580fc7851c24426c8da478f00e690 100644 GIT binary patch literal 90022 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 diff --git a/ruoyi-admin/src/main/resources/templates/index.html b/ruoyi-admin/src/main/resources/templates/index.html index fe089a65..909bca61 100644 --- a/ruoyi-admin/src/main/resources/templates/index.html +++ b/ruoyi-admin/src/main/resources/templates/index.html @@ -4,7 +4,7 @@ - 若依系统首页 + 系统首页 @@ -26,7 +26,7 @@

-
+
+ +
+
-
捐赠
+
用户项目列表
+
-
- 请作者喝杯咖啡(点击图片放大) -
-

- 请使用手机支付宝或者微信扫码支付 - -

- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
状态日期用户
进行中... + 11:20青衣5858 24%
已取消 + 10:40徐子崴 66%
进行中... + 01:30姜岚昕 54%
进行中... + 02:20武汉大兵哥 12%
进行中... + 09:40荆莹儿 22%
已完成 + 04:10栾某某 66%
进行中... + 12:08范范范二妮 23%
-
+ + - + + + diff --git a/ruoyi-admin/src/main/resources/templates/main_readme.html b/ruoyi-admin/src/main/resources/templates/main_readme.html new file mode 100644 index 00000000..e9cbbc4f --- /dev/null +++ b/ruoyi-admin/src/main/resources/templates/main_readme.html @@ -0,0 +1,1222 @@ + + + + + + + 若依介绍 + + + + + + + + +
+
+
+ 领取阿里云通用云产品1888优惠券 +
https://www.aliyun.com/minisite/goods?userCode=brki8iof
+ 领取腾讯云通用云产品2860优惠券 +
https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console
+ 阿里云服务器折扣区 ☛☛点我进入☚☚     腾讯云服务器秒杀区 ☛☛点我进入☚☚
+

云产品通用红包,可叠加官网常规优惠使用。(仅限新用户)

+
+ +
+
+
+

Hello,Guest

+ 移动设备访问请扫描以下二维码: +
+
+ +
+
+
+

若依后台管理框架

+

一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了若依管理系统。,她可以用于所有的Web应用程序,如网站管理后台网站会员中心CMSCRMOA等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。

+

+ 当前版本:v[[${version}]] +

+

+ ¥免费开源 +

+
+

+ + 访问码云 + + + 访问主页 + +

+
+
+

技术选型:

+
    +
  1. 核心框架:Spring Boot。
  2. +
  3. 安全框架:Apache Shiro。
  4. +
  5. 模板引擎:Thymeleaf。
  6. +
  7. 持久层框架:MyBatis。
  8. +
  9. 定时任务:Quartz。
  10. +
  11. 数据库连接池:Druid。
  12. +
  13. 工具类:Fastjson。
  14. +
  15. 更多……
  16. +
+
+ +
+
+
+
+ +
+
+
联系信息
+ +
+
+

官网:http://www.ruoyi.vip +

+

QQ群:满1389287 满1679294 满1529866 满1772718 满1366522 满1382251 满1145125 满86752435 满134072510 满210336300 满339522636 满130035985 143151071 +

+

微信:/ *若依 +

+

支付宝:/ *若依 +

+
+
+
+
+
+
+
更新日志
+
+
+
+
+
+
+
+ v4.6.02021.01.01 +
+
+
+
+
    +
  1. 新增缓存监控管理
  2. +
  3. 新增锁定屏幕功能
  4. +
  5. 菜单新增是否刷新页面
  6. +
  7. 删除用户和角色解绑关联
  8. +
  9. 新增密码强度字符范围提示
  10. +
  11. 防止匿名访问进行过滤
  12. +
  13. 升级SpringBoot到最新版本2.2.12
  14. +
  15. 升级poi到最新版本4.1.2
  16. +
  17. 升级bitwalker到最新版本1.21
  18. +
  19. 升级bootstrap-fileinput到最新版本5.1.3
  20. +
  21. 升级bootstrapTable到最新版本v1.18.0
  22. +
  23. 升级bootstrapTable相关组件到最新版本v1.18.0
  24. +
  25. 升级oshi到最新版本v5.3.6
  26. +
  27. 新增示例(标签 & 提示)
  28. +
  29. 添加单据打印示例
  30. +
  31. 修改表格初始参数sortName默认值为undefined
  32. +
  33. 新增表格参数(自定义打印页面模板printPageBuilder)
  34. +
  35. 新增表格参数(是否显示行间隔色striped)
  36. +
  37. 新增表格参数(渲染完成后执行的事件onPostBody)
  38. +
  39. Excel注解支持Image图片导出
  40. +
  41. Excel支持注解align对齐方式
  42. +
  43. Excel支持导入Boolean型数据
  44. +
  45. 主子表操作添加通用addColumn方法
  46. +
  47. 代码生成日期控件区分范围
  48. +
  49. 代码生成数据库文本类型生成表单文本域
  50. +
  51. 修复生成主子表外键名错误
  52. +
  53. 选项卡新增是否刷新属性
  54. +
  55. 修复树表格表头跟表格宽度不同步的问题
  56. +
  57. 表格树加载完成触发tooltip方法
  58. +
  59. 使用widthUnit定义树表格选项单位
  60. +
  61. 修复主子表editColumn序列问题
  62. +
  63. 修复添加全屏在无参数时没有替换url参数问题
  64. +
  65. 弹出层openOptions移动端自适应
  66. +
  67. 防止错误页返回主页出现嵌套问题
  68. +
  69. 设置回显数据字典验证防止空值
  70. +
  71. 其他细节优化
  72. +
+
+
+
+
+
+
+ v4.5.12020.11.18 +
+
+
+
+
    +
  1. 阻止任意文件下载漏洞
  2. +
  3. 升级shiro到最新版1.7.0 阻止权限绕过漏洞
  4. +
  5. 升级druid到最新版本v1.2.2
  6. +
  7. 新增表格行触发事件(onCheck、onUncheck、onCheckAll、onUncheckAll)
  8. +
  9. 修复多页签关闭非当前选项出现空白问题
  10. +
  11. 代码生成预览支持高亮显示
  12. +
  13. mapperLocations配置支持分隔符
  14. +
  15. 权限信息调整
  16. +
  17. 个人中心头像和上传头像增加默认图片
  18. +
  19. 全局配置类保持和其他应用命名相同
  20. +
+
+
+
+
+
+
+ v4.5.02020.10.20 +
+
+
+
+
    +
  1. 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单)
  2. +
  3. 菜单&数据权限新增(展开/折叠 全选/全不选 父子联动)
  4. +
  5. 账号密码支持自定义更新周期
  6. +
  7. 初始密码支持自定义修改策略
  8. +
  9. 新增校验用户修改新密码不能与旧密码相同
  10. +
  11. 添加检查密码范围支持的特殊字符包括:~!@#$%^&*()-=_+
  12. +
  13. 注册账号设置默认用户名称及密码最后更新时间
  14. +
  15. 去除用户手机邮箱部门必填验证
  16. +
  17. 新增日期格式化方法
  18. +
  19. 代码生成添加bit类型
  20. +
  21. 树结构加载添加callBack回调方法
  22. +
  23. 修复用户管理页面滚动返回顶部条失效
  24. +
  25. 修复代码生成模板文件上传组件缺少ctx的问题
  26. +
  27. 限制系统内置参数不允许删除
  28. +
  29. 新增表格列宽拖动插件
  30. +
  31. 新增Ajax局部刷新demo
  32. +
  33. 新增是否开启页脚功能
  34. +
  35. 新增表格参数(通过自定义函数设置标题样式headerStyle)
  36. +
  37. 新增表格参数(通过自定义函数设置页脚样式footerStyle)
  38. +
  39. 修复窗体大小改变后浮动提示框失效问题
  40. +
  41. 生成代码补充必填样式
  42. +
  43. 生成页面时不忽略remark属性
  44. +
  45. 字典数据列表页添加关闭按钮
  46. +
  47. Excel注解支持自动统计数据总和
  48. +
  49. 升级springboot到2.1.17 提升安全性
  50. +
  51. 升级pagehelper到最新版1.3.0
  52. +
  53. 升级druid到最新版本v1.2.1
  54. +
  55. 升级fastjson到最新版1.2.74
  56. +
  57. 升级bootstrap-fileinput到最新版本5.1.2
  58. +
  59. 升级oshi到最新版本v5.2.5
  60. +
  61. 表单向导插件更换为jquery-smartwizard
  62. +
  63. 修改主子表提交示例代码防止渲染失效
  64. +
  65. 添加导入数据弹出窗体自定义宽高
  66. +
  67. 用户信息参数返回忽略掉密码字段
  68. +
  69. 优化关闭窗体添加index参数
  70. +
  71. 回显数据字典(字符串数组)增加空值判断
  72. +
  73. 修改前端密码长度校验和错误提示不符问题
  74. +
  75. AjaxResult重写put方法,以方便链式调用
  76. +
  77. 增强验证码校验的语义,更易懂
  78. +
  79. 导入excel整形值校验优化
  80. +
  81. Excel导出类型NUMERIC支持精度浮点类型
  82. +
  83. 导出Excel调整targetAttr获取值方法,防止get方法不规范
  84. +
  85. 输入框组验证错误后置图标提示颜色
  86. +
  87. 上传媒体类型添加视频格式
  88. +
  89. 数据权限判断参数类型
  90. +
  91. 修正数据库字符串类型nvarchar
  92. +
  93. 优化递归子节点
  94. +
  95. 修复多表格搜索formId无效
  96. +
  97. 其他细节优化
  98. +
+
+
+
+
+
+
+ v4.4.02020.08.24 +
+
+
+
+
    +
  1. 升级bootstrapTable到最新版本1.17.1
  2. +
  3. 升级shiro到最新版1.6.0 阻止权限绕过漏洞
  4. +
  5. 升级fastjson到最新版1.2.73
  6. +
  7. 代码生成支持同步数据库
  8. +
  9. 代码生成支持富文本控件
  10. +
  11. 用户密码支持自定义配置规则
  12. +
  13. 新增表格自动刷新插件
  14. +
  15. 新增表格打印配置插件
  16. +
  17. 更换图片裁剪工具为cropper
  18. +
  19. Excel支持sort导出排序
  20. +
  21. 代码生成支持自定义路径
  22. +
  23. 代码生成支持选择上级菜单
  24. +
  25. 代码生成支持上传控件
  26. +
  27. 新增表格参数(自定义加载文本的字体大小loadingFontSize)
  28. +
  29. Excel注解支持设置BigDecimal精度&舍入规则
  30. +
  31. 操作日志记录排除敏感属性字段
  32. +
  33. 修复不同浏览器附件下载中文名乱码的问题
  34. +
  35. 用户分配角色不允许选择超级管理员角色
  36. +
  37. 更换表格冻结列插件
  38. +
  39. 添加右侧冻结列示例
  40. +
  41. 升级表格行编辑&移动端适应插件
  42. +
  43. 修复更新表格插件后无法设置实例配置问题
  44. +
  45. 修复更新表格插件后导致的主子表错误
  46. +
  47. 修复页面存在多表格,回调函数res数据不正确问题
  48. +
  49. 强退&过期清理登录帐号缓存会话
  50. +
  51. 表格树标题内容支持html语义化标签
  52. +
  53. 修复配置应用的访问路径首页页签重复问题
  54. +
  55. 优化openTab打开时滚动到当前页签
  56. +
  57. 表格请求方式method支持自定义配置
  58. +
  59. 菜单页签联动优化
  60. +
  61. 用户邮箱长度限制修改为50
  62. +
  63. 主子表示例添加日期格式案例
  64. +
  65. 修改表格行内编辑示例旧值参数
  66. +
  67. 操作日志查询方式调整
  68. +
  69. 唯一限制条件只返回单条数据
  70. +
  71. 修改Excel设置STRING单元格类型
  72. +
  73. 添加获取当前的环境配置方法
  74. +
  75. 截取返回参数长度,防止超出异常
  76. +
  77. 定时任务cron表达式验证
  78. +
  79. 拆分表格插件,按需引入
  80. +
  81. 多行文本框补齐必填错误提示背景
  82. +
  83. 其他细节优化
  84. +
+
+
+
+
+
+
+ v4.3.12020.07.05 +
+
+
+
+
    +
  1. 国家信息安全漏洞(请务必保持cipherKey密钥唯一性)
  2. +
  3. 升级shiro到最新版1.5.3 阻止权限绕过漏洞
  4. +
  5. 修改验证码在使用后清除,防止多次使用
  6. +
  7. 检查字符支持小数点&降级改成异常提醒
  8. +
  9. openOptions函数中加入自定义maxmin属性
  10. +
  11. 支持openOptions方法最大化
  12. +
  13. 支持openOptions方法多个按钮回调
  14. +
  15. 新增isLinkage支持页签与菜单联动
  16. +
  17. 修改代码生成导入表结构出现异常页面不提醒问题
  18. +
  19. 优化用户头像发生错误,则显示一个默认头像
  20. +
  21. Excel导出支持字典类型
  22. +
+
+
+
+
+
+
+ v4.3.02020.06.22 +
+
+
+
+
    +
  1. 代码生成模板支持主子表
  2. +
  3. 代码生成显示类型支持复选框
  4. +
  5. 前端表单样式修改成圆角
  6. +
  7. 新增回显数据字典(字符串数组)
  8. +
  9. 修复浏览器手动缩放比例后菜单无法自适应问题
  10. +
  11. 限制用户不允许选择系统管理员角色
  12. +
  13. 用户信息添加输入框组图标&鼠标按下显示密码
  14. +
  15. 升级fastjson到最新版1.2.70 修复高危安全漏洞
  16. +
  17. 升级Bootstrap版本到v3.3.7
  18. +
  19. 修复selectColumns方法获取子对象数据无效问题
  20. +
  21. 修改数据源类型优先级,先根据方法,再根据类
  22. +
  23. 修改上级部门(选择项排除本身和下级)
  24. +
  25. 首页菜单显示调整
  26. +
  27. 添加是否开启swagger配置
  28. +
  29. 新增示例(主子表提交)
  30. +
  31. 新增示例(多级联动下拉示例)
  32. +
  33. 新增示例(表格属性data数据加载)
  34. +
  35. 新增表格列参数(是否列选项可见ignore)
  36. +
  37. 新增表格参数(是否启用显示卡片视图cardView)
  38. +
  39. 新增表格参数(是否显示全屏按钮showFullscreen)
  40. +
  41. 新增表格参数(是否启用分页条无限循环的功能paginationLoop)
  42. +
  43. 新增表格参数(是否显示表头showHeader)
  44. +
  45. 表格添加显示/隐藏所有列方法 showAllColumns/hideAllColumns
  46. +
  47. 修复部分情况节点不展开问题
  48. +
  49. 修复关闭标签页后刷新还是上次地址问题
  50. +
  51. 修复选择菜单后刷新页面,菜单箭头显示不对问题
  52. +
  53. 修复jquery表单序列化时复选框未选中不会序列化到对象中问题
  54. +
  55. Excel支持readConverterExp读取字符串组内容
  56. +
  57. 更换IP地址查询接口
  58. +
  59. 默认关闭获取ip地址
  60. +
  61. 操作处理ajaxSuccess判断修正
  62. +
  63. HttpUtils.sendPost()方法,参数无需拼接参数到url
  64. +
  65. 通用http发送方法增加参数 contentType 编码类型
  66. +
  67. HTML过滤器不替换&实体
  68. +
  69. 代码生成浮点型改用BigDecimal
  70. +
  71. 修复表单构建单选和多选框渲染问题
  72. +
  73. 代码生成模板调整,字段为String并且必填则加空串条件
  74. +
  75. 字典数据查询列表根据dictSort升序排序
  76. +
  77. 修复树表对imageView和tooltip方法无效问题
  78. +
  79. 修复Long类型比较相等问题调整
  80. +
  81. 示例demo页面清除html链接,防止点击后跳转出现404
  82. +
  83. 在线用户强退方法合并
  84. +
  85. 添加校验部门包含未停用的子部门
  86. +
  87. 取消回车自动提交表单
  88. +
  89. 'A','I','BUTTON' 标签忽略clickToSelect事件,防止点击操作按钮时选中
  90. +
  91. 邮箱显示截取部分字符串,防止低分辨率错位
  92. +
  93. 代码生成列属性根据sort排序
  94. +
  95. 修复更多操作部分浏览器不兼容情况
  96. +
  97. 图片预览事件属性修正
  98. +
  99. 修复冻结列排序样式无效问题
  100. +
  101. 修复context-path的情况下个人中心刷新导致样式问题
  102. +
  103. 全屏editFull打开适配表树
  104. +
  105. 其他细节优化
  106. +
+
+
+
+
+
+
+ v4.2.02020.03.23 +
+
+
+
+
    +
  1. 用户管理添加分配角色页面
  2. +
  3. 定时任务添加调度日志按钮
  4. +
  5. 新增是否开启用户注册功能
  6. +
  7. 新增页面滚动显示返回顶部按钮
  8. +
  9. 用户&角色&任务添加更多操作按钮
  10. +
  11. iframe框架页会话过期弹出超时提示
  12. +
  13. 移动端登录不显示左侧菜单
  14. +
  15. 侧边栏添加一套深蓝色主题
  16. +
  17. 首页logo固定,不随菜单滚动
  18. +
  19. 支持mode配置history(表示去掉地址栏的#)
  20. +
  21. 任务分组字典翻译(调度日志详细)
  22. +
  23. 字典管理添加缓存读取
  24. +
  25. 字典数据列表标签显示样式
  26. +
  27. 参数管理支持缓存操作
  28. +
  29. 日期控件清空结束时间设置开始默认值为2099-12-31
  30. +
  31. 表格树添加获取数据后响应回调处理
  32. +
  33. 批量替换表前缀调整
  34. +
  35. 支持表格导入模板的弹窗表单加入其它输入控件
  36. +
  37. 表单重置刷新表格树
  38. +
  39. 新增支持导出数据字段排序
  40. +
  41. 新增表格参数(是否单选checkbox)
  42. +
  43. druid未授权不允许访问
  44. +
  45. 表格树父节点兼容0,'0','',null
  46. +
  47. 表单必填的项添加星号
  48. +
  49. 修复select2不显示校验错误信息
  50. +
  51. 添加自定义HTML过滤器
  52. +
  53. 修复多数据源下开关关闭出现异常问题
  54. +
  55. 修复翻页记住选择项数据问题
  56. +
  57. 用户邮箱长度限制20
  58. +
  59. 修改错误页面返回主页出现嵌套问题
  60. +
  61. 表格浮动提示单双引号转义
  62. +
  63. 支持配置四级菜单
  64. +
  65. 升级shiro到最新版1.4.2 阻止rememberMe漏洞攻击
  66. +
  67. 升级summernote到最新版本v0.8.12
  68. +
  69. 导入Excel根据dateFormat属性格式处理
  70. +
  71. 修复War部署无法正常shutdown,ehcache内存泄漏
  72. +
  73. 修复代码生成短字段无法识别问题
  74. +
  75. 修复serviceImpl模版,修改方法判断日期错误
  76. +
  77. 代码生成模板增加导出功能日志记录
  78. +
  79. 代码生成唯一编号调整为tableId
  80. +
  81. 代码生成查询时忽略大小写
  82. +
  83. 代码生成支持翻页记住选中
  84. +
  85. 代码生成表注释未填写也允许导入
  86. +
  87. Global全局配置类修改为注解,防止多环境配置下读取问题
  88. +
  89. 修复多表格情况下,firstLoad只对第一个表格生效
  90. +
  91. 处理Maven打包出现警告问题
  92. +
  93. 默认主题样式,防止网速慢情况下出现空白
  94. +
  95. 修复文件上传多级目录识别问题
  96. +
  97. 锚链接解码url,防止中文导致页面不能加载问题
  98. +
  99. 修复右键Tab页刷新事件重复请求问题
  100. +
  101. 角色禁用&菜单隐藏不查询权限
  102. +
  103. 其他细节优化
  104. +
+
+
+
+
+
+
+ v4.1.02019.10.22 +
+
+
+
+
    +
  1. 支持多表格实例操作
  2. +
  3. 浮动提示方法tooltip支持弹窗
  4. +
  5. 代码生成&字典数据支持模糊条件查询
  6. +
  7. 增加页签全屏方法
  8. +
  9. 增加清除表单验证错误信息方法
  10. +
  11. 支持iframe局部刷新页面
  12. +
  13. 支持在线切换主题
  14. +
  15. 修改图片预览设置的高宽参数颠倒问题
  16. +
  17. 操作日志新增解锁账户功能
  18. +
  19. 管理员用户&角色不允许操作
  20. +
  21. 去掉jsoup包调用自定义转义工具
  22. +
  23. 添加时间轴示例
  24. +
  25. 修复翻页记住选择时获取指定列值的问题
  26. +
  27. 代码生成sql脚本添加导出按钮
  28. +
  29. 添加表格父子视图示例
  30. +
  31. 添加表格行内编辑示例
  32. +
  33. 升级fastjson到最新版1.2.60 阻止漏洞攻击
  34. +
  35. 升级echarts到最新版4.2.1
  36. +
  37. 操作日志新增返回参数
  38. +
  39. 支持mybatis通配符扫描任意多个包
  40. +
  41. 权限验证多种情况处理
  42. +
  43. 修复树形类型的代码生成的部分必要属性无法显示
  44. +
  45. 修复非表格插件情况下重置出现异常
  46. +
  47. 修复富文本编辑器有序列表冲突
  48. +
  49. 代码生成表前缀配置支持多个
  50. +
  51. 修复自动去除表前缀配置无效问题
  52. +
  53. 菜单列表按钮数据可见不显示(权限标识控制)
  54. +
  55. 修复设置会话超时时间无效问题
  56. +
  57. 新增本地资源通用下载方法
  58. +
  59. 操作日志记录新增请求方式
  60. +
  61. 代码生成单选按钮属性重名修复
  62. +
  63. 优化select2下拉框宽度不会随浏览器改变
  64. +
  65. 修复代码生成树表异常
  66. +
  67. 其他细节优化
  68. +
+
+
+
+
+
+
+ v4.0.02019.08.08 +
+
+
+
+
    +
  1. 代码生成支持预览、编辑,保存方案
  2. +
  3. 新增防止表单重复提交注解
  4. +
  5. 新增后端校验(和前端保持一致)
  6. +
  7. 新增同一个用户最大会话数控制
  8. +
  9. Excel导出子对象支持多个字段
  10. +
  11. 定时任务支持静态调用和多参数
  12. +
  13. 定时任务增加分组条件查询
  14. +
  15. 字典类型增加任务分组数据
  16. +
  17. 新增表格是否首次加载数据
  18. +
  19. 新增parentTab选项卡可在同一页签打开
  20. +
  21. 多数据源支持类注解(允许继承父类的注解)
  22. +
  23. 部门及以下数据权限(调整为以下及所有子节点)
  24. +
  25. 新增角色数据权限配(仅本人数据权限)
  26. +
  27. 修改菜单权限显示问题
  28. +
  29. 上传文件修改路径及返回名称
  30. +
  31. 添加报表插件及示例
  32. +
  33. 添加首页统计模板
  34. +
  35. 添加表格拖拽示例
  36. +
  37. 添加卡片列表示例
  38. +
  39. 添加富文本编辑器示例
  40. +
  41. 添加表格动态增删改查示例
  42. +
  43. 添加用户页面岗位选择框提示
  44. +
  45. 点击菜单操作添加背景高亮显示
  46. +
  47. 表格树新增showSearch是否显示检索信息
  48. +
  49. 解决表格列设置sortName无效问题
  50. +
  51. 表格图片预览支持自定义设置宽高
  52. +
  53. 添加表格列浮动提示(单击文本复制)
  54. +
  55. PC端收起菜单后支持浮动显示
  56. +
  57. 详细操作样式调整
  58. +
  59. 修改用户更新描述空串不更新问题
  60. +
  61. 导入修改为模板渲染
  62. +
  63. 修改菜单及部门排序规则
  64. +
  65. 角色导出数据范围表达式翻译
  66. +
  67. 添加summernote富文本字体大小
  68. +
  69. 优化表格底部下边框防重叠&汇总像素问题
  70. +
  71. 树表格支持属性多层级访问
  72. +
  73. 修复IE浏览器用户管理界面右侧留白问题
  74. +
  75. 重置按钮刷新表格
  76. +
  77. 重置密码更新用户缓存
  78. +
  79. 优化验证码属性参数
  80. +
  81. 支持数据监控配置用户名和密码
  82. +
  83. 文件上传修改按钮背景及加载动画
  84. +
  85. 支持配置一级菜单href跳转
  86. +
  87. 侧边栏添加一套浅色主题
  88. +
  89. 树表格添加回调函数(校验异常状态)
  90. +
  91. 用户个人中心适配手机端显示
  92. +
  93. Excel支持设置导出类型&更换样式
  94. +
  95. 检查属性改变修改为克隆方式(防止热部署强转异常)
  96. +
  97. 其他细节优化
  98. +
+
+
+
+
+
+
+ v3.4.02019.06.03 +
+
+
+
+
    +
  1. 新增实例演示菜单及demo
  2. +
  3. 新增页签右键操作
  4. +
  5. 菜单管理新增打开方式
  6. +
  7. 新增点击某行触发的事件
  8. +
  9. 新增双击某行触发的事件
  10. +
  11. 新增单击某格触发的事件
  12. +
  13. 新增双击某格触发的事件
  14. +
  15. 新增是否启用显示细节视图
  16. +
  17. 支持上传任意格式文件
  18. +
  19. 修复角色权限注解失效问题
  20. +
  21. 左侧的菜单栏宽度调整
  22. +
  23. 新增响应完成后自定义回调函数
  24. +
  25. 支持前端及其他模块直接获取用户信息
  26. +
  27. 升级swagger到最新版2.9.2
  28. +
  29. 升级jquery.slimscroll到最新版1.3.8
  30. +
  31. 升级select2到最新版4.0.7
  32. +
  33. 新增角色配置本部门数据权限
  34. +
  35. 新增角色配置本部门及以下数据权限
  36. +
  37. 优化底部操作防止跳到页面顶端
  38. +
  39. 修改冻结列选框无效及样式问题
  40. +
  41. 修复部门四层级修改祖级无效问题
  42. +
  43. 更换开关切换按钮样式
  44. +
  45. 新增select2-bootstrap美化下拉框
  46. +
  47. 添加表格内图片预览方法
  48. +
  49. 修复权限校验失败跳转页面路径错误
  50. +
  51. 国际化资源文件调整
  52. +
  53. 通知公告布局调整
  54. +
  55. 删除页签操作功能
  56. +
  57. 表格树新增查询指定列值
  58. +
  59. 更改系统接口扫描方式及完善测试案例
  60. +
  61. 表格列浮动提示及字典回显默认去背景
  62. +
  63. 修复启用翻页记住前面的选择check没选中问题
  64. +
  65. 去除监控页面底部的广告
  66. +
  67. 日期控件功问题修复及data功能增强
  68. +
  69. 新增角色权限可见性(前端直接调用)
  70. +
  71. 新增获取当前登录用户方法(前端及子模块调用)
  72. +
  73. 修复热部署重启导致菜单丢失问题
  74. +
  75. 优化业务校验失败普通请求跳转页面
  76. +
  77. 操作日志新增状态条件查询
  78. +
  79. 操作类型支持多选条件查询
  80. +
  81. 通知公告防止滚动触底回弹优化
  82. +
  83. 其他细节优化
  84. +
+
+
+
+
+
+
+ v3.3.02019.04.01 +
+
+
+
+
    +
  1. 新增线程池统一管理
  2. +
  3. 新增支持左右冻结列
  4. +
  5. 新增表格字符超长浮动提示
  6. +
  7. 升级datepicker拓展并汉化
  8. +
  9. 升级druid到最新版本v1.1.14
  10. +
  11. 修复个人头像为图片服务器跨域问题
  12. +
  13. 修改上传文件按日期存储
  14. +
  15. 新增表格客户端分页选项
  16. +
  17. 新增表格的高度参数
  18. +
  19. 新增表格销毁方法
  20. +
  21. 新增表格下拉按钮切换方法
  22. +
  23. 新增表格分页跳转到指定页码
  24. +
  25. 新增表格启用点击选中行参数
  26. +
  27. 修复表格数据重新加载未触发部分按钮禁用
  28. +
  29. 使用jsonview展示操作日志参数
  30. +
  31. 新增方法(addTab、editTab)
  32. +
  33. 修改用户管理界面为Tab打开方式
  34. +
  35. 表单验证代码优化
  36. +
  37. 修复@Excel注解 prompt 属性使用报错
  38. +
  39. 修复combo属性Excel兼容性问题
  40. +
  41. 新增@Excel导入导出支持父类字段
  42. +
  43. 修复关闭最后选项卡无法激活滚动问题
  44. +
  45. 增加日期控件显示类型及回显格式扩展选项
  46. +
  47. 修复定时任务执行失败后入库状态为成功状态
  48. +
  49. 支持定时任务并发开关控制
  50. +
  51. 优化权限校验失败普通请求跳转页面
  52. +
  53. 捕获线程池执行任务抛出的异常
  54. +
  55. 修复IE浏览器导出功能报错
  56. +
  57. 新增角色管理分配用户功能
  58. +
  59. 新增表格翻页记住前面的选择
  60. +
  61. 调整用户个人中心页面
  62. +
  63. 修复界面存在的一些安全问题
  64. +
  65. 其他细节优化
  66. +
+
+
+
+
+
+
+ v3.2.02019.01.18 +
+
+
+
+
    +
  1. 部门修改时不允许选择最后节点
  2. +
  3. 修复部门菜单排序字段无效
  4. +
  5. 修复光驱磁盘导致服务监控异常
  6. +
  7. 登录界面去除check插件
  8. +
  9. 验证码文本字符间距修正
  10. +
  11. 升级SpringBoot到最新版本2.1.1
  12. +
  13. 升级MYSQL驱动
  14. +
  15. 修正登录必填项位置偏移
  16. +
  17. Session会话检查优化
  18. +
  19. Excel注解支持多级获取
  20. +
  21. 新增序列号生成方法
  22. +
  23. 修复WAR部署tomcat退出线程异常
  24. +
  25. 全屏操作增加默认确认/关闭
  26. +
  27. 修复个人信息可能导致漏洞
  28. +
  29. 字典数据根据下拉选择新增类型
  30. +
  31. 升级Summernote到最新版本v0.8.11
  32. +
  33. 新增用户数据导入
  34. +
  35. 首页主题样式更换
  36. +
  37. layer扩展主题更换
  38. +
  39. 用户管理移动端默认隐藏左侧布局
  40. +
  41. 详细信息弹出层显示在顶层
  42. +
  43. 表格支持切换状态(用户/角色/定时任务)
  44. +
  45. Druid数据源支持配置继承
  46. +
  47. 修正部分iPhone手机端表格适配问题
  48. +
  49. 新增防止重复提交表单方法
  50. +
  51. 新增表格数据统计汇总方法
  52. +
  53. 支持富文本上传图片文件
  54. +
+
+
+
+
+
+
+ v3.1.02018.12.03 +
+
+
+
+
    +
  1. 新增内网不获取IP地址
  2. +
  3. 新增cron表达式有效校验
  4. +
  5. 定时任务新增详细信息
  6. +
  7. 定时任务默认策略修改(不触发立即执行)
  8. +
  9. 定时任务显示下一个执行周期
  10. +
  11. 支持前端任意日期格式处理
  12. +
  13. 上传头像删除多余提交按钮
  14. +
  15. 表格增加行间隔色配置项
  16. +
  17. 表格增加转义HTML字符串配置项
  18. +
  19. 表格增加显示/隐藏指定列
  20. +
  21. 代码生成优化
  22. +
  23. 操作日志参数格式化显示
  24. +
  25. 页签新增新增全屏显示
  26. +
  27. 新增一键打包部署
  28. +
  29. Excel注解新增多个参数
  30. +
  31. 新增提交静默更新表格方法
  32. +
  33. 新增服务监控菜单
  34. +
+
+
+
+
+
+
+ v3.0.02018.10.08 +
+
+
+
+
    +
  1. 升级poi到最新版3.17
  2. +
  3. 导出修改临时目录绝对路径
  4. +
  5. 升级laydate到最新版5.0.9
  6. +
  7. 升级SpringBoot到最新版本2.0.5
  8. +
  9. 优化开始/结束时间校验限制
  10. +
  11. 重置密码参数表中获取默认值
  12. +
  13. 修复头像修改显示问题
  14. +
  15. 新增数据权限过滤注解
  16. +
  17. 新增表格检索折叠按钮
  18. +
  19. 新增清空(登录、操作、调度)日志
  20. +
  21. 固定按钮位置(提交/关闭)
  22. +
  23. 部门/菜单支持(展开/折叠)
  24. +
  25. 部分细节调整优化
  26. +
  27. 项目采用分模块
  28. +
+
+
+
+
+
+
+ v2.4.02018.09.03 +
+
+
+
+
    +
  1. 支持部门多级查询
  2. +
  3. 修复菜单状态查询无效
  4. +
  5. 支持IP地址开关
  6. +
  7. 支持XSS开关
  8. +
  9. 记录日志异步处理
  10. +
  11. 字典回显样式更改为下拉框
  12. +
  13. 菜单类型必填校验
  14. +
  15. 修复在线用户排序报错
  16. +
  17. 增加重置按钮
  18. +
  19. 支持注解导入数据
  20. +
  21. 支持弹层外区域关闭
  22. +
  23. 备注更换为文本区域
  24. +
  25. 新增角色逻辑删除
  26. +
  27. 新增部门逻辑删除
  28. +
  29. 支持部门数据权限
  30. +
  31. 管理员默认拥有所有授权
  32. +
  33. 字典数据采用分页
  34. +
  35. 部分细节调整优化
  36. +
+
+
+
+
+
+
+ v2.3.02018.08.06 +
+
+
+
+
    +
  1. 支持表格不分页开关控制
  2. +
  3. 修改字典类型同步修改字典数据
  4. +
  5. 代码生成新增修改后缀处理
  6. +
  7. 代码生成新增实体toString
  8. +
  9. 代码生成非字符串去除!=''
  10. +
  11. 导出数据前加载遮罩层
  12. +
  13. 部门删除校验条件修改
  14. +
  15. 搜索查询下载优化
  16. +
  17. 手机打开弹出层自适应
  18. +
  19. 角色岗位禁用显示置灰
  20. +
  21. 角色禁用不显示菜单
  22. +
  23. 新增导出权限
  24. +
  25. 角色权限唯一校验
  26. +
  27. 岗位名称编码唯一校验
  28. +
  29. TreeTable优化
  30. +
  31. 支持多数据源
  32. +
  33. 其他细节优化
  34. +
+
+
+
+
+
+
+ v2.2.02018.07.23 +
+
+
+
+
    +
  1. 修复批量生成代码异常问题
  2. +
  3. 修复定时器保存失败问题
  4. +
  5. 修复热部署转换问题
  6. +
  7. 支持查询菜单管理,部门管理
  8. +
  9. 大多数功能支持时间查询
  10. +
  11. 自定义导出注解自动匹配column
  12. +
  13. 新增任务执行策略
  14. +
  15. 操作详细动态显示类型
  16. +
  17. 支持动态回显字典数据
  18. +
  19. 后台代码优化调整
  20. +
  21. 其他细节优化
  22. +
+
+
+
+
+
+
+ v2.1.02018.07.10 +
+
+
+
+
    +
  1. 新增登录超时提醒
  2. +
  3. 修复定时器热部署转换问题
  4. +
  5. 修复登录验证码校验无效问题
  6. +
  7. 定时任务新增立即执行一次
  8. +
  9. 存在字典数据不允许删除字典
  10. +
  11. 字典数据支持按名称查询
  12. +
  13. 代码生成增加日志注解&表格优化
  14. +
  15. 修复用户逻辑删除后能登录问题
  16. +
  17. 表格支持多字段动态排序
  18. +
  19. 支持三级菜单显示
  20. +
  21. 新增ry.sh启动程序脚本
  22. +
  23. 其他细节优化
  24. +
+
+
+
+
+
+
+ v2.0.02018.07.02 +
+
+
+
+
    +
  1. 升级SpringBoot到最新版本2.0.3
  2. +
  3. 新增公告管理
  4. +
  5. 表单校验示提体验优化
  6. +
  7. 前端通用方法封装调整
  8. +
  9. 前端去除js文件,合并到html
  10. +
  11. 操作加载遮罩层
  12. +
  13. 支持全屏模式操作
  14. +
  15. 支持注解导出数据
  16. +
  17. 系统支持多查询&下载
  18. +
  19. 系统样式调整
  20. +
+
+
+
+
+
+
+ v1.1.62018.06.04 +
+
+
+
+
    +
  1. 新增用户列表部门列
  2. +
  3. 新增登录地点
  4. +
  5. 新增swagger
  6. +
  7. 修复排序数字校验
  8. +
  9. 优化头像上传文件类型限定为图片
  10. +
  11. 新增XSS过滤
  12. +
  13. 新增热部署提高开发效率
  14. +
  15. 修复treegrid居中无效
  16. +
  17. 角色多条件查询
  18. +
+
+
+
+
+
+
+ v1.1.52018.05.28 +
+
+
+
+
    +
  1. 优化登录失败刷新验证码
  2. +
  3. 新增用户登录地址时间
  4. +
  5. 修复ajax超时退出问题
  6. +
  7. 新增html调用数据字典(若依首创)
  8. +
  9. 调整系统部分样式
  10. +
  11. 新增用户逻辑删除
  12. +
  13. 新增管理员不允许删除修改
  14. +
  15. 升级bootstrapTable到最新版本1.12.1
  16. +
  17. 升级layer到最新版本3.1.1
  18. +
+
+
+
+
+
+
+ v1.1.42018.05.20 +
+
+
+
+
    +
  1. 新增参数管理
  2. +
  3. 修复头像上传bug
  4. +
  5. 手机邮箱唯一校验
  6. +
  7. 支持手机邮箱登录
  8. +
  9. 代码生成优化
  10. +
  11. 支持模糊查询
  12. +
  13. 支持切换主题皮肤
  14. +
  15. 修改权限即时生效
  16. +
  17. 修复页签Tab关闭问题
  18. +
+
+
+
+
+
+
+ v1.1.32018.05.14 +
+
+
+
+
    +
  1. 新增验证码(数组计算、字符验证)
  2. +
  3. 新增cookie记住我
  4. +
  5. 新增头像上传
  6. +
  7. 用户名密码长度限制
  8. +
  9. 通用字段提取
  10. +
  11. 支持自定义条件查询
  12. +
  13. 部门名称必填、时间格式调整
  14. +
  15. 其他细节优化
  16. +
+
+
+
+
+
+
+ v1.1.22018.05.07 +
+
+
+
+
    +
  1. 新增个人信息修改
  2. +
  3. 菜单存在子菜单不允许删除
  4. +
  5. 菜单分配角色不允许删除
  6. +
  7. 角色分配人员不允许删除
  8. +
  9. 岗位使用后不允许删除
  10. +
  11. 保证用户的数据完整性加入事物
  12. +
  13. 新增环境使用手册、数据建模
  14. +
  15. Thymeleaf升级到3.0
  16. +
  17. 支持非ROOT部署
  18. +
+
+
+
+
+
+
+ v1.1.12018.04.23 +
+
+
+
+
    +
  1. 新增表单构建器
  2. +
  3. 代码生成优化
  4. +
  5. 支持新增主部门
  6. +
  7. 支持选择上级部门、上级菜单
  8. +
  9. 新增字典管理单条删除
  10. +
  11. 优化一些其他细节
  12. +
+
+
+
+
+
+
+ v1.1.02018.04.20 +
+
+
+
+
    +
  1. 支持密码盐
  2. +
  3. 支持新增主目录
  4. +
  5. 支持批量生成代码
  6. +
  7. 支持表格导出(csv、txt、doc、excel)
  8. +
  9. 自动适应宽高模式窗体
  10. +
  11. 重复校验(角色名、菜单名、部门名)
  12. +
  13. 优化一些其他细节
  14. +
+
+
+
+
+
+
+ v1.0.92018.04.14 +
+
+
+
+
    +
  1. 新增代码生成(生成包括 java、html、js、xml、sql)
  2. +
  3. 新增按钮权限控制隐藏(若依首创)
  4. +
+
+
+
+
+
+
+ v1.0.82018.04.08 +
+
+
+
+
    +
  1. 新增定时任务(新增、修改、删除、查询、启动/暂停)
  2. +
  3. 新增调度日志(查询、删除)
  4. +
+
+
+
+
+
+
+ v1.0.72018.04.04 +
+
+
+
+
    +
  1. 新增岗位管理(新增、修改、删除、查询)
  2. +
  3. 优化用户管理,菜单管理部分细节
  4. +
+
+
+
+
+
+
+ v1.0.62018.03.15 +
+
+
+
+
    +
  1. 新增字典管理(新增、删除、修改、查询、数据选择)
  2. +
  3. 新增用户密码重置
  4. +
  5. 优化一些其他细节
  6. +
+
+
+
+
+
+
+ v1.0.52018.03.12 +
+
+
+
+
    +
  1. 新增菜单管理(新增、删除、修改、查询、图标选择)
  2. +
  3. 部门管理优化(添加责任人、联系电话、邮箱、修改者)
  4. +
+
+
+
+
+
+
+ v1.0.42018.03.11 +
+
+
+
+
    +
  1. 新增角色管理(新增、删除、修改、查询、菜单选择)
  2. +
+
+
+
+
+
+
+ v1.0.32018.03.08 +
+
+
+
+
    +
  1. 新增用户管理(新增、删除、修改、查询、部门选择)
  2. +
+
+
+
+
+
+
+ v1.0.22018.03.04 +
+
+
+
+
    +
  1. 新增部门管理 (新增、删除、修改、查询)
  2. +
+
+
+
+
+
+
+ v1.0.12018.03.03 +
+
+
+
+
    +
  1. 新增在线用户 (批量强退、单条强退、查询)
  2. +
  3. 新增登录日志 (批量删除、查询)
  4. +
  5. 新增操作日志 (批量删除、查询、详细)
  6. +
  7. 新增数据监控 (监控DB池连接和SQL的执行)
  8. +
+
+
+
+
+
+

+ v1.0.02018.03.01 +

+
+
+
+
    +
  1. 若依管理系统正式发布。
  2. +
+
+
+
+
+
+
+
+
+
+
+
+
捐赠
+
+
+
+ 请作者喝杯咖啡(点击图片放大) +
+

+ 请使用手机支付宝或者微信扫码支付 + +

+ +
+
+
+
+
+ + + + + + diff --git a/ruoyi-admin/src/main/resources/templates/main_v1.html b/ruoyi-admin/src/main/resources/templates/main_v1.html deleted file mode 100644 index f0e434bc..00000000 --- a/ruoyi-admin/src/main/resources/templates/main_v1.html +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - 统计 - - - - - - - - -
- -
-
-
-
- -
收入
-
-
-

40 886,200

-
98% -
- 总收入 -
-
-
-
-
-
- 全年 -
订单
-
-
-

275,800

-
20% -
- 新订单 -
-
-
-
-
-
- 今天 -
访客
-
-
-

106,120

-
44% -
- 新访客 -
-
-
-
-
-
- 最近一个月 -
活跃用户
-
-
-

80,600

-
38% -
- 12月 -
-
-
-
- -
-
-
-
-
订单
-
-
- - - -
-
-
-
-
-
-
-
-
-
-
-
    -
  • -

    2,346

    - 订单总数 -
    48% -
    -
    -
    -
    -
  • -
  • -

    4,422

    - 最近一个月订单 -
    60% -
    -
    -
    -
    -
  • -
  • -

    9,180

    - 最近一个月销售额 -
    22% -
    -
    -
    -
    -
  • -
-
-
-
-
-
-
- -
-
-
-
-
用户项目列表
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
状态日期用户
进行中... - 11:20青衣5858 24%
已取消 - 10:40徐子崴 66%
进行中... - 01:30姜岚昕 54%
进行中... - 02:20武汉大兵哥 12%
进行中... - 09:40荆莹儿 22%
已完成 - 04:10栾某某 66%
进行中... - 12:08范范范二妮 23%
-
-
-
-
-
- - - - - - - - - diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 7148fca3..a7622fb8 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -34,7 +34,7 @@ org.apache.shiro shiro-core - + org.apache.shiro @@ -101,6 +101,13 @@ javax.servlet-api + + + cn.hutool + hutool-json + 5.4.0 + + \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java index ebd301ea..74377b14 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java @@ -30,6 +30,8 @@ public class AjaxResult extends HashMap SUCCESS(0), /** 警告 */ WARN(301), + /** 未登录或无权限 */ + FORBIDDEN(403), /** 错误 */ ERROR(500); private final int value; @@ -193,4 +195,8 @@ public class AjaxResult extends HashMap { return new AjaxResult(Type.ERROR, msg, data); } + + public static AjaxResult notLogin(){ + return new AjaxResult(Type.FORBIDDEN, "未登录或权限不足"); + } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/wx/NotLoginException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/wx/NotLoginException.java new file mode 100644 index 00000000..9c3ff2bd --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/wx/NotLoginException.java @@ -0,0 +1,8 @@ +package com.ruoyi.common.exception.wx; + +/** + * 未登录异常 + */ +public class NotLoginException extends RuntimeException{ + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/wx/WxBusinessException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/wx/WxBusinessException.java new file mode 100644 index 00000000..143e04ca --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/wx/WxBusinessException.java @@ -0,0 +1,9 @@ +package com.ruoyi.common.exception.wx; + +import com.ruoyi.common.exception.base.BaseException; + +public class WxBusinessException extends BaseException { + public WxBusinessException(String defaultMessage) { + super(defaultMessage); + } +} diff --git a/ruoyi-framework/pom.xml b/ruoyi-framework/pom.xml index 9287ec41..c422304c 100644 --- a/ruoyi-framework/pom.xml +++ b/ruoyi-framework/pom.xml @@ -77,6 +77,12 @@ ruoyi-system + + + com.ruoyi + wx-record-order + + \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java index 4a1c6310..61b7c9d8 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java @@ -3,10 +3,7 @@ package com.ruoyi.framework.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.config.annotation.*; import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.constant.Constants; import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor; @@ -56,4 +53,13 @@ public class ResourcesConfig implements WebMvcConfigurer { registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**"); } + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/wx/api/**") + .allowedOrigins("*") + .allowedMethods("OPTIONS", "POST", "GET", "DELETE") + .allowedHeaders("Origin", "Content-Type", "Accept", "token") + .allowCredentials(true) + .maxAge(3600); + } } \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java index d6feedb8..b8d351a8 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java @@ -279,6 +279,10 @@ public class ShiroConfig filterChainDefinitionMap.put("/js/**", "anon"); filterChainDefinitionMap.put("/ruoyi/**", "anon"); filterChainDefinitionMap.put("/captcha/captchaImage**", "anon"); + + filterChainDefinitionMap.put("/wx/api/**", "anon"); + filterChainDefinitionMap.put("/s/**", "anon"); + // 退出 logout地址,shiro去清除session filterChainDefinitionMap.put("/logout", "logout"); // 不需要拦截的访问 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java index 2ff35774..15336058 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java @@ -1,6 +1,12 @@ package com.ruoyi.framework.web.exception; -import javax.servlet.http.HttpServletRequest; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.BusinessException; +import com.ruoyi.common.exception.DemoModeException; +import com.ruoyi.common.exception.wx.NotLoginException; +import com.ruoyi.common.exception.wx.WxBusinessException; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.security.PermissionUtils; import org.apache.shiro.authz.AuthorizationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -9,35 +15,27 @@ import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.ModelAndView; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.exception.BusinessException; -import com.ruoyi.common.exception.DemoModeException; -import com.ruoyi.common.utils.ServletUtils; -import com.ruoyi.common.utils.security.PermissionUtils; + +import javax.servlet.http.HttpServletRequest; /** * 全局异常处理器 - * + * * @author ruoyi */ @RestControllerAdvice -public class GlobalExceptionHandler -{ +public class GlobalExceptionHandler { private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); /** * 权限校验失败 如果请求为ajax返回json,普通请求跳转页面 */ @ExceptionHandler(AuthorizationException.class) - public Object handleAuthorizationException(HttpServletRequest request, AuthorizationException e) - { + public Object handleAuthorizationException(HttpServletRequest request, AuthorizationException e) { log.error(e.getMessage(), e); - if (ServletUtils.isAjaxRequest(request)) - { + if (ServletUtils.isAjaxRequest(request)) { return AjaxResult.error(PermissionUtils.getMsg(e.getMessage())); - } - else - { + } else { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error/unauth"); return modelAndView; @@ -47,9 +45,8 @@ public class GlobalExceptionHandler /** * 请求方式不支持 */ - @ExceptionHandler({ HttpRequestMethodNotSupportedException.class }) - public AjaxResult handleException(HttpRequestMethodNotSupportedException e) - { + @ExceptionHandler({HttpRequestMethodNotSupportedException.class}) + public AjaxResult handleException(HttpRequestMethodNotSupportedException e) { log.error(e.getMessage(), e); return AjaxResult.error("不支持' " + e.getMethod() + "'请求"); } @@ -58,8 +55,7 @@ public class GlobalExceptionHandler * 拦截未知的运行时异常 */ @ExceptionHandler(RuntimeException.class) - public AjaxResult notFount(RuntimeException e) - { + public AjaxResult notFount(RuntimeException e) { log.error("运行时异常:", e); return AjaxResult.error("运行时异常:" + e.getMessage()); } @@ -68,8 +64,7 @@ public class GlobalExceptionHandler * 系统异常 */ @ExceptionHandler(Exception.class) - public AjaxResult handleException(Exception e) - { + public AjaxResult handleException(Exception e) { log.error(e.getMessage(), e); return AjaxResult.error("服务器错误,请联系管理员"); } @@ -78,15 +73,11 @@ public class GlobalExceptionHandler * 业务异常 */ @ExceptionHandler(BusinessException.class) - public Object businessException(HttpServletRequest request, BusinessException e) - { + public Object businessException(HttpServletRequest request, BusinessException e) { log.error(e.getMessage(), e); - if (ServletUtils.isAjaxRequest(request)) - { + if (ServletUtils.isAjaxRequest(request)) { return AjaxResult.error(e.getMessage()); - } - else - { + } else { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("errorMessage", e.getMessage()); modelAndView.setViewName("error/business"); @@ -98,8 +89,7 @@ public class GlobalExceptionHandler * 自定义验证异常 */ @ExceptionHandler(BindException.class) - public AjaxResult validatedBindException(BindException e) - { + public AjaxResult validatedBindException(BindException e) { log.error(e.getMessage(), e); String message = e.getAllErrors().get(0).getDefaultMessage(); return AjaxResult.error(message); @@ -109,8 +99,20 @@ public class GlobalExceptionHandler * 演示模式异常 */ @ExceptionHandler(DemoModeException.class) - public AjaxResult demoModeException(DemoModeException e) - { + public AjaxResult demoModeException(DemoModeException e) { return AjaxResult.error("演示模式,不允许操作"); } + + /** + * 小程序未登录异常 + */ + @ExceptionHandler(NotLoginException.class) + public AjaxResult notLoginException() { + return AjaxResult.notLogin(); + } + + @ExceptionHandler(WxBusinessException.class) + public AjaxResult wxBusinessException(WxBusinessException e) { + return AjaxResult.error(e.getMessage()); + } } diff --git a/wx-record-order/doc/docus.cn.csr b/wx-record-order/doc/docus.cn.csr new file mode 100644 index 00000000..e69de29b diff --git a/wx-record-order/doc/docus.cn.key b/wx-record-order/doc/docus.cn.key new file mode 100644 index 00000000..e69de29b diff --git a/wx-record-order/doc/docus.cn.pem b/wx-record-order/doc/docus.cn.pem new file mode 100644 index 00000000..e69de29b diff --git a/wx-record-order/doc/wx.docus.cn.csr b/wx-record-order/doc/wx.docus.cn.csr new file mode 100644 index 00000000..e69de29b diff --git a/wx-record-order/doc/wx.docus.cn.key b/wx-record-order/doc/wx.docus.cn.key new file mode 100644 index 00000000..e69de29b diff --git a/wx-record-order/doc/wx.docus.cn.pem b/wx-record-order/doc/wx.docus.cn.pem new file mode 100644 index 00000000..e69de29b diff --git a/wx-record-order/doc/小程序表设计.xlsx b/wx-record-order/doc/小程序表设计.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..37f14f5fcb1d14f14388ca658eff0101d27febe2 GIT binary patch literal 11638 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 WS98Wp + + + ruoyi + com.ruoyi + 4.6.0 + + 4.0.0 + + wx-record-order + + + 8 + 8 + + + + + com.ruoyi + ruoyi-common + + + + + com.github.binarywang + weixin-java-miniapp + 4.0.0 + + + + com.aliyun + dysmsapi20170525 + 2.0.1 + + + com.aliyun + tea + 1.1.8 + + + + \ No newline at end of file diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/controller/ApiRestController.java b/wx-record-order/src/main/java/com/ruoyi/wx/controller/ApiRestController.java new file mode 100644 index 00000000..22e8c5d4 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/controller/ApiRestController.java @@ -0,0 +1,63 @@ +package com.ruoyi.wx.controller; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.wx.domain.MrRecordOrder; +import com.ruoyi.wx.dto.req.OrderListReqDTO; +import com.ruoyi.wx.dto.req.UserSignInfo; +import com.ruoyi.wx.service.IMrRecordOrderService; +import com.ruoyi.wx.service.IWxUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("wx/api/") +public class ApiRestController { + @Autowired + private IWxUserService wxUserService; + + @Autowired + private IMrRecordOrderService mrRecordOrderService; + + /** + * 小程序授权时调用 + */ + @PostMapping("autoLogin") + public AjaxResult autoLogin(String wxCode) { + return AjaxResult.success(wxUserService.login(wxCode)); + } + + /** + * 小程序提交审核时发起 + * 更新用户的基本信息 + */ + @PostMapping("signIn") + public AjaxResult signIn(@RequestBody UserSignInfo userSignInfo) { + wxUserService.signIn(userSignInfo); + return AjaxResult.success(); + } + + /** + * 获取用户审核状态,并更新用户资料 + */ + @PostMapping("info") + public AjaxResult info(@RequestBody UserSignInfo userSignInfo) { + return AjaxResult.success(wxUserService.info(userSignInfo)); + } + + /** + * 提交申请 + */ + @PostMapping("order") + public AjaxResult order(@RequestBody MrRecordOrder order) { + mrRecordOrderService.createOrder(order); + return AjaxResult.success(); + } + + /** + * 查询申请列表 + */ + @PostMapping("orderList") + public AjaxResult orderList(@RequestBody OrderListReqDTO orderListReqDTO) { + return AjaxResult.success(mrRecordOrderService.list(orderListReqDTO)); + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/controller/MrRecordOrderController.java b/wx-record-order/src/main/java/com/ruoyi/wx/controller/MrRecordOrderController.java new file mode 100644 index 00000000..fee075e4 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/controller/MrRecordOrderController.java @@ -0,0 +1,151 @@ +package com.ruoyi.wx.controller; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.wx.domain.MrRecordOrder; +import com.ruoyi.wx.service.IMrRecordOrderService; +import com.ruoyi.wx.util.ShortUrlUtils; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.List; + +/** + * 病案申请Controller + * + * @author ruoyi + * @date 2021-02-24 + */ +@Controller +@RequestMapping("/wx/order") +public class MrRecordOrderController extends BaseController { + private String prefix = "wx/order"; + + @Value("${server.servlet.domain}") + private String domain; + + @Autowired + private IMrRecordOrderService mrRecordOrderService; + + @RequiresPermissions("wx:order:view") + @GetMapping() + public String order() { + return prefix + "/order"; + } + + /** + * 查询病案申请列表 + */ + @RequiresPermissions("wx:order:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(MrRecordOrder mrRecordOrder) { + startPage(); + List list = mrRecordOrderService.selectMrRecordOrderList(mrRecordOrder); + return getDataTable(list); + } + + /** + * 导出病案申请列表 + */ + @RequiresPermissions("wx:order:export") + @Log(title = "病案申请", businessType = BusinessType.EXPORT) + @PostMapping("/export") + @ResponseBody + public AjaxResult export(MrRecordOrder mrRecordOrder) { + List list = mrRecordOrderService.selectMrRecordOrderList(mrRecordOrder); + ExcelUtil util = new ExcelUtil(MrRecordOrder.class); + return util.exportExcel(list, "order"); + } + + /** + * 新增病案申请 + */ + @GetMapping("/add") + public String add() { + return prefix + "/add"; + } + + /** + * 新增保存病案申请 + */ + @RequiresPermissions("wx:order:add") + @Log(title = "病案申请", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(MrRecordOrder mrRecordOrder) { + return toAjax(mrRecordOrderService.insertMrRecordOrder(mrRecordOrder)); + } + + /** + * 修改病案申请 + */ + @GetMapping("/edit/{id}") + public String edit(@PathVariable("id") Long id, ModelMap mmap) { + MrRecordOrder mrRecordOrder = mrRecordOrderService.selectMrRecordOrderById(id); + mmap.put("mrRecordOrder", mrRecordOrder); + return prefix + "/edit"; + } + + /** + * 修改保存病案申请 + */ + @RequiresPermissions("wx:order:edit") + @Log(title = "病案申请", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(MrRecordOrder mrRecordOrder) { + return toAjax(mrRecordOrderService.updateMrRecordOrder(mrRecordOrder)); + } + + /** + * 删除病案申请 + */ + @RequiresPermissions("wx:order:remove") + @Log(title = "病案申请", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) { + return toAjax(mrRecordOrderService.deleteMrRecordOrderByIds(ids)); + } + + @GetMapping("/sendView/{id}") + public String sendView(@PathVariable("id") Long id, ModelMap mmap) { + MrRecordOrder mrRecordOrder = mrRecordOrderService.selectMrRecordOrderById(id); + mmap.put("mrRecordOrder", mrRecordOrder); + mmap.put("randomCode", RandomStringUtils.random(8,true,true)); + return prefix + "/sendView"; + } + + @Log(title = "发送病案处理短信", businessType = BusinessType.UPDATE) + @PostMapping("/sendSms") + @ResponseBody + public AjaxResult sendSms(MrRecordOrder mrRecordOrder) { + return toAjax(mrRecordOrderService.sendSms(mrRecordOrder)); + } + + @PostMapping("/upload") + @ResponseBody + public AjaxResult upload(@RequestParam("file_data") MultipartFile file) throws IOException { + // 上传文件路径 + String filePath = RuoYiConfig.getUploadPath(); + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + // 保存短网址对应关系 + String code=mrRecordOrderService.randomCode(fileName,file.getOriginalFilename()); + return AjaxResult.success("上传成功", domain+"/s/"+code); + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/controller/ShortUrlController.java b/wx-record-order/src/main/java/com/ruoyi/wx/controller/ShortUrlController.java new file mode 100644 index 00000000..9529bb1f --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/controller/ShortUrlController.java @@ -0,0 +1,30 @@ +package com.ruoyi.wx.controller; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.ruoyi.wx.service.IMrRecordOrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +@Controller +@RequestMapping("s") +public class ShortUrlController { + @Autowired + private IMrRecordOrderService mrRecordOrderService; + + @RequestMapping("{code}") + public String redirectTo(@PathVariable String code, HttpServletResponse response) { + Map urlHeaders = mrRecordOrderService.getUrlHeaders(code); + String headers = urlHeaders.get("headers"); + JSONObject jsonObject = JSONUtil.parseObj(headers); + jsonObject.forEach((k, v) -> { + response.setHeader(k, (String) v); + }); + return "forward:" + urlHeaders.get("url"); + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/controller/WxUserController.java b/wx-record-order/src/main/java/com/ruoyi/wx/controller/WxUserController.java new file mode 100644 index 00000000..a633b047 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/controller/WxUserController.java @@ -0,0 +1,141 @@ +package com.ruoyi.wx.controller; + +import java.util.List; + +import com.ruoyi.wx.domain.WxUser; +import com.ruoyi.wx.service.IWxUserService; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 微信小程序用户Controller + * + * @author ruoyi + * @date 2021-02-24 + */ +@Controller +@RequestMapping("/wx/user") +public class WxUserController extends BaseController +{ + private String prefix = "wx/user"; + + @Autowired + private IWxUserService wxUserService; + + @RequiresPermissions("wx:user:view") + @GetMapping() + public String user() + { + return prefix + "/user"; + } + + /** + * 查询微信小程序用户列表 + */ + @RequiresPermissions("wx:user:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(WxUser wxUser) + { + startPage(); + List list = wxUserService.selectWxUserList(wxUser); + return getDataTable(list); + } + + /** + * 导出微信小程序用户列表 + */ + @RequiresPermissions("wx:user:export") + @Log(title = "微信小程序用户", businessType = BusinessType.EXPORT) + @PostMapping("/export") + @ResponseBody + public AjaxResult export(WxUser wxUser) + { + List list = wxUserService.selectWxUserList(wxUser); + ExcelUtil util = new ExcelUtil(WxUser.class); + return util.exportExcel(list, "user"); + } + + /** + * 新增微信小程序用户 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 新增保存微信小程序用户 + */ + @RequiresPermissions("wx:user:add") + @Log(title = "微信小程序用户", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(WxUser wxUser) + { + return toAjax(wxUserService.insertWxUser(wxUser)); + } + + /** + * 修改微信小程序用户 + */ + @GetMapping("/edit/{id}") + public String edit(@PathVariable("id") Long id, ModelMap mmap) + { + WxUser wxUser = wxUserService.selectWxUserById(id); + mmap.put("wxUser", wxUser); + return prefix + "/edit"; + } + + /** + * 修改保存微信小程序用户 + */ + @RequiresPermissions("wx:user:edit") + @Log(title = "微信小程序用户", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(WxUser wxUser) + { + return toAjax(wxUserService.updateWxUser(wxUser)); + } + + /** + * 删除微信小程序用户 + */ + @RequiresPermissions("wx:user:remove") + @Log(title = "微信小程序用户", businessType = BusinessType.DELETE) + @PostMapping( "/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(wxUserService.deleteWxUserByIds(ids)); + } + + @Log(title = "审核微信小程序用户", businessType = BusinessType.UPDATE) + @PostMapping( "/checkUser") + @ResponseBody + public AjaxResult checkUser(Long id){ + return toAjax(wxUserService.checkUser(id)); + } + + @Log(title = "修改微信小程序用户状态", businessType = BusinessType.UPDATE) + @PostMapping( "/triggerStatus") + @ResponseBody + public AjaxResult triggerStatus(Long id){ + return toAjax(wxUserService.triggerStatus(id)); + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/domain/MrRecordOrder.java b/wx-record-order/src/main/java/com/ruoyi/wx/domain/MrRecordOrder.java new file mode 100644 index 00000000..5b343b63 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/domain/MrRecordOrder.java @@ -0,0 +1,216 @@ +package com.ruoyi.wx.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 病案申请对象 mr_record_order + * + * @author ruoyi + * @date 2021-02-24 + */ +public class MrRecordOrder extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 申请类型:0原件寄回,1电子扫描件 */ + @Excel(name = "申请类型:") + private Integer type; + + /** 病案号 */ + @Excel(name = "病案号") + private String mrNumber; + + /** 患者姓名 */ + @Excel(name = "患者姓名") + private String patientName; + + /** 出院日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "出院日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date dischargeDate; + + /** 住院次数 */ + @Excel(name = "住院次数") + private Long times; + + /** 申请人申请人 对应wx_user表id */ + @Excel(name = "申请人") + private Long applicantId; + + /** 医院名称 */ + @Excel(name = "医院名称") + private String hospital; + + /** 寄送地址 */ + @Excel(name = "寄送地址") + private String address; + @Excel(name = "快递公司") + private String delivery; + @Excel(name = "运单号") + private String trackingNumber; + + /** 下载地址 */ + @Excel(name = "下载地址") + private String downloadUrl; + + /** 解压密码 */ + @Excel(name = "解压密码") + private String unzipPwd; + + /** 申请状态 0 申请中 1 已完成 */ + @Excel(name = "申请状态") + private Integer status; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setType(Integer type) + { + this.type = type; + } + + public Integer getType() + { + return type; + } + public void setMrNumber(String mrNumber) + { + this.mrNumber = mrNumber; + } + + public String getMrNumber() + { + return mrNumber; + } + public void setPatientName(String patientName) + { + this.patientName = patientName; + } + + public String getPatientName() + { + return patientName; + } + public void setDischargeDate(Date dischargeDate) + { + this.dischargeDate = dischargeDate; + } + + public Date getDischargeDate() + { + return dischargeDate; + } + public void setTimes(Long times) + { + this.times = times; + } + + public Long getTimes() + { + return times; + } + public void setApplicantId(Long applicantId) + { + this.applicantId = applicantId; + } + + public Long getApplicantId() + { + return applicantId; + } + public void setHospital(String hospital) + { + this.hospital = hospital; + } + + public String getHospital() + { + return hospital; + } + public void setAddress(String address) + { + this.address = address; + } + + public String getAddress() + { + return address; + } + public void setDownloadUrl(String downloadUrl) + { + this.downloadUrl = downloadUrl; + } + + public String getDownloadUrl() + { + return downloadUrl; + } + public void setUnzipPwd(String unzipPwd) + { + this.unzipPwd = unzipPwd; + } + + public String getUnzipPwd() + { + return unzipPwd; + } + public void setStatus(Integer status) + { + this.status = status; + } + + public Integer getStatus() + { + return status; + } + + public String getDelivery() { + return delivery; + } + + public void setDelivery(String delivery) { + this.delivery = delivery; + } + + public String getTrackingNumber() { + return trackingNumber; + } + + public void setTrackingNumber(String trackingNumber) { + this.trackingNumber = trackingNumber; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("type", getType()) + .append("mrNumber", getMrNumber()) + .append("patientName", getPatientName()) + .append("dischargeDate", getDischargeDate()) + .append("times", getTimes()) + .append("applicantId", getApplicantId()) + .append("hospital", getHospital()) + .append("address", getAddress()) + .append("downloadUrl", getDownloadUrl()) + .append("unzipPwd", getUnzipPwd()) + .append("status", getStatus()) + .append("createTime", getCreateTime()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/domain/WxUser.java b/wx-record-order/src/main/java/com/ruoyi/wx/domain/WxUser.java new file mode 100644 index 00000000..f5aecd1b --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/domain/WxUser.java @@ -0,0 +1,196 @@ +package com.ruoyi.wx.domain; + +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 微信小程序用户对象 wx_user + * + * @author ruoyi + * @date 2021-02-24 + */ +public class WxUser extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + private Long id; + + /** + * 用户姓名 + */ + @Excel(name = "用户姓名") + private String name; + /** + * 手机号码 + */ + @Excel(name = "手机号码") + private String phone; + + private String openid; + + /** + * 用户状态 0正常 1停用 + */ + @Excel(name = "用户状态") + private Integer status; + + /** + * 审核状态 0审核中 1审核成功 + */ + @Excel(name = "审核状态") + private Integer flag; + + /** + * 医院名称 + */ + @Excel(name = "医院名称") + private String hospital; + + /** + * 收货地址 + */ + @Excel(name = "收货地址") + private String address; + + /** + * 微信昵称 + */ + @Excel(name = "微信昵称") + private String nickname; + + /** + * 微信头像 + */ + @Excel(name = "微信头像") + private String avatar; + + /** + * 性别 + */ + private String gender; + + /** + * 登录token + */ + private String token; + + public void setId(Long id) { + this.id = id; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public Long getId() { + return id; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + public String getOpenid() { + return openid; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getStatus() { + return status; + } + + public void setFlag(Integer flag) { + this.flag = flag; + } + + public Integer getFlag() { + return flag; + } + + public void setHospital(String hospital) { + this.hospital = hospital; + } + + public String getHospital() { + return hospital; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getAddress() { + return address; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public String getNickname() { + return nickname; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getAvatar() { + return avatar; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("openid", getOpenid()) + .append("status", getStatus()) + .append("flag", getFlag()) + .append("hospital", getHospital()) + .append("address", getAddress()) + .append("createTime", getCreateTime()) + .append("updateTime", getUpdateTime()) + .append("nickname", getNickname()) + .append("avatar", getAvatar()) + .append("phone", getPhone()) + .append("token", getToken()) + .append("gender", getGender()) + .toString(); + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/dto/RecordOrderDTO.java b/wx-record-order/src/main/java/com/ruoyi/wx/dto/RecordOrderDTO.java new file mode 100644 index 00000000..dabf9bb5 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/dto/RecordOrderDTO.java @@ -0,0 +1,129 @@ +package com.ruoyi.wx.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.util.Date; + +public class RecordOrderDTO { + /** + * 主键 + */ + private Long id; + + private String type; + + /** + * 病案号 + */ + private String mrNumber; + + /** + * 患者姓名 + */ + private String patientName; + + /** + * 出院日期 + */ + @JsonFormat(pattern = "yyyy-MM-dd") + private Date dischargeDate; + + /** + * 住院次数 + */ + private Long times; + + /** + * 医院名称 + */ + private String hospital; + + /** + * 寄送地址 + */ + private String address; + + private String status; + + private String downUrl; + + public String getDownUrl() { + return downUrl; + } + + public void setDownUrl(String downUrl) { + this.downUrl = downUrl; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getMrNumber() { + return mrNumber; + } + + public void setMrNumber(String mrNumber) { + this.mrNumber = mrNumber; + } + + public String getPatientName() { + return patientName; + } + + public void setPatientName(String patientName) { + this.patientName = patientName; + } + + public Date getDischargeDate() { + return dischargeDate; + } + + public void setDischargeDate(Date dischargeDate) { + this.dischargeDate = dischargeDate; + } + + public Long getTimes() { + return times; + } + + public void setTimes(Long times) { + this.times = times; + } + + public String getHospital() { + return hospital; + } + + public void setHospital(String hospital) { + this.hospital = hospital; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/dto/WxUserDTO.java b/wx-record-order/src/main/java/com/ruoyi/wx/dto/WxUserDTO.java new file mode 100644 index 00000000..76f9e34a --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/dto/WxUserDTO.java @@ -0,0 +1,112 @@ +package com.ruoyi.wx.dto; + +import com.ruoyi.common.annotation.Excel; + +/** + * 用户登录对象 + */ +public class WxUserDTO { + /** + * 主键 + */ + private Long id; + + /** + * 用户姓名 + */ + @Excel(name = "用户姓名") + private String name; + /** + * 手机号码 + */ + @Excel(name = "手机号码") + private String phone; + /** + * 用户状态 0正常 1停用 + */ + @Excel(name = "用户状态") + private Integer status; + /** + * 审核状态 0审核中 1审核成功 + */ + @Excel(name = "审核状态") + private Integer flag; + + /** + * 医院名称 + */ + @Excel(name = "医院名称") + private String hospital; + + /** + * 收货地址 + */ + @Excel(name = "收货地址") + private String address; + + private String token; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getFlag() { + return flag; + } + + public void setFlag(Integer flag) { + this.flag = flag; + } + + public String getHospital() { + return hospital; + } + + public void setHospital(String hospital) { + this.hospital = hospital; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/dto/req/OrderListReqDTO.java b/wx-record-order/src/main/java/com/ruoyi/wx/dto/req/OrderListReqDTO.java new file mode 100644 index 00000000..fd8cdea6 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/dto/req/OrderListReqDTO.java @@ -0,0 +1,31 @@ +package com.ruoyi.wx.dto.req; + +public class OrderListReqDTO { + private String keyword; + private Integer page; + private Integer status; + + public String getKeyword() { + return keyword; + } + + public void setKeyword(String keyword) { + this.keyword = keyword; + } + + public Integer getPage() { + return page; + } + + public void setPage(Integer page) { + this.page = page; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/dto/req/UserSignInfo.java b/wx-record-order/src/main/java/com/ruoyi/wx/dto/req/UserSignInfo.java new file mode 100644 index 00000000..d209fd1f --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/dto/req/UserSignInfo.java @@ -0,0 +1,58 @@ +package com.ruoyi.wx.dto.req; + +public class UserSignInfo { + private String nickName; + private String gender; + private String avatar; + private String name; + private String phone; + private String hospital; + + public String getNickName() { + return nickName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getHospital() { + return hospital; + } + + public void setHospital(String hospital) { + this.hospital = hospital; + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/mapper/MrRecordOrderMapper.java b/wx-record-order/src/main/java/com/ruoyi/wx/mapper/MrRecordOrderMapper.java new file mode 100644 index 00000000..9a89ed30 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/mapper/MrRecordOrderMapper.java @@ -0,0 +1,71 @@ +package com.ruoyi.wx.mapper; + +import java.util.List; +import java.util.Map; + +import com.ruoyi.wx.domain.MrRecordOrder; +import com.ruoyi.wx.dto.RecordOrderDTO; +import org.apache.ibatis.annotations.Param; + +/** + * 病案申请Mapper接口 + * + * @author ruoyi + * @date 2021-02-24 + */ +public interface MrRecordOrderMapper +{ + /** + * 查询病案申请 + * + * @param id 病案申请ID + * @return 病案申请 + */ + public MrRecordOrder selectMrRecordOrderById(Long id); + + /** + * 查询病案申请列表 + * + * @param mrRecordOrder 病案申请 + * @return 病案申请集合 + */ + public List selectMrRecordOrderList(MrRecordOrder mrRecordOrder); + + /** + * 新增病案申请 + * + * @param mrRecordOrder 病案申请 + * @return 结果 + */ + public int insertMrRecordOrder(MrRecordOrder mrRecordOrder); + + /** + * 修改病案申请 + * + * @param mrRecordOrder 病案申请 + * @return 结果 + */ + public int updateMrRecordOrder(MrRecordOrder mrRecordOrder); + + /** + * 删除病案申请 + * + * @param id 病案申请ID + * @return 结果 + */ + public int deleteMrRecordOrderById(Long id); + + /** + * 批量删除病案申请 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteMrRecordOrderByIds(String[] ids); + + List searchList(@Param("userId")Long userId,@Param("keyword") String keyword,@Param("status") Integer status,@Param("startRow") Integer startRow,@Param("endRow") Integer endRow); + + Map getUrlHeaders(String code); + + boolean saveCodeUrl(@Param("code") String code, @Param("url") String url, @Param("headers") String headers); +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/mapper/WxUserMapper.java b/wx-record-order/src/main/java/com/ruoyi/wx/mapper/WxUserMapper.java new file mode 100644 index 00000000..fe2ddee2 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/mapper/WxUserMapper.java @@ -0,0 +1,70 @@ +package com.ruoyi.wx.mapper; + +import java.util.List; +import com.ruoyi.wx.domain.WxUser; + +/** + * 微信小程序用户Mapper接口 + * + * @author ruoyi + * @date 2021-02-24 + */ +public interface WxUserMapper +{ + /** + * 查询微信小程序用户 + * + * @param id 微信小程序用户ID + * @return 微信小程序用户 + */ + public WxUser selectWxUserById(Long id); + + /** + * 查询微信小程序用户列表 + * + * @param wxUser 微信小程序用户 + * @return 微信小程序用户集合 + */ + public List selectWxUserList(WxUser wxUser); + + /** + * 新增微信小程序用户 + * + * @param wxUser 微信小程序用户 + * @return 结果 + */ + public int insertWxUser(WxUser wxUser); + + /** + * 修改微信小程序用户 + * + * @param wxUser 微信小程序用户 + * @return 结果 + */ + public int updateWxUser(WxUser wxUser); + + /** + * 删除微信小程序用户 + * + * @param id 微信小程序用户ID + * @return 结果 + */ + public int deleteWxUserById(Long id); + + /** + * 批量删除微信小程序用户 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteWxUserByIds(String[] ids); + + /** + * 根据token获取用户信息 + * @param token + * @return + */ + WxUser selectWxUserByToken(String token); + + WxUser selectWxUserByOpenid(String openid); +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/service/IMrRecordOrderService.java b/wx-record-order/src/main/java/com/ruoyi/wx/service/IMrRecordOrderService.java new file mode 100644 index 00000000..10384c5f --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/service/IMrRecordOrderService.java @@ -0,0 +1,75 @@ +package com.ruoyi.wx.service; + +import java.util.List; +import java.util.Map; + +import com.ruoyi.wx.domain.MrRecordOrder; +import com.ruoyi.wx.dto.RecordOrderDTO; +import com.ruoyi.wx.dto.req.OrderListReqDTO; + +/** + * 病案申请Service接口 + * + * @author ruoyi + * @date 2021-02-24 + */ +public interface IMrRecordOrderService +{ + /** + * 查询病案申请 + * + * @param id 病案申请ID + * @return 病案申请 + */ + public MrRecordOrder selectMrRecordOrderById(Long id); + + /** + * 查询病案申请列表 + * + * @param mrRecordOrder 病案申请 + * @return 病案申请集合 + */ + public List selectMrRecordOrderList(MrRecordOrder mrRecordOrder); + + /** + * 新增病案申请 + * + * @param mrRecordOrder 病案申请 + * @return 结果 + */ + public int insertMrRecordOrder(MrRecordOrder mrRecordOrder); + + /** + * 修改病案申请 + * + * @param mrRecordOrder 病案申请 + * @return 结果 + */ + public int updateMrRecordOrder(MrRecordOrder mrRecordOrder); + + /** + * 批量删除病案申请 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteMrRecordOrderByIds(String ids); + + /** + * 删除病案申请信息 + * + * @param id 病案申请ID + * @return 结果 + */ + public int deleteMrRecordOrderById(Long id); + + void createOrder(MrRecordOrder order); + + List list(OrderListReqDTO orderListReqDTO); + + boolean sendSms(MrRecordOrder mrRecordOrder); + + Map getUrlHeaders(String code); + + String randomCode(String url, String filename); +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/service/IWxUserService.java b/wx-record-order/src/main/java/com/ruoyi/wx/service/IWxUserService.java new file mode 100644 index 00000000..94f11437 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/service/IWxUserService.java @@ -0,0 +1,82 @@ +package com.ruoyi.wx.service; + +import java.util.List; + +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import com.ruoyi.wx.domain.WxUser; +import com.ruoyi.wx.dto.WxUserDTO; +import com.ruoyi.wx.dto.req.UserSignInfo; + +/** + * 微信小程序用户Service接口 + * + * @author ruoyi + * @date 2021-02-24 + */ +public interface IWxUserService +{ + /** + * 查询微信小程序用户 + * + * @param id 微信小程序用户ID + * @return 微信小程序用户 + */ + public WxUser selectWxUserById(Long id); + + /** + * 查询微信小程序用户列表 + * + * @param wxUser 微信小程序用户 + * @return 微信小程序用户集合 + */ + public List selectWxUserList(WxUser wxUser); + + /** + * 新增微信小程序用户 + * + * @param wxUser 微信小程序用户 + * @return 结果 + */ + public int insertWxUser(WxUser wxUser); + + /** + * 修改微信小程序用户 + * + * @param wxUser 微信小程序用户 + * @return 结果 + */ + public int updateWxUser(WxUser wxUser); + + /** + * 批量删除微信小程序用户 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteWxUserByIds(String ids); + + /** + * 删除微信小程序用户信息 + * + * @param id 微信小程序用户ID + * @return 结果 + */ + public int deleteWxUserById(Long id); + + /** + * 根据token获取用户资料 + * @param token + * @return + */ + WxUser selectWxUserByToken(String token); + + WxUserDTO login(String wxCode); + + void signIn(UserSignInfo userSignInfo); + + WxUserDTO info(UserSignInfo userSignInfo); + + boolean checkUser(Long id); + + boolean triggerStatus(Long id); +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/service/impl/MrRecordOrderServiceImpl.java b/wx-record-order/src/main/java/com/ruoyi/wx/service/impl/MrRecordOrderServiceImpl.java new file mode 100644 index 00000000..2db0e61e --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/service/impl/MrRecordOrderServiceImpl.java @@ -0,0 +1,218 @@ +package com.ruoyi.wx.service.impl; + +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.exception.BusinessException; +import com.ruoyi.common.exception.wx.WxBusinessException; +import com.ruoyi.common.json.JSONObject; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.html.EscapeUtil; +import com.ruoyi.wx.domain.MrRecordOrder; +import com.ruoyi.wx.domain.WxUser; +import com.ruoyi.wx.dto.RecordOrderDTO; +import com.ruoyi.wx.dto.WxUserDTO; +import com.ruoyi.wx.dto.req.OrderListReqDTO; +import com.ruoyi.wx.mapper.MrRecordOrderMapper; +import com.ruoyi.wx.mapper.WxUserMapper; +import com.ruoyi.wx.service.IMrRecordOrderService; +import com.ruoyi.wx.util.SmsUtils; +import com.ruoyi.wx.util.WxServiceUtils; +import com.ruoyi.wx.util.WxUserUtils; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * 病案申请Service业务层处理 + * + * @author ruoyi + * @date 2021-02-24 + */ +@Service +public class MrRecordOrderServiceImpl implements IMrRecordOrderService { + @Autowired + private MrRecordOrderMapper mrRecordOrderMapper; + + /** + * 查询病案申请 + * + * @param id 病案申请ID + * @return 病案申请 + */ + @Override + public MrRecordOrder selectMrRecordOrderById(Long id) { + return mrRecordOrderMapper.selectMrRecordOrderById(id); + } + + /** + * 查询病案申请列表 + * + * @param mrRecordOrder 病案申请 + * @return 病案申请 + */ + @Override + public List selectMrRecordOrderList(MrRecordOrder mrRecordOrder) { + return mrRecordOrderMapper.selectMrRecordOrderList(mrRecordOrder); + } + + /** + * 新增病案申请 + * + * @param mrRecordOrder 病案申请 + * @return 结果 + */ + @Override + public int insertMrRecordOrder(MrRecordOrder mrRecordOrder) { + mrRecordOrder.setCreateTime(DateUtils.getNowDate()); + return mrRecordOrderMapper.insertMrRecordOrder(mrRecordOrder); + } + + /** + * 修改病案申请 + * + * @param mrRecordOrder 病案申请 + * @return 结果 + */ + @Override + public int updateMrRecordOrder(MrRecordOrder mrRecordOrder) { + mrRecordOrder.setUpdateTime(DateUtils.getNowDate()); + return mrRecordOrderMapper.updateMrRecordOrder(mrRecordOrder); + } + + /** + * 删除病案申请对象 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteMrRecordOrderByIds(String ids) { + return mrRecordOrderMapper.deleteMrRecordOrderByIds(Convert.toStrArray(ids)); + } + + /** + * 删除病案申请信息 + * + * @param id 病案申请ID + * @return 结果 + */ + @Override + public int deleteMrRecordOrderById(Long id) { + return mrRecordOrderMapper.deleteMrRecordOrderById(id); + } + + @Autowired + private WxUserUtils wxUserUtils; + @Autowired + private WxUserMapper wxUserMapper; + + @Transactional(rollbackFor = Exception.class) + @Override + public void createOrder(MrRecordOrder order) { + // 判断参数是否遗漏 + if (StringUtils.isBlank(order.getMrNumber())) { + throw new WxBusinessException("病案号必填"); + } + if (StringUtils.isBlank(order.getPatientName())) { + throw new WxBusinessException("患者姓名必填"); + } + if (Objects.isNull(order.getDischargeDate())) { + throw new WxBusinessException("出院时间必填"); + } + if (Objects.isNull(order.getTimes())) { + throw new WxBusinessException("就诊次数必填"); + } + if (order.getType() == 0) { + if (Objects.isNull(order.getAddress())) { + throw new WxBusinessException("配送地址必填"); + } + } + + // 判断是否已有相同订单 + MrRecordOrder searchOrder = new MrRecordOrder(); + searchOrder.setMrNumber(order.getMrNumber()); + searchOrder.setType(order.getType()); + searchOrder.setStatus(0); + List mrRecordOrders = mrRecordOrderMapper.selectMrRecordOrderList(searchOrder); + if (mrRecordOrders != null && !mrRecordOrders.isEmpty()) { + throw new WxBusinessException("已有相同申请!"); + } + + WxUserDTO userInfo = wxUserUtils.getUserInfo(); + order.setApplicantId(userInfo.getId()); + order.setHospital(userInfo.getHospital()); + + if (StringUtils.isNotBlank(order.getAddress())) { + WxUser wxUser = new WxUser(); + wxUser.setId(userInfo.getId()); + wxUser.setAddress(order.getAddress()); + wxUserMapper.updateWxUser(wxUser); + } + + order.setCreateTime(new Date()); + order.setUpdateTime(new Date()); + order.setStatus(0); + mrRecordOrderMapper.insertMrRecordOrder(order); + } + + @Override + public List list(OrderListReqDTO orderListReqDTO) { + int rowCount = 10; + int startRow = rowCount * (orderListReqDTO.getPage() - 1); + int endRow = rowCount * orderListReqDTO.getPage(); + return mrRecordOrderMapper.searchList(wxUserUtils.getUserInfo().getId(), orderListReqDTO.getKeyword(), orderListReqDTO.getStatus(), startRow, endRow); + } + + @Override + public boolean sendSms(MrRecordOrder mrRecordOrder) { + MrRecordOrder mrRecordOrder1 = mrRecordOrderMapper.selectMrRecordOrderById(mrRecordOrder.getId()); + if (Objects.nonNull(mrRecordOrder1)) { + WxUser wxUser = wxUserMapper.selectWxUserById(mrRecordOrder1.getApplicantId()); + // 发送短信 + if (mrRecordOrder.getType() == 1) { + SmsUtils.sendSms(SmsUtils.TemplateType.DOWN, wxUser.getPhone(), mrRecordOrder.getUnzipPwd()); + } else if (mrRecordOrder.getType() == 0) { + SmsUtils.sendSms(SmsUtils.TemplateType.Express, wxUser.getPhone(), mrRecordOrder.getTrackingNumber()); + } + // 更新订单 + mrRecordOrder.setStatus(1); + mrRecordOrder.setUpdateTime(new Date()); + mrRecordOrderMapper.updateMrRecordOrder(mrRecordOrder); + } + return true; + } + + @Override + public Map getUrlHeaders(String code) { + return mrRecordOrderMapper.getUrlHeaders(code); + } + + @Override + public String randomCode(String url, String filename) { + return saveUrl(url, filename, 1); + } + + private String saveUrl(String url, String filename, int times) { + try { + String code = RandomStringUtils.random(4, true, true); + JSONObject jsonObject = new JSONObject(); + jsonObject.set("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, Charset.defaultCharset().displayName())); + mrRecordOrderMapper.saveCodeUrl(code, url, jsonObject.toCompactString()); + return code; + } catch (Exception e) { + // code为唯一建,失败了就重试,最多重试5次 + if (times > 5) { + throw new BusinessException("创建短网址失败"); + } + return saveUrl(url, filename, ++times); + } + } +} \ No newline at end of file diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/service/impl/WxUserServiceImpl.java b/wx-record-order/src/main/java/com/ruoyi/wx/service/impl/WxUserServiceImpl.java new file mode 100644 index 00000000..d7653433 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/service/impl/WxUserServiceImpl.java @@ -0,0 +1,207 @@ +package com.ruoyi.wx.service.impl; + +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.exception.BusinessException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.wx.domain.WxUser; +import com.ruoyi.wx.dto.WxUserDTO; +import com.ruoyi.wx.dto.req.UserSignInfo; +import com.ruoyi.wx.mapper.WxUserMapper; +import com.ruoyi.wx.service.IWxUserService; +import com.ruoyi.wx.util.WxServiceUtils; +import com.ruoyi.wx.util.WxUserUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; +import java.util.Objects; + +/** + * 微信小程序用户Service业务层处理 + * + * @author ruoyi + * @date 2021-02-24 + */ +@Service +public class WxUserServiceImpl implements IWxUserService { + @Autowired + private WxUserMapper wxUserMapper; + @Autowired + private WxServiceUtils wxServiceUtils; + @Autowired + private WxUserUtils wxUserUtils; + + /** + * 查询微信小程序用户 + * + * @param id 微信小程序用户ID + * @return 微信小程序用户 + */ + @Override + public WxUser selectWxUserById(Long id) { + return wxUserMapper.selectWxUserById(id); + } + + /** + * 查询微信小程序用户列表 + * + * @param wxUser 微信小程序用户 + * @return 微信小程序用户 + */ + @Override + public List selectWxUserList(WxUser wxUser) { + return wxUserMapper.selectWxUserList(wxUser); + } + + /** + * 新增微信小程序用户 + * + * @param wxUser 微信小程序用户 + * @return 结果 + */ + @Override + public int insertWxUser(WxUser wxUser) { + wxUser.setCreateTime(DateUtils.getNowDate()); + return wxUserMapper.insertWxUser(wxUser); + } + + /** + * 修改微信小程序用户 + * + * @param wxUser 微信小程序用户 + * @return 结果 + */ + @Override + public int updateWxUser(WxUser wxUser) { + wxUser.setUpdateTime(DateUtils.getNowDate()); + return wxUserMapper.updateWxUser(wxUser); + } + + /** + * 删除微信小程序用户对象 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteWxUserByIds(String ids) { + return wxUserMapper.deleteWxUserByIds(Convert.toStrArray(ids)); + } + + /** + * 删除微信小程序用户信息 + * + * @param id 微信小程序用户ID + * @return 结果 + */ + @Override + public int deleteWxUserById(Long id) { + return wxUserMapper.deleteWxUserById(id); + } + + @Override + public WxUser selectWxUserByToken(String token) { + return wxUserMapper.selectWxUserByToken(token); + } + + @Override + public WxUserDTO login(String wxCode) { + WxUserDTO wxUserDTO = new WxUserDTO(); + WxMaJscode2SessionResult login = wxServiceUtils.login(wxCode); + // 根据openid查询用户 + WxUser wxUser = wxUserMapper.selectWxUserByOpenid(login.getOpenid()); + + if (Objects.nonNull(wxUser)) { + wxUser.setToken(login.getSessionKey()); + wxUser.setUpdateTime(new Date()); + wxUserMapper.updateWxUser(wxUser); + } else { + wxUser = new WxUser(); + wxUser.setToken(login.getSessionKey()); + wxUser.setOpenid(login.getOpenid()); + wxUser.setStatus(2); + wxUser.setFlag(0); + wxUser.setCreateTime(new Date()); + wxUserMapper.insertWxUser(wxUser); + } + BeanUtils.copyProperties(wxUser, wxUserDTO); + return wxUserDTO; + } + + @Override + public void signIn(UserSignInfo userSignInfo) { + WxUserDTO userInfo = wxUserUtils.getUserInfo(); + + WxUser wxUser = wxUserMapper.selectWxUserById(userInfo.getId()); + wxUser.setUpdateTime(new Date()); + wxUser.setAvatar(userSignInfo.getAvatar()); + wxUser.setNickname(userSignInfo.getNickName()); + String gender = "未知"; + if (StringUtils.equals("1", userSignInfo.getGender())) { + gender = "男"; + } else if (StringUtils.equals("2", userSignInfo.getGender())) { + gender = "女"; + } + wxUser.setGender(gender); + wxUser.setHospital(userSignInfo.getHospital()); + wxUser.setName(userSignInfo.getName()); + wxUser.setPhone(userSignInfo.getPhone()); + + wxUser.setStatus(0); + + wxUserMapper.updateWxUser(wxUser); + wxUserUtils.clearCache(); + } + + @Override + public WxUserDTO info(UserSignInfo userSignInfo) { + WxUserDTO userInfo = wxUserUtils.getUserInfo(); + + WxUser wxUser = wxUserMapper.selectWxUserById(userInfo.getId()); + if (!wxUser.getStatus().equals(userInfo.getStatus()) || !wxUser.getFlag().equals(userInfo.getFlag())) {// 状态变更时更新用户信息 + wxUser.setUpdateTime(new Date()); + wxUser.setAvatar(userSignInfo.getAvatar()); + wxUser.setNickname(userSignInfo.getNickName()); + String gender = "未知"; + if (StringUtils.equals("1", userSignInfo.getGender())) { + gender = "男"; + } else if (StringUtils.equals("2", userSignInfo.getGender())) { + gender = "女"; + } + wxUser.setGender(gender); + + wxUserMapper.updateWxUser(wxUser); + wxUserUtils.clearCache(); + BeanUtils.copyProperties(wxUser, userInfo); + } + + return userInfo; + } + + @Override + public boolean checkUser(Long id) { + WxUser wxUser=new WxUser(); + wxUser.setId(id); + wxUser.setFlag(1); + updateWxUser(wxUser); + return true; + } + + @Override + public boolean triggerStatus(Long id) { + WxUser wxUser=selectWxUserById(id); + if(wxUser.getStatus()==1){ + wxUser.setStatus(0); + updateWxUser(wxUser); + }else if(wxUser.getStatus()==0){ + wxUser.setStatus(1); + updateWxUser(wxUser); + } + return true; + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/util/ShortUrlUtils.java b/wx-record-order/src/main/java/com/ruoyi/wx/util/ShortUrlUtils.java new file mode 100644 index 00000000..b04f993d --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/util/ShortUrlUtils.java @@ -0,0 +1,22 @@ +package com.ruoyi.wx.util; + +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.utils.http.HttpUtils; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.Charset; + +public class ShortUrlUtils { + private static final String API_PATH = "http://www.uc4.cn/ajax.php"; + + public static String getShortUrl(String url) throws UnsupportedEncodingException { + String resp = HttpUtils.sendGet(API_PATH, "act=creat1&url=" + URLEncoder.encode(url, Charset.defaultCharset().displayName()) + "&pattern=1&type=c4icn"); + JSONObject obj = JSONObject.parseObject(resp); + return obj.getString("dwz"); + } + + public static void main(String[] args) throws UnsupportedEncodingException { + System.out.println(getShortUrl("https://wx.docus.cn/profile/upload/2021/03/01/dad2a531-b3bf-4ede-8f41-26d611053c73.zip")); + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/util/SmsUtils.java b/wx-record-order/src/main/java/com/ruoyi/wx/util/SmsUtils.java new file mode 100644 index 00000000..538bcc21 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/util/SmsUtils.java @@ -0,0 +1,119 @@ +package com.ruoyi.wx.util; + +import com.aliyun.dysmsapi20170525.Client; +import com.aliyun.dysmsapi20170525.models.SendSmsRequest; +import com.aliyun.dysmsapi20170525.models.SendSmsResponse; +import com.aliyun.teaopenapi.models.Config; +import com.ruoyi.common.exception.BusinessException; +import com.ruoyi.common.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +@Component +public class SmsUtils { + private static final Logger log = LoggerFactory.getLogger(SmsUtils.class); + + private static String accessKeyId; + private static String accessKeySecret; + private static String signName; + + @Value("${aliyun.accesskey-id}") + String aliAccessKeyId; + @Value("${aliyun.accesskey-secret}") + String aliAccessKeySecret; + @Value("${aliyun.sms.sign-name}") + String pSignName; + + @PostConstruct + private void initialization() { + accessKeyId = aliAccessKeyId; + accessKeySecret = aliAccessKeySecret; + signName = pSignName; + } + + /** + * 使用AK&SK初始化账号Client + * + * @return Client + * @throws Exception + */ + public static Client getClient() throws Exception { + Config config = new Config() + // 您的AccessKey ID + .setAccessKeyId(accessKeyId) + // 您的AccessKey Secret + .setAccessKeySecret(accessKeySecret); + // 访问的域名 + config.endpoint = "dysmsapi.aliyuncs.com"; + return new Client(config); + } + + /** + * 发送短信 + * + * @param type 模板类型 + * @param telephone 手机号码 + * @param objs 参数值数组,对应模板参数数组传入 + */ + public static void sendSms(TemplateType type, String telephone, Object... objs) { + // 组装请求对象-具体描述见控制台-文档部分内容 + SendSmsRequest request = new SendSmsRequest(); + // 必填:待发送手机号 + request.setPhoneNumbers(telephone); + //必填:短信签名-可在短信控制台中找到 + request.setSignName(signName); + // 必填:短信模板-可在短信控制台中找到 + request.setTemplateCode(type.code); + if (type.args != null && type.args.length > 0) { + JSONObject jsonObject = new JSONObject(); + for (int i = 0; i < type.args.length; i++) { + jsonObject.put(type.args[i], objs[i]); + } + request.setTemplateParam(jsonObject.toCompactString()); + } + //请求失败这里会抛ClientException异常 + SendSmsResponse sendSmsResponse = null; + try { + sendSmsResponse = getClient().sendSms(request); + } catch (Exception e) { + e.printStackTrace(); + } + if (sendSmsResponse != null && "OK".equals(sendSmsResponse.getBody().getCode())) { + log.debug("send Message to [{}] successful", telephone); + } else { + if (null != sendSmsResponse) { + throw new BusinessException("发送短信失败," + sendSmsResponse.getBody().getMessage()); + } else { + throw new BusinessException("发送短信失败"); + } + } + } + + public enum TemplateType { + /** + * 下载扫描件通知模板 + */ + DOWN("SMS_212471722", "pwd"), + /** + * 快递单通知模板 + */ + Express("SMS_212476711", "nu"); + /** + * 参数名称数组 + */ + private final String[] args; + /** + * 模板id + */ + private final String code; + + TemplateType(String code, String... args) { + this.args = args; + this.code = code; + } + } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/util/WxServiceUtils.java b/wx-record-order/src/main/java/com/ruoyi/wx/util/WxServiceUtils.java new file mode 100644 index 00000000..786d0cbc --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/util/WxServiceUtils.java @@ -0,0 +1,76 @@ +package com.ruoyi.wx.util; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.WxMaUserService; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; +import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; +import com.ruoyi.common.exception.base.BaseException; +import com.ruoyi.common.utils.CacheUtils; +import me.chanjar.weixin.common.error.WxErrorException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.Objects; + +@Component +public class WxServiceUtils { + @Value("${wx.appid}") + private String appid; + @Value("${wx.appsecret}") + private String appsecret; + + private static WxMaService wxMaService; + + private static final String CACHE_NAME ="wx-accessCache"; + + @PostConstruct + private void init() { + WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl(); + config.setAppid(appid); + config.setSecret(appsecret); + wxMaService = new WxMaServiceImpl(); + wxMaService.setWxMaConfig(config); +// config.setAccessToken(getAccessToken()); + } + +// private String getAccessToken(){ +// Object accessToken = CacheUtils.get(CACHE_NAME, "access_token"); +// if(Objects.isNull(accessToken)){ +// try { +// accessToken=wxMaService.getAccessToken(); +// } catch (WxErrorException e) { +// return null; +// } +// CacheUtils.put(CACHE_NAME,"access_token",accessToken); +// } +// return (String)accessToken; +// } + + public WxMaJscode2SessionResult login(String code) { + try { + return wxMaService.getUserService().getSessionInfo(code); + } catch (WxErrorException e) { + throw new BaseException("小程序登录失败!" + e.getMessage()); + } + } + + public WxMaUserService getUserService() { + return wxMaService.getUserService(); + } + +// public static void sendKefuMsg(String content,String openid){ +// WxMaKefuMessage wxMaKefuMessage=new WxMaKefuMessage(); +// wxMaKefuMessage.setToUser(openid); +// wxMaKefuMessage.setMsgType("text"); +// WxMaKefuMessage.KfText text=new WxMaKefuMessage.KfText(content); +// wxMaKefuMessage.setText(text); +// try { +// wxMaService.getMsgService().sendKefuMsg(wxMaKefuMessage); +// } catch (WxErrorException e) { +// e.printStackTrace(); +// } +// } +} diff --git a/wx-record-order/src/main/java/com/ruoyi/wx/util/WxUserUtils.java b/wx-record-order/src/main/java/com/ruoyi/wx/util/WxUserUtils.java new file mode 100644 index 00000000..7c544697 --- /dev/null +++ b/wx-record-order/src/main/java/com/ruoyi/wx/util/WxUserUtils.java @@ -0,0 +1,48 @@ +package com.ruoyi.wx.util; + +import com.ruoyi.common.exception.wx.NotLoginException; +import com.ruoyi.common.utils.CacheUtils; +import com.ruoyi.common.utils.bean.BeanUtils; +import com.ruoyi.wx.domain.WxUser; +import com.ruoyi.wx.dto.WxUserDTO; +import com.ruoyi.wx.service.IWxUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.util.Objects; + +@Component +public class WxUserUtils { + @Autowired + private HttpServletRequest request; + @Autowired + private IWxUserService wxUserService; + private final String cacheName = "wx-userCache"; + + private String getToken() { + return request.getHeader("token"); + } + + public WxUserDTO getUserInfo() { + String token = getToken(); + Object userCache = CacheUtils.get(cacheName, "wx-token:" + token); + if (Objects.nonNull(userCache)) { + return (WxUserDTO) userCache; + } else { + WxUser wxUser = wxUserService.selectWxUserByToken(getToken()); + if (Objects.nonNull(wxUser)) { + WxUserDTO wxUserDTO = new WxUserDTO(); + BeanUtils.copyProperties(wxUser, wxUserDTO); + CacheUtils.put(cacheName, "wx-token:" + token, wxUserDTO); + return wxUserDTO; + } else { + throw new NotLoginException(); + } + } + } + + public void clearCache() { + CacheUtils.remove(cacheName, "wx-token:" + getToken()); + } +} diff --git a/wx-record-order/src/main/resources/mapper/wx/MrRecordOrderMapper.xml b/wx-record-order/src/main/resources/mapper/wx/MrRecordOrderMapper.xml new file mode 100644 index 00000000..6b483fa9 --- /dev/null +++ b/wx-record-order/src/main/resources/mapper/wx/MrRecordOrderMapper.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select id, type, mr_number, patient_name, delivery, tracking_number, discharge_date, times, applicant_id, hospital, address, download_url, unzip_pwd, status, create_time, update_time from mr_record_order + + + + + + + + + + insert into mr_record_order + + type, + mr_number, + patient_name, + discharge_date, + times, + applicant_id, + hospital, + address, + download_url, + unzip_pwd, + status, + create_time, + update_time, + delivery, + tracking_number, + + + #{type}, + #{mrNumber}, + #{patientName}, + #{dischargeDate}, + #{times}, + #{applicantId}, + #{hospital}, + #{address}, + #{downloadUrl}, + #{unzipPwd}, + #{status}, + #{createTime}, + #{updateTime}, + #{delivery}, + #{trackingNumber} + + + + + update mr_record_order + + type = #{type}, + mr_number = #{mrNumber}, + patient_name = #{patientName}, + discharge_date = #{dischargeDate}, + times = #{times}, + applicant_id = #{applicantId}, + hospital = #{hospital}, + address = #{address}, + download_url = #{downloadUrl}, + unzip_pwd = #{unzipPwd}, + status = #{status}, + create_time = #{createTime}, + update_time = #{updateTime}, + delivery = #{delivery}, + tracking_number = #{trackingNumber}, + + where id = #{id} + + + + delete from mr_record_order where id = #{id} + + + + delete from mr_record_order where id in + + #{id} + + + + + + + + insert into code_url (code,url,headers)values(#{code},#{url},#{headers}) + + + \ No newline at end of file diff --git a/wx-record-order/src/main/resources/mapper/wx/WxUserMapper.xml b/wx-record-order/src/main/resources/mapper/wx/WxUserMapper.xml new file mode 100644 index 00000000..8cbdab15 --- /dev/null +++ b/wx-record-order/src/main/resources/mapper/wx/WxUserMapper.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + select id, name, phone, openid, status, flag, hospital, address, create_time, update_time, nickname, avatar, token from wx_user + + + + + + + + + + + + + insert into wx_user + + name, + phone, + openid, + status, + flag, + hospital, + address, + create_time, + update_time, + nickname, + avatar, + token, + + + #{name}, + #{phone}, + #{openid}, + #{status}, + #{flag}, + #{hospital}, + #{address}, + #{createTime}, + #{updateTime}, + #{nickname}, + #{avatar}, + #{token}, + + + + + update wx_user + + name = #{name}, + phone = #{phone}, + openid = #{openid}, + status = #{status}, + flag = #{flag}, + hospital = #{hospital}, + address = #{address}, + create_time = #{createTime}, + update_time = #{updateTime}, + nickname = #{nickname}, + avatar = #{avatar}, + token = #{token}, + + where id = #{id} + + + + delete from wx_user where id = #{id} + + + + delete from wx_user where id in + + #{id} + + + + \ No newline at end of file diff --git a/wx-record-order/src/main/resources/templates/wx/order/add.html b/wx-record-order/src/main/resources/templates/wx/order/add.html new file mode 100644 index 00000000..b06fc6a6 --- /dev/null +++ b/wx-record-order/src/main/resources/templates/wx/order/add.html @@ -0,0 +1,135 @@ + + + + + + + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ + +
+
+
+
+ +
+ +
+
+
+ +
+
+ +
+ + +
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ + +
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/wx-record-order/src/main/resources/templates/wx/order/edit.html b/wx-record-order/src/main/resources/templates/wx/order/edit.html new file mode 100644 index 00000000..670b970c --- /dev/null +++ b/wx-record-order/src/main/resources/templates/wx/order/edit.html @@ -0,0 +1,81 @@ + + + + + + + +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ + +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/wx-record-order/src/main/resources/templates/wx/order/order.html b/wx-record-order/src/main/resources/templates/wx/order/order.html new file mode 100644 index 00000000..f90dbdf6 --- /dev/null +++ b/wx-record-order/src/main/resources/templates/wx/order/order.html @@ -0,0 +1,171 @@ + + + + + + +
+
+
+
+
+
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • +  搜索 +  重置 +
  • +
+
+
+
+ + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/wx-record-order/src/main/resources/templates/wx/order/sendView.html b/wx-record-order/src/main/resources/templates/wx/order/sendView.html new file mode 100644 index 00000000..4d27763c --- /dev/null +++ b/wx-record-order/src/main/resources/templates/wx/order/sendView.html @@ -0,0 +1,69 @@ + + + + + + + + +
+
+ + +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + + + \ No newline at end of file diff --git a/wx-record-order/src/main/resources/templates/wx/user/add.html b/wx-record-order/src/main/resources/templates/wx/user/add.html new file mode 100644 index 00000000..6d9f6670 --- /dev/null +++ b/wx-record-order/src/main/resources/templates/wx/user/add.html @@ -0,0 +1,76 @@ + + + + + + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ + +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/wx-record-order/src/main/resources/templates/wx/user/edit.html b/wx-record-order/src/main/resources/templates/wx/user/edit.html new file mode 100644 index 00000000..4daae263 --- /dev/null +++ b/wx-record-order/src/main/resources/templates/wx/user/edit.html @@ -0,0 +1,44 @@ + + + + + + +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/wx-record-order/src/main/resources/templates/wx/user/user.html b/wx-record-order/src/main/resources/templates/wx/user/user.html new file mode 100644 index 00000000..0aee9990 --- /dev/null +++ b/wx-record-order/src/main/resources/templates/wx/user/user.html @@ -0,0 +1,159 @@ + + + + + + +
+
+
+
+
+
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • +  搜索 +  重置 +
  • +
+
+
+
+ + +
+
+
+
+
+ + + + \ No newline at end of file