Browse Source

初始化

linxk 1 month ago
commit
fa1145c085
100 changed files with 9048 additions and 0 deletions
  1. 26 0
      .gitignore
  2. 45 0
      README.md
  3. 24 0
      backstage-api/pom.xml
  4. 80 0
      backstage-api/src/main/java/com/medipath/dto/MytestDTO.java
  5. 332 0
      backstage-api/src/main/java/com/medipath/dto/PermissionDTO.java
  6. 92 0
      backstage-api/src/main/java/com/medipath/dto/Result.java
  7. 185 0
      backstage-api/src/main/java/com/medipath/dto/RoleDTO.java
  8. 79 0
      backstage-api/src/main/java/com/medipath/dto/RolePermissionDTO.java
  9. 290 0
      backstage-api/src/main/java/com/medipath/dto/UserDTO.java
  10. 79 0
      backstage-api/src/main/java/com/medipath/dto/UserRoleDTO.java
  11. 94 0
      backstage-service/pom.xml
  12. 97 0
      backstage-service/src/main/java/com/medipath/backstage/BackstageApplication.java
  13. 19 0
      backstage-service/src/main/java/com/medipath/backstage/FeignConfiguration.java
  14. 284 0
      backstage-service/src/main/java/com/medipath/backstage/configurer/MyWebMvcConfigurer.java
  15. 49 0
      backstage-service/src/main/java/com/medipath/backstage/configurer/MybatisConfigurer.java
  16. 44 0
      backstage-service/src/main/java/com/medipath/backstage/configurer/Parameters.java
  17. 62 0
      backstage-service/src/main/java/com/medipath/backstage/configurer/SwaggerConfig.java
  18. 48 0
      backstage-service/src/main/java/com/medipath/backstage/configurer/WebLogAspect.java
  19. 14 0
      backstage-service/src/main/java/com/medipath/backstage/consts/AuthConst.java
  20. 9 0
      backstage-service/src/main/java/com/medipath/backstage/consts/SymbolConst.java
  21. 85 0
      backstage-service/src/main/java/com/medipath/backstage/core/AbstractService.java
  22. 56 0
      backstage-service/src/main/java/com/medipath/backstage/core/BaseBeen.java
  23. 19 0
      backstage-service/src/main/java/com/medipath/backstage/core/Mapper.java
  24. 47 0
      backstage-service/src/main/java/com/medipath/backstage/core/MessageTemplteType.java
  25. 29 0
      backstage-service/src/main/java/com/medipath/backstage/core/ProjectConstant.java
  26. 595 0
      backstage-service/src/main/java/com/medipath/backstage/core/RedisUtil.java
  27. 100 0
      backstage-service/src/main/java/com/medipath/backstage/core/ResultCode.java
  28. 37 0
      backstage-service/src/main/java/com/medipath/backstage/core/ResultGenerator.java
  29. 22 0
      backstage-service/src/main/java/com/medipath/backstage/core/Service.java
  30. 57 0
      backstage-service/src/main/java/com/medipath/backstage/core/SmsTempletType.java
  31. 34 0
      backstage-service/src/main/java/com/medipath/backstage/core/cache/CacheKey.java
  32. 26 0
      backstage-service/src/main/java/com/medipath/backstage/core/cache/CacheType.java
  33. 13 0
      backstage-service/src/main/java/com/medipath/backstage/core/interceptor/LoginType.java
  34. 13 0
      backstage-service/src/main/java/com/medipath/backstage/core/interceptor/NoToken.java
  35. 21 0
      backstage-service/src/main/java/com/medipath/backstage/core/interceptor/ThreadUser.java
  36. 7 0
      backstage-service/src/main/java/com/medipath/backstage/dao/MytestMapper.java
  37. 21 0
      backstage-service/src/main/java/com/medipath/backstage/dao/PermissionMapper.java
  38. 7 0
      backstage-service/src/main/java/com/medipath/backstage/dao/RoleMapper.java
  39. 7 0
      backstage-service/src/main/java/com/medipath/backstage/dao/RolePermissionMapper.java
  40. 7 0
      backstage-service/src/main/java/com/medipath/backstage/dao/UserMapper.java
  41. 7 0
      backstage-service/src/main/java/com/medipath/backstage/dao/UserRoleMapper.java
  42. 29 0
      backstage-service/src/main/java/com/medipath/backstage/dto/AuthPermissionUrl.java
  43. 23 0
      backstage-service/src/main/java/com/medipath/backstage/dto/LoginUser.java
  44. 19 0
      backstage-service/src/main/java/com/medipath/backstage/dto/PermissionGroupDto.java
  45. 17 0
      backstage-service/src/main/java/com/medipath/backstage/dto/ResultAuthPermissionUrl.java
  46. 187 0
      backstage-service/src/main/java/com/medipath/backstage/filter/AccessFilter.java
  47. 58 0
      backstage-service/src/main/java/com/medipath/backstage/model/Mytest.java
  48. 387 0
      backstage-service/src/main/java/com/medipath/backstage/model/Permission.java
  49. 216 0
      backstage-service/src/main/java/com/medipath/backstage/model/Role.java
  50. 79 0
      backstage-service/src/main/java/com/medipath/backstage/model/RolePermission.java
  51. 356 0
      backstage-service/src/main/java/com/medipath/backstage/model/User.java
  52. 58 0
      backstage-service/src/main/java/com/medipath/backstage/model/UserRole.java
  53. 22 0
      backstage-service/src/main/java/com/medipath/backstage/mq/RabbitConfig.java
  54. 31 0
      backstage-service/src/main/java/com/medipath/backstage/mq/Receiver.java
  55. 15 0
      backstage-service/src/main/java/com/medipath/backstage/mq/Sender.java
  56. 10 0
      backstage-service/src/main/java/com/medipath/backstage/service/MytestService.java
  57. 17 0
      backstage-service/src/main/java/com/medipath/backstage/service/PermissionService.java
  58. 15 0
      backstage-service/src/main/java/com/medipath/backstage/service/RolePermissionService.java
  59. 12 0
      backstage-service/src/main/java/com/medipath/backstage/service/RoleService.java
  60. 13 0
      backstage-service/src/main/java/com/medipath/backstage/service/UserRoleService.java
  61. 14 0
      backstage-service/src/main/java/com/medipath/backstage/service/UserService.java
  62. 22 0
      backstage-service/src/main/java/com/medipath/backstage/service/impl/MytestServiceImpl.java
  63. 32 0
      backstage-service/src/main/java/com/medipath/backstage/service/impl/PermissionServiceImpl.java
  64. 59 0
      backstage-service/src/main/java/com/medipath/backstage/service/impl/RolePermissionServiceImpl.java
  65. 52 0
      backstage-service/src/main/java/com/medipath/backstage/service/impl/RoleServiceImpl.java
  66. 27 0
      backstage-service/src/main/java/com/medipath/backstage/service/impl/UserRoleServiceImpl.java
  67. 74 0
      backstage-service/src/main/java/com/medipath/backstage/service/impl/UserServiceImpl.java
  68. 47 0
      backstage-service/src/main/java/com/medipath/backstage/task/CouponExpireNoticeTask.java
  69. 24 0
      backstage-service/src/main/java/com/medipath/backstage/task/RefreshPermissionTask.java
  70. 233 0
      backstage-service/src/main/java/com/medipath/backstage/util/Base64.java
  71. 85 0
      backstage-service/src/main/java/com/medipath/backstage/util/ConvertUtil.java
  72. 44 0
      backstage-service/src/main/java/com/medipath/backstage/util/FilterUrlMatcherUtil.java
  73. 31 0
      backstage-service/src/main/java/com/medipath/backstage/util/Md5Check.java
  74. 491 0
      backstage-service/src/main/java/com/medipath/backstage/util/OSSUtil.java
  75. 121 0
      backstage-service/src/main/java/com/medipath/backstage/util/StringUtil.java
  76. 47 0
      backstage-service/src/main/java/com/medipath/backstage/util/UserUtil.java
  77. 196 0
      backstage-service/src/main/java/com/medipath/backstage/web/LoginController.java
  78. 407 0
      backstage-service/src/main/java/com/medipath/backstage/web/PermissionController.java
  79. 278 0
      backstage-service/src/main/java/com/medipath/backstage/web/RoleController.java
  80. 53 0
      backstage-service/src/main/java/com/medipath/backstage/web/TestRedisController.java
  81. 269 0
      backstage-service/src/main/java/com/medipath/backstage/web/UserController.java
  82. 53 0
      backstage-service/src/main/java/com/medipath/backstage/web/mng/MytestController.java
  83. 40 0
      backstage-service/src/main/java/com/medipath/backstage/web/para/LoginAccountParameters.java
  84. 276 0
      backstage-service/src/main/java/com/medipath/backstage/web/para/PermissionBo.java
  85. 40 0
      backstage-service/src/main/java/com/medipath/backstage/web/para/RestpwdParameters.java
  86. 29 0
      backstage-service/src/main/java/com/medipath/backstage/web/para/UserParameters.java
  87. 26 0
      backstage-service/src/main/java/com/medipath/backstage/web/para/UserQueryParameters.java
  88. 83 0
      backstage-service/src/main/resources/bootstrap.properties
  89. 92 0
      backstage-service/src/main/resources/logback.xml
  90. 12 0
      backstage-service/src/main/resources/mapper/MytestMapper.xml
  91. 64 0
      backstage-service/src/main/resources/mapper/PermissionMapper.xml
  92. 17 0
      backstage-service/src/main/resources/mapper/RoleMapper.xml
  93. 12 0
      backstage-service/src/main/resources/mapper/RolePermissionMapper.xml
  94. 22 0
      backstage-service/src/main/resources/mapper/UserMapper.xml
  95. 12 0
      backstage-service/src/main/resources/mapper/UserRoleMapper.xml
  96. 26 0
      backstage-service/src/main/resources/templates/uploadimg.html
  97. 437 0
      backstage-service/src/test/java/CodeGenerator.java
  98. 313 0
      backstage-service/src/test/java/com/conpany/project/MyCommentGenerator.java
  99. 110 0
      backstage-service/src/test/java/com/conpany/project/SerializablePlugin.java
  100. 52 0
      backstage-service/src/test/java/com/conpany/project/TestRedis.java

+ 26 - 0
.gitignore

@@ -0,0 +1,26 @@
+/target/
+!.mvn/wrapper/maven-wrapper.jar
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+/build/
+target/

+ 45 - 0
README.md

@@ -0,0 +1,45 @@
+![Licence](https://img.shields.io/badge/licence-none-green.svg)
+[![GitHub Release](https://img.shields.io/github/release/lihengming/spring-boot-api-project-seed.svg)](https://github.com/lihengming/spring-boot-api-project-seed/releases)
+## 简介
+Spring Boot API Project Seed 是一个基于Spring Boot & MyBatis的种子项目,用于快速构建中小型API、RESTful API项目,该种子项目已经有过多个真实项目的实践,稳定、简单、快速,使我们摆脱那些重复劳动,专注于业务代码的编写,减少加班。下面是一个简单的使用演示,看如何基于本项目在短短几十秒钟内实现一套简单的API,并运行提供服务。
+
+[![请选择超清](https://raw.githubusercontent.com/lihengming/java-codes/master/shared-resources/github-images/project-example-youku.png)](http://v.youku.com/v_show/id_XMjg1NjYwNDgxNg==.html?spm=a2h3j.8428770.3416059.1)
+## 特征&提供
+- 最佳实践的项目结构、配置文件、精简的POM([查看项目结构图](https://github.com/lihengming/java-codes/blob/master/shared-resources/github-images/project-struct.png))
+- 统一响应结果封装及生成工具
+- 统一异常处理
+- 简单的接口签名认证
+- 常用基础方法抽象封装
+- 使用Druid Spring Boot Starter 集成Druid数据库连接池与监控
+- 使用FastJsonHttpMessageConverter,提高JSON序列化速度
+- 集成MyBatis、通用Mapper插件、PageHelper分页插件,实现单表业务零SQL
+- 提供代码生成器根据表名生成对应的Model、Mapper、MapperXML、Service、ServiceImpl、Controller等基础代码,其中Controller模板默认提供POST和RESTful两套,根据需求在```CodeGenerator.genController(tableName)```方法中自己选择,默认使用POST模板。代码模板可根据实际项目的需求来扩展,由于每个公司业务都不太一样,所以只提供了一些比较基础、通用的模板,主要是提供一个思路来减少重复代码的编写,我在实际项目的使用中,其实根据公司业务的抽象编写了大量的模板。另外,使用模板也有助于保持团队代码风格的统一
+- 另有彩蛋,待你探索
+## 快速开始
+1. 克隆项目
+2. 对```test```包内的代码生成器```CodeGenerator```进行配置,主要是JDBC,因为要根据表名来生成代码
+3. 如果只是想根据上面的演示来亲自试试的话可以使用```test resources```目录下的```demo-user.sql```,否则忽略该步
+3. 输入表名,运行```CodeGenerator.main()```方法,生成基础代码(可能需要刷新项目目录才会出来)
+4. 根据业务在基础代码上进行扩展
+5. 对开发环境配置文件```application-dev.properties```进行配置,启动项目,Have Fun!
+## 开发建议
+- 表名,建议使用小写,多个单词使用下划线拼接
+- Model内成员变量建议与表字段数量对应,如需扩展成员变量(比如连表查询)建议创建DTO,否则需在扩展的成员变量上加```@Transient```注解,详情见[通用Mapper插件文档说明](https://mapperhelper.github.io/docs/2.use/)
+- 建议业务失败直接使用```ServiceException("message")```抛出,由统一异常处理器来封装业务失败的响应结果,比如```throw new ServiceException("该手机号已被注册")```,会直接被封装为```{"code":400,"message":"该手机号已被注册"}```返回,无需自己处理,尽情抛出
+- 需要工具类的话建议先从```apache-commons-*```和```guava```中找,实在没有再造轮子或引入类库,尽量精简项目
+- 开发规范建议遵循阿里巴巴Java开发手册([最新版下载](https://github.com/lihengming/java-codes/blob/master/shared-resources/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8CV1.2.0.pdf))
+- 建议在公司内部使用[ShowDoc](https://github.com/star7th/showdoc)、[SpringFox-Swagger2](https://github.com/springfox/springfox) 、[RAP](https://github.com/thx/RAP)等开源项目来编写、管理API文档
+## 技术选型&文档
+- Spring Boot([查看Spring Boot学习&使用指南](http://www.jianshu.com/p/1a9fd8936bd8))
+- MyBatis([查看官方中文文档](http://www.mybatis.org/mybatis-3/zh/index.html))
+- MyBatisb通用Mapper插件([查看官方中文文档](https://mapperhelper.github.io/docs/))
+- MyBatis PageHelper分页插件([查看官方中文文档](https://pagehelper.github.io/))
+- Druid Spring Boot Starter([查看官方中文文档](https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter/))
+- Fastjson([查看官方中文文档](https://github.com/Alibaba/fastjson/wiki/%E9%A6%96%E9%A1%B5))
+- 其他略
+1
+## License
+无,纯粹开源分享,感谢大家 [Star](https://github.com/lihengming/spring-boot-api-project-seed/stargazers) & [Fork](https://github.com/lihengming/spring-boot-api-project-seed/network/members) 的支持。

+ 24 - 0
backstage-api/pom.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>backstage</artifactId>
+        <groupId>com.medipath</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>backstage-api</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <dependencies>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.10</version>
+            <scope>provided</scope>
+        </dependency>
+
+
+    </dependencies>
+
+</project>

+ 80 - 0
backstage-api/src/main/java/com/medipath/dto/MytestDTO.java

@@ -0,0 +1,80 @@
+/*
+*
+* MytestDTO.java
+* Copyright(C) 2017-2020 fendo公司
+* @date 2022-04-06
+*/
+package com.medipath.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class MytestDTO implements Serializable {
+    /**
+     * 
+     */
+    private Integer id;
+
+    /**
+     * 
+     */
+    private String content;
+
+    /**
+     * 
+     */
+    private Date createTime;
+
+    /**
+     * m_mytest
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     * @return id 
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * 
+     * @param id 
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 
+     * @return content 
+     */
+    public String getContent() {
+        return content;
+    }
+
+    /**
+     * 
+     * @param content 
+     */
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    /**
+     * 
+     * @return create_time 
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    /**
+     * 
+     * @param createTime 
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+}

+ 332 - 0
backstage-api/src/main/java/com/medipath/dto/PermissionDTO.java

@@ -0,0 +1,332 @@
+/*
+*
+* PermissionDTO.java
+* Copyright(C) 2017-2020 fendo公司
+* @date 2019-11-01
+*/
+package com.medipath.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class PermissionDTO implements Serializable {
+    /**
+     * 
+     */
+    private Integer id;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 英文名
+     */
+    private String eName;
+
+    /**
+     * logo图
+     */
+    private String logo;
+
+    /**
+     * 类型 0 菜单 1 页面 2动作
+     */
+    private String type;
+
+    /**
+     * 是否允许点击
+     */
+    private String isAction;
+
+    /**
+     * 状态 0正常 1禁用
+     */
+    private Integer status;
+
+    /**
+     * 跳转地址
+     */
+    private String url;
+
+    /**
+     * 前端排版
+     */
+    private String composingKey;
+
+    /**
+     * 排序
+     */
+    private Integer seq;
+
+    /**
+     * 上级菜单
+     */
+    private String parentId;
+
+    /**
+     * 创建人
+     */
+    private String createUserId;
+
+    /**
+     * 更新人
+     */
+    private String updateUserId;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * b_permission
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     * @return id 
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * 
+     * @param id 
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 名称
+     * @return name 名称
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 名称
+     * @param name 名称
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 英文名
+     * @return e_name 英文名
+     */
+    public String geteName() {
+        return eName;
+    }
+
+    /**
+     * 英文名
+     * @param eName 英文名
+     */
+    public void seteName(String eName) {
+        this.eName = eName;
+    }
+
+    /**
+     * logo图
+     * @return logo logo图
+     */
+    public String getLogo() {
+        return logo;
+    }
+
+    /**
+     * logo图
+     * @param logo logo图
+     */
+    public void setLogo(String logo) {
+        this.logo = logo;
+    }
+
+    /**
+     * 类型 0 菜单 1 页面 2动作
+     * @return type 类型 0 菜单 1 页面 2动作
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * 类型 0 菜单 1 页面 2动作
+     * @param type 类型 0 菜单 1 页面 2动作
+     */
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * 是否允许点击
+     * @return is_action 是否允许点击
+     */
+    public String getIsAction() {
+        return isAction;
+    }
+
+    /**
+     * 是否允许点击
+     * @param isAction 是否允许点击
+     */
+    public void setIsAction(String isAction) {
+        this.isAction = isAction;
+    }
+
+    /**
+     * 状态 0正常 1禁用
+     * @return status 状态 0正常 1禁用
+     */
+    public Integer getStatus() {
+        return status;
+    }
+
+    /**
+     * 状态 0正常 1禁用
+     * @param status 状态 0正常 1禁用
+     */
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    /**
+     * 跳转地址
+     * @return url 跳转地址
+     */
+    public String getUrl() {
+        return url;
+    }
+
+    /**
+     * 跳转地址
+     * @param url 跳转地址
+     */
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    /**
+     * 前端排版
+     * @return composing_key 前端排版
+     */
+    public String getComposingKey() {
+        return composingKey;
+    }
+
+    /**
+     * 前端排版
+     * @param composingKey 前端排版
+     */
+    public void setComposingKey(String composingKey) {
+        this.composingKey = composingKey;
+    }
+
+    /**
+     * 排序
+     * @return seq 排序
+     */
+    public Integer getSeq() {
+        return seq;
+    }
+
+    /**
+     * 排序
+     * @param seq 排序
+     */
+    public void setSeq(Integer seq) {
+        this.seq = seq;
+    }
+
+    /**
+     * 上级菜单
+     * @return parent_id 上级菜单
+     */
+    public String getParentId() {
+        return parentId;
+    }
+
+    /**
+     * 上级菜单
+     * @param parentId 上级菜单
+     */
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    /**
+     * 创建人
+     * @return create_user_id 创建人
+     */
+    public String getCreateUserId() {
+        return createUserId;
+    }
+
+    /**
+     * 创建人
+     * @param createUserId 创建人
+     */
+    public void setCreateUserId(String createUserId) {
+        this.createUserId = createUserId;
+    }
+
+    /**
+     * 更新人
+     * @return update_user_id 更新人
+     */
+    public String getUpdateUserId() {
+        return updateUserId;
+    }
+
+    /**
+     * 更新人
+     * @param updateUserId 更新人
+     */
+    public void setUpdateUserId(String updateUserId) {
+        this.updateUserId = updateUserId;
+    }
+
+    /**
+     * 创建时间
+     * @return create_time 创建时间
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    /**
+     * 创建时间
+     * @param createTime 创建时间
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * 更新时间
+     * @return update_time 更新时间
+     */
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    /**
+     * 更新时间
+     * @param updateTime 更新时间
+     */
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 92 - 0
backstage-api/src/main/java/com/medipath/dto/Result.java

@@ -0,0 +1,92 @@
+package com.medipath.dto;
+
+
+import java.io.Serializable;
+
+/**
+ * 统一API响应结果封装
+ */
+public class Result<T> implements Serializable {
+    private String code;
+    private String message;
+    private T data;
+
+    public Result() {
+    }
+
+    public Result(String code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Result(String code, String message, T data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public Result setCode(String code) {
+        this.code = code;
+        return this;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public Result setMessage(String message) {
+        this.message = message;
+        return this;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public Result setData(T data) {
+        this.data = data;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString();
+    }
+
+    public static Result genSuccessResult() {
+        return new Result()
+                .setCode("200")
+                .setMessage("操作成功");
+    }
+
+    public static Result genSuccessResult(Object data) {
+        return new Result()
+                .setCode("200")
+                .setMessage("操作成功")
+                .setData(data);
+    }
+
+    public static Result genResult(String code,String message) {
+        return new Result()
+                .setCode(code)
+                .setMessage(message);
+    }
+
+    public static Result genFailResult(String code,String message,Object data) {
+        return new Result()
+                .setCode(code)
+                .setMessage(message)
+                .setData(data);
+    }
+
+    public static Result genFailResult(Object data) {
+        return new Result()
+                .setCode("400")
+                .setMessage("操作失败")
+                .setData(data);
+    }
+}

+ 185 - 0
backstage-api/src/main/java/com/medipath/dto/RoleDTO.java

@@ -0,0 +1,185 @@
+/*
+*
+* RoleDTO.java
+* Copyright(C) 2017-2020 fendo公司
+* @date 2019-11-01
+*/
+package com.medipath.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class RoleDTO implements Serializable {
+    /**
+     * 
+     */
+    private Integer id;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 保留
+     */
+    private String type;
+
+    /**
+     * 状态 0启用 1禁用
+     */
+    private String status;
+
+    /**
+     * 创建人
+     */
+    private String createUserId;
+
+    /**
+     * 更新人
+     */
+    private String updateUserId;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * b_role
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     * @return id 
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * 
+     * @param id 
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 名称
+     * @return name 名称
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 名称
+     * @param name 名称
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 保留
+     * @return type 保留
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * 保留
+     * @param type 保留
+     */
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * 状态 0启用 1禁用
+     * @return status 状态 0启用 1禁用
+     */
+    public String getStatus() {
+        return status;
+    }
+
+    /**
+     * 状态 0启用 1禁用
+     * @param status 状态 0启用 1禁用
+     */
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    /**
+     * 创建人
+     * @return create_user_id 创建人
+     */
+    public String getCreateUserId() {
+        return createUserId;
+    }
+
+    /**
+     * 创建人
+     * @param createUserId 创建人
+     */
+    public void setCreateUserId(String createUserId) {
+        this.createUserId = createUserId;
+    }
+
+    /**
+     * 更新人
+     * @return update_user_id 更新人
+     */
+    public String getUpdateUserId() {
+        return updateUserId;
+    }
+
+    /**
+     * 更新人
+     * @param updateUserId 更新人
+     */
+    public void setUpdateUserId(String updateUserId) {
+        this.updateUserId = updateUserId;
+    }
+
+    /**
+     * 创建时间
+     * @return create_time 创建时间
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    /**
+     * 创建时间
+     * @param createTime 创建时间
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * 更新时间
+     * @return update_time 更新时间
+     */
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    /**
+     * 更新时间
+     * @param updateTime 更新时间
+     */
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 79 - 0
backstage-api/src/main/java/com/medipath/dto/RolePermissionDTO.java

@@ -0,0 +1,79 @@
+/*
+*
+* RolePermissionDTO.java
+* Copyright(C) 2017-2020 fendo公司
+* @date 2019-11-01
+*/
+package com.medipath.dto;
+
+import java.io.Serializable;
+
+public class RolePermissionDTO implements Serializable {
+    /**
+     * 
+     */
+    private Integer id;
+
+    /**
+     * 角色id
+     */
+    private String roleId;
+
+    /**
+     * 权限id
+     */
+    private String permissionId;
+
+    /**
+     * b_role_permission
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     * @return id 
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * 
+     * @param id 
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 角色id
+     * @return role_id 角色id
+     */
+    public String getRoleId() {
+        return roleId;
+    }
+
+    /**
+     * 角色id
+     * @param roleId 角色id
+     */
+    public void setRoleId(String roleId) {
+        this.roleId = roleId;
+    }
+
+    /**
+     * 权限id
+     * @return permission_id 权限id
+     */
+    public String getPermissionId() {
+        return permissionId;
+    }
+
+    /**
+     * 权限id
+     * @param permissionId 权限id
+     */
+    public void setPermissionId(String permissionId) {
+        this.permissionId = permissionId;
+    }
+}

+ 290 - 0
backstage-api/src/main/java/com/medipath/dto/UserDTO.java

@@ -0,0 +1,290 @@
+/*
+*
+* UserDTO.java
+* Copyright(C) 2017-2020 fendo公司
+* @date 2019-11-01
+*/
+package com.medipath.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class UserDTO implements Serializable {
+    /**
+     * 
+     */
+    private Integer id;
+
+    /**
+     * 姓名
+     */
+    private String name;
+
+    /**
+     * 登录账号
+     */
+    private String loginAccount;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 密码盐
+     */
+    private String salt;
+
+    /**
+     * 手机号码
+     */
+    private String phoneNo;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 状态 0 正常 1注销 
+     */
+    private String status;
+
+    /**
+     * 公司id
+     */
+    private String companyId;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 创建人
+     */
+    private String createUserId;
+
+    /**
+     * 更新人
+     */
+    private String updateUserId;
+
+    /**
+     * b_user
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     * @return id 
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * 
+     * @param id 
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 姓名
+     * @return name 姓名
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 姓名
+     * @param name 姓名
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 登录账号
+     * @return login_account 登录账号
+     */
+    public String getLoginAccount() {
+        return loginAccount;
+    }
+
+    /**
+     * 登录账号
+     * @param loginAccount 登录账号
+     */
+    public void setLoginAccount(String loginAccount) {
+        this.loginAccount = loginAccount;
+    }
+
+    /**
+     * 密码
+     * @return password 密码
+     */
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+     * 密码
+     * @param password 密码
+     */
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    /**
+     * 密码盐
+     * @return salt 密码盐
+     */
+    public String getSalt() {
+        return salt;
+    }
+
+    /**
+     * 密码盐
+     * @param salt 密码盐
+     */
+    public void setSalt(String salt) {
+        this.salt = salt;
+    }
+
+    /**
+     * 手机号码
+     * @return phone_no 手机号码
+     */
+    public String getPhoneNo() {
+        return phoneNo;
+    }
+
+    /**
+     * 手机号码
+     * @param phoneNo 手机号码
+     */
+    public void setPhoneNo(String phoneNo) {
+        this.phoneNo = phoneNo;
+    }
+
+    /**
+     * 邮箱
+     * @return email 邮箱
+     */
+    public String getEmail() {
+        return email;
+    }
+
+    /**
+     * 邮箱
+     * @param email 邮箱
+     */
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    /**
+     * 状态 0 正常 1注销 
+     * @return status 状态 0 正常 1注销 
+     */
+    public String getStatus() {
+        return status;
+    }
+
+    /**
+     * 状态 0 正常 1注销 
+     * @param status 状态 0 正常 1注销 
+     */
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    /**
+     * 公司id
+     * @return company_id 公司id
+     */
+    public String getCompanyId() {
+        return companyId;
+    }
+
+    /**
+     * 公司id
+     * @param companyId 公司id
+     */
+    public void setCompanyId(String companyId) {
+        this.companyId = companyId;
+    }
+
+    /**
+     * 创建时间
+     * @return create_time 创建时间
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    /**
+     * 创建时间
+     * @param createTime 创建时间
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * 更新时间
+     * @return update_time 更新时间
+     */
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    /**
+     * 更新时间
+     * @param updateTime 更新时间
+     */
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    /**
+     * 创建人
+     * @return create_user_id 创建人
+     */
+    public String getCreateUserId() {
+        return createUserId;
+    }
+
+    /**
+     * 创建人
+     * @param createUserId 创建人
+     */
+    public void setCreateUserId(String createUserId) {
+        this.createUserId = createUserId;
+    }
+
+    /**
+     * 更新人
+     * @return update_user_id 更新人
+     */
+    public String getUpdateUserId() {
+        return updateUserId;
+    }
+
+    /**
+     * 更新人
+     * @param updateUserId 更新人
+     */
+    public void setUpdateUserId(String updateUserId) {
+        this.updateUserId = updateUserId;
+    }
+}

+ 79 - 0
backstage-api/src/main/java/com/medipath/dto/UserRoleDTO.java

@@ -0,0 +1,79 @@
+/*
+*
+* UserRoleDTO.java
+* Copyright(C) 2017-2020 fendo公司
+* @date 2019-11-01
+*/
+package com.medipath.dto;
+
+import java.io.Serializable;
+
+public class UserRoleDTO implements Serializable {
+    /**
+     * 
+     */
+    private Integer id;
+
+    /**
+     * 
+     */
+    private Integer userId;
+
+    /**
+     * 
+     */
+    private Integer roleId;
+
+    /**
+     * b_user_role
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     * @return id 
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * 
+     * @param id 
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 
+     * @return user_id 
+     */
+    public Integer getUserId() {
+        return userId;
+    }
+
+    /**
+     * 
+     * @param userId 
+     */
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    /**
+     * 
+     * @return role_id 
+     */
+    public Integer getRoleId() {
+        return roleId;
+    }
+
+    /**
+     * 
+     * @param roleId 
+     */
+    public void setRoleId(Integer roleId) {
+        this.roleId = roleId;
+    }
+}

+ 94 - 0
backstage-service/pom.xml

@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <artifactId>backstage</artifactId>
+        <groupId>com.medipath</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>backstage-service</artifactId>
+    <packaging>jar</packaging>
+    <version>1.0.0-SNAPSHOT</version>
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+
+    <!-- Inherit defaults from Spring Boot -->
+    <dependencies>
+        <!--Spring Boot依赖-->
+<!--        <dependency>-->
+<!--            <groupId>com.yiweikeji</groupId>-->
+<!--            <artifactId>operating-interface</artifactId>-->
+<!--            <version>1.0.0-SNAPSHOT</version>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>com.medipath</groupId>-->
+<!--            <artifactId>cif-api</artifactId>-->
+<!--            <version>1.0.0-SNAPSHOT</version>-->
+<!--        </dependency>-->
+
+
+        <!--异维科技公共包依赖-->
+        <dependency>
+            <groupId>com.medipath</groupId>
+            <artifactId>common</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+
+        <!--异维科技dubbo接口包依赖-->
+        <dependency>
+            <groupId>com.medipath</groupId>
+            <artifactId>backstage-api</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
+        </dependency>
+
+        <!--test依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.esotericsoftware</groupId>
+            <artifactId>kryo</artifactId>
+            <version>4.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>de.javakaffee</groupId>
+            <artifactId>kryo-serializers</artifactId>
+            <version>0.45</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+    	<plugins>
+	           <plugin>
+	                <groupId>org.springframework.boot</groupId>
+	                <artifactId>spring-boot-maven-plugin</artifactId>
+	                <configuration>
+	                	<finalName>backstage</finalName>
+	                </configuration>
+	            </plugin>
+	            <plugin>
+	                <artifactId>maven-compiler-plugin</artifactId>
+	                <configuration>
+	                    <source>${java.version}</source>
+	                    <target>${java.version}</target>
+	                    <encoding>UTF-8</encoding>
+	                </configuration>
+	            </plugin>
+          </plugins>
+    </build>
+    
+
+</project>

+ 97 - 0
backstage-service/src/main/java/com/medipath/backstage/BackstageApplication.java

@@ -0,0 +1,97 @@
+package com.medipath.backstage;
+
+import cn.hutool.core.util.StrUtil;
+import com.spring4all.swagger.EnableSwagger2Doc;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
+import org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapper;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import springfox.documentation.swagger.web.SwaggerResource;
+import springfox.documentation.swagger.web.SwaggerResourcesProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@EnableZuulProxy
+@EnableDiscoveryClient
+@SpringBootApplication
+@EnableSwagger2Doc
+@EnableFeignClients(basePackages = {"com.medipath"})
+public class BackstageApplication extends SpringBootServletInitializer {
+
+    @Value("${swagger.resource}")
+    private String        swaggerResource;
+
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+        return application.sources(BackstageApplication.class);
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        SpringApplication.run(BackstageApplication.class, args);
+    }
+
+    @Bean
+    public PatternServiceRouteMapper serviceRouteMapper() {
+        return new PatternServiceRouteMapper(
+                "(?<name>^.+)-(?<version>v.+$)",
+                "${version}/${name}");
+    }
+
+    @Component
+    @Primary
+    class DocumentationConfig implements SwaggerResourcesProvider {
+        @Override
+        public List<SwaggerResource> get() {
+            List resources = new ArrayList<>();
+            resources.add(swaggerResource("backstage", "/v2/api-docs", "1.0"));
+            if (StrUtil.isNotBlank(swaggerResource)){
+                for (String resource:swaggerResource.split(",")) {
+                    resources.add(swaggerResource(resource, "/"+resource+"/v2/api-docs", "1.0"));
+                }
+            }
+            return resources;
+        }
+
+        private SwaggerResource swaggerResource(String name, String location, String version) {
+            SwaggerResource swaggerResource = new SwaggerResource();
+            swaggerResource.setName(name);
+            swaggerResource.setLocation(location);
+            swaggerResource.setSwaggerVersion(version);
+            return swaggerResource;
+        }
+    }
+
+    @Bean
+    public CorsFilter corsFilter() {
+        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        final CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true); // 允许cookies跨域
+        config.addAllowedOrigin("*");// 允许向该服务器提交请求的URI,*表示全部允许。。这里尽量限制来源域,比如http://xxxx:8080 ,以降低安全风险。。
+        config.addAllowedHeader("*");// 允许访问的头信息,*表示全部
+        config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
+        config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许,也可以单独设置GET、PUT等
+        config.addAllowedMethod("HEAD");
+        config.addAllowedMethod("GET");// 允许Get的请求方法
+        config.addAllowedMethod("PUT");
+        config.addAllowedMethod("POST");
+        config.addAllowedMethod("DELETE");
+        config.addAllowedMethod("PATCH");
+        source.registerCorsConfiguration("/**", config);
+        return new CorsFilter(source);
+    }
+
+}
+

+ 19 - 0
backstage-service/src/main/java/com/medipath/backstage/FeignConfiguration.java

@@ -0,0 +1,19 @@
+//package com.yiweikeji.backstage;
+//import feign.Request;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//
+//@Configuration
+//public class FeignConfiguration {
+//    @Value("${feign.connectTimeout:60000}")
+//    private int connectTimeout;
+//
+//    @Value("${feign.readTimeOut:60000}")
+//    private int readTimeout;
+//
+//    @Bean
+//    public Request.Options options() {
+//        return new Request.Options(connectTimeout, readTimeout);
+//    }
+//}

+ 284 - 0
backstage-service/src/main/java/com/medipath/backstage/configurer/MyWebMvcConfigurer.java

@@ -0,0 +1,284 @@
+package com.medipath.backstage.configurer;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson.support.config.FastJsonConfig;
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.medipath.backstage.core.RedisUtil;
+import com.medipath.backstage.core.ResultCode;
+import com.medipath.backstage.core.cache.CacheKey;
+import com.medipath.backstage.core.cache.CacheType;
+import com.medipath.backstage.core.interceptor.NoToken;
+import com.medipath.backstage.core.ProjectConstant;
+import com.medipath.core.Result;
+
+import com.medipath.core.ServiceException;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerExceptionResolver;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.NoHandlerFoundException;
+import org.springframework.web.servlet.config.annotation.*;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.annotation.Resource;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Spring MVC 配置
+ */
+@Configuration
+public class MyWebMvcConfigurer implements WebMvcConfigurer {
+
+    private final Logger  logger = LoggerFactory.getLogger(MyWebMvcConfigurer.class);
+
+
+    @Resource
+    private Parameters parameters;
+
+    @Resource
+    private RedisUtil redisUtil;
+
+
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry.addResourceHandler("swagger-ui.html")
+                .addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("doc.html")
+                .addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("/webjars/**")
+                .addResourceLocations("classpath:/META-INF/resources/webjars/");
+    }
+
+    // 使用阿里 FastJson 作为JSON MessageConverter
+    @Override
+    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
+        FastJsonConfig config = new FastJsonConfig();
+        config.setSerializerFeatures(SerializerFeature.WriteMapNullValue,// 保留空的字段
+                SerializerFeature.WriteNullStringAsEmpty,// String null -> ""
+                SerializerFeature.WriteNullNumberAsZero);// Number null -> 0
+        converter.setFastJsonConfig(config);
+        converter.setDefaultCharset(Charset.forName("UTF-8"));
+        converters.add(converter);
+        // 设置项目名称
+        ProjectConstant.application = parameters.getApplication();
+    }
+
+    // 统一异常处理
+    @Override
+    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
+        exceptionResolvers.add(new HandlerExceptionResolver() {
+            @Override
+            public ModelAndView resolveException(HttpServletRequest request,
+                                                 HttpServletResponse response, Object handler,
+                                                 Exception e) {
+                Result result = new Result();
+                if (e instanceof ServiceException) {// 业务失败的异常,如“账号或密码错误”
+                    result.setCode(ResultCode.FAIL.getCode()).setMessage(e.getMessage());
+                    logger.info(e.getMessage());
+                } else if (e instanceof NoHandlerFoundException) {
+                    result.setCode(ResultCode.NOT_FOUND.getCode()).setMessage(
+                            "接口 [" + request.getRequestURI() + "] 不存在");
+                } else if (e instanceof ServletException) {
+                    result.setCode(ResultCode.FAIL.getCode()).setMessage(e.getMessage());
+                } else {
+                    result.setCode(ResultCode.INTERNAL_SERVER_ERROR.getCode()).setMessage(
+                            "接口 [" + request.getRequestURI() + "] 内部错误,请联系管理员");
+                    String message;
+                    if (handler instanceof HandlerMethod) {
+                        HandlerMethod handlerMethod = (HandlerMethod) handler;
+                        message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s",
+                                request.getRequestURI(), handlerMethod.getBean().getClass().getName(),
+                                handlerMethod.getMethod().getName(), e.getMessage());
+                    } else {
+                        message = e.getMessage();
+                    }
+                    logger.error(message, e);
+                }
+                responseResult(response, result);
+                return new ModelAndView();
+            }
+
+        });
+    }
+
+    // 解决跨域问题
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**")
+                .allowedOrigins("*")
+                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
+                .allowCredentials(true)
+                .maxAge(3600)
+                .allowedHeaders("*");
+    }
+
+    // 添加拦截器
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 接口签名认证拦截器,该签名认证比较简单,实际项目中可以使用Json Web Token或其他更好的方式替代。
+        if ("true".equals(parameters.getSignature())) { // 开发环境忽略签名认证
+            registry.addInterceptor(new HandlerInterceptorAdapter() {
+                @Override
+                public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
+                                         Object handler) throws Exception {
+                    // 验证签名
+                    boolean pass = validateSign(request);
+                    if (pass) {
+                        return true;
+                    } else {
+                        logger.warn("签名认证失败,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(),
+                                getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
+
+                        Result result = new Result();
+                        result.setCode(ResultCode.UNAUTHORIZED.getCode()).setMessage("签名认证失败");
+                        responseResult(response, result);
+                        return false;
+                    }
+                }
+            });
+        }
+
+        if ("true".equals(parameters.getLoginCheck())) {
+            // 登录拦截
+            registry.addInterceptor(new HandlerInterceptorAdapter() {
+                @Override
+                public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
+                                         Object handler) throws Exception {
+                    // 验证
+                    if (handler instanceof HandlerMethod ){
+                        HandlerMethod handlerMethod = (HandlerMethod) handler;
+                        if (handlerMethod.hasMethodAnnotation(NoToken.class)) {
+                            return true;
+                        }
+                        if (StrUtil.equals("/error",request.getRequestURI())){
+                            return true;
+                        }
+                        boolean pass = validateLogin(request);
+                        if (pass) {
+                            return true;
+                        } else {
+                            logger.warn("登录认证失败,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(),
+                                    getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
+
+                            Result result = new Result();
+                            result.setCode(ResultCode.UNAUTHORIZED.getCode()).setMessage("登录认证失败");
+                            responseResult(response, result);
+                            return false;
+                        }
+                    } else{
+                        return true;
+                    }
+                }
+
+            });
+        }
+
+    }
+
+    private void responseResult(HttpServletResponse response, Result result) {
+        response.setCharacterEncoding("UTF-8");
+        response.setHeader("Content-type", "application/json;charset=UTF-8");
+        response.setStatus(200);
+        try {
+            response.getWriter().write(JSON.toJSONString(result));
+        } catch (IOException ex) {
+            logger.error(ex.getMessage());
+        }
+    }
+
+    /**
+     * 一个简单的登录认证
+     */
+    private boolean validateLogin(HttpServletRequest request) {
+        //        过滤白名单
+        if (StrUtil.isNotBlank(parameters.getWebWhiteList())){
+            String[] whiteUrls = parameters.getWebWhiteList().split(",");
+            for (String url:whiteUrls) {
+                if (StrUtil.equals(url,request.getRequestURI())){
+                    return true;
+                }
+            }
+        }
+        String token = request.getHeader("accessToken");
+        if (StringUtils.isBlank(token)) {
+            return false;
+        }
+        CacheKey key = CacheKey.generateKey(CacheType.UserConfig, token);
+        Object j = redisUtil.get(key.toString());
+        if (j != null) {
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+
+    /**
+     * 一个简单的签名认证,规则: 1. 将请求参数按ascii码排序 2. 拼接为a=value&b=value...这样的字符串(不包含sign)
+     * 3. 混合密钥(secret)进行md5获得签名,与请求的签名进行比较
+     */
+    private boolean validateSign(HttpServletRequest request) {
+        String requestSign = request.getParameter("sign");// 获得请求签名,如sign=19e907700db7ad91318424a97c54ed57
+        if (StringUtils.isEmpty(requestSign)) {
+            return false;
+        }
+        List<String> keys = new ArrayList<String>(request.getParameterMap().keySet());
+        keys.remove("sign");// 排除sign参数
+        Collections.sort(keys);// 排序
+
+        StringBuilder sb = new StringBuilder();
+        for (String key : keys) {
+            sb.append(key).append("=").append(request.getParameter(key)).append("&");// 拼接字符串
+        }
+        String linkString = sb.toString();
+        linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);// 去除最后一个'&'
+
+        String secret = "Potato";// 密钥,自己修改
+        String sign = DigestUtils.md5Hex(linkString + secret);// 混合密钥md5
+
+        return StringUtils.equals(sign, requestSign);// 比较
+    }
+
+    private String getIpAddress(HttpServletRequest request) {
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_CLIENT_IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        // 如果是多级代理,那么取第一个ip为客户端ip
+        if (ip != null && ip.indexOf(",") != -1) {
+            ip = ip.substring(0, ip.indexOf(",")).trim();
+        }
+
+        return ip;
+    }
+}

+ 49 - 0
backstage-service/src/main/java/com/medipath/backstage/configurer/MybatisConfigurer.java

@@ -0,0 +1,49 @@
+package com.medipath.backstage.configurer;
+
+import com.medipath.backstage.core.ProjectConstant;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import tk.mybatis.spring.mapper.MapperScannerConfigurer;
+
+import javax.sql.DataSource;
+import java.util.Properties;
+
+/**
+ * Mybatis & Mapper & PageHelper 配置
+ */
+@Configuration
+public class MybatisConfigurer {
+
+    @Bean
+    public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
+        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
+        factory.setDataSource(dataSource);
+        factory.setTypeAliasesPackage(ProjectConstant.MODEL_PACKAGE);
+
+        //添加XML目录
+        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+        factory.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
+        return factory.getObject();
+    }
+
+    @Bean
+    public MapperScannerConfigurer mapperScannerConfigurer() {
+        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
+        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
+        mapperScannerConfigurer.setBasePackage(ProjectConstant.MAPPER_PACKAGE);
+
+        //配置通用Mapper,详情请查阅官方文档
+        Properties properties = new Properties();
+        properties.setProperty("mappers", ProjectConstant.MAPPER_INTERFACE_REFERENCE);
+        properties.setProperty("notEmpty", "false");//insert、update是否判断字符串类型!='' 即 test="str != null"表达式内是否追加 and str != ''
+        properties.setProperty("IDENTITY", "MYSQL");
+        mapperScannerConfigurer.setProperties(properties);
+
+        return mapperScannerConfigurer;
+    }
+
+}

+ 44 - 0
backstage-service/src/main/java/com/medipath/backstage/configurer/Parameters.java

@@ -0,0 +1,44 @@
+package com.medipath.backstage.configurer;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+@Component
+@Data
+@RefreshScope
+public class Parameters {
+    /**
+     *
+     当前激活的配置文件
+     */
+    @Value("${web.white.list}")
+    private String         webWhiteList;
+
+    @Value("${permission.switch}")
+    private String         permissionSwitch;
+
+    /**
+     * 是否启用登录验证
+     */
+    @Value("${login.check}")
+    private String        loginCheck;
+
+    /**
+     * 当前激活的配置文件
+     */
+    @Value("${spring.profiles.active}")
+    private String        env;
+
+    /**
+     * 是否启用签名
+     */
+    @Value("${signature}")
+    private String        signature;
+
+    @Value("${spring.application.name}")
+    private String        application;
+
+
+}

+ 62 - 0
backstage-service/src/main/java/com/medipath/backstage/configurer/SwaggerConfig.java

@@ -0,0 +1,62 @@
+package com.medipath.backstage.configurer;
+
+import io.swagger.annotations.ApiOperation;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.ParameterBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.Parameter;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+@EnableSwagger2
+@Profile({"dev","test"})
+public class SwaggerConfig {
+
+    @Bean
+    public Docket docket(){
+        //添加header参数
+        List<Parameter> pars = new ArrayList<>();
+        ParameterBuilder ticketPar = new ParameterBuilder();
+        ticketPar.name("token").description("user token")
+                .modelRef(new ModelRef("string")).parameterType("header")
+                .required(false).build(); //header中的ticket参数非必填,传空也可以
+        ticketPar = new ParameterBuilder();
+        ticketPar.name("appCode").description("appCode")
+                .modelRef(new ModelRef("string")).parameterType("header")
+                .required(false).build(); //header中的ticket参数非必填,传空也可以
+
+        pars.add(ticketPar.build());
+        return new Docket(DocumentationType.SWAGGER_2)
+                .globalOperationParameters(pars)
+                .groupName("demo")
+                .apiInfo(getApiInfo())
+                .select()
+                //设置basePackage会将包下的所有被@Api标记类的所有方法作为api
+                .apis(RequestHandlerSelectors.basePackage("com.medipath.web"))
+                //只有标记了@ApiOperation的方法才会暴露出给swagger
+                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
+                .paths(PathSelectors.regex("/api/.*")).build();
+    }
+
+    private ApiInfo getApiInfo(){
+        return new ApiInfoBuilder()
+                .title("API接口文档")
+                .description("swagger2 demo api")
+                .termsOfServiceUrl("http://localhost/swagger-ui.html")
+                .version("1.0").contact(new Contact("admin", "http://localhost/swagger-ui.html", "xxx@qq.com"))
+                .build();
+    }
+
+}

+ 48 - 0
backstage-service/src/main/java/com/medipath/backstage/configurer/WebLogAspect.java

@@ -0,0 +1,48 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+package com.medipath.backstage.configurer;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+
+@Aspect
+@Component
+public class WebLogAspect {
+    private static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
+
+    public WebLogAspect() {
+    }
+
+    @Pointcut("execution(public * com.medipath..*Controller.*(..))")
+    public void webLog() {
+    }
+
+    @Before("webLog()")
+    public void doBefore(JoinPoint joinPoint) throws Throwable {
+        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        logger.info("URL : {} HTTP_METHOD : {} ARGS : {} token : {}", new Object[]{request.getRequestURL().toString(), request.getMethod(), Arrays.toString(joinPoint.getArgs()),request.getHeader("accessToken")});
+    }
+
+    @AfterReturning(
+        returning = "ret",
+        pointcut = "webLog()"
+    )
+    public void doAfterReturning(Object ret) throws Throwable {
+        logger.info("RESPONSE : {}", ret);
+    }
+}

+ 14 - 0
backstage-service/src/main/java/com/medipath/backstage/consts/AuthConst.java

@@ -0,0 +1,14 @@
+package com.medipath.backstage.consts;
+
+public interface AuthConst {
+
+    String USER_ID = "userId";
+
+    String USER_NAME = "userName";
+
+    String AUTH_LOGIN_PREFIX = "auth:login:";
+
+    String AUTH_PERMISSION = "auth:permission:set";
+
+    String JWT_TOKEN = "token";
+}

+ 9 - 0
backstage-service/src/main/java/com/medipath/backstage/consts/SymbolConst.java

@@ -0,0 +1,9 @@
+package com.medipath.backstage.consts;
+
+public interface SymbolConst {
+
+    String comma = ",";
+    String semicolon = ":";
+
+
+}

+ 85 - 0
backstage-service/src/main/java/com/medipath/backstage/core/AbstractService.java

@@ -0,0 +1,85 @@
+package com.medipath.backstage.core;
+
+
+import com.medipath.core.ServiceException;
+import org.apache.ibatis.exceptions.TooManyResultsException;
+import org.springframework.beans.factory.annotation.Autowired;
+import tk.mybatis.mapper.entity.Condition;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.util.List;
+
+/**
+ * 基于通用MyBatis Mapper插件的Service接口的实现
+ */
+public abstract class AbstractService<T> implements Service<T> {
+
+    @Autowired
+    protected Mapper<T> mapper;
+
+    private Class<T> modelClass;    // 当前泛型真实类型的Class
+
+    public AbstractService() {
+        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
+        modelClass = (Class<T>) pt.getActualTypeArguments()[0];
+    }
+
+    @Override
+    public int  save(T model) {
+       return mapper.insertUseGeneratedKeys(model);
+    }
+
+    @Override
+    public int  save(List<T> models) {
+    	return mapper.insertList(models);
+    }
+
+    @Override
+    public void deleteById(Number id) {
+        mapper.deleteByPrimaryKey(id);
+    }
+
+    @Override
+    public void deleteByIds(String ids) {
+        mapper.deleteByIds(ids);
+    }
+
+    @Override
+    public void update(T model) {
+        mapper.updateByPrimaryKeySelective(model);
+    }
+
+    @Override
+    public T findById(Number id) {
+        return mapper.selectByPrimaryKey(id);
+    }
+
+    @Override
+    public T findBy(String fieldName, Object value) throws TooManyResultsException {
+        try {
+            T model = modelClass.newInstance();
+            Field field = modelClass.getDeclaredField(fieldName);
+            field.setAccessible(true);
+            field.set(model, value);
+            return mapper.selectOne(model);
+        } catch (ReflectiveOperationException e) {
+            throw new ServiceException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public List<T> findByIds(String ids) {
+        return mapper.selectByIds(ids);
+    }
+
+    @Override
+    public List<T> findByCondition(Condition condition) {
+        return mapper.selectByCondition(condition);
+    }
+
+    @Override
+    public List<T> findAll() {
+        return mapper.selectAll();
+    }
+}

+ 56 - 0
backstage-service/src/main/java/com/medipath/backstage/core/BaseBeen.java

@@ -0,0 +1,56 @@
+package com.medipath.backstage.core;
+
+import javax.persistence.Transient;
+
+import lombok.ToString;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+@ToString
+public class BaseBeen {
+    
+    @Transient 
+    private String startTime;
+    
+    @Transient 
+    private String endTime;
+
+    @Transient
+    private Integer page;
+
+    @Transient
+    private Integer size;
+
+    public Integer getPage() {
+        return page;
+    }
+
+    public void setPage(Integer page) {
+        this.page = page;
+    }
+
+    public Integer getSize() {
+        return size;
+    }
+
+    public void setSize(Integer size) {
+        this.size = size;
+    }
+
+    public String getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(String startTime) {
+        this.startTime = startTime;
+    }
+
+    public String getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(String endTime) {
+        this.endTime = endTime;
+    }
+
+}

+ 19 - 0
backstage-service/src/main/java/com/medipath/backstage/core/Mapper.java

@@ -0,0 +1,19 @@
+package com.medipath.backstage.core;
+
+import tk.mybatis.mapper.common.BaseMapper;
+import tk.mybatis.mapper.common.ConditionMapper;
+import tk.mybatis.mapper.common.IdsMapper;
+import tk.mybatis.mapper.common.special.InsertListMapper;
+import tk.mybatis.mapper.common.special.InsertUseGeneratedKeysMapper;
+
+/**
+ * 定制版MyBatis Mapper插件接口,如需其他接口参考官方文档自行添加。
+ */
+public interface Mapper<T>
+        extends
+        BaseMapper<T>,
+        ConditionMapper<T>,
+        IdsMapper<T>,
+        InsertListMapper<T>,
+        InsertUseGeneratedKeysMapper<T> {
+}

+ 47 - 0
backstage-service/src/main/java/com/medipath/backstage/core/MessageTemplteType.java

@@ -0,0 +1,47 @@
+package com.medipath.backstage.core;
+
+/**
+ * 消息模板枚举
+ */
+public enum MessageTemplteType {
+
+	/** 保修报事-派单通知 */
+	DISPATCH_NOTICE("dispatchNotice", "保修报事-派单通知"),
+	/** 物业缴费-缴费提醒通知 */
+	PAYMENT_REMINDER_NOTICE("paymentReminderNotice", "物业缴费-缴费提醒通知"),
+
+
+	;
+
+	private final String code; // 状态码
+	private final String desc;
+
+	MessageTemplteType(String code, String desc) {
+		this.code = code;
+		this.desc = desc;
+	}
+
+	public String getCode() {
+		return code;
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+
+	/**
+	 * 通过状态码获取ENUM的名字
+	 * 
+	 * @param statusCode
+	 * @return
+	 */
+	public static ResultCode getEnumByStatusCode(String code) {
+		for (ResultCode p : ResultCode.values()) {
+			if (p.code().equalsIgnoreCase(code)) {
+				return p;
+			}
+		}
+
+		return null;
+	}
+}

+ 29 - 0
backstage-service/src/main/java/com/medipath/backstage/core/ProjectConstant.java

@@ -0,0 +1,29 @@
+package com.medipath.backstage.core;
+
+/**
+ * 项目常量
+ */
+public final class ProjectConstant {
+    public static final String BASE_PACKAGE = "com.medipath.backstage";//项目基础包名称,根据自己公司的项目修改
+
+    public static final String MODEL_PACKAGE = BASE_PACKAGE + ".model";//Model所在包
+    public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".dao";//Mapper所在包
+    public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service";//Service所在包
+    public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";//ServiceImpl所在包
+    public static final String SERVICE_DTO_PACKAGE = BASE_PACKAGE + ".dto";//dto所在包
+    public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".web.mng";//Controller所在包
+
+    public static final String MAPPER_INTERFACE_REFERENCE = BASE_PACKAGE + ".core.Mapper";//Mapper插件基础接口的完全限定名
+    //项目名称
+    public static  String application;
+
+    // redis里的accessToken
+    public static final String WX_ACCESS_TOKEN = "access_token:wx:wxappid";
+
+    // redis里的accessToken超时时间
+    public static final String WX_ACCESS_TOKEN_EXPIRES_TIME = "access_token_expires_time:wx:wxappid";
+
+    public static final String WX_JSAPI_TICKET = "jsapi:wx:wxappid";
+
+    public static final String WX_JSAPI_TICKET_EXPIRES_TIME = "jsapi_expires_time:wx:wxappid";
+}

+ 595 - 0
backstage-service/src/main/java/com/medipath/backstage/core/RedisUtil.java

@@ -0,0 +1,595 @@
+package com.medipath.backstage.core;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Resource;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+
+/**
+ *
+ * @author
+ * 基于spring和redis的redisTemplate工具类
+ * 针对所有的hash 都是以h开头的方法
+ * 针对所有的Set 都是以s开头的方法                    不含通用方法
+ * 针对所有的List 都是以l开头的方法
+ */
+@Component
+@Slf4j
+public class RedisUtil {
+
+	@Resource
+	private RedisTemplate<String, Object> redisTemplate;
+
+	//=============================common============================
+	/**
+	 * 指定缓存失效时间
+	 * @param key 键
+	 * @param time 时间(秒)
+	 * @return
+	 */
+	public boolean expire(String key,long time){
+		try {
+			if(time>0){
+				redisTemplate.expire(key, time, TimeUnit.SECONDS);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 根据key 获取过期时间
+	 * @param key 键 不能为null
+	 * @return 时间(秒) 返回0代表为永久有效
+	 */
+	public long getExpire(String key){
+		return redisTemplate.getExpire(key,TimeUnit.SECONDS);
+	}
+
+	/**
+	 * 判断key是否存在
+	 * @param key 键
+	 * @return true 存在 false不存在
+	 */
+	public boolean hasKey(String key){
+		try {
+			return redisTemplate.hasKey(key);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 删除缓存
+	 * @param key 可以传一个值 或多个
+	 */
+	@SuppressWarnings("unchecked")
+	public void del(String ... key){
+		if(key!=null&&key.length>0){
+			if(key.length==1){
+				redisTemplate.delete(key[0]);
+			}else{
+				redisTemplate.delete(CollectionUtils.arrayToList(key));
+			}
+		}
+	}
+
+	/**
+	 * 删除缓存
+	 * @param key 可以传一个值 或多个
+	 */
+	@SuppressWarnings("unchecked")
+	public Long del2(String ... key){
+		if(key!=null&&key.length>0){
+			if(key.length==1){
+				if (redisTemplate.delete(key[0])){
+					return -1L;
+				} else {
+					return -2L;
+				}
+			}else{
+				return redisTemplate.delete(CollectionUtils.arrayToList(key));
+			}
+		}
+		return null;
+	}
+
+	//============================String=============================
+	/**
+	 * 普通缓存获取
+	 * @param key 键
+	 * @return 值
+	 */
+	public Object get(String key){
+		return key==null?null:redisTemplate.opsForValue().get(key);
+	}
+
+	/**
+	 * 普通缓存放入
+	 * @param key 键
+	 * @param value 值
+	 * @return true成功 false失败
+	 */
+	public boolean set(String key,Object value) {
+		try {
+			redisTemplate.opsForValue().set(key, value);
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+
+	}
+
+	/**
+	 * 普通缓存放入并设置时间
+	 * @param key 键
+	 * @param value 值
+	 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
+	 * @return true成功 false 失败
+	 */
+	public boolean set(String key,Object value,long time){
+		try {
+			if(time>0){
+				redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+			}else{
+				set(key, value);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 普通缓存放入并设置时间
+	 * @param key 键
+	 * @param value 值
+	 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
+	 * @return true成功 false 失败
+	 */
+	public boolean set(String key,Object value,long time, TimeUnit timeUnit){
+		try {
+			if(time>0){
+				redisTemplate.opsForValue().set(key, value, time, timeUnit);
+			}else{
+				set(key, value);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 递增
+	 * @param key 键
+	 * @param delta 要增加几(大于0)
+	 * @return
+	 */
+	public long incr(String key, long delta){
+		if(delta<0){
+			throw new RuntimeException("递增因子必须大于0");
+		}
+		return redisTemplate.opsForValue().increment(key, delta);
+	}
+
+	/**
+	 * 递减
+	 * @param key 键
+	 * @param delta 要减少几(小于0)
+	 * @return
+	 */
+	public long decr(String key, long delta){
+		if(delta<0){
+			throw new RuntimeException("递减因子必须大于0");
+		}
+		return redisTemplate.opsForValue().increment(key, -delta);
+	}
+
+	//================================Map=================================
+	/**
+	 * HashGet
+	 * @param key 键 不能为null
+	 * @param item 项 不能为null
+	 * @return 值
+	 */
+	public Object hget(String key,String item){
+		return redisTemplate.opsForHash().get(key, item);
+	}
+
+	/**
+	 * 获取hashKey对应的所有键值
+	 * @param key 键
+	 * @return 对应的多个键值
+	 */
+	public Map<Object,Object> hmget(String key){
+		return redisTemplate.opsForHash().entries(key);
+	}
+
+	/**
+	 * HashSet
+	 * @param key 键
+	 * @param map 对应多个键值
+	 * @return true 成功 false 失败
+	 */
+	public boolean hmset(String key, Map<String,Object> map){
+		try {
+			redisTemplate.opsForHash().putAll(key, map);
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * HashSet 并设置时间
+	 * @param key 键
+	 * @param map 对应多个键值
+	 * @param time 时间(秒)
+	 * @return true成功 false失败
+	 */
+	public boolean hmset(String key, Map<String,Object> map, long time){
+		try {
+			redisTemplate.opsForHash().putAll(key, map);
+			if(time>0){
+				expire(key, time);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 向一张hash表中放入数据,如果不存在将创建
+	 * @param key 键
+	 * @param item 项
+	 * @param value 值
+	 * @return true 成功 false失败
+	 */
+	public boolean hset(String key,String item,Object value) {
+		try {
+			redisTemplate.opsForHash().put(key, item, value);
+			return true;
+		} catch (Exception e) {
+			log.error("hset error",e);
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 向一张hash表中放入数据,如果不存在将创建
+	 * @param key 键
+	 * @param item 项
+	 * @param value 值
+	 * @param time 时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间
+	 * @return true 成功 false失败
+	 */
+	public boolean hset(String key,String item,Object value,long time) {
+		try {
+			redisTemplate.opsForHash().put(key, item, value);
+			if(time>0){
+				expire(key, time);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 删除hash表中的值
+	 * @param key 键 不能为null
+	 * @param item 项 可以使多个 不能为null
+	 */
+	public void hdel(String key, Object... item){
+		redisTemplate.opsForHash().delete(key,item);
+	}
+
+	/**
+	 * hash表大小
+	 * @param key 键 不能为null
+	 * @return size 大小
+	 */
+	public Long size(String key){
+		return redisTemplate.opsForHash().size(key);
+	}
+
+	/**
+	 * 判断hash表中是否有该项的值
+	 * @param key 键 不能为null
+	 * @param item 项 不能为null
+	 * @return true 存在 false不存在
+	 */
+	public boolean hHasKey(String key, String item){
+		return redisTemplate.opsForHash().hasKey(key, item);
+	}
+
+	/**
+	 * hash递增 如果不存在,就会创建一个 并把新增后的值返回
+	 * @param key 键
+	 * @param item 项
+	 * @param by 要增加几(大于0)
+	 * @return
+	 */
+	public double hincr(String key, String item,double by){
+		return redisTemplate.opsForHash().increment(key, item, by);
+	}
+
+	/**
+	 * hash递减
+	 * @param key 键
+	 * @param item 项
+	 * @param by 要减少记(小于0)
+	 * @return
+	 */
+	public double hdecr(String key, String item,double by){
+		return redisTemplate.opsForHash().increment(key, item,-by);
+	}
+
+	//============================set=============================
+	/**
+	 * 根据key获取Set中的所有值
+	 * @param key 键
+	 * @return
+	 */
+	public Set<Object> sGet(String key){
+		try {
+			return redisTemplate.opsForSet().members(key);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	/**
+	 * 根据value从一个set中查询,是否存在
+	 * @param key 键
+	 * @param value 值
+	 * @return true 存在 false不存在
+	 */
+	public boolean sHasKey(String key,Object value){
+		try {
+			return redisTemplate.opsForSet().isMember(key, value);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 将数据放入set缓存
+	 * @param key 键
+	 * @param values 值 可以是多个
+	 * @return 成功个数
+	 */
+	public long sSet(String key, Object...values) {
+		try {
+			return redisTemplate.opsForSet().add(key, values);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return 0;
+		}
+	}
+
+	/**
+	 * 将set数据放入缓存
+	 * @param key 键
+	 * @param time 时间(秒)
+	 * @param values 值 可以是多个
+	 * @return 成功个数
+	 */
+	public long sSetAndTime(String key,long time,Object...values) {
+		try {
+			Long count = redisTemplate.opsForSet().add(key, values);
+			if(time>0){
+				expire(key, time);
+			}
+			return count;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return 0;
+		}
+	}
+
+	/**
+	 * 获取set缓存的长度
+	 * @param key 键
+	 * @return
+	 */
+	public long sGetSetSize(String key){
+		try {
+			return redisTemplate.opsForSet().size(key);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return 0;
+		}
+	}
+
+	/**
+	 * 移除值为value的
+	 * @param key 键
+	 * @param values 值 可以是多个
+	 * @return 移除的个数
+	 */
+	public long setRemove(String key, Object ...values) {
+		try {
+			Long count = redisTemplate.opsForSet().remove(key, values);
+			return count;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return 0;
+		}
+	}
+	//===============================list=================================
+
+	/**
+	 * 获取list缓存的内容
+	 * @param key 键
+	 * @param start 开始
+	 * @param end 结束  0 到 -1代表所有值
+	 * @return
+	 */
+	public List<Object> lGet(String key,long start, long end){
+		try {
+			return redisTemplate.opsForList().range(key, start, end);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	/**
+	 * 获取list缓存的长度
+	 * @param key 键
+	 * @return
+	 */
+	public long lGetListSize(String key){
+		try {
+			return redisTemplate.opsForList().size(key);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return 0;
+		}
+	}
+
+	/**
+	 * 通过索引 获取list中的值
+	 * @param key 键
+	 * @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
+	 * @return
+	 */
+	public Object lGetIndex(String key,long index){
+		try {
+			return redisTemplate.opsForList().index(key, index);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	/**
+	 * 将list放入缓存
+	 * @param key 键
+	 * @param value 值
+	 * @return
+	 */
+	public boolean lSet(String key, Object value) {
+		try {
+			redisTemplate.opsForList().rightPush(key, value);
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 将list放入缓存
+	 * @param key 键
+	 * @param value 值
+	 * @param time 时间(秒)
+	 * @return
+	 */
+	public boolean lSet(String key, Object value, long time) {
+		try {
+			redisTemplate.opsForList().rightPush(key, value);
+			if (time > 0) {
+				expire(key, time);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 将list放入缓存
+	 * @param key 键
+	 * @param value 值
+	 * @return
+	 */
+	public boolean lSet(String key, List<Object> value) {
+		try {
+			redisTemplate.opsForList().rightPushAll(key, value);
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 将list放入缓存
+	 * @param key 键
+	 * @param value 值
+	 * @param time 时间(秒)
+	 * @return
+	 */
+	public boolean lSet(String key, List<Object> value, long time) {
+		try {
+			redisTemplate.opsForList().rightPushAll(key, value);
+			if (time > 0){
+				expire(key, time);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 根据索引修改list中的某条数据
+	 * @param key 键
+	 * @param index 索引
+	 * @param value 值
+	 * @return
+	 */
+	public boolean lUpdateIndex(String key, long index,Object value) {
+		try {
+			redisTemplate.opsForList().set(key, index, value);
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	/**
+	 * 移除N个值为value
+	 * @param key 键
+	 * @param count 移除多少个
+	 * @param value 值
+	 * @return 移除的个数
+	 */
+	public long lRemove(String key,long count,Object value) {
+		try {
+			Long remove = redisTemplate.opsForList().remove(key, count, value);
+			return remove;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return 0;
+		}
+	}
+
+}

+ 100 - 0
backstage-service/src/main/java/com/medipath/backstage/core/ResultCode.java

@@ -0,0 +1,100 @@
+package com.medipath.backstage.core;
+
+/**
+ * 响应码枚举,参考HTTP状态码的语义
+ */
+public enum ResultCode {
+    /**
+     * 系统错误
+     */
+    SUCCESS("200","成功"),//成功
+    FAIL("400","失败"),//失败
+    UNAUTHORIZED("401","未认证(签名错误)"),//未认证(签名错误)
+    NOT_FOUND("404","接口不存在"),//接口不存在
+    INTERNAL_SERVER_ERROR("500","服务器内部错误"),
+    PERMISSION_NOT_HAS("409","没有操作权限"),
+    BACKSTAGE_IS_ERROR("501","网关异常"),
+    
+    /**
+     * 业务错误
+     */
+    OBJECT_IS_NULL("6000","对象不能为空"),
+    ID_IS_NULL("6001","对象ID不能为空"),
+    CODE_IS_NULL("6002","编号不能为空"),
+    NAME_IS_NULL("6003","名称不能为空"),
+    SEQ_IS_NULL("6004","排序不能为空"),
+    LEVEL_IS_NULL("6005","级别不能为空"),
+    USERID_IS_NULL("6006","用户id不能为空"),
+    RESULT_IS_NULL("6007","查询结果为空"),
+    TYPE_IS_NULL("6008","查询结果为空"),
+    SQL_ERROR("6009","数据库异常"),
+    IDENTITY_IS_NULL("6010","身份证不能为空"),
+    CUSTOMERID_IS_NULL("6011","客户号不能为空"),
+    CUSTOMERID_IS_ERROR("6012","未查询到用户信息"),
+    SELECT_IS_ERROR("6013","数据异常查询失败,请联系检查用户信息"),
+    IDENTITYUPKEY_IS_ERROR("6014","身份证正面照片key不能为空"),
+    CODE_IS_INVALID("6015","验证码无效"),
+    TOKEN_IS_NULL("6016","TOKEN不能为空"),
+
+    /**
+     * 权限
+     */
+    PERMISSION_ENAME_IS_NULL("6040","英文名不能为空"),
+    PERMISSION_ISACTION_IS_NULL("6041","是否有动作不能为空"),
+    PERMISSION_COMPOSINGKEY_IS_NULL("6042","排版不能为空"),
+    PERMISSIONID_IS_NULL("6043","权限id不能为空"),
+
+    /**
+     * 登录
+     */
+    LOGIN_ACCOUNT_IS_NULL("6030","登录账号不能为空"),
+    LOGIN_ACCOUNT_IS_ERROR("6035","登录账号不存在"),
+    LOGIN_PASSWORD_IS_NULL("6031","登录密码不能为空"),
+    LOGIN_PASSWORD_IS_ERROR("6033","登录密码错误"),
+    LOGIN_USER_STATUS_IS_ERROR("6034","用户状态有误"),
+
+
+    ACCOUNT_IS_NULL("7001","账号不能为空" ),
+    USER_IS_NULL("7002","用户未找到" ),
+    USER_IS_ERROR("7003", "用户异常"), UNLOGIN_PWD_ERROR("7004", "登录密码错误")
+    , ROLEID_IS_NULL("7005", "角色id不能为空" ), ADMIN_ROLE_UNDELETE("7006", "超级管理员不能被删除");//服务器内部错误
+
+    private final String code;   //状态码
+    private final String message;
+
+    ResultCode(String code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public String code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * 通过状态码获取ENUM的名字
+     * @param code
+     * @return
+     */
+    public static ResultCode getEnumByStatusCode(String code) {
+        for (ResultCode p : ResultCode.values()) {
+            if (p.code().equalsIgnoreCase(code)) {
+                return p;
+            }
+        }
+
+        return null;
+    }
+}

+ 37 - 0
backstage-service/src/main/java/com/medipath/backstage/core/ResultGenerator.java

@@ -0,0 +1,37 @@
+package com.medipath.backstage.core;
+
+
+import com.medipath.core.Result;
+
+/**
+ * 响应结果生成工具
+ */
+public class ResultGenerator {
+    private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";
+
+    public static Result genSuccessResult() {
+        return new Result()
+                .setCode(ResultCode.SUCCESS.getCode())
+                .setMessage(DEFAULT_SUCCESS_MESSAGE);
+    }
+
+    public static Result genSuccessResult(Object data) {
+        return new Result()
+                .setCode(ResultCode.SUCCESS.getCode())
+                .setMessage(DEFAULT_SUCCESS_MESSAGE)
+                .setData(data);
+    }
+
+    public static Result genFailResult(ResultCode code) {
+        return new Result()
+                .setCode(code.getCode())
+                .setMessage(code.getMessage());
+    }
+    
+    public static Result genFailResult(ResultCode code,Object data) {
+        return new Result()
+                .setCode(code.getCode())
+                .setMessage(code.getMessage())
+                .setData(data);
+    }
+}

+ 22 - 0
backstage-service/src/main/java/com/medipath/backstage/core/Service.java

@@ -0,0 +1,22 @@
+package com.medipath.backstage.core;
+
+import org.apache.ibatis.exceptions.TooManyResultsException;
+import tk.mybatis.mapper.entity.Condition;
+
+import java.util.List;
+
+/**
+ * Service 层 基础接口,其他Service 接口 请继承该接口
+ */
+public interface Service<T> {
+	int  save(T model);//持久化
+	int  save(List<T> models);//批量持久化
+    void deleteById(Number id);//通过主鍵刪除
+    void deleteByIds(String ids);//批量刪除 eg:ids -> “1,2,3,4”
+    void update(T model);//更新
+    T findById(Number id);//通过ID查找
+    T findBy(String fieldName, Object value) throws TooManyResultsException; //通过Model中某个成员变量名称(非数据表中column的名称)查找,value需符合unique约束
+    List<T> findByIds(String ids);//通过多个ID查找//eg:ids -> “1,2,3,4”
+    List<T> findByCondition(Condition condition);//根据条件查找
+    List<T> findAll();//获取所有
+}

+ 57 - 0
backstage-service/src/main/java/com/medipath/backstage/core/SmsTempletType.java

@@ -0,0 +1,57 @@
+package com.medipath.backstage.core;
+
+/**
+ * 短信模板枚举
+ */
+public enum SmsTempletType {
+	
+	RAPID_REGISTRATION("rapidRegistration","快速注册短信验证码"),
+	THIRD_PARTY_LOGIN("thirdPartyLogin","第三方登陆短信验证码"),
+	VERIFICATION_CODE_LANDING("verificationCodeLanding","验证码登陆"),
+	UPDATE_VERIFICATION_CODE("updateVerificationCode","更绑手机验证码"),
+	SET_PASSWORD_VERIFICATION_CODE("setPasswordVerificationCode","设置密码验证码"),
+	
+	;
+	
+	private String code;
+	private String desc;
+	
+	SmsTempletType(String code, String desc) {
+		this.code = code;
+		this.desc = desc;
+	}
+	
+	
+	/**
+	 * 通过状态码获取ENUM的名字
+	 * 
+	 * @param code
+	 * @return
+	 */
+	public static ResultCode getEnumByStatusCode(String code) {
+		for (ResultCode p : ResultCode.values()) {
+			if (p.code().equalsIgnoreCase(code)) {
+				return p;
+			}
+		}
+
+		return null;
+	}
+	
+	public String getCode() {
+		return code;
+	}
+	public void setCode(String code) {
+		this.code = code;
+	}
+	public String getDesc() {
+		return desc;
+	}
+	public void setDesc(String desc) {
+		this.desc = desc;
+	}
+	
+	
+	
+
+}

+ 34 - 0
backstage-service/src/main/java/com/medipath/backstage/core/cache/CacheKey.java

@@ -0,0 +1,34 @@
+package com.medipath.backstage.core.cache;
+
+import java.io.Serializable;
+
+
+public class CacheKey implements Serializable {
+
+	private CacheType cacheType;
+
+	private String subKey;
+
+	private CacheKey() {
+	}
+
+	public static CacheKey generateKey(CacheType cacheType, String subKey) {
+		if (cacheType == null) {
+			throw new NullPointerException("CacheKey不允许存在空参数");
+		}
+		CacheKey key = new CacheKey();
+		key.cacheType = cacheType;
+		key.subKey = subKey;
+		return key;
+	}
+
+	@Override
+	public String toString() {
+		return new StringBuilder().append(cacheType).append("_").append(subKey != null ? subKey : "").toString();
+	}
+
+	public CacheType getType() {
+		return cacheType;
+	}
+
+}

+ 26 - 0
backstage-service/src/main/java/com/medipath/backstage/core/cache/CacheType.java

@@ -0,0 +1,26 @@
+package com.medipath.backstage.core.cache;
+
+import com.medipath.backstage.core.ProjectConstant;
+
+public enum CacheType {
+
+	// ----------------------- token 密钥相关 ------------------------
+
+	/**
+	 * app端密钥
+	 */
+	AppSecretKey,
+
+	// ------------------------- 订单相关 -------------------------
+	/**
+	 * 用户相关的一些配置:黑名单等
+	 */
+	UserConfig;
+
+	private static String keyHead = ProjectConstant.application;
+
+	@Override
+	public String toString() {
+		return keyHead + "_" + name();
+	};
+}

+ 13 - 0
backstage-service/src/main/java/com/medipath/backstage/core/interceptor/LoginType.java

@@ -0,0 +1,13 @@
+package com.medipath.backstage.core.interceptor;
+
+public enum LoginType {
+	/**
+	 * 普通用户
+	 */
+	Common,
+
+	/**
+	 * 商家用户
+	 */
+	Provider
+}

+ 13 - 0
backstage-service/src/main/java/com/medipath/backstage/core/interceptor/NoToken.java

@@ -0,0 +1,13 @@
+package com.medipath.backstage.core.interceptor;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD, ElementType.TYPE })
+public @interface NoToken {
+	public LoginType type() default LoginType.Common;
+}

+ 21 - 0
backstage-service/src/main/java/com/medipath/backstage/core/interceptor/ThreadUser.java

@@ -0,0 +1,21 @@
+package com.medipath.backstage.core.interceptor;
+
+import com.medipath.core.BaseUser;
+
+public class ThreadUser {
+
+	private static ThreadLocal<BaseUser> local = new ThreadLocal<BaseUser>();
+
+	public static void putLoginUser(BaseUser user) {
+		local.set(user);
+	}
+
+	public static BaseUser getLoginUser() {
+		return local.get();
+	}
+
+	public static void remove() {
+		local.remove();
+	}
+
+}

+ 7 - 0
backstage-service/src/main/java/com/medipath/backstage/dao/MytestMapper.java

@@ -0,0 +1,7 @@
+package com.medipath.backstage.dao;
+
+import com.medipath.backstage.core.Mapper;
+import com.medipath.backstage.model.Mytest;
+
+public interface MytestMapper extends Mapper<Mytest> {
+}

+ 21 - 0
backstage-service/src/main/java/com/medipath/backstage/dao/PermissionMapper.java

@@ -0,0 +1,21 @@
+package com.medipath.backstage.dao;
+
+import com.medipath.backstage.core.Mapper;
+import com.medipath.backstage.dto.PermissionGroupDto;
+import com.medipath.backstage.model.Permission;
+
+import java.util.List;
+
+public interface PermissionMapper extends Mapper<Permission> {
+
+    List<Permission> selectEenu(String userId);
+
+    List<Permission> selectPermissionByUserId(String userId);
+
+    /**
+     * 查询所有接口的权限
+     *
+     * @return
+     */
+    List<PermissionGroupDto> selectPermissionGroup();
+}

+ 7 - 0
backstage-service/src/main/java/com/medipath/backstage/dao/RoleMapper.java

@@ -0,0 +1,7 @@
+package com.medipath.backstage.dao;
+
+import com.medipath.backstage.core.Mapper;
+import com.medipath.backstage.model.Role;
+
+public interface RoleMapper extends Mapper<Role> {
+}

+ 7 - 0
backstage-service/src/main/java/com/medipath/backstage/dao/RolePermissionMapper.java

@@ -0,0 +1,7 @@
+package com.medipath.backstage.dao;
+
+import com.medipath.backstage.core.Mapper;
+import com.medipath.backstage.model.RolePermission;
+
+public interface RolePermissionMapper extends Mapper<RolePermission> {
+}

+ 7 - 0
backstage-service/src/main/java/com/medipath/backstage/dao/UserMapper.java

@@ -0,0 +1,7 @@
+package com.medipath.backstage.dao;
+
+import com.medipath.backstage.core.Mapper;
+import com.medipath.backstage.model.User;
+
+public interface UserMapper extends Mapper<User> {
+}

+ 7 - 0
backstage-service/src/main/java/com/medipath/backstage/dao/UserRoleMapper.java

@@ -0,0 +1,7 @@
+package com.medipath.backstage.dao;
+
+import com.medipath.backstage.core.Mapper;
+import com.medipath.backstage.model.UserRole;
+
+public interface UserRoleMapper extends Mapper<UserRole> {
+}

+ 29 - 0
backstage-service/src/main/java/com/medipath/backstage/dto/AuthPermissionUrl.java

@@ -0,0 +1,29 @@
+//package com.medipath.backstage.dto;
+//
+//import lombok.AllArgsConstructor;
+//import lombok.Data;
+//
+//import java.util.Set;
+//
+//@Data
+//@AllArgsConstructor
+//public class AuthPermissionUrl {
+//
+//    /**
+//     * url
+//     */
+//    private String url;
+//
+//    /**
+//     * 权限集合
+//     */
+//    private Set<String> authorities;
+//
+//    public AuthPermissionUrl() {
+//    }
+//
+//    public AuthPermissionUrl(String url, String method) {
+//        this.url = url;
+//        this.method = method;
+//    }
+//}

+ 23 - 0
backstage-service/src/main/java/com/medipath/backstage/dto/LoginUser.java

@@ -0,0 +1,23 @@
+package com.medipath.backstage.dto;
+
+import com.medipath.backstage.model.Role;
+import com.medipath.backstage.model.User;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+import java.util.Set;
+
+@Data
+@NoArgsConstructor
+public class LoginUser {
+
+    private User user;
+
+    //存储权限信息
+    private Set<String> permissions;
+
+    private List<Role> roles;
+
+
+}

+ 19 - 0
backstage-service/src/main/java/com/medipath/backstage/dto/PermissionGroupDto.java

@@ -0,0 +1,19 @@
+package com.medipath.backstage.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class PermissionGroupDto implements Serializable {
+
+    private static final long serialVersionUID = -2497412971584900843L;
+
+    private String url;
+
+    private String permissionValues;
+}

+ 17 - 0
backstage-service/src/main/java/com/medipath/backstage/dto/ResultAuthPermissionUrl.java

@@ -0,0 +1,17 @@
+package com.medipath.backstage.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Set;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ResultAuthPermissionUrl {
+
+    private boolean isUrlMatcher = false;
+
+    private Set<String> authorities;
+}

+ 187 - 0
backstage-service/src/main/java/com/medipath/backstage/filter/AccessFilter.java

@@ -0,0 +1,187 @@
+package com.medipath.backstage.filter;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import com.medipath.backstage.configurer.Parameters;
+import com.medipath.backstage.model.Permission;
+import com.medipath.backstage.model.User;
+import com.medipath.backstage.service.PermissionService;
+import com.medipath.backstage.util.UserUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+@Component
+public class AccessFilter extends ZuulFilter  {
+
+    private static Logger log = LoggerFactory.getLogger(AccessFilter.class);
+
+    @Resource
+    private Parameters parameters;
+
+    @Resource
+    private PermissionService permissionService;
+
+    @Resource
+    private UserUtil userUtil;
+
+    @Override
+    public String filterType() {
+        return "pre";
+    }
+
+    @Override
+    public int filterOrder() {
+        return 0;
+    }
+
+    @Override
+    public boolean shouldFilter() {
+        return true;
+    }
+
+    @Override
+    public Object run() {
+        RequestContext ctx = RequestContext.getCurrentContext();
+        HttpServletRequest request = ctx.getRequest();
+        String servicePath = request.getRequestURI();
+        log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
+        //        过滤白名单
+        if (StrUtil.isNotBlank(parameters.getWebWhiteList())){
+            String[] whiteUrls = parameters.getWebWhiteList().split(",");
+            for (String url:whiteUrls) {
+                if (StrUtil.equals(url,servicePath)){
+                    return null;
+                }
+            }
+        }
+        if (StrUtil.endWith(servicePath,"/v2/api-docs")){
+            return null;
+        }
+        Object accessToken = request.getHeader("accessToken");
+        if(accessToken == null) {
+            log.warn("access token is empty");
+            ctx.setSendZuulResponse(false);
+            ctx.setResponseStatusCode(200);
+            ctx.setResponseBody("{\"code\":\"595\",\"message\":\"backstage Access Filter - token is empty\"}");
+            return false;
+        }
+
+        if (StrUtil.equals(parameters.getLoginCheck(),"true")){
+            // 登录拦截
+            boolean pass = validateLogin(request);
+            if (!pass) {
+                log.warn("登录认证失败,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(),
+                        getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
+                // responseResult(response, result);
+                ctx.setSendZuulResponse(false);
+                ctx.setResponseStatusCode(200);
+                ctx.setResponseBody("{\"code\":\"598\",\"message\":\"登录失败,请重新登录\"}");
+                return false;
+            }
+            User user = userUtil.getTokenUser(request);
+            if (StrUtil.isNotBlank(user.getCompanyId())){
+                ctx.addZuulRequestHeader("companyId", user.getCompanyId());
+            }
+            ctx.addZuulRequestHeader("userName", user.getName());
+            ctx.addZuulRequestHeader("userId", user.getId()+"");
+        }
+        // 权限拦截
+        if (StrUtil.equals("off",parameters.getPermissionSwitch())){
+            log.warn("接口权限校验已关闭,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(),
+                    getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
+        } else {
+            boolean pass2 = validatePermission(request);
+            if (!pass2) {
+                log.warn("接口权限校验失败,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(),
+                        getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
+                ctx.setSendZuulResponse(false);
+                ctx.setResponseStatusCode(200);
+                ctx.setResponseBody("{\"code\":\"597\",\"message\":\"接口:"+request.getRequestURI()+"权限验证失败,请联系管理员\"}");
+                return false;
+            }
+        }
+        log.info("access token ok");
+        return null;
+    }
+
+    private boolean validatePermission(HttpServletRequest request) {
+        String uri = request.getRequestURI();
+        if (StrUtil.isBlank(uri)){
+            return false;
+        }
+        User user = userUtil.getTokenUser(request);
+        if (user == null){
+            return false;
+        }
+        // 校验user是否拥有该权限
+        List<Permission> q = permissionService.selectPermissionByUserId(user.getId() + "");
+        for (Permission permission2 : q) {
+            if (StringUtils.equals(uri, permission2.geteName())) {
+                return true;
+            }
+            if (StringUtils.equals(uri, permission2.getUrl())) {
+                return true;
+            }
+            if(StrUtil.isNotBlank(permission2.getUrl())){
+                if (permission2.getUrl().contains("*")){
+                    if (uri.startsWith(permission2.getUrl().substring(0,permission2.getUrl().indexOf("*")))){
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 一个简单的登录认证
+     */
+    private boolean validateLogin(HttpServletRequest request) {
+        String accessToken = request.getHeader("accessToken");
+        if (StringUtils.isBlank(accessToken)) {
+            return false;
+        }
+        User user = userUtil.getTokenUser(request);
+        if (user != null) {
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+
+    private String getIpAddress(HttpServletRequest request) {
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_CLIENT_IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        // 如果是多级代理,那么取第一个ip为客户端ip
+        if (ip != null && ip.indexOf(",") != -1) {
+            ip = ip.substring(0, ip.indexOf(",")).trim();
+        }
+
+        return ip;
+    }
+
+}

+ 58 - 0
backstage-service/src/main/java/com/medipath/backstage/model/Mytest.java

@@ -0,0 +1,58 @@
+package com.medipath.backstage.model;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Table(name = "m_mytest")
+public class Mytest {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    private String content;
+
+    @Column(name = "create_time")
+    private Date createTime;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return content
+     */
+    public String getContent() {
+        return content;
+    }
+
+    /**
+     * @param content
+     */
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    /**
+     * @return create_time
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    /**
+     * @param createTime
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+}

+ 387 - 0
backstage-service/src/main/java/com/medipath/backstage/model/Permission.java

@@ -0,0 +1,387 @@
+package com.medipath.backstage.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+import javax.persistence.*;
+
+@Data
+@ApiModel
+@Table(name = "b_permission")
+public class Permission {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @ApiModelProperty(name = "id", value = "id")
+    private Integer id;
+
+    /**
+     * 名称
+     */
+    @ApiModelProperty(name = "name", value = "名称")
+    private String name;
+
+    /**
+     * 英文名
+     */
+    @Column(name = "e_name")
+    @ApiModelProperty(name = "eName", value = "英文名")
+    private String eName;
+
+    /**
+     * logo图
+     */
+    @ApiModelProperty(name = "logo", value = "logo")
+    private String logo;
+
+    /**
+     * 类型 0 菜单 1 页面 2动作
+     */
+    @ApiModelProperty(name = "type", value = "类型 0 菜单 1 页面 2动作")
+    private String type;
+
+    /**
+     * 是否允许点击
+     */
+    @Column(name = "is_action")
+    @ApiModelProperty(name = "isAction", value = "是否允许点击")
+    private String isAction;
+
+    /**
+     * 状态 0正常 1禁用
+     */
+    @ApiModelProperty(name = "status", value = "状态 0正常 1禁用")
+    private Integer status;
+
+    /**
+     * 跳转地址
+     */
+    @ApiModelProperty(name = "url", value = "跳转地址")
+    private String url;
+
+    /**
+     * 前端排版
+     */
+    @Column(name = "composing_key")
+    @ApiModelProperty(name = "composingKey", value = "前端排版")
+    private String composingKey;
+
+    /**
+     * 排序
+     */
+
+    @ApiModelProperty(name = "seq", value = "排序")
+    private Integer seq;
+
+    /**
+     * 上级菜单
+     */
+    @Column(name = "parent_id")
+    @ApiModelProperty(name = "parentId", value = "上级菜单")
+    private String parentId;
+
+    /**
+     * 创建人
+     */
+    @Column(name = "create_user_id")
+    private String createUserId;
+
+    /**
+     * 更新人
+     */
+    @Column(name = "update_user_id")
+    private String updateUserId;
+
+    /**
+     * 创建时间
+     */
+    @Column(name = "create_time")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @Column(name = "update_time")
+    private Date updateTime;
+
+    //孩子节点
+    @Transient
+    @ApiModelProperty(name = "children", value = "孩子节点")
+    private List<Permission> children;
+
+    public List<Permission> getChildren() {
+        return children;
+    }
+
+    public void setChildren(List<Permission> children) {
+        this.children = children;
+    }
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 获取名称
+     *
+     * @return name - 名称
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 设置名称
+     *
+     * @param name 名称
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 获取英文名
+     *
+     * @return e_name - 英文名
+     */
+    public String geteName() {
+        return eName;
+    }
+
+    /**
+     * 设置英文名
+     *
+     * @param eName 英文名
+     */
+    public void seteName(String eName) {
+        this.eName = eName;
+    }
+
+    /**
+     * 获取logo图
+     *
+     * @return logo - logo图
+     */
+    public String getLogo() {
+        return logo;
+    }
+
+    /**
+     * 设置logo图
+     *
+     * @param logo logo图
+     */
+    public void setLogo(String logo) {
+        this.logo = logo;
+    }
+
+    /**
+     * 获取类型 0 菜单 1 页面 2动作
+     *
+     * @return type - 类型 0 菜单 1 页面 2动作
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * 设置类型 0 菜单 1 页面 2动作
+     *
+     * @param type 类型 0 菜单 1 页面 2动作
+     */
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * 获取是否允许点击
+     *
+     * @return is_action - 是否允许点击
+     */
+    public String getIsAction() {
+        return isAction;
+    }
+
+    /**
+     * 设置是否允许点击
+     *
+     * @param isAction 是否允许点击
+     */
+    public void setIsAction(String isAction) {
+        this.isAction = isAction;
+    }
+
+    /**
+     * 获取状态 0正常 1禁用
+     *
+     * @return status - 状态 0正常 1禁用
+     */
+    public Integer getStatus() {
+        return status;
+    }
+
+    /**
+     * 设置状态 0正常 1禁用
+     *
+     * @param status 状态 0正常 1禁用
+     */
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    /**
+     * 获取跳转地址
+     *
+     * @return url - 跳转地址
+     */
+    public String getUrl() {
+        return url;
+    }
+
+    /**
+     * 设置跳转地址
+     *
+     * @param url 跳转地址
+     */
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    /**
+     * 获取前端排版
+     *
+     * @return composing_key - 前端排版
+     */
+    public String getComposingKey() {
+        return composingKey;
+    }
+
+    /**
+     * 设置前端排版
+     *
+     * @param composingKey 前端排版
+     */
+    public void setComposingKey(String composingKey) {
+        this.composingKey = composingKey;
+    }
+
+    /**
+     * 获取排序
+     *
+     * @return seq - 排序
+     */
+    public Integer getSeq() {
+        return seq;
+    }
+
+    /**
+     * 设置排序
+     *
+     * @param seq 排序
+     */
+    public void setSeq(Integer seq) {
+        this.seq = seq;
+    }
+
+    /**
+     * 获取上级菜单
+     *
+     * @return parent_id - 上级菜单
+     */
+    public String getParentId() {
+        return parentId;
+    }
+
+    /**
+     * 设置上级菜单
+     *
+     * @param parentId 上级菜单
+     */
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    /**
+     * 获取创建人
+     *
+     * @return create_user_id - 创建人
+     */
+    public String getCreateUserId() {
+        return createUserId;
+    }
+
+    /**
+     * 设置创建人
+     *
+     * @param createUserId 创建人
+     */
+    public void setCreateUserId(String createUserId) {
+        this.createUserId = createUserId;
+    }
+
+    /**
+     * 获取更新人
+     *
+     * @return update_user_id - 更新人
+     */
+    public String getUpdateUserId() {
+        return updateUserId;
+    }
+
+    /**
+     * 设置更新人
+     *
+     * @param updateUserId 更新人
+     */
+    public void setUpdateUserId(String updateUserId) {
+        this.updateUserId = updateUserId;
+    }
+
+    /**
+     * 获取创建时间
+     *
+     * @return create_time - 创建时间
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    /**
+     * 设置创建时间
+     *
+     * @param createTime 创建时间
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * 获取更新时间
+     *
+     * @return update_time - 更新时间
+     */
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    /**
+     * 设置更新时间
+     *
+     * @param updateTime 更新时间
+     */
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 216 - 0
backstage-service/src/main/java/com/medipath/backstage/model/Role.java

@@ -0,0 +1,216 @@
+package com.medipath.backstage.model;
+
+import com.medipath.backstage.core.BaseBeen;
+import com.medipath.backstage.web.para.PermissionBo;
+
+import java.util.Date;
+import java.util.List;
+import javax.persistence.*;
+
+@Table(name = "b_role")
+public class Role extends BaseBeen {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 保留
+     */
+    private String type;
+
+    /**
+     * 状态 0启用 1禁用
+     */
+    private String status;
+
+    /**
+     * 创建人
+     */
+    @Column(name = "create_user_id")
+    private String createUserId;
+
+    /**
+     * 更新人
+     */
+    @Column(name = "update_user_id")
+    private String updateUserId;
+
+    /**
+     * 创建时间
+     */
+    @Column(name = "create_time")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @Column(name = "update_time")
+    private Date updateTime;
+
+    @Transient
+    private String permissionIds;
+
+    @Transient
+    private List<PermissionBo> permissions;
+
+    public String getPermissionIds() {
+        return permissionIds;
+    }
+
+    public void setPermissionIds(String permissionIds) {
+        this.permissionIds = permissionIds;
+    }
+
+    public List<PermissionBo> getPermissions() {
+        return permissions;
+    }
+
+    public void setPermissions(List<PermissionBo> permissions) {
+        this.permissions = permissions;
+    }
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 获取名称
+     *
+     * @return name - 名称
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 设置名称
+     *
+     * @param name 名称
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 获取保留
+     *
+     * @return type - 保留
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * 设置保留
+     *
+     * @param type 保留
+     */
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * 获取状态 0启用 1禁用
+     *
+     * @return status - 状态 0启用 1禁用
+     */
+    public String getStatus() {
+        return status;
+    }
+
+    /**
+     * 设置状态 0启用 1禁用
+     *
+     * @param status 状态 0启用 1禁用
+     */
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    /**
+     * 获取创建人
+     *
+     * @return create_user_id - 创建人
+     */
+    public String getCreateUserId() {
+        return createUserId;
+    }
+
+    /**
+     * 设置创建人
+     *
+     * @param createUserId 创建人
+     */
+    public void setCreateUserId(String createUserId) {
+        this.createUserId = createUserId;
+    }
+
+    /**
+     * 获取更新人
+     *
+     * @return update_user_id - 更新人
+     */
+    public String getUpdateUserId() {
+        return updateUserId;
+    }
+
+    /**
+     * 设置更新人
+     *
+     * @param updateUserId 更新人
+     */
+    public void setUpdateUserId(String updateUserId) {
+        this.updateUserId = updateUserId;
+    }
+
+    /**
+     * 获取创建时间
+     *
+     * @return create_time - 创建时间
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    /**
+     * 设置创建时间
+     *
+     * @param createTime 创建时间
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * 获取更新时间
+     *
+     * @return update_time - 更新时间
+     */
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    /**
+     * 设置更新时间
+     *
+     * @param updateTime 更新时间
+     */
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 79 - 0
backstage-service/src/main/java/com/medipath/backstage/model/RolePermission.java

@@ -0,0 +1,79 @@
+package com.medipath.backstage.model;
+
+import lombok.*;
+
+import javax.persistence.*;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Getter
+@Setter
+@Table(name = "b_role_permission")
+public class RolePermission {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    /**
+     * 角色id
+     */
+    @Column(name = "role_id")
+    private String roleId;
+
+    /**
+     * 权限id
+     */
+    @Column(name = "permission_id")
+    private String permissionId;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 获取角色id
+     *
+     * @return role_id - 角色id
+     */
+    public String getRoleId() {
+        return roleId;
+    }
+
+    /**
+     * 设置角色id
+     *
+     * @param roleId 角色id
+     */
+    public void setRoleId(String roleId) {
+        this.roleId = roleId;
+    }
+
+    /**
+     * 获取权限id
+     *
+     * @return permission_id - 权限id
+     */
+    public String getPermissionId() {
+        return permissionId;
+    }
+
+    /**
+     * 设置权限id
+     *
+     * @param permissionId 权限id
+     */
+    public void setPermissionId(String permissionId) {
+        this.permissionId = permissionId;
+    }
+}

+ 356 - 0
backstage-service/src/main/java/com/medipath/backstage/model/User.java

@@ -0,0 +1,356 @@
+package com.medipath.backstage.model;
+
+import com.medipath.backstage.core.BaseBeen;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.*;
+
+@Table(name = "b_user")
+public class User extends BaseBeen {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    /**
+     * 姓名
+     */
+    private String name;
+
+    /**
+     * 登录账号
+     */
+    @Column(name = "login_account")
+    private String loginAccount;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 密码盐
+     */
+    private String salt;
+
+    /**
+     * 手机号码
+     */
+    @Column(name = "phone_no")
+    private String phoneNo;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 状态 0 正常 1注销 
+     */
+    private String status;
+
+    /**
+     * 公司id
+     */
+    @Column(name = "company_id")
+    private String companyId;
+
+    /**
+     * 创建时间
+     */
+    @Column(name = "create_time")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @Column(name = "update_time")
+    private Date updateTime;
+
+    /**
+     * 创建人
+     */
+    @Column(name = "create_user_id")
+    private String createUserId;
+
+    /**
+     * 更新人
+     */
+    @Column(name = "update_user_id")
+    private String updateUserId;
+
+    @Transient
+    private String token;
+
+    @Transient
+    private String roleName;
+
+    @Transient
+    private String roleIds;
+
+    public String getRoleIds() {
+        return roleIds;
+    }
+
+    public void setRoleIds(String roleIds) {
+        this.roleIds = roleIds;
+    }
+
+    @Transient
+    private List<UserRole> userRoles;
+
+    public String getRoleName() {
+        return roleName;
+    }
+
+    public void setRoleName(String roleName) {
+        this.roleName = roleName;
+    }
+
+    public List<UserRole> getUserRoles() {
+        return userRoles;
+    }
+
+    public void setUserRoles(List<UserRole> userRoles) {
+        this.userRoles = userRoles;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 获取姓名
+     *
+     * @return name - 姓名
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 设置姓名
+     *
+     * @param name 姓名
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 获取登录账号
+     *
+     * @return login_account - 登录账号
+     */
+    public String getLoginAccount() {
+        return loginAccount;
+    }
+
+    /**
+     * 设置登录账号
+     *
+     * @param loginAccount 登录账号
+     */
+    public void setLoginAccount(String loginAccount) {
+        this.loginAccount = loginAccount;
+    }
+
+    /**
+     * 获取密码
+     *
+     * @return password - 密码
+     */
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+     * 设置密码
+     *
+     * @param password 密码
+     */
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    /**
+     * 获取密码盐
+     *
+     * @return salt - 密码盐
+     */
+    public String getSalt() {
+        return salt;
+    }
+
+    /**
+     * 设置密码盐
+     *
+     * @param salt 密码盐
+     */
+    public void setSalt(String salt) {
+        this.salt = salt;
+    }
+
+    /**
+     * 获取手机号码
+     *
+     * @return phone_no - 手机号码
+     */
+    public String getPhoneNo() {
+        return phoneNo;
+    }
+
+    /**
+     * 设置手机号码
+     *
+     * @param phoneNo 手机号码
+     */
+    public void setPhoneNo(String phoneNo) {
+        this.phoneNo = phoneNo;
+    }
+
+    /**
+     * 获取邮箱
+     *
+     * @return email - 邮箱
+     */
+    public String getEmail() {
+        return email;
+    }
+
+    /**
+     * 设置邮箱
+     *
+     * @param email 邮箱
+     */
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    /**
+     * 获取状态 0 正常 1注销 
+     *
+     * @return status - 状态 0 正常 1注销 
+     */
+    public String getStatus() {
+        return status;
+    }
+
+    /**
+     * 设置状态 0 正常 1注销 
+     *
+     * @param status 状态 0 正常 1注销 
+     */
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    /**
+     * 获取公司id
+     *
+     * @return company_id - 公司id
+     */
+    public String getCompanyId() {
+        return companyId;
+    }
+
+    /**
+     * 设置公司id
+     *
+     * @param companyId 公司id
+     */
+    public void setCompanyId(String companyId) {
+        this.companyId = companyId;
+    }
+
+    /**
+     * 获取创建时间
+     *
+     * @return create_time - 创建时间
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    /**
+     * 设置创建时间
+     *
+     * @param createTime 创建时间
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * 获取更新时间
+     *
+     * @return update_time - 更新时间
+     */
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    /**
+     * 设置更新时间
+     *
+     * @param updateTime 更新时间
+     */
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    /**
+     * 获取创建人
+     *
+     * @return create_user_id - 创建人
+     */
+    public String getCreateUserId() {
+        return createUserId;
+    }
+
+    /**
+     * 设置创建人
+     *
+     * @param createUserId 创建人
+     */
+    public void setCreateUserId(String createUserId) {
+        this.createUserId = createUserId;
+    }
+
+    /**
+     * 获取更新人
+     *
+     * @return update_user_id - 更新人
+     */
+    public String getUpdateUserId() {
+        return updateUserId;
+    }
+
+    /**
+     * 设置更新人
+     *
+     * @param updateUserId 更新人
+     */
+    public void setUpdateUserId(String updateUserId) {
+        this.updateUserId = updateUserId;
+    }
+}

+ 58 - 0
backstage-service/src/main/java/com/medipath/backstage/model/UserRole.java

@@ -0,0 +1,58 @@
+package com.medipath.backstage.model;
+
+import javax.persistence.*;
+
+@Table(name = "b_user_role")
+public class UserRole {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+
+    @Column(name = "user_id")
+    private Integer userId;
+
+    @Column(name = "role_id")
+    private Integer roleId;
+
+    /**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * @return user_id
+     */
+    public Integer getUserId() {
+        return userId;
+    }
+
+    /**
+     * @param userId
+     */
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    /**
+     * @return role_id
+     */
+    public Integer getRoleId() {
+        return roleId;
+    }
+
+    /**
+     * @param roleId
+     */
+    public void setRoleId(Integer roleId) {
+        this.roleId = roleId;
+    }
+}

+ 22 - 0
backstage-service/src/main/java/com/medipath/backstage/mq/RabbitConfig.java

@@ -0,0 +1,22 @@
+//package com.yiweikeji.project.mq;
+//
+//import org.springframework.amqp.core.Queue;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//
+///**
+// *  MQ配置类
+// *
+// * @author limincheng
+// * @version $Id: RabbitConfig.java, v 0.1 2019年1月8日 上午11:45:06 limincheng Exp $
+// */
+//@Configuration
+//public class RabbitConfig {
+//
+//    @Bean
+//    public Queue fooQueue() {
+//        return new Queue("cif");
+//    }
+//
+//
+//}

+ 31 - 0
backstage-service/src/main/java/com/medipath/backstage/mq/Receiver.java

@@ -0,0 +1,31 @@
+//package com.yiweikeji.project.mq;
+//import javax.annotation.Resource;
+//
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.amqp.rabbit.annotation.RabbitListener;
+//import org.springframework.messaging.handler.annotation.Payload;
+//import org.springframework.stereotype.Component;
+//
+//import com.alibaba.fastjson.JSON;
+//
+//@Component
+//public class Receiver {
+//
+//    private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class);
+//
+//    @Resource
+//    private Sender sender;
+//
+//    @RabbitListener(queues = "cif")
+//    public void process(@Payload String data) {
+//        try {
+//            LOGGER.info("【MQ触发】:处理订单");
+//            System.out.println("paycallback======="+data);
+//            LOGGER.info("Listener:22 " + "paycallback======="+data);
+//        } catch (Exception e) {
+//            LOGGER.error("Mq处理订单发生异常", e);
+//        }
+//    }
+//
+//}

+ 15 - 0
backstage-service/src/main/java/com/medipath/backstage/mq/Sender.java

@@ -0,0 +1,15 @@
+//package com.yiweikeji.project.mq;
+//
+//import javax.annotation.Resource;
+//
+//import org.springframework.amqp.rabbit.core.RabbitTemplate;
+//import org.springframework.stereotype.Component;
+//
+//
+//@Component
+//public class Sender {
+//
+//    @Resource
+//    private RabbitTemplate rabbitTemplate;
+//
+//}

+ 10 - 0
backstage-service/src/main/java/com/medipath/backstage/service/MytestService.java

@@ -0,0 +1,10 @@
+package com.medipath.backstage.service;
+import com.medipath.backstage.model.Mytest;
+import com.medipath.backstage.core.Service;
+
+/**
+ * Created by CodeGenerator on 2022/04/06.
+ */
+public interface MytestService extends Service<Mytest> {
+
+}

+ 17 - 0
backstage-service/src/main/java/com/medipath/backstage/service/PermissionService.java

@@ -0,0 +1,17 @@
+package com.medipath.backstage.service;
+import com.medipath.backstage.model.Permission;
+import com.medipath.backstage.core.Service;
+
+import java.util.List;
+
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+public interface PermissionService extends Service<Permission> {
+
+    List<Permission> selectEenu(String userId);
+
+    List<Permission> selectPermissionByUserId(String userId);
+
+}

+ 15 - 0
backstage-service/src/main/java/com/medipath/backstage/service/RolePermissionService.java

@@ -0,0 +1,15 @@
+package com.medipath.backstage.service;
+import com.medipath.backstage.model.Role;
+import com.medipath.backstage.model.RolePermission;
+import com.medipath.backstage.core.Service;
+
+import java.util.List;
+
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+public interface RolePermissionService extends Service<RolePermission> {
+
+    int bangRolePermission(List<RolePermission> temp, Role temp2);
+}

+ 12 - 0
backstage-service/src/main/java/com/medipath/backstage/service/RoleService.java

@@ -0,0 +1,12 @@
+package com.medipath.backstage.service;
+import com.medipath.backstage.model.Role;
+import com.medipath.backstage.core.Service;
+
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+public interface RoleService extends Service<Role> {
+
+    boolean saveAndPermissionIds(Role role, String permissionIds);
+}

+ 13 - 0
backstage-service/src/main/java/com/medipath/backstage/service/UserRoleService.java

@@ -0,0 +1,13 @@
+package com.medipath.backstage.service;
+import com.medipath.backstage.core.Service;
+import com.medipath.backstage.model.UserRole;
+import tk.mybatis.mapper.entity.Condition;
+
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+public interface UserRoleService extends Service<UserRole> {
+
+    void deleteByCondition(Condition condition);
+}

+ 14 - 0
backstage-service/src/main/java/com/medipath/backstage/service/UserService.java

@@ -0,0 +1,14 @@
+package com.medipath.backstage.service;
+import com.medipath.backstage.core.Service;
+import com.medipath.backstage.model.User;
+
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+public interface UserService extends Service<User> {
+
+    void saveAndBandRole(User user, String roleIds);
+
+    void updateAndBandRole(User user, String roleIds);
+}

+ 22 - 0
backstage-service/src/main/java/com/medipath/backstage/service/impl/MytestServiceImpl.java

@@ -0,0 +1,22 @@
+package com.medipath.backstage.service.impl;
+
+import com.medipath.backstage.model.Mytest;
+import com.medipath.backstage.service.MytestService;
+import com.medipath.backstage.core.AbstractService;
+import com.medipath.backstage.dao.MytestMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+
+/**
+ * Created by CodeGenerator on 2022/04/06.
+ */
+@Service
+@Transactional
+public class MytestServiceImpl extends AbstractService<Mytest> implements MytestService {
+    @Resource
+    private MytestMapper mMytestMapper;
+
+}

+ 32 - 0
backstage-service/src/main/java/com/medipath/backstage/service/impl/PermissionServiceImpl.java

@@ -0,0 +1,32 @@
+package com.medipath.backstage.service.impl;
+
+import com.medipath.backstage.core.AbstractService;
+import com.medipath.backstage.service.PermissionService;
+import com.medipath.backstage.dao.PermissionMapper;
+import com.medipath.backstage.model.Permission;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+@Service
+@Transactional
+public class PermissionServiceImpl extends AbstractService<Permission> implements PermissionService {
+    @Resource
+    private PermissionMapper bPermissionMapper;
+
+    @Override
+    public List<Permission> selectEenu(String userId) {
+        return bPermissionMapper.selectEenu(userId);
+    }
+
+    @Override
+    public List<Permission> selectPermissionByUserId(String userId) {
+        return bPermissionMapper.selectPermissionByUserId(userId);
+    }
+}

+ 59 - 0
backstage-service/src/main/java/com/medipath/backstage/service/impl/RolePermissionServiceImpl.java

@@ -0,0 +1,59 @@
+package com.medipath.backstage.service.impl;
+
+import com.medipath.backstage.model.Role;
+import com.medipath.backstage.model.RolePermission;
+import com.medipath.backstage.service.RolePermissionService;
+import com.medipath.backstage.core.AbstractService;
+import com.medipath.backstage.dao.RoleMapper;
+import com.medipath.backstage.dao.RolePermissionMapper;
+import com.medipath.core.ServiceException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import tk.mybatis.mapper.entity.Condition;
+import tk.mybatis.mapper.entity.Example.Criteria;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+@Service
+@Transactional
+public class RolePermissionServiceImpl extends AbstractService<RolePermission>
+        implements RolePermissionService {
+    @Resource
+    private RolePermissionMapper bRolePermissionMapper;
+    @Resource
+    private RoleMapper           bRoleMapper;
+
+    /**
+     * 做删除操作后,进行插入
+     */
+    @Override
+    public int save(List<RolePermission> models) {
+        Condition condition = new Condition(RolePermission.class);
+        Criteria criteria = condition.createCriteria();
+        criteria.andEqualTo("roleId", models.get(0).getRoleId());
+        bRolePermissionMapper.deleteByCondition(condition);
+        return bRolePermissionMapper.insertList(models);
+    }
+
+    @Override
+    public int bangRolePermission(List<RolePermission> temp, Role role) {
+        if (role==null) {
+            throw new ServiceException("角色不能为空");
+        }
+        if (role.getId() == null) {
+            throw new ServiceException("角色id不能为空");
+        } else {
+            if(bRoleMapper.updateByPrimaryKeySelective(role) > 0){
+                return save(temp);
+            } else {
+                throw new ServiceException("更新关联关系操作失败");
+            }
+        }
+
+    }
+}

+ 52 - 0
backstage-service/src/main/java/com/medipath/backstage/service/impl/RoleServiceImpl.java

@@ -0,0 +1,52 @@
+package com.medipath.backstage.service.impl;
+
+import com.medipath.backstage.model.Role;
+import com.medipath.backstage.model.RolePermission;
+import com.medipath.backstage.service.RolePermissionService;
+import com.medipath.backstage.service.RoleService;
+import com.medipath.backstage.core.AbstractService;
+import com.medipath.backstage.dao.RoleMapper;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+@Service
+@Transactional
+public class RoleServiceImpl extends AbstractService<Role> implements RoleService {
+    @Resource
+    private RoleMapper bRoleMapper;
+
+    @Resource
+    private RolePermissionService rolePermissionService;
+
+
+    @Override
+    public boolean saveAndPermissionIds(Role role, String permissionIds) {
+        if (role == null) {
+            return false;
+        }
+        if(save(role)>0){
+            if (StringUtils.isNotBlank(permissionIds)) {
+                String[] ids = permissionIds.split(",");
+                List<RolePermission> temp = new ArrayList<RolePermission>();
+                for (String id : ids) {
+                    RolePermission cd = new RolePermission();
+                    cd.setRoleId(role.getId()+"");
+                    cd.setPermissionId(id);
+                    temp.add(cd);
+                }
+                rolePermissionService.save(temp);
+            }
+            return true;
+        }
+        return false;
+    }
+}

+ 27 - 0
backstage-service/src/main/java/com/medipath/backstage/service/impl/UserRoleServiceImpl.java

@@ -0,0 +1,27 @@
+package com.medipath.backstage.service.impl;
+
+import com.medipath.backstage.core.AbstractService;
+import com.medipath.backstage.dao.UserRoleMapper;
+import com.medipath.backstage.service.UserRoleService;
+import com.medipath.backstage.model.UserRole;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import tk.mybatis.mapper.entity.Condition;
+
+import javax.annotation.Resource;
+
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+@Service
+@Transactional
+public class UserRoleServiceImpl extends AbstractService<UserRole> implements UserRoleService {
+    @Resource
+    private UserRoleMapper bUserRoleMapper;
+
+    @Override
+    public void deleteByCondition(Condition condition) {
+        bUserRoleMapper.deleteByCondition(condition);
+    }
+}

+ 74 - 0
backstage-service/src/main/java/com/medipath/backstage/service/impl/UserServiceImpl.java

@@ -0,0 +1,74 @@
+package com.medipath.backstage.service.impl;
+
+import com.medipath.backstage.service.UserRoleService;
+import com.medipath.backstage.service.UserService;
+import com.medipath.backstage.core.AbstractService;
+import com.medipath.backstage.dao.UserMapper;
+import com.medipath.backstage.model.User;
+import com.medipath.backstage.model.UserRole;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import tk.mybatis.mapper.entity.Condition;
+import tk.mybatis.mapper.entity.Example.Criteria;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+@Service
+@Transactional
+public class UserServiceImpl extends AbstractService<User> implements UserService {
+    @Resource
+    private UserMapper bUserMapper;
+
+    @Resource
+    private UserRoleService userRoleService;
+
+    @Override
+    public void saveAndBandRole(User user, String roleIds) {
+        if (save(user) > 0) {
+            String[] ids = roleIds.split(",");
+            List<UserRole> temp = new ArrayList<UserRole>();
+            for (String rId : ids) {
+                UserRole cd = new UserRole();
+                cd.setRoleId(Integer.parseInt(rId));
+                cd.setUserId(user.getId());
+                temp.add(cd);
+            }
+            if (temp != null) {
+                Condition condition = new Condition(UserRole.class);
+                Criteria criteria = condition.createCriteria();
+                criteria.andEqualTo("userId", user.getId());
+                userRoleService.deleteByCondition(condition);
+                userRoleService.save(temp);
+            }
+        }
+    }
+
+    @Override
+    public void updateAndBandRole(User user, String roleIds) {
+        update(user);
+        if (StringUtils.isNotBlank(roleIds)) {
+            String[] ids = roleIds.split(",");
+            List<UserRole> temp = new ArrayList<UserRole>();
+            for (String rId : ids) {
+                UserRole cd = new UserRole();
+                cd.setRoleId(Integer.parseInt(rId));
+                cd.setUserId(user.getId());
+                temp.add(cd);
+            }
+            if (temp != null) {
+                Condition condition = new Condition(UserRole.class);
+                Criteria criteria = condition.createCriteria();
+                criteria.andEqualTo("userId", user.getId());
+                userRoleService.deleteByCondition(condition);
+                userRoleService.save(temp);
+            }
+        }
+    }
+}

+ 47 - 0
backstage-service/src/main/java/com/medipath/backstage/task/CouponExpireNoticeTask.java

@@ -0,0 +1,47 @@
+package com.medipath.backstage.task;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.lang.time.DateUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+import com.alibaba.fastjson.JSON;
+
+import tk.mybatis.mapper.entity.Condition;
+import tk.mybatis.mapper.entity.Example.Criteria;
+
+/**
+ * 卡券到期通知任务
+ */
+@Configuration
+@EnableScheduling
+public class CouponExpireNoticeTask {
+
+	private final Logger logger = LoggerFactory.getLogger(getClass());
+
+//	@Resource
+//	private MemberService memberService;
+
+
+	@Scheduled(cron = "0 0 0 1/1 * ? ") // 每天0点执行一次
+	public void scheduler() {
+		try {
+
+
+		} catch (Exception e) {
+			logger.error("原因:e{}", e);
+			return;
+		}
+	}
+
+}

+ 24 - 0
backstage-service/src/main/java/com/medipath/backstage/task/RefreshPermissionTask.java

@@ -0,0 +1,24 @@
+//package com.medipath.backstage.task;
+//
+//import com.medipath.backstage.dto.AuthPermissionUrl;
+//import com.medipath.backstage.service.PermissionService;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.scheduling.annotation.Scheduled;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.Set;
+//
+//@Slf4j
+//@Component
+//public class RefreshPermissionTask {
+//
+//    @Autowired
+//    private PermissionService permissionService;
+//
+//    //@Scheduled(cron = "0/5 * * * * ?")
+//    @Scheduled(cron = "0 */1 * * * ?")
+//    public void autoRefreshPermission() {
+//        Set<AuthPermissionUrl> authPermissionUrlSet = permissionService.refreshPermission();
+//    }
+//}

+ 233 - 0
backstage-service/src/main/java/com/medipath/backstage/util/Base64.java

@@ -0,0 +1,233 @@
+package com.medipath.backstage.util;
+
+/**
+ * 编码加密类
+ */
+public final class Base64 {
+
+    static private final int     BASELENGTH           = 128;
+    static private final int     LOOKUPLENGTH         = 64;
+    static private final int     TWENTYFOURBITGROUP   = 24;
+    static private final int     EIGHTBIT             = 8;
+    static private final int     SIXTEENBIT           = 16;
+    static private final int     FOURBYTE             = 4;
+    static private final int     SIGN                 = -128;
+    static private final char    PAD                  = '=';
+    static private final boolean fDebug               = false;
+    static final private byte[]  base64Alphabet       = new byte[BASELENGTH];
+    static final private char[]  lookUpBase64Alphabet = new char[LOOKUPLENGTH];
+
+    static {
+        for (int i = 0; i < BASELENGTH; ++i) {
+            base64Alphabet[i] = -1;
+        }
+        for (int i = 'Z'; i >= 'A'; i--) {
+            base64Alphabet[i] = (byte) (i - 'A');
+        }
+        for (int i = 'z'; i >= 'a'; i--) {
+            base64Alphabet[i] = (byte) (i - 'a' + 26);
+        }
+        for (int i = '9'; i >= '0'; i--) {
+            base64Alphabet[i] = (byte) (i - '0' + 52);
+        }
+        base64Alphabet['+'] = 62;
+        base64Alphabet['/'] = 63;
+        for (int i = 0; i <= 25; i++) {
+            lookUpBase64Alphabet[i] = (char) ('A' + i);
+        }
+        for (int i = 26, j = 0; i <= 51; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('a' + j);
+        }
+        for (int i = 52, j = 0; i <= 61; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('0' + j);
+        }
+        lookUpBase64Alphabet[62] = '+';
+        lookUpBase64Alphabet[63] = '/';
+    }
+
+    private static boolean isWhiteSpace(char octect) {
+        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+    }
+    private static boolean isPad(char octect) {
+        return (octect == PAD);
+    }
+    private static boolean isData(char octect) {
+        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
+    }
+
+    /**
+     * Encodes hex octects into Base64
+     * @param binaryData Array containing binaryData
+     * @return Encoded Base64 array
+     */
+    public static String encode(byte[] binaryData) {
+        if (binaryData == null) {
+            return null;
+        }
+        int lengthDataBits = binaryData.length * EIGHTBIT;
+        if (lengthDataBits == 0) {
+            return "";
+        }
+        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
+        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
+        char encodedData[] = null;
+        encodedData = new char[numberQuartet * 4];
+        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        if (fDebug) {
+            System.out.println("number of triplets = " + numberTriplets);
+        }
+        for (int i = 0; i < numberTriplets; i++) {
+            b1 = binaryData[dataIndex++];
+            b2 = binaryData[dataIndex++];
+            b3 = binaryData[dataIndex++];
+            if (fDebug) {
+                System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
+            }
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
+            byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
+            if (fDebug) {
+                System.out.println("val2 = " + val2);
+                System.out.println("k4   = " + (k << 4));
+                System.out.println("vak  = " + (val2 | (k << 4)));
+            }
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
+        }
+        // form integral number of 6-bit groups
+        if (fewerThan24bits == EIGHTBIT) {
+            b1 = binaryData[dataIndex];
+            k = (byte) (b1 & 0x03);
+            if (fDebug) {
+                System.out.println("b1=" + b1);
+                System.out.println("b1<<2 = " + (b1 >> 2));
+            }
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
+            encodedData[encodedIndex++] = PAD;
+            encodedData[encodedIndex++] = PAD;
+        } else if (fewerThan24bits == SIXTEENBIT) {
+            b1 = binaryData[dataIndex];
+            b2 = binaryData[dataIndex + 1];
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
+            encodedData[encodedIndex++] = PAD;
+        }
+        return new String(encodedData);
+    }
+
+    /**
+     * Decodes Base64 data into octects
+     * @param encoded string containing Base64 data
+     * @return Array containind decoded data.
+     */
+    public static byte[] decode(String encoded) {
+        if (encoded == null) {
+            return null;
+        }
+        char[] base64Data = encoded.toCharArray();
+        // remove white spaces
+        int len = removeWhiteSpace(base64Data);
+        if (len % FOURBYTE != 0) {
+            return null;//should be divisible by four
+        }
+        int numberQuadruple = (len / FOURBYTE);
+        if (numberQuadruple == 0) {
+            return new byte[0];
+        }
+        byte decodedData[] = null;
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+        char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
+        int i = 0;
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        decodedData = new byte[(numberQuadruple) * 3];
+        for (; i < numberQuadruple - 1; i++) {
+            if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
+                    || !isData((d3 = base64Data[dataIndex++]))
+                    || !isData((d4 = base64Data[dataIndex++]))) {
+                return null;
+            }//if found "no data" just return null
+            b1 = base64Alphabet[d1];
+            b2 = base64Alphabet[d2];
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+        }
+        if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
+            return null;//if found "no data" just return null
+        }
+        b1 = base64Alphabet[d1];
+        b2 = base64Alphabet[d2];
+        d3 = base64Data[dataIndex++];
+        d4 = base64Data[dataIndex++];
+        if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters
+            if (isPad(d3) && isPad(d4)) {
+                if ((b2 & 0xf) != 0)//last 4 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 1];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
+                return tmp;
+            } else if (!isPad(d3) && isPad(d4)) {
+                b3 = base64Alphabet[d3];
+                if ((b3 & 0x3) != 0)//last 2 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 2];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+                tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+                return tmp;
+            } else {
+                return null;
+            }
+        } else { //No PAD e.g 3cQl
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+        }
+        return decodedData;
+    }
+
+    /**
+     * remove WhiteSpace from MIME containing encoded Base64 data.
+     * @param data  the byte array of base64 data (with WS)
+     * @return the new length
+     */
+    private static int removeWhiteSpace(char[] data) {
+        if (data == null) {
+            return 0;
+        }
+        // count characters that's not whitespace
+        int newSize = 0;
+        int len = data.length;
+        for (int i = 0; i < len; i++) {
+            if (!isWhiteSpace(data[i])) {
+                data[newSize++] = data[i];
+            }
+        }
+        return newSize;
+    }
+
+}

+ 85 - 0
backstage-service/src/main/java/com/medipath/backstage/util/ConvertUtil.java

@@ -0,0 +1,85 @@
+package com.medipath.backstage.util;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class ConvertUtil {
+    /**
+     * inputStream转outputStream
+     * @param in
+     * @return
+     * @throws Exception
+     */
+    public static ByteArrayOutputStream parse(InputStream in) throws Exception
+    {
+        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
+        int ch;
+        while ((ch = in.read()) != -1) {   
+            swapStream.write(ch);   
+        }
+        return swapStream;
+    }
+    /**
+     * outputStream转inputStream
+     * @param out
+     * @return
+     * @throws Exception
+     */
+    public static ByteArrayInputStream parse(OutputStream out) throws Exception
+    {
+        ByteArrayOutputStream   baos=new   ByteArrayOutputStream();
+        baos=(ByteArrayOutputStream) out;
+        ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
+        return swapStream;
+    }
+    /**
+     * inputStream转String
+     * @param in
+     * @return
+     * @throws Exception
+     */
+    public static String parse_String(InputStream in) throws Exception
+    {
+        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
+        int ch;
+        while ((ch = in.read()) != -1) {   
+            swapStream.write(ch);   
+        }
+        return swapStream.toString();
+    }
+    /**
+     * OutputStream 转String
+     * @param out
+     * @return
+     * @throws Exception
+     */
+    public static String parse_String(OutputStream out)throws Exception
+    {
+        ByteArrayOutputStream   baos=new   ByteArrayOutputStream();
+        baos=(ByteArrayOutputStream) out;
+        ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
+        return swapStream.toString();
+    }
+    /**
+     * String转inputStream
+     * @param in
+     * @return
+     * @throws Exception
+     */
+    public static ByteArrayInputStream parse_inputStream(String in)throws Exception
+    {
+        ByteArrayInputStream input=new ByteArrayInputStream(in.getBytes());
+        return input;
+    }
+    /**
+     * String 转outputStream
+     * @param in
+     * @return
+     * @throws Exception
+     */
+    public static ByteArrayOutputStream parse_outputStream(String in)throws Exception
+    {
+        return parse(parse_inputStream(in));
+    }
+}

+ 44 - 0
backstage-service/src/main/java/com/medipath/backstage/util/FilterUrlMatcherUtil.java

@@ -0,0 +1,44 @@
+//package com.medipath.backstage.util;
+//
+//import com.alibaba.fastjson.JSON;
+//import com.medipath.backstage.dto.AuthPermissionUrl;
+//import com.medipath.backstage.dto.ResultAuthPermissionUrl;
+//import org.springframework.http.HttpMethod;
+//import org.springframework.util.AntPathMatcher;
+//
+//import java.util.HashSet;
+//import java.util.Set;
+//
+//
+//public class FilterUrlMatcherUtil {
+//
+//    public static ResultAuthPermissionUrl matcher(AuthPermissionUrl targetUrl, Set<AuthPermissionUrl> authPermissionUrlList) {
+//        AntPathMatcher antPathMatcher = new AntPathMatcher();
+//        ResultAuthPermissionUrl resultAuthPermissionUrl = new ResultAuthPermissionUrl();
+//        for (AuthPermissionUrl url : authPermissionUrlList) {
+//            if (antPathMatcher.match(url.getUrl(), targetUrl.getUrl()) && url.getMethod().equals(targetUrl.getMethod())) {
+//                resultAuthPermissionUrl.setUrlMatcher(true);
+//                resultAuthPermissionUrl.setAuthorities(url.getAuthorities());
+//                break;
+//            }
+//        }
+//        return resultAuthPermissionUrl;
+//    }
+//
+//    //todo 仅测试 需要删除
+//    public static void main(String[] args) {
+//        Set<AuthPermissionUrl> authPermissionUrlList = new HashSet();
+//        authPermissionUrlList.add(new AuthPermissionUrl("/api/v1/service/terms/{uid}", HttpMethod.GET.name()));
+//        authPermissionUrlList.add(new AuthPermissionUrl("/api/v1/service/add", HttpMethod.POST.name()));
+//        AuthPermissionUrl authPermissionUrlMatcher = new AuthPermissionUrl("/api/v1/service/terms/1", HttpMethod.resolve("GET").name());
+//        ResultAuthPermissionUrl matcher = FilterUrlMatcherUtil.matcher(authPermissionUrlMatcher, authPermissionUrlList);
+//
+//        System.out.println(JSON.toJSONString(matcher));
+//
+//
+//        AntPathMatcher antPathMatcher = new AntPathMatcher();
+//        boolean match = antPathMatcher.match("/exception/filter/403", "/exception/filter/{}");
+//        System.out.println(match);
+//    }
+//
+//}

+ 31 - 0
backstage-service/src/main/java/com/medipath/backstage/util/Md5Check.java

@@ -0,0 +1,31 @@
+package com.medipath.backstage.util;
+
+import java.security.MessageDigest;
+
+public class Md5Check {
+
+
+    public static String MD5(String s) {
+
+        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+        try {
+            byte[] strTemp = s.getBytes();
+            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
+            mdTemp.update(strTemp);
+            byte[] md = mdTemp.digest();
+            int j = md.length;
+            char str[] = new char[j * 2];
+            int k = 0;
+            for (int i = 0; i < j; i++) {
+                byte byte0 = md[i];
+                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
+                str[k++] = hexDigits[byte0 & 0xf];
+            }
+            return new String(str);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+  
+
+}

+ 491 - 0
backstage-service/src/main/java/com/medipath/backstage/util/OSSUtil.java

@@ -0,0 +1,491 @@
+///**
+// * 示例说明
+// *
+// * HelloOSS是OSS Java SDK的示例程序,您可以修改endpoint、accessKeyId、accessKeySecret、bucketName后直接运行。
+// * 运行方法请参考README。
+// *
+// * 本示例中的并不包括OSS Java SDK的所有功能,详细功能及使用方法,请参看“SDK手册 > Java-SDK”,
+// * 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/preface.html?spm=5176.docoss/sdk/java-sdk/。
+// *
+// * 调用OSS Java SDK的方法时,抛出异常表示有错误发生;没有抛出异常表示成功执行。
+// * 当错误发生时,OSS Java SDK的方法会抛出异常,异常中包括错误码、错误信息,详细请参看“SDK手册 > Java-SDK > 异常处理”,
+// * 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/exception.html?spm=5176.docoss/api-reference/error-response。
+// *
+// * OSS控制台可以直观的看到您调用OSS Java SDK的结果,OSS控制台地址是:https://oss.console.aliyun.com/index#/。
+// * OSS控制台使用方法请参看文档中心的“控制台用户指南”, 指南的来链接地址是:https://help.aliyun.com/document_detail/oss/getting-started/get-started.html?spm=5176.docoss/user_guide。
+// *
+// * OSS的文档中心地址是:https://help.aliyun.com/document_detail/oss/user_guide/overview.html。
+// * OSS Java SDK的文档地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/install.html?spm=5176.docoss/sdk/java-sdk。
+// *
+// */
+//
+//package com.yiweikeji.project.util;
+//
+//import java.io.File;
+//import java.io.FileInputStream;
+//import java.io.FileNotFoundException;
+//import java.io.IOException;
+//import java.io.InputStream;
+//import java.net.URL;
+//import java.util.Date;
+//import java.util.UUID;
+//
+//import com.yiweikeji.project.core.ServiceException;
+//import org.apache.commons.codec.digest.DigestUtils;
+//import org.apache.commons.lang.StringUtils;
+//import org.apache.tomcat.util.http.fileupload.FileItem;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Component;
+//import org.springframework.web.multipart.MultipartFile;
+//
+//import com.aliyun.oss.ClientException;
+//import com.aliyun.oss.OSSClient;
+//import com.aliyun.oss.OSSException;
+//import com.aliyun.oss.model.OSSObject;
+//import com.aliyun.oss.model.ObjectMetadata;
+//import com.aliyun.oss.model.PutObjectResult;
+//import com.yiweikeji.project.core.Result;
+//
+//@Component
+//public class OSSUtil {
+////    static Logger         logger   = Logger.getLogger(OSSUtil.class);
+//
+//    static Logger logger = LoggerFactory.getLogger(OSSUtil.class);
+//    // endpoint是访问OSS的域名。如果您已经在OSS的控制台上 创建了Bucket,请在控制台上查看域名。
+//    // 如果您还没有创建Bucket,endpoint选择请参看文档中心的“开发人员指南 > 基本概念 > 访问域名”,
+//    // 链接地址是:https://help.aliyun.com/document_detail/oss/user_guide/oss_concept/endpoint.html?spm=5176.docoss/user_guide/endpoint_region
+//    // endpoint的格式形如“http://oss-cn-hangzhou.aliyuncs.com/”,注意http://后不带bucket名称,
+//    // 比如“http://bucket-name.oss-cn-hangzhou.aliyuncs.com”,是错误的endpoint,请去掉其中的“bucket-name”。
+//    @Value("${oss.endpoint}")
+//    private String        endpoint;
+//
+//    // accessKeyId和accessKeySecret是OSS的访问密钥,您可以在控制台上创建和查看,
+//    // 创建和查看访问密钥的链接地址是:https://ak-console.aliyun.com/#/。
+//    // 注意:accessKeyId和accessKeySecret前后都没有空格,从控制台复制时请检查并去除多余的空格。
+//    @Value("${oss.accessKeyId}")
+//    private String        accessKeyId;
+//
+//    @Value("${oss.accessKeySecret}")
+//    private String        accessKeySecret;
+//
+//    // Bucket用来管理所存储Object的存储空间,详细描述请参看“开发人员指南 > 基本概念 > OSS基本概念介绍”。
+//    // Bucket命名规范如下:只能包括小写字母,数字和短横线(-),必须以小写字母或者数字开头,长度必须在3-63字节之间。
+//    @Value("${oss.bucketName}")
+//    private String        bucketName;
+//
+//    // Object是OSS存储数据的基本单元,称为OSS的对象,也被称为OSS的文件。详细描述请参看“开发人员指南 > 基本概念 >
+//    // OSS基本概念介绍”。
+//    // Object命名规范如下:使用UTF-8编码,长度必须在1-1023字节之间,不能以“/”或者“\”字符开头。
+//    private static String firstKey = "my-first-key";
+//
+//    private OSSClient     ossClient;
+//
+////    private String filedir = "cif";
+//
+//    public OSSUtil() {
+//    }
+//
+//    /**
+//     * 初始化
+//     */
+//    public void init() {
+//        ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
+//    }
+//
+//    /**
+//     * 销毁
+//     */
+//    public void destory() {
+//        ossClient.shutdown();
+//    }
+//
+//    public String getAccessKeyId() {
+//        return accessKeyId;
+//    }
+//
+//    /**
+//     * 保存文件
+//     */
+//    public boolean putFile(String key, File file) {
+//        if (StringUtils.isBlank(key)) {
+//            throw new ServiceException("参数key不能为空");
+//        }
+//        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
+//        try {
+//            if (!ossClient.doesBucketExist(bucketName)) {
+//                throw new ServiceException("没有找到您的Bucket");
+//            }
+//            ossClient.putObject(bucketName, key, file);
+//        } catch (OSSException oe) {
+//            logger.error(oe.getMessage());
+//            throw new ServiceException("调用oss异常,异常oe:{}", oe);
+//        } catch (ClientException ce) {
+//            logger.error(ce.getMessage());
+//            throw new ServiceException("调用oss异常,异常ce:{}", ce);
+//        } catch (Exception e) {
+//            logger.error(e.getMessage());
+//            throw new ServiceException("调用oss异常,异常e:{}", e);
+//        } finally {
+//            ossClient.shutdown();
+//        }
+//        return true;
+//    }
+//
+//    /**
+//     * 获得图片路径
+//     *
+//     * @param fileUrl
+//     * @return
+//     */
+//    public String getImgUrl(String fileUrl) {
+//      if (!StringUtils.isEmpty(fileUrl)) {
+//        String[] split = fileUrl.split("/");
+//        return this.getUrl(split[split.length - 1]);
+//      }
+//      return null;
+//    }
+//
+//    /**
+//     * 获取文件
+//     */
+//    public OSSObject getFile(String key) {
+//        if (StringUtils.isBlank(key)) {
+//            throw new ServiceException("参数key不能为空");
+//        }
+//        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
+//        try {
+//            if (!ossClient.doesBucketExist(bucketName)) {
+//                throw new ServiceException("没有找到您的Bucket");
+//            }
+//            OSSObject obj = ossClient.getObject(bucketName, key);
+//            if (null == obj) {
+//                logger.debug("没有要下载的文件");
+//                throw new ServiceException("没有要下载的文件");
+//            } else {
+//                return obj;
+//            }
+//        } catch (OSSException oe) {
+//            logger.error(oe.getMessage());
+//            throw new ServiceException("调用oss异常,异常oe:{}", oe);
+//        } catch (ClientException ce) {
+//            logger.error(ce.getMessage());
+//            throw new ServiceException("调用oss异常,异常ce:{}", ce);
+//        } catch (Exception e) {
+//            logger.error(e.getMessage());
+//            throw new ServiceException("调用oss异常,异常e:{}", e);
+//        } finally {
+//            ossClient.shutdown();
+//        }
+//    }
+//
+//    /**
+//     *
+//     * 功能描述: <br>
+//     * 〈文件上传〉
+//     *
+//     * @param item 上传文件流
+//     * @return
+//     * @throws OSSException
+//     * @throws ClientException
+//     * @throws FileNotFoundException
+//     * @see [相关类/方法](可选)
+//     * @since [产品/模块版本](可选)
+//     */
+//    public Result uploadFile(FileItem item, String key) throws OSSException, ClientException,
+//                                                       FileNotFoundException {
+//        String fileName = item.getName();
+//        ObjectMetadata objectMeta = new ObjectMetadata();
+//        objectMeta.setContentLength(item.getSize());
+//        // 可以在metadata中标记文件类型
+//        objectMeta.setContentType(item.getContentType());
+//        Result result = new Result();
+//        try {
+//            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
+//            InputStream input = item.getInputStream();
+//            InputStream md5Input = item.getInputStream();
+//            logger.debug("文件:{" + fileName + "}开始上传。");
+//            PutObjectResult putObjectResult = ossClient.putObject(bucketName, key, input,
+//                objectMeta);
+//            String md5 = DigestUtils.md5Hex(md5Input);
+//            md5Input.close();
+//            if (!md5.equalsIgnoreCase(putObjectResult.getETag())) {
+//                logger.error("md5验证失败,文件:{" + fileName + "}");
+//                throw new ServiceException("md5验证失败,文件:{" + fileName + "}");
+//            }
+//        } catch (IOException e) {
+//            logger.error("文件:{" + fileName + "}上传失败,异常信息:{}", e);
+//            throw new ServiceException("文件上传失败");
+//        }
+//        return result;
+//    }
+//    /**
+//     * 上传图片
+//     *
+//     * @param url
+//     */
+//    public void uploadImg2Oss(String url) {
+//      File fileOnServer = new File(url);
+//      FileInputStream fin;
+//      try {
+//        fin = new FileInputStream(fileOnServer);
+//        String[] split = url.split("/");
+//        this.uploadFile2OSS(fin, split[split.length - 1]);
+//      } catch (FileNotFoundException e) {
+//        throw new ServiceException("图片上传失败");
+//      }
+//    }
+//
+//    public String uploadImg2Oss(MultipartFile file) {
+//        if (file.getSize() > 1024 * 1024) {
+//            throw new ServiceException("上传图片大小不能超过1M!");
+//        }
+//        String originalFilename = file.getOriginalFilename();
+//        String substring = originalFilename.substring(originalFilename.lastIndexOf("."))
+//            .toLowerCase();
+//        String name = UUID.randomUUID().toString().toUpperCase() + substring;
+//        try {
+//            InputStream inputStream = file.getInputStream();
+//            this.uploadFile2OSS(inputStream, name);
+//            return name;
+//        } catch (Exception e) {
+//            throw new ServiceException("图片上传失败");
+//        }
+//    }
+//
+//    /**
+//     * 上传到OSS服务器  如果同名文件会覆盖服务器上的
+//     *
+//     * @param instream 文件流
+//     * @return 出错返回"" ,唯一MD5数字签名
+//     */
+//    public String uploadStream2OSS(InputStream instream, String fileName) {
+//        String ret = "";
+//        try {
+//            if (ossClient == null) {
+//                init();
+//            }
+//            PutObjectResult putResult = ossClient.putObject(bucketName, fileName, instream);
+//            ret = putResult.getETag();
+//        } catch (Exception e) {
+//            logger.error(e.getMessage(), e);
+//        } finally {
+//            try {
+//                if (instream != null) {
+//                    instream.close();
+//                }
+//            } catch (IOException e) {
+//                e.printStackTrace();
+//            }
+//        }
+//        return ret;
+//    }
+//
+//    /**
+//     * 上传到OSS服务器  如果同名文件会覆盖服务器上的
+//     *
+//     * @param instream 文件流
+//     * @param fileName 文件名称 包括后缀名
+//     * @return 出错返回"" ,唯一MD5数字签名
+//     */
+//    public String uploadFile2OSS(InputStream instream, String fileName) {
+//        String ret = "";
+//        try {
+//            //创建上传Object的Metadata
+//            ObjectMetadata objectMetadata = new ObjectMetadata();
+//            objectMetadata.setContentLength(instream.available());
+//            objectMetadata.setCacheControl("no-cache");
+//            objectMetadata.setHeader("Pragma", "no-cache");
+//            objectMetadata.setContentType(getcontentType(fileName.substring(fileName
+//                .lastIndexOf("."))));
+//            objectMetadata.setContentDisposition("inline;filename=" + fileName);
+//            //上传文件
+//            if (ossClient == null) {
+//                init();
+//            }
+//            PutObjectResult putResult = ossClient.putObject(bucketName, fileName,
+//                instream, objectMetadata);
+//            System.out.println( fileName);
+//            ret = putResult.getETag();
+//        } catch (IOException e) {
+//            logger.error(e.getMessage(), e);
+//        } finally {
+//            try {
+//                if (instream != null) {
+//                    instream.close();
+//                }
+//            } catch (IOException e) {
+//                e.printStackTrace();
+//            }
+//        }
+//        return ret;
+//    }
+//
+//    /**
+//     * Description: 判断OSS服务文件上传时文件的contentType
+//     *
+//     * @param FilenameExtension 文件后缀
+//     * @return String
+//     */
+//    public static String getcontentType(String FilenameExtension) {
+//        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
+//            return "image/bmp";
+//        }
+//        if (FilenameExtension.equalsIgnoreCase(".gif")) {
+//            return "image/gif";
+//        }
+//        if (FilenameExtension.equalsIgnoreCase(".jpeg")
+//            || FilenameExtension.equalsIgnoreCase(".jpg")
+//            || FilenameExtension.equalsIgnoreCase(".png")) {
+//            return "image/jpeg";
+//        }
+//        if (FilenameExtension.equalsIgnoreCase(".html")) {
+//            return "text/html";
+//        }
+//        if (FilenameExtension.equalsIgnoreCase(".txt")) {
+//            return "text/plain";
+//        }
+//        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
+//            return "application/vnd.visio";
+//        }
+//        if (FilenameExtension.equalsIgnoreCase(".pptx")
+//            || FilenameExtension.equalsIgnoreCase(".ppt")) {
+//            return "application/vnd.ms-powerpoint";
+//        }
+//        if (FilenameExtension.equalsIgnoreCase(".docx")
+//            || FilenameExtension.equalsIgnoreCase(".doc")) {
+//            return "application/msword";
+//        }
+//        if (FilenameExtension.equalsIgnoreCase(".xml")) {
+//            return "text/xml";
+//        }
+//        return "image/jpeg";
+//    }
+//
+//    /**
+//     * 获得url链接
+//     *
+//     * @param key
+//     * @return
+//     */
+//    public String getUrl(String key) {
+//      // 设置URL过期时间为10年  3600l* 1000*24*365*10
+//      Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
+//      // 生成URL
+//      if (ossClient == null) {
+//          init();
+//      }
+//      URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
+//      if (url != null) {
+//        return url.toString();
+//      }
+//      return null;
+//    }
+//
+//    public OSSObject downloadFile(String uuid) {
+//        try {
+//            if (ossClient == null) {
+//                init();
+//            }
+//            return ossClient.getObject(bucketName, uuid);
+//        } catch (Exception e) {
+//            throw new ServiceException();
+//        }
+//    }
+//
+//
+//
+//    //	public static void main(String[] args) {
+//    //
+//    //		// 日志配置,OSS Java
+//    //		// SDK使用log4j记录错误信息。示例程序会在工程目录下生成“oss-demo.log”日志文件,默认日志级别是INFO。
+//    //		// 日志的配置文件是“conf/log4j.properties”,如果您不需要日志,可以没有日志配置文件和下面的日志配置。
+//    //		// PropertyConfigurator.configure("conf/log4j.properties");
+//    //
+//    //		logger.info("Started");
+//    //
+//    //		// 生成OSSClient,您可以指定一些参数,详见“SDK手册 > Java-SDK > 初始化”,
+//    //		// 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/init.html?spm=5176.docoss/sdk/java-sdk/get-start
+//    //		OSSClient ossClient = new OSSClient(endpoint, accessKeyId,
+//    //				accessKeySecret);
+//    //
+//    //		try {
+//    //
+//    //			// 判断Bucket是否存在。详细请参看“SDK手册 > Java-SDK > 管理Bucket”。
+//    //			// 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_bucket.html?spm=5176.docoss/sdk/java-sdk/init
+//    //			if (ossClient.doesBucketExist(bucketName)) {
+//    //				System.out.println("您已经创建Bucket:" + bucketName + "。");
+//    //			} else {
+//    //				System.out.println("您的Bucket不存在,创建Bucket:" + bucketName + "。");
+//    //				// 创建Bucket。详细请参看“SDK手册 > Java-SDK > 管理Bucket”。
+//    //				// 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_bucket.html?spm=5176.docoss/sdk/java-sdk/init
+//    //				ossClient.createBucket(bucketName);
+//    //			}
+//    //
+//    //			// 查看Bucket信息。详细请参看“SDK手册 > Java-SDK > 管理Bucket”。
+//    //			// 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_bucket.html?spm=5176.docoss/sdk/java-sdk/init
+//    //			BucketInfo info = ossClient.getBucketInfo(bucketName);
+//    //			System.out.println("Bucket " + bucketName + "的信息如下:");
+//    //			System.out.println("\t数据中心:" + info.getBucket().getLocation());
+//    //			System.out.println("\t创建时间:" + info.getBucket().getCreationDate());
+//    //			System.out.println("\t用户标志:" + info.getBucket().getOwner());
+//    //
+//    //			// 把字符串存入OSS,Object的名称为firstKey。详细请参看“SDK手册 > Java-SDK > 上传文件”。
+//    //			// 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/upload_object.html?spm=5176.docoss/user_guide/upload_object
+//    //			InputStream is = new ByteArrayInputStream("Hello OSS".getBytes());
+//    //			ossClient.putObject(bucketName, firstKey, is);
+//    //			System.out.println("Object:" + firstKey + "存入OSS成功。");
+//    //
+//    //			// 下载文件。详细请参看“SDK手册 > Java-SDK > 下载文件”。
+//    //			// 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/download_object.html?spm=5176.docoss/sdk/java-sdk/manage_object
+//    //			OSSObject ossObject = ossClient.getObject(bucketName, firstKey);
+//    //			InputStream inputStream = ossObject.getObjectContent();
+//    //			StringBuilder objectContent = new StringBuilder();
+//    //			BufferedReader reader = new BufferedReader(new InputStreamReader(
+//    //					inputStream));
+//    //			while (true) {
+//    //				String line = reader.readLine();
+//    //				if (line == null)
+//    //					break;
+//    //				objectContent.append(line);
+//    //			}
+//    //			inputStream.close();
+//    //			System.out.println("Object:" + firstKey + "的内容是:" + objectContent);
+//    //
+//    //			// 文件存储入OSS,Object的名称为fileKey。详细请参看“SDK手册 > Java-SDK > 上传文件”。
+//    //			// 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/upload_object.html?spm=5176.docoss/user_guide/upload_object
+//    //			String fileKey = "README.md";
+//    //			ossClient.putObject(bucketName, fileKey, new File("README.md"));
+//    //			System.out.println("Object:" + fileKey + "存入OSS成功。");
+//    //
+//    //			// 查看Bucket中的Object。详细请参看“SDK手册 > Java-SDK > 管理文件”。
+//    //			// 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_object.html?spm=5176.docoss/sdk/java-sdk/manage_bucket
+//    //			ObjectListing objectListing = ossClient.listObjects(bucketName);
+//    //			List<OSSObjectSummary> objectSummary = objectListing
+//    //					.getObjectSummaries();
+//    //			System.out.println("您有以下Object:");
+//    //			for (OSSObjectSummary object : objectSummary) {
+//    //				System.out.println("\t" + object.getKey());
+//    //			}
+//    //
+//    //			// 删除Object。详细请参看“SDK手册 > Java-SDK > 管理文件”。
+//    //			// 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_object.html?spm=5176.docoss/sdk/java-sdk/manage_bucket
+//    //			ossClient.deleteObject(bucketName, firstKey);
+//    //			System.out.println("删除Object:" + firstKey + "成功。");
+//    //			ossClient.deleteObject(bucketName, fileKey);
+//    //			System.out.println("删除Object:" + fileKey + "成功。");
+//    //
+//    //		} catch (OSSException oe) {
+//    //			oe.printStackTrace();
+//    //		} catch (ClientException ce) {
+//    //			ce.printStackTrace();
+//    //		} catch (Exception e) {
+//    //			e.printStackTrace();
+//    //		} finally {
+//    //			ossClient.shutdown();
+//    //		}
+//    //		logger.info("Completed");
+//    //	}
+//
+//}

+ 121 - 0
backstage-service/src/main/java/com/medipath/backstage/util/StringUtil.java

@@ -0,0 +1,121 @@
+package com.medipath.backstage.util;
+
+import java.io.UnsupportedEncodingException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+public class StringUtil {
+
+	
+	//获取指定位数的随机字符串(包含小写字母、大写字母、数字,0<length)
+	public static String getRandomString(int length) {
+	    //随机字符串的随机字符库
+	    String KeyString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+	    StringBuffer sb = new StringBuffer();
+	    int len = KeyString.length();
+	    for (int i = 0; i < length; i++) {
+	       sb.append(KeyString.charAt((int) Math.round(Math.random() * (len - 1))));
+	    }
+	    return sb.toString();
+	}
+	
+	
+	   //获取指定位数的随机字符串(包含小写字母、大写字母、数字,0<length)
+    public static String getRandomInteger(int length) throws UnsupportedEncodingException {
+        //随机字符串的随机字符库
+        String KeyString = "0123456789";
+        StringBuffer sb = new StringBuffer();
+        int len = KeyString.length();
+        for (int i = 0; i < length; i++) {
+           sb.append(KeyString.charAt((int) Math.round(Math.random() * (len - 1))));
+        }
+        String code = new String(sb.toString().getBytes(),"utf-8");
+        return code;
+    }
+    
+    
+    /**
+     * code+yyyyMMddHHmmss+随机4位数字
+     * 
+     * @param code 活动标识
+     * @return
+     * @throws ParseException
+     */
+  	public static String getCodeByDate(String code) throws ParseException{
+  	    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+  	    String stringDate = sdf.format(new Date());
+  	    Double d =((Math.random()*9+1)*1000);
+		return code.toUpperCase()+stringDate+d.intValue();
+  	    
+  	}
+    
+	//校验密码是否符合规则(6到12位字母加数字组合密码)
+	public static String ensurePwd(String password){
+	    String returnMes = "";
+	    if(!password.equals("")){
+	        if(password.length()<6 || password.length() >12){
+	            returnMes += "密码长度需为6到12位;";
+	        }
+	        //判断密码是否包含数字:包含返回1,不包含返回0
+	        int i = password.matches(".*\\d+.*") ? 1 : 0;
+	        if(i==0){
+	            returnMes += "密码必须包含数字;";
+	        }
+	        //判断密码是否包含字母:包含返回1,不包含返回0
+	        int j = password.matches(".*[a-zA-Z]+.*") ? 1 : 0; 
+	        if(j ==0){
+	            returnMes += "密码必须包含字母;";
+	        }
+	        //判断密码是否包含特殊符号(~!@#$%^&*()_+|<>,.?/:;'[]{}\):包含返回1,不包含返回0
+	        int k = password.matches(".*[~!@#$%^&*()_+|<>,.?/:;'\\[\\]{}\"]+.*") ? 1 : 0;
+	        if(k ==1){
+	            returnMes += "密码必须不能包含特殊字符;";
+	        }
+	    }else{
+	        returnMes = "密码不可为空";
+	    }
+	    
+	    if("".equals(returnMes)){
+	        returnMes = "200";
+	    }
+        return returnMes;
+	    
+	}
+	
+	/**
+	 * 
+	 * 传入字符串加签,返回字符串
+	 * @return
+	 */
+	public static String signature(String message){
+	    
+        return null;
+	    
+	}
+	
+	/**
+	 * 使用RSA对报文正文加密
+	 *
+	 * @param message
+	 * @return
+	 */
+	public static String encrypt(String message){
+	    
+        return null;
+	    
+	}
+	
+	/**
+	 * 使用RSA对报文正文解密密
+	 *
+	 * @return
+	 */
+	public static String decrypt(String message){
+	    
+        return null;
+	    
+	}
+
+}

+ 47 - 0
backstage-service/src/main/java/com/medipath/backstage/util/UserUtil.java

@@ -0,0 +1,47 @@
+package com.medipath.backstage.util;
+
+import cn.hutool.json.JSONUtil;
+import com.medipath.backstage.core.RedisUtil;
+import com.medipath.backstage.core.cache.CacheKey;
+import com.medipath.backstage.core.cache.CacheType;
+import com.medipath.backstage.model.User;
+import com.medipath.backstage.service.UserService;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @Date: 2019/10/10 10:12
+ * @Version 1.0
+ */
+@Component
+public class UserUtil {
+
+    @Resource
+    private RedisUtil redisUtil;
+
+    @Resource
+    private UserService userService;
+
+
+    public User getTokenUser(HttpServletRequest request) {
+        if (request == null){
+            ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+            if (null != sra) {
+                request = sra.getRequest();
+            } else {
+                return null;
+            }
+        }
+        String token = request.getHeader("accessToken");
+        CacheKey key = CacheKey.generateKey(CacheType.UserConfig, token);
+        Object user = redisUtil.get(key.toString());
+        if (user != null) {
+            return JSONUtil.toBean(user.toString(), User.class);
+        }
+        return null;
+    }
+}

+ 196 - 0
backstage-service/src/main/java/com/medipath/backstage/web/LoginController.java

@@ -0,0 +1,196 @@
+package com.medipath.backstage.web;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.json.JSONUtil;
+import com.medipath.backstage.core.RedisUtil;
+import com.medipath.backstage.core.ResultCode;
+import com.medipath.backstage.core.ResultGenerator;
+import com.medipath.backstage.core.cache.CacheKey;
+import com.medipath.backstage.core.cache.CacheType;
+import com.medipath.backstage.core.interceptor.NoToken;
+import com.medipath.backstage.model.Permission;
+import com.medipath.backstage.model.Role;
+import com.medipath.backstage.model.UserRole;
+import com.medipath.backstage.service.PermissionService;
+import com.medipath.backstage.service.RoleService;
+import com.medipath.backstage.service.UserRoleService;
+import com.medipath.backstage.util.UserUtil;
+import com.medipath.backstage.web.para.LoginAccountParameters;
+import com.medipath.backstage.web.para.PermissionBo;
+import com.medipath.core.Result;
+import com.medipath.backstage.model.User;
+import com.medipath.backstage.service.UserService;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.web.bind.annotation.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import tk.mybatis.mapper.entity.Condition;
+import tk.mybatis.mapper.entity.Example.Criteria;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+@Api(tags = "登录管理")
+@RestController
+@RequestMapping("/login")
+public class LoginController {
+
+    private static Logger log = LoggerFactory.getLogger(LoginController.class);
+
+    @Resource
+    private UserService userService;
+
+    @Resource
+    private RedisUtil redisUtil;
+
+    @Resource
+    private UserUtil userUtil;
+
+    @Resource
+    private PermissionService permissionService;
+
+    @Resource
+    private UserRoleService userRoleService;
+
+    @Resource
+    private RoleService roleService;
+
+    @NoToken
+    @PostMapping("/login")
+    @ApiOperation(value = "后台登录",httpMethod = "POST")
+    public Result add(@RequestBody LoginAccountParameters loginParameters) {
+        if(loginParameters == null){
+            return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+        }
+        if(StringUtils.isBlank(loginParameters.getAccount())){
+            return ResultGenerator.genFailResult(ResultCode.ACCOUNT_IS_NULL);
+        }
+        Condition condition = new Condition(User.class);
+        condition.createCriteria().andEqualTo("loginAccount",loginParameters.getAccount());
+        List<User> users = userService.findByCondition(condition);
+        if(CollUtil.isEmpty(users)){
+            return ResultGenerator.genFailResult(ResultCode.USER_IS_NULL);
+        }
+        if(users.size() != 1){
+            return ResultGenerator.genFailResult(ResultCode.USER_IS_ERROR);
+        }
+        User user = users.get(0);
+        if(StrUtil.equals("1",user.getStatus())){
+            return ResultGenerator.genFailResult(ResultCode.LOGIN_USER_STATUS_IS_ERROR);
+        }
+        String pwd2 = SecureUtil.md5(loginParameters.getPwd() + user.getSalt()).toUpperCase();
+        log.error("[密码]"+loginParameters.getAccount() + " :"+pwd2);
+        //		String pwd2 = MD5Util.getMD5((loginParameters.getPwd() + user.getSalt()).toUpperCase());
+        if (StringUtils.equals(user.getPassword().toUpperCase(), pwd2)) {
+            String token = StrUtil.uuid();
+            CacheKey key = CacheKey.generateKey(CacheType.UserConfig, token);
+            user.setToken(token);
+            //设置redis缓存1小时
+            redisUtil.set(key.toString(), JSONUtil.toJsonStr(user), 7, TimeUnit.DAYS);
+            user.setPassword("***");
+            user.setSalt("***");
+            condition = new Condition(UserRole.class);
+            condition.createCriteria().andEqualTo("userId",user.getId());
+            List<UserRole> userRoles = userRoleService.findByCondition(condition);
+            if (CollUtil.isNotEmpty(userRoles)){
+                Role role = roleService.findById(userRoles.get(0).getRoleId());
+                if (role != null){
+                    user.setRoleName(role.getName());
+                }
+            }
+            return ResultGenerator.genSuccessResult(user);
+        } else {
+            return ResultGenerator.genFailResult(ResultCode.UNLOGIN_PWD_ERROR);
+        }
+    }
+
+    /**
+     * 通过userId获取菜单,需要TOKEN的.
+     *
+     */
+    @ApiOperation(value = "获取用户菜单",httpMethod = "GET")
+    @RequestMapping(value = "/queryMenu", method = { RequestMethod.GET, RequestMethod.POST })
+    public Result<List<PermissionBo>> queryMenu(HttpServletRequest request) {
+        //校验权限
+        try {
+            User tokenUser = userUtil.getTokenUser(request);
+            if (tokenUser == null){
+                return ResultGenerator.genFailResult(ResultCode.USER_IS_NULL);
+            }
+            List<Permission> ps = permissionService.selectEenu(tokenUser.getId() + "");
+
+            List<PermissionBo> bos = new LinkedList<PermissionBo>();
+            for (Permission permission : ps) {
+                PermissionBo t = new PermissionBo();
+                BeanUtils.copyProperties( permission,t);
+                bos.add(t);
+            }
+            bos = assemblyChildren(bos);
+            return ResultGenerator.genSuccessResult(bos);
+        } catch (Exception e) {
+            log.error("获取菜单异常e:{}", e);
+            return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+        }
+
+    }
+
+    /**
+     * 组装资源组
+     *
+     * @param rs
+     * @return
+     */
+    private static List<PermissionBo> assemblyChildren(List<PermissionBo> rs) {
+        if (rs == null) {
+            return null;
+        }
+        List<PermissionBo> temp = new LinkedList<>();
+        temp.addAll(rs);
+        List<PermissionBo> ret = new LinkedList<>();
+        // 组装一个map
+        Map<String, PermissionBo> tempMap = new TreeMap<>();
+        for (PermissionBo r : temp) {
+            tempMap.put(r.getId() + "", r);
+        }
+        for (PermissionBo r : temp) {
+            if (StringUtils.isNotBlank(r.getParentId())) {
+                PermissionBo parent = tempMap.get(r.getParentId());
+                if (parent != null) {
+                    List<PermissionBo> children = parent.getChildren();
+                    if (children == null) {
+                        children = new LinkedList<>();
+                    }
+                    children.add(tempMap.get(r.getId() + ""));
+                    parent.setChildren(children);
+                }
+            }
+        }
+        for (PermissionBo r : temp) {
+            if (StringUtils.isBlank(r.getParentId())) {
+                ret.add(tempMap.get(r.getId() + ""));
+            }
+        }
+        return ret;
+    }
+
+
+
+
+}

+ 407 - 0
backstage-service/src/main/java/com/medipath/backstage/web/PermissionController.java

@@ -0,0 +1,407 @@
+package com.medipath.backstage.web;
+import com.medipath.backstage.core.ResultCode;
+import com.medipath.backstage.core.ResultGenerator;
+import com.medipath.backstage.model.Role;
+import com.medipath.backstage.model.RolePermission;
+import com.medipath.backstage.model.User;
+import com.medipath.backstage.service.PermissionService;
+import com.medipath.backstage.service.RolePermissionService;
+import com.medipath.backstage.util.UserUtil;
+import com.medipath.backstage.web.para.PermissionBo;
+import com.medipath.core.Result;
+import com.medipath.backstage.model.Permission;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.web.bind.annotation.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import tk.mybatis.mapper.entity.Condition;
+import tk.mybatis.mapper.entity.Example.Criteria;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+@Api(tags = "permission管理")
+@RestController
+@RequestMapping("/permission")
+public class PermissionController {
+
+	private static Logger log = LoggerFactory.getLogger(PermissionController.class);
+
+	@Resource
+	private PermissionService permissionService;
+
+	@Resource
+	private RolePermissionService rolePermissionService;
+
+	@Resource
+	private UserUtil userUtil;
+
+	@PostMapping("/add")
+	@ApiOperation(value = "permission新增",httpMethod = "POST")
+	public Result add(@RequestBody Permission permission, HttpServletRequest request) {
+		if(permission == null){
+			return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+		}
+		if (StringUtils.isBlank(permission.getType())) {
+			return ResultGenerator.genFailResult(ResultCode.TYPE_IS_NULL);
+		}
+		if (StringUtils.isBlank(permission.getName())) {
+			return ResultGenerator.genFailResult(ResultCode.NAME_IS_NULL);
+		}
+		try {
+			if ("1".equals(permission.getType())){
+				permission.setIsAction("1");
+			} else {
+				permission.setIsAction("0");
+			}
+			User user = userUtil.getTokenUser(request);
+			permission.setCreateTime(new Date());
+			permission.setStatus(0);
+			if(permission.getSeq() == null){
+				permission.setSeq(0);
+			}
+			if (user != null){
+				permission.setCreateUserId(user.getName());
+			} else {
+				permission.setCreateUserId("sys");
+			}
+			permissionService.save(permission);
+			rolePermissionService.save(RolePermission.builder().permissionId(permission.getId()+"").roleId("1").build());
+		} catch (Exception e) {
+			log.error("新增对象操作异常e:{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult();
+
+	}
+
+	@PostMapping("/delete")
+	@ApiOperation(value = "permission删除",httpMethod = "POST")
+	public Result delete(@RequestParam Integer id) {
+		if(id == null){
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+		try {
+			permissionService.deleteById(id);
+		} catch (Exception e) {
+			log.error("删除对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult();
+	}
+
+	@PostMapping("/update")
+	@ApiOperation(value = "permission更新",httpMethod = "POST")
+	public Result update(@RequestBody Permission permission, HttpServletRequest request) {
+		if(permission == null){
+			return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+		}
+		if(permission.getId() == null){
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+		try {
+			User user = userUtil.getTokenUser(request);
+			permission.setUpdateTime(new Date());
+			if (user != null){
+				permission.setUpdateUserId(user.getName());
+			} else {
+				permission.setUpdateUserId("sys");
+			}
+			permissionService.update(permission);
+		} catch (Exception e) {
+			log.error("更新对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult();
+	}
+
+	@PostMapping("/detail")
+	@ApiOperation(value = "permission获取详情",httpMethod = "POST")
+	public Result<Permission> detail(@RequestParam Integer id) {
+		if(id == null){
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+		Permission permission = null;
+		try {
+			permission = permissionService.findById(id);
+		} catch (Exception e) {
+			log.error("查询对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+
+		return ResultGenerator.genSuccessResult(permission);
+	}
+
+	@PostMapping("/list")
+	@ApiOperation(value = "permission获取列表",httpMethod = "POST")
+	public Result<List<Permission>> list(@RequestBody Permission permission, @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "0") Integer size) {
+		PageHelper.startPage(page, size);
+
+		Condition condition = new Condition(permission.getClass());
+		Criteria criteria = condition.createCriteria();
+		//        criteria.andEqualTo("name", city.getName());
+		PageInfo pageInfo = null;
+		try {
+			List<Permission> list = permissionService.findByCondition(condition);
+			pageInfo = new PageInfo(list);
+		} catch (Exception e) {
+			log.error("查询对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult(pageInfo);
+	}
+
+	/**
+	 * 获取权限树
+	 * @return
+	 */
+	@ApiOperation(value = "获取权限树",httpMethod = "GET")
+	@RequestMapping(value = "/getTree", method = { RequestMethod.GET, RequestMethod.POST })
+	public Result<List<PermissionBo>> getPermissionTree() {
+		try {
+			Condition condition2 = new Condition(Permission.class);
+			condition2.orderBy("seq");
+
+			List<Permission> ps = permissionService.findByCondition(condition2);
+			if (ps == null || ps.isEmpty()) {
+				return ResultGenerator.genFailResult(ResultCode.RESULT_IS_NULL);
+			}
+
+			List<PermissionBo> bos = new LinkedList<PermissionBo>();
+			for (Permission permission : ps) {
+				PermissionBo t = new PermissionBo();
+				BeanUtils.copyProperties( permission,t);
+				bos.add(t);
+			}
+			List<PermissionBo> list = assemblyChildren(bos);
+			return ResultGenerator.genSuccessResult(list);
+		} catch (Exception e) {
+			log.error("获取权限树异常:e{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+
+	}
+
+	/**
+	 * 获取有关系的权限树
+	 * @param roleId 角色id
+	 * @return
+	 */
+	@ApiOperation(value = "获取有关系的权限树",httpMethod = "GET")
+	@RequestMapping(value = "/getDataTree", method = { RequestMethod.GET, RequestMethod.POST })
+	public Result<List<PermissionBo>> getPermissionTreeHasData( String roleId) {
+		try {
+			Condition condition = new Condition(RolePermission.class);
+			Criteria criteria = condition.createCriteria();
+			if (StringUtils.isNotBlank(roleId)) {
+				criteria.andEqualTo("roleId", roleId);
+			}
+			List<RolePermission> rps = rolePermissionService.findByCondition(condition);
+			Condition condition2 = new Condition(Permission.class);
+			condition2.orderBy("seq");
+			List<Permission> ps = permissionService.findByCondition(condition2);
+			if (ps == null || ps.isEmpty()) {
+				return ResultGenerator.genFailResult(ResultCode.RESULT_IS_NULL);
+			}
+			List<PermissionBo> bos = new ArrayList<PermissionBo>();
+			for (Permission permission : ps) {
+				PermissionBo t = new PermissionBo();
+				BeanUtils.copyProperties(permission,t);
+				t.setHasRelevance("0");
+				for (RolePermission rp : rps) {
+					if (StringUtils.equals(rp.getPermissionId(), permission.getId() + "")) {
+						t.setHasRelevance("1");
+					}
+				}
+				bos.add(t);
+			}
+			List<PermissionBo> list = assemblyChildren(bos);
+			return ResultGenerator.genSuccessResult(list);
+		} catch (Exception e) {
+			log.error("获取有关系的权限树异常:e{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+
+	}
+
+	/**
+	 * 获取有关系的页面和动作
+	 * @param roleId 角色id
+	 * @return
+	 */
+	@ApiOperation(value = "获取有关系的页面和动作",httpMethod = "GET")
+	@RequestMapping(value = "/getByParentIds", method = { RequestMethod.GET, RequestMethod.POST })
+	public Result getPermissionByParentIds( String roleId, String ids) {
+		if (StringUtils.isBlank(ids)) {
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+		try {
+			List<PermissionBo> bos = new ArrayList<PermissionBo>();
+
+			List<Permission> ps = permissionService.findAll();
+			if (ps == null || ps.isEmpty()) {
+				return ResultGenerator.genFailResult(ResultCode.RESULT_IS_NULL);
+			}
+
+			if (StringUtils.isNotBlank(roleId)) {
+				Condition condition = new Condition(RolePermission.class);
+				Criteria criteria = condition.createCriteria();
+				criteria.andEqualTo("roleId", roleId);
+				List<RolePermission> rps = rolePermissionService.findByCondition(condition);
+				for (Permission permission : ps) {
+					PermissionBo t = new PermissionBo();
+					BeanUtils.copyProperties( permission,t);
+					t.setHasRelevance("0");
+					for (RolePermission rp : rps) {
+						if (StringUtils.equals(rp.getPermissionId(), permission.getId() + "")) {
+							t.setHasRelevance("1");
+						}
+					}
+					bos.add(t);
+				}
+			} else {
+				for (Permission permission : ps) {
+					PermissionBo t = new PermissionBo();
+					BeanUtils.copyProperties(permission,t);
+					t.setHasRelevance("0");
+					bos.add(t);
+				}
+			}
+
+			Map<String, List<PermissionBo>> list = new HashMap<String, List<PermissionBo>>();
+			String[] is = ids.split(",");
+			for (String id : is) {
+				ArrayList<PermissionBo> l = new ArrayList<PermissionBo>();
+				for (PermissionBo bo : bos) {
+					if (!StringUtils.equals(bo.getType(), "0")) {
+						if (StringUtils.equals(bo.getParentId(), id)) {
+							l.add(bo);
+						}
+					}
+				}
+				list.put(id, l);
+			}
+			return ResultGenerator.genSuccessResult(list);
+		} catch (Exception e) {
+			log.error("获取有关系的权限树异常:e{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+
+	}
+
+	/**
+	 * 更新角色并
+	 * 绑定角色权限关系
+	 * @return
+	 */
+	@ApiOperation(value = "更新角色并绑定角色权限关系",httpMethod = "GET")
+	@RequestMapping(value = "/bangRolePermission", method = { RequestMethod.GET, RequestMethod.POST })
+	public Result bangRolePermission(@RequestBody Role role, HttpServletRequest request) {
+		if (role == null) {
+			log.error("参数不能为空");
+			return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+		}
+		if (role.getId() == null) {
+			log.error("参数不能为空");
+			return ResultGenerator.genFailResult(ResultCode.ROLEID_IS_NULL);
+		}
+		if (StringUtils.isBlank(role.getPermissionIds())) {
+			log.error("参数不能为空");
+			return ResultGenerator.genFailResult(ResultCode.PERMISSIONID_IS_NULL);
+		}
+		try {
+			User user = userUtil.getTokenUser(request);
+			if (user == null){
+				return ResultGenerator.genFailResult(ResultCode.USER_IS_NULL);
+			}
+			String[] ids = role.getPermissionIds().split(",");
+			List<RolePermission> temp = new ArrayList<RolePermission>();
+			for (String id : ids) {
+				RolePermission cd = new RolePermission();
+				cd.setRoleId(role.getId()+"");
+				cd.setPermissionId(id);
+				temp.add(cd);
+			}
+			Role temp2 = new Role();
+			temp2.setId(role.getId());
+			temp2.setUpdateTime(new Date());
+			temp2.setUpdateUserId(user.getName());
+			temp2.setName(role.getName());
+			temp2.setStatus(role.getStatus());
+			if (rolePermissionService.bangRolePermission(temp, temp2) > 0) {
+				return ResultGenerator.genSuccessResult();
+			} else {
+				return ResultGenerator.genFailResult(ResultCode.SQL_ERROR);
+			}
+		} catch (Exception e) {
+			log.error("绑定关系异常:e{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+	}
+
+	/**
+	 * 组装资源组
+	 *
+	 * @param rs
+	 * @return
+	 */
+	private static List<PermissionBo> assemblyChildren(List<PermissionBo> rs) {
+		if (rs == null) {
+			return null;
+		}
+		//权限的集合对象   对象里面有权限的子权限(孩子节点)
+		List<PermissionBo> temp = new LinkedList<PermissionBo>();
+		temp.addAll(rs);
+
+
+		List<PermissionBo> ret = new LinkedList<PermissionBo>();
+		// 组装一个map
+		//把ID为k  每个权限对象 组装为map
+		Map<String, PermissionBo> tempMap = new LinkedHashMap<String, PermissionBo>();
+		for (PermissionBo r : temp) {
+			tempMap.put(r.getId() + "", r);
+		}
+
+		//组装子父权限集合
+		for (PermissionBo r : temp) {
+			//判断是否有父节点
+			if (StringUtils.isNotBlank(r.getParentId())) {
+				//取出当前对象的父节点对象
+				PermissionBo parent = tempMap.get(r.getParentId());
+				//判断不为空
+				if (parent != null) {
+					//取出对象中子节点集合
+					List<PermissionBo> children = parent.getChildren();
+
+					//LIst等于空   就创建一个有序集合
+					if (children == null) {
+						children = new LinkedList<PermissionBo>();
+					}
+					//在集合添加此对象ID
+					children.add(tempMap.get(r.getId() + ""));
+					parent.setChildren(children);
+				}
+			}
+		}
+		//组装最大的父权限
+		//判断权限集合每个对象是否有父节点
+		for (PermissionBo r : temp) {
+			if (StringUtils.isBlank(r.getParentId())) {
+				ret.add(tempMap.get(r.getId() + ""));
+			}
+		}
+		return ret;
+	}
+}

+ 278 - 0
backstage-service/src/main/java/com/medipath/backstage/web/RoleController.java

@@ -0,0 +1,278 @@
+package com.medipath.backstage.web;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.medipath.backstage.core.ResultCode;
+import com.medipath.backstage.core.ResultGenerator;
+import com.medipath.backstage.model.Permission;
+import com.medipath.backstage.model.RolePermission;
+import com.medipath.backstage.model.User;
+import com.medipath.backstage.service.PermissionService;
+import com.medipath.backstage.service.RolePermissionService;
+import com.medipath.backstage.util.UserUtil;
+import com.medipath.backstage.web.para.PermissionBo;
+import com.medipath.core.Result;
+import com.medipath.backstage.model.Role;
+import com.medipath.backstage.service.RoleService;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import tk.mybatis.mapper.entity.Condition;
+import tk.mybatis.mapper.entity.Example.Criteria;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+@Api(tags = "role管理")
+@RestController
+@RequestMapping("/role")
+public class RoleController {
+
+	private static Logger log = LoggerFactory.getLogger(RoleController.class);
+
+	@Resource
+	private RoleService roleService;
+
+	@Resource
+	private UserUtil userUtil;
+
+	@Resource
+	private PermissionService permissionService;
+
+	@Resource
+	private RolePermissionService rolePermissionService;
+
+	@PostMapping("/add")
+	@ApiOperation(value = "role新增",httpMethod = "POST")
+	public Result add(@RequestBody Role role, HttpServletRequest request) {
+		if (role == null) {
+			return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+		}
+		if (StringUtils.isBlank(role.getName())) {
+			return ResultGenerator.genFailResult(ResultCode.NAME_IS_NULL);
+		}
+		try {
+			User tokenUser = userUtil.getTokenUser(request);
+			role.setStatus("0");
+			role.setCreateTime(DateUtil.date());
+			if(tokenUser == null || StrUtil.isBlank(tokenUser.getName())){
+				role.setCreateUserId("sys");
+			} else {
+				role.setCreateUserId(tokenUser.getName());
+			}
+			roleService.saveAndPermissionIds(role, role.getPermissionIds());
+		} catch (Exception e) {
+			log.error("新增对象操作异常e:{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+
+		return ResultGenerator.genSuccessResult();
+	}
+
+	@PostMapping("/delete")
+	@ApiOperation(value = "role删除",httpMethod = "POST")
+	public Result delete(@RequestParam Integer id) {
+		if(id == null){
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+		try {
+			if (id == 1){
+				return ResultGenerator.genFailResult(ResultCode.ADMIN_ROLE_UNDELETE);
+			}
+			roleService.deleteById(id);
+		} catch (Exception e) {
+			log.error("删除对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult();
+	}
+
+	@PostMapping("/update")
+	@ApiOperation(value = "role更新",httpMethod = "POST")
+	public Result update(@RequestBody Role role, HttpServletRequest request) {
+		if (role == null) {
+			log.error("参数不能为空");
+			return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+		}
+		if (role.getId() == null) {
+			log.error("参数不能为空");
+			return ResultGenerator.genFailResult(ResultCode.ROLEID_IS_NULL);
+		}
+		if (StringUtils.isBlank(role.getPermissionIds())) {
+			log.error("参数不能为空");
+			return ResultGenerator.genFailResult(ResultCode.PERMISSIONID_IS_NULL);
+		}
+		try {
+			User tokenUser = userUtil.getTokenUser(request);
+			if (tokenUser == null){
+				return ResultGenerator.genFailResult(ResultCode.USER_IS_NULL);
+			}
+			String[] ids = role.getPermissionIds().split(",");
+			List<RolePermission> temp = new ArrayList<RolePermission>();
+			for (String id : ids) {
+				RolePermission cd = new RolePermission();
+				cd.setRoleId(role.getId()+"");
+				cd.setPermissionId(id);
+				temp.add(cd);
+			}
+			Role temp2 = new Role();
+			temp2.setId(role.getId());
+			temp2.setUpdateTime(new Date());
+			temp2.setUpdateUserId(tokenUser.getName());
+			temp2.setName(role.getName());
+			temp2.setStatus(role.getStatus());
+			if (rolePermissionService.bangRolePermission(temp, temp2) > 0) {
+				return ResultGenerator.genSuccessResult();
+			} else {
+				return ResultGenerator.genFailResult(ResultCode.SQL_ERROR);
+			}
+		} catch (Exception e) {
+			log.error("绑定关系异常:e{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+	}
+
+	@PostMapping("/detail")
+	@ApiOperation(value = "role获取详情",httpMethod = "POST")
+	public Result<Role> detail(@RequestParam Integer id) {
+		if(id == null){
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+
+		Role role = null;
+		try {
+			role = roleService.findById(id);
+			Condition condition = new Condition(RolePermission.class);
+			Criteria criteria = condition.createCriteria();
+			if (id != null) {
+				criteria.andEqualTo("roleId", id+"");
+			}
+			List<RolePermission> rps = rolePermissionService.findByCondition(condition);
+			Condition condition2 = new Condition(Permission.class);
+			condition2.orderBy("seq");
+			List<Permission> ps = permissionService.findByCondition(condition2);
+			if (ps == null || ps.isEmpty()) {
+				return ResultGenerator.genFailResult(ResultCode.RESULT_IS_NULL);
+			}
+			List<PermissionBo> bos = new ArrayList<PermissionBo>();
+			for (Permission permission : ps) {
+				PermissionBo t = new PermissionBo();
+				BeanUtils.copyProperties(permission,t);
+				t.setHasRelevance("0");
+				for (RolePermission rp : rps) {
+					if (StringUtils.equals(rp.getPermissionId(), permission.getId() + "")) {
+						t.setHasRelevance("1");
+					}
+				}
+				bos.add(t);
+			}
+			List<PermissionBo> list = assemblyChildren(bos);
+			role.setPermissions(list);
+		} catch (Exception e) {
+			log.error("查询对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+
+		return ResultGenerator.genSuccessResult(role);
+	}
+
+	/**
+	 * 组装资源组
+	 *
+	 * @param rs
+	 * @return
+	 */
+	private static List<PermissionBo> assemblyChildren(List<PermissionBo> rs) {
+		if (rs == null) {
+			return null;
+		}
+		//权限的集合对象   对象里面有权限的子权限(孩子节点)
+		List<PermissionBo> temp = new LinkedList<PermissionBo>();
+		temp.addAll(rs);
+
+
+		List<PermissionBo> ret = new LinkedList<PermissionBo>();
+		// 组装一个map
+		//把ID为k  每个权限对象 组装为map
+		Map<String, PermissionBo> tempMap = new LinkedHashMap<String, PermissionBo>();
+		for (PermissionBo r : temp) {
+			tempMap.put(r.getId() + "", r);
+		}
+
+		//组装子父权限集合
+		for (PermissionBo r : temp) {
+			//判断是否有父节点
+			if (StringUtils.isNotBlank(r.getParentId())) {
+				//取出当前对象的父节点对象
+				PermissionBo parent = tempMap.get(r.getParentId());
+				//判断不为空
+				if (parent != null) {
+					//取出对象中子节点集合
+					List<PermissionBo> children = parent.getChildren();
+
+					//LIst等于空   就创建一个有序集合
+					if (children == null) {
+						children = new LinkedList<PermissionBo>();
+					}
+					//在集合添加此对象ID
+					children.add(tempMap.get(r.getId() + ""));
+					parent.setChildren(children);
+				}
+			}
+		}
+		//组装最大的父权限
+		//判断权限集合每个对象是否有父节点
+		for (PermissionBo r : temp) {
+			if (StringUtils.isBlank(r.getParentId())) {
+				ret.add(tempMap.get(r.getId() + ""));
+			}
+		}
+		return ret;
+	}
+
+	@PostMapping("/list")
+	@ApiOperation(value = "role获取列表",httpMethod = "POST")
+	public Result<List<Role>> list(@RequestBody Role role) {
+		PageHelper.startPage(role.getPage(), role.getSize());
+		Condition condition = new Condition(role.getClass());
+		Criteria criteria = condition.createCriteria();
+
+		if (StringUtils.isNotBlank(role.getName())) {
+			criteria.andLike("name", "%" + role.getName() + "%");
+		}
+		if (StringUtils.isNotBlank(role.getStatus())) {
+			criteria.andEqualTo("status", role.getStatus());
+		}
+		if (StringUtils.isNotBlank(role.getStartTime())) {
+			criteria.andGreaterThanOrEqualTo("createTime", role.getStartTime());
+		}
+		if (StringUtils.isNotBlank(role.getEndTime())) {
+			criteria.andLessThanOrEqualTo("createTime", role.getEndTime());
+		}
+		PageInfo pageInfo = null;
+		try {
+			List<Role> list = roleService.findByCondition(condition);
+			pageInfo = new PageInfo(list);
+		} catch (Exception e) {
+			log.error("查询对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult(pageInfo);
+	}
+}

+ 53 - 0
backstage-service/src/main/java/com/medipath/backstage/web/TestRedisController.java

@@ -0,0 +1,53 @@
+//package com.medipath.backstage.web;
+//
+//import com.medipath.backstage.core.RedisUtil;
+//import com.medipath.backstage.core.interceptor.NoToken;
+//import org.springframework.web.bind.annotation.GetMapping;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import org.springframework.web.bind.annotation.RestController;
+//
+//import javax.annotation.Resource;
+//import java.util.concurrent.TimeUnit;
+//
+///**
+// * @Author: lxk
+// * @Date: 2019/12/26 16:43
+// * @Version 1.0
+// */
+//@RestController
+//@RequestMapping("testRedis")
+//public class TestRedisController {
+//
+//    @Resource
+//    private RedisUtil redisUtil;
+//    @NoToken
+//    @GetMapping("get")
+//    public Object get(String key) {
+//        Object testRedis1 = redisUtil.get(key);
+//        return testRedis1;
+//    }
+//
+//    @GetMapping("incr")
+//    public Object incr(String key,Long num) {
+//        Object testRedis1 = redisUtil.incr(key,num);
+//        return testRedis1;
+//    }
+//
+//    @GetMapping("hget")
+//    public Object hget(String key,String item) {
+//        Object testRedis1 = redisUtil.hget(key,item);
+//        return testRedis1;
+//    }
+//    @NoToken
+//    @GetMapping("set")
+//    public Object set(String key,Object value,Integer time) {
+//        Object testRedis1 = redisUtil.set(key, value,time, TimeUnit.SECONDS);
+//        return testRedis1;
+//    }
+//    @NoToken
+//    @GetMapping("del")
+//    public Object del(String key) {
+//        redisUtil.del(key);
+//        return "success";
+//    }
+//}

+ 269 - 0
backstage-service/src/main/java/com/medipath/backstage/web/UserController.java

@@ -0,0 +1,269 @@
+package com.medipath.backstage.web;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import com.medipath.backstage.core.ResultCode;
+import com.medipath.backstage.core.ResultGenerator;
+import com.medipath.backstage.model.UserRole;
+import com.medipath.backstage.service.RoleService;
+import com.medipath.backstage.service.UserRoleService;
+import com.medipath.backstage.util.StringUtil;
+import com.medipath.backstage.util.UserUtil;
+import com.medipath.backstage.web.para.RestpwdParameters;
+import com.medipath.backstage.web.para.UserParameters;
+import com.medipath.core.Result;
+import com.medipath.backstage.model.User;
+import com.medipath.backstage.service.UserService;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import tk.mybatis.mapper.entity.Condition;
+import tk.mybatis.mapper.entity.Example.Criteria;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+import java.util.List;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Created by CodeGenerator on 2019/11/01.
+ */
+@Api(tags = "user管理")
+@RestController
+@RequestMapping("/user")
+public class UserController {
+
+	private static Logger log = LoggerFactory.getLogger(UserController.class);
+
+	@Resource
+	private UserService userService;
+
+	@Resource
+	private UserUtil userUtil;
+
+	@Resource
+	private UserRoleService userRoleService;
+
+	@Resource
+	private RoleService roleService;
+
+	@PostMapping("/add")
+	@ApiOperation(value = "user新增",httpMethod = "POST")
+	public Result add(@RequestBody UserParameters parameters, HttpServletRequest request) {
+		if (parameters == null) {
+			return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+		}
+		if (StringUtils.isBlank(parameters.getAccount())) {
+			return ResultGenerator.genFailResult(ResultCode.LOGIN_ACCOUNT_IS_NULL);
+		}
+		if (StringUtils.isBlank(parameters.getPwd())) {
+			return ResultGenerator.genFailResult(ResultCode.LOGIN_PASSWORD_IS_NULL);
+		}
+		try {
+			User tokenUser = userUtil.getTokenUser(request);
+			if (tokenUser == null){
+				return ResultGenerator.genFailResult(ResultCode.USER_IS_NULL);
+			}
+			String salt = StringUtil.getRandomString(4);
+			User user = new User();
+			user.setLoginAccount(parameters.getAccount());
+			user.setSalt(salt);
+			user.setName(parameters.getAccount());
+			user.setStatus("0");
+			user.setPassword(SecureUtil.md5(parameters.getPwd() + salt).toUpperCase());
+			user.setCreateTime(new Date());
+			user.setCreateUserId(tokenUser.getName());
+			userService.saveAndBandRole(user, parameters.getRoleIds());
+		} catch (Exception e) {
+			log.error("新增对象操作异常e:{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult();
+	}
+
+	@PostMapping("/delete")
+	@ApiOperation(value = "user删除",httpMethod = "POST")
+	public Result delete(@RequestParam Integer id) {
+		if(id == null){
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+		try {
+			userService.deleteById(id);
+		} catch (Exception e) {
+			log.error("删除对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult();
+	}
+
+	@PostMapping("/status")
+	@ApiOperation(value = "状态改变:启用禁用",httpMethod = "POST")
+	public Result status(@RequestParam Integer id) {
+		if(id == null){
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+		try {
+			User temp = userService.findById(id);
+			if (temp == null) {
+				return ResultGenerator.genFailResult(ResultCode.RESULT_IS_NULL);
+			}
+			User temp2 = new User();
+			temp2.setId(id);
+			if(StrUtil.equals(temp.getStatus(),"1")){
+				temp2.setStatus("0");
+			} else {
+				temp2.setStatus("1");
+			}
+			userService.update(temp2);
+		} catch (Exception e) {
+			log.error("删除对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult();
+	}
+
+	@PostMapping("/update")
+	@ApiOperation(value = "user更新",httpMethod = "POST")
+	public Result update(@RequestBody User user, HttpServletRequest request) {
+		if (user == null) {
+			return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+		}
+		if (user.getId() == null) {
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+		try {
+			User tokenUser = userUtil.getTokenUser(request);
+			if (tokenUser == null){
+				return ResultGenerator.genFailResult(ResultCode.USER_IS_NULL);
+			}
+			User temp = userService.findById(user.getId());
+			if (temp == null) {
+				return ResultGenerator.genFailResult(ResultCode.RESULT_IS_NULL);
+			}
+			user.setUpdateTime(new Date());
+			user.setLoginAccount(user.getName());
+			user.setPassword(null);
+			user.setUpdateUserId(tokenUser.getName());
+			if (StringUtils.isNotBlank(user.getRoleIds())){
+				userService.updateAndBandRole(user, user.getRoleIds());
+			}
+		} catch (Exception e) {
+			log.error("更新对象操作异常e:{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult();
+	}
+
+	@PostMapping("/detail")
+	@ApiOperation(value = "user获取详情",httpMethod = "POST")
+	public Result<User> detail(@RequestParam Integer id) {
+		if(id == null){
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+		User user = null;
+		try {
+			user = userService.findById(id);
+			user.setPassword("******");
+			user.setSalt("***");
+			Condition condition = new Condition(UserRole.class);
+			Criteria criteria = condition.createCriteria();
+			criteria.andEqualTo("userId", id + "");
+			List<UserRole> list = userRoleService.findByCondition(condition);
+			user.setUserRoles(list);
+		} catch (Exception e) {
+			log.error("查询对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+
+		return ResultGenerator.genSuccessResult(user);
+	}
+
+	@PostMapping("/list")
+	@ApiOperation(value = "user获取列表",httpMethod = "POST")
+	public Result<List<User>> list(@RequestBody User user) {
+		PageHelper.startPage(user.getPage(), user.getSize());
+		Condition condition = new Condition(user.getClass());
+		Criteria criteria = condition.createCriteria();
+		Criteria criteria1 = condition.or();
+		if (StringUtils.isNotBlank(user.getName())) {
+			criteria.andLike("name", "%" + user.getName() + "%");
+			criteria1.andEqualTo("id",user.getName());
+		}
+		if (StringUtils.isNotBlank(user.getStatus())) {
+			criteria.andEqualTo("status", user.getStatus());
+			criteria1.andEqualTo("status", user.getStatus());
+		}
+		if (StringUtils.isNotBlank(user.getStartTime())) {
+			criteria.andGreaterThanOrEqualTo("createTime", user.getStartTime());
+			criteria1.andGreaterThanOrEqualTo("createTime", user.getStartTime());
+		}
+		if (StringUtils.isNotBlank(user.getEndTime())) {
+			criteria.andLessThanOrEqualTo("createTime", user.getEndTime());
+			criteria1.andLessThanOrEqualTo("createTime", user.getEndTime());
+		}
+
+		PageInfo pageInfo = null;
+		try {
+			List<User> list = userService.findByCondition(condition);
+			for (User user2 : list) {
+				user2.setPassword("******");
+				user2.setSalt("***");
+			}
+			pageInfo = new PageInfo(list);
+		} catch (Exception e) {
+			log.error("查询对象操作异常e:{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult(pageInfo);
+	}
+
+	/**
+	 * 重置密码
+	 *
+	 * @return
+	 */
+	@PostMapping("/restpwd")
+	@ApiOperation(value = "重置密码",httpMethod = "POST")
+	public Result restpwd(@RequestBody RestpwdParameters parameters, HttpServletRequest request) {
+		// 校验权限
+		if (parameters == null) {
+			return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+		}
+		if (parameters.getUserId() == null) {
+			return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+		}
+		try {
+			User tokenUser =userUtil.getTokenUser(request);
+			if (tokenUser == null){
+				return ResultGenerator.genFailResult(ResultCode.USER_IS_NULL);
+			}
+			User temp = userService.findById(parameters.getUserId());
+			if (temp == null) {
+				return ResultGenerator.genFailResult(ResultCode.RESULT_IS_NULL);
+			}
+			User user = new User();
+			user.setId(parameters.getUserId());
+			user.setUpdateTime(new Date());
+			user.setUpdateUserId(tokenUser.getName());
+			if (StringUtils.isNotBlank(parameters.getPwd())) {
+				user.setPassword(SecureUtil.md5((parameters.getPwd() + temp.getSalt())).toUpperCase());
+			}
+			userService.update(user);
+
+		} catch (Exception e) {
+			log.error("更新对象操作异常e:{}", e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+		return ResultGenerator.genSuccessResult();
+	}
+}

+ 53 - 0
backstage-service/src/main/java/com/medipath/backstage/web/mng/MytestController.java

@@ -0,0 +1,53 @@
+package com.medipath.backstage.web.mng;
+import cn.hutool.core.date.DateUtil;
+import com.medipath.backstage.core.ResultCode;
+import com.medipath.backstage.core.ResultGenerator;
+import com.medipath.backstage.core.interceptor.NoToken;
+import com.medipath.backstage.model.Mytest;
+import com.medipath.backstage.service.MytestService;
+import com.medipath.core.Result;
+
+import org.springframework.web.bind.annotation.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+
+import javax.annotation.Resource;
+
+/**
+* Created by CodeGenerator on 2022/04/06.
+*/
+@Api(tags = "mytest管理")
+@RestController
+@RequestMapping("/mytest")
+public class MytestController {
+
+	private static Logger log = LoggerFactory.getLogger(MytestController.class);
+
+    @Resource
+    private MytestService mytestService;
+
+    @NoToken
+	@RequestMapping(value = "/add", method = {RequestMethod.POST,RequestMethod.GET}, produces = {"application/json; charset=utf-8"})
+	@ApiOperation(value = "mytest新增",httpMethod = "GET")
+    public Result add(String str) {
+    	if(str == null){
+    		return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+    	}
+    	try {
+    		Mytest mytest = new Mytest();
+    		mytest.setContent(str);
+    		mytest.setCreateTime(DateUtil.date());
+    		mytestService.save(mytest);
+		} catch (Exception e) {
+			log.error("新增对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+        
+        return ResultGenerator.genSuccessResult();
+    }
+
+
+}

+ 40 - 0
backstage-service/src/main/java/com/medipath/backstage/web/para/LoginAccountParameters.java

@@ -0,0 +1,40 @@
+package com.medipath.backstage.web.para;
+
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiParam;
+
+/**
+ * 账号登录参数
+ */
+@ApiModel("账号登录参数")
+public class LoginAccountParameters {
+
+    @ApiModelProperty(name="account",value = "登录账号",required=true)
+    private String account;
+
+    @ApiModelProperty(name="pwd",value = "登录密码",required=true)
+    private String pwd;
+
+    public String getAccount() {
+        return account;
+    }
+
+    public void setAccount(String account) {
+        this.account = account;
+    }
+
+    public String getPwd() {
+        return pwd;
+    }
+
+    public void setPwd(String pwd) {
+        this.pwd = pwd;
+    }
+
+    @Override
+    public String toString() {
+        return JSONObject.toJSONString(this);
+    }
+}

+ 276 - 0
backstage-service/src/main/java/com/medipath/backstage/web/para/PermissionBo.java

@@ -0,0 +1,276 @@
+package com.medipath.backstage.web.para;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+import java.util.List;
+
+public class PermissionBo {
+
+    private Integer id;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 名称
+     */
+    private String label;
+
+
+    /**
+     * logo
+     */
+    private String logo;
+
+    /**
+     * 类型 0 一级菜单 1 二级菜单  2 三级菜单 3 页面 4动作
+     */
+    private String type;
+
+    /**
+     * 前端排版
+     */
+    private String composingKey;
+
+    /**
+     * 跳转地址
+     */
+    private String url;
+
+    /**
+     * 排序
+     */
+    private Integer seq;
+
+    /**
+     * 上级菜单
+     */
+    private String parentId;
+
+    private String createUserId;
+
+    private String updateUserId;
+
+    private Date createTime;
+
+    private Date updateTime;
+
+    //有关联 0无 1有
+    private String hasRelevance;
+
+    /**
+     * 是否允许点击
+     */
+    @ApiModelProperty(name="isAction",value = "是否允许点击")
+    private String isAction;
+
+    public String getIsAction() {
+        return isAction;
+    }
+
+    public void setIsAction(String isAction) {
+        this.isAction = isAction;
+    }
+
+    public String getLabel() {
+        return name;
+    }
+
+    //孩子节点
+    private List<PermissionBo> children;
+
+    public String getComposingKey() {
+        return composingKey;
+    }
+
+    public void setComposingKey(String composingKey) {
+        this.composingKey = composingKey;
+    }
+
+    public String getLogo() {
+		return logo;
+	}
+
+	public void setLogo(String logo) {
+		this.logo = logo;
+	}
+
+	public String getHasRelevance() {
+		return hasRelevance;
+	}
+
+	public void setHasRelevance(String hasRelevance) {
+		this.hasRelevance = hasRelevance;
+	}
+
+	public List<PermissionBo> getChildren() {
+		return children;
+	}
+
+	public void setChildren(List<PermissionBo> children) {
+		this.children = children;
+	}
+
+	/**
+     * @return id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * @param id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 获取名称
+     *
+     * @return name - 名称
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * 设置名称
+     *
+     * @param name 名称
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 获取类型 0 一级菜单 1 二级菜单  2 三级菜单 3 页面 4动作
+     *
+     * @return type - 类型 0 一级菜单 1 二级菜单  2 三级菜单 3 页面 4动作
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * 设置类型 0 一级菜单 1 二级菜单  2 三级菜单 3 页面 4动作
+     *
+     * @param type 类型 0 一级菜单 1 二级菜单  2 三级菜单 3 页面 4动作
+     */
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * 获取跳转地址
+     *
+     * @return url - 跳转地址
+     */
+    public String getUrl() {
+        return url;
+    }
+
+    /**
+     * 设置跳转地址
+     *
+     * @param url 跳转地址
+     */
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    /**
+     * 获取排序
+     *
+     * @return seq - 排序
+     */
+    public Integer getSeq() {
+        return seq;
+    }
+
+    /**
+     * 设置排序
+     *
+     * @param seq 排序
+     */
+    public void setSeq(Integer seq) {
+        this.seq = seq;
+    }
+
+    /**
+     * 获取上级菜单
+     *
+     * @return parent_id - 上级菜单
+     */
+    public String getParentId() {
+        return parentId;
+    }
+
+    /**
+     * 设置上级菜单
+     *
+     * @param parentId 上级菜单
+     */
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    /**
+     * @return create_user_id
+     */
+    public String getCreateUserId() {
+        return createUserId;
+    }
+
+    /**
+     * @param createUserId
+     */
+    public void setCreateUserId(String createUserId) {
+        this.createUserId = createUserId;
+    }
+
+    /**
+     * @return update_user_id
+     */
+    public String getUpdateUserId() {
+        return updateUserId;
+    }
+
+    /**
+     * @param updateUserId
+     */
+    public void setUpdateUserId(String updateUserId) {
+        this.updateUserId = updateUserId;
+    }
+
+    /**
+     * @return create_time
+     */
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    /**
+     * @param createTime
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * @return update_time
+     */
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    /**
+     * @param updateTime
+     */
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 40 - 0
backstage-service/src/main/java/com/medipath/backstage/web/para/RestpwdParameters.java

@@ -0,0 +1,40 @@
+package com.medipath.backstage.web.para;
+
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiParam;
+
+/**
+ * 账号登录参数
+ */
+@ApiModel("重置密码参数")
+public class RestpwdParameters {
+
+    @ApiModelProperty(name="userId",value = "用户id",required=true)
+    private Integer userId;
+
+    @ApiModelProperty(name="pwd",value = "登录密码",required=true)
+    private String pwd;
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public String getPwd() {
+        return pwd;
+    }
+
+    public void setPwd(String pwd) {
+        this.pwd = pwd;
+    }
+
+    @Override
+    public String toString() {
+        return JSONObject.toJSONString(this);
+    }
+}

+ 29 - 0
backstage-service/src/main/java/com/medipath/backstage/web/para/UserParameters.java

@@ -0,0 +1,29 @@
+package com.medipath.backstage.web.para;
+
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiParam;
+import lombok.Data;
+
+/**
+ * 账号登录参数
+ */
+@Data
+@ApiModel("账号注册参数")
+public class UserParameters {
+
+    @ApiModelProperty(name="account",value = "登录账号",required=true)
+    private String account;
+
+    @ApiModelProperty(name="pwd",value = "登录密码",required=true)
+    private String pwd;
+
+    @ApiModelProperty(name="roleIds",value = "角色ids",required=true)
+    private String roleIds;
+
+    @Override
+    public String toString() {
+        return JSONObject.toJSONString(this);
+    }
+}

+ 26 - 0
backstage-service/src/main/java/com/medipath/backstage/web/para/UserQueryParameters.java

@@ -0,0 +1,26 @@
+package com.medipath.backstage.web.para;
+
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiParam;
+import lombok.Data;
+
+/**
+ * 账号登录参数
+ */
+@Data
+@ApiModel("账号查询参数")
+public class UserQueryParameters {
+
+    @ApiModelProperty(name="account",value = "登录账号或id",required=true)
+    private String account;
+
+    @ApiModelProperty(name="roleId",value = "角色id",required=true)
+    private String roleId;
+
+    @Override
+    public String toString() {
+        return JSONObject.toJSONString(this);
+    }
+}

+ 83 - 0
backstage-service/src/main/resources/bootstrap.properties

@@ -0,0 +1,83 @@
+spring.application.name=backstage
+server.port=8401
+spring.mvc.throw-exception-if-no-handler-found=true
+spring.resources.add-mappings=true
+
+web.white.list=/swagger-resources,/operating/area/list,/operating/area/China/init,/operating/conversion/export,/report/spectaculars/report
+
+spring.profiles.active=dev
+local.nacos=127.0.0.1:8848
+dev.nacos=172.10.100.112:8848
+test.nacos=172.10.100.40:8848
+pro.nacos=172.10.100.10:30308
+spring.cloud.nacos.discovery.server-addr=${${spring.profiles.active}.nacos}
+spring.cloud.nacos.config.server-addr=${${spring.profiles.active}.nacos}
+#spring.cloud.nacos.config.namespace=7eea2e46-08a2-44b9-b067-51148ee2d71e
+#spring.cloud.nacos.config.group=dev
+spring.cloud.nacos.config.prefix=backstage
+spring.cloud.nacos.config.file-extension=properties
+
+spring.cloud.nacos.config.ext-config[0].data-id=mq-${spring.profiles.active}.properties
+spring.cloud.nacos.config.ext-config[0].refresh=true
+spring.cloud.nacos.config.ext-config[1].data-id=redis-${spring.profiles.active}.properties
+spring.cloud.nacos.config.ext-config[1].refresh=true
+dubbo.protocol.serialization=kryo
+dubbo.protocol.optimizer=
+dubbo.protocol.name=dubbo
+dubbo.protocol.port=-1
+dubbo.registry.file=/var/logs/${spring.application.name}/dubbo_${server.port}.cache
+dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}
+dubbo.scan.base-packages=com.medipath.${spring.application.name}.dubbo.impl
+dubbo.cloud.subscribed-services=
+dubbo.application.qos.enable=false
+dubbo.application.qos.port=28111
+dubbo.application.qos.accept.foreign.ip=false
+
+dubbo.reference.com.foo.BarService.check=false
+dubbo.reference.check=false
+dubbo.consumer.check=false
+dubbo.registry.check=false
+
+permission.switch=on
+
+zuul.ignored-services='*'
+zuul.sensitive-headers=Access-Control-Allow-Origin
+zuul.ignored-headers=Access-Control-Allow-Origin,H-APP-Id,accessToken
+
+zuul.host.max-per-route-connections=2000
+zuul.host.max-total-connections=20000
+
+#zuul.ribbon-isolation-strategy=thread
+hystrix.command.default.execution.isolation.strategy=THREAD
+hystrix.threadpool.default.coreSize=10000
+hystrix.threadpool.default.allowMaximumSizeToDivergeFromCoreSize=true
+hystrix.threadpool.default.maxQueueSize=-1
+hystrix.threadpool.default.maximumSize=400
+hystrix.command.default.execution.isolation.thread.strategy=SEMAPHORE
+hystrix.command.default.execution.isolation.thread.semaphore.max-semaphores=2000
+hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=50000
+hystrix.command.default.circuitBreaker.forceOpen=false
+feign.hystrix.enabled=false 
+hystrix.command.default.execution.timeout.enabled=false
+
+multipart.maxFileSize=100Mb
+server.undertow.max-http-post-size=83886080
+#spring.servlet.multipart.enabled=true
+spring.servlet.multipart.max-file-size=100Mb
+spring.servlet.multipart.max-request-size=1000Mb
+dubbo.protocol.dubbo.payload=83886080
+
+#zuul.ignore-security-headers=false
+
+ribbon.ConnectTimeout=3000
+ribbon.ReadTimeout=3000
+ribbon.MaxAutoRetries=1
+ribbon.MaxAutoRetriesNextServer=1
+zuul.semaphore.max-semaphores=5000
+
+swagger.resource=cif,operating,report
+
+
+
+
+

+ 92 - 0
backstage-service/src/main/resources/logback.xml

@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false">
+    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
+    <property name="LOG_HOME" value="/var/logs/backstage" />
+    <!-- 控制台输出 -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+    <!-- 按照每天生成日志文件 -->
+<!--    <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">-->
+<!--        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
+<!--            &lt;!&ndash;日志文件输出的文件名&ndash;&gt;-->
+<!--            <FileNamePattern>${LOG_HOME}/backstage.log.%d{yyyy-MM-dd}.log</FileNamePattern>-->
+<!--            &lt;!&ndash;日志文件保留天数&ndash;&gt;-->
+<!--            <MaxHistory>30</MaxHistory>-->
+<!--        </rollingPolicy>-->
+<!--        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">-->
+<!--            &lt;!&ndash;格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符&ndash;&gt;-->
+<!--            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>-->
+<!--        </encoder>-->
+<!--        &lt;!&ndash;日志文件最大的大小&ndash;&gt;-->
+<!--        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">-->
+<!--&lt;!&ndash;             <MaxFileSize>10MB</MaxFileSize> &ndash;&gt;-->
+<!--        </triggeringPolicy>-->
+<!--    </appender>-->
+
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- rollover daily -->
+            <fileNamePattern>${LOG_HOME}/log.backstage.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
+            <maxFileSize>100MB</maxFileSize>
+            <maxHistory>5</maxHistory>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+        <!-- 按照每天生成日志文件 -->
+    <appender name="ERROR_FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <FileNamePattern>${LOG_HOME}/error.backstage.log.%d{yyyy-MM-dd}.log</FileNamePattern>
+            <MaxHistory>30</MaxHistory>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
+	        <level>ERROR</level>
+	        <onMatch>ACCEPT</onMatch>
+	        <onMismatch>DENY</onMismatch>
+	    </filter>
+    </appender>
+    <!-- show parameters for hibernate sql 专为 Hibernate 定制 -->
+<!--     <logger name="org.hibernate.type.descriptor.sql.BasicBinder"  level="TRACE" /> -->
+<!--     <logger name="org.hibernate.type.descriptor.sql.BasicExtractor"  level="DEBUG" /> -->
+<!--     <logger name="org.hibernate.SQL" level="DEBUG" /> -->
+<!--     <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" /> -->
+<!--     <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" /> -->
+
+    <!--myibatis log configure-->
+    <logger name="com.apache.ibatis" level="TRACE"/>
+    <logger name="java.sql.Connection" level="DEBUG"/>
+    <logger name="java.sql.Statement" level="DEBUG"/>
+    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
+	<logger name="com.kameng.project" />
+
+    <!-- 日志输出级别 -->
+    <root level="INFO">
+        <appender-ref ref="STDOUT" />
+        <appender-ref ref="FILE" />
+        <appender-ref ref="ERROR_FILE" />
+    </root>
+
+    <!--日志异步到数据库 -->
+    <!--<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">-->
+        <!--&lt;!&ndash;日志异步到数据库 &ndash;&gt;-->
+        <!--<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">-->
+            <!--&lt;!&ndash;连接池 &ndash;&gt;-->
+            <!--<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">-->
+                <!--<driverClass>com.mysql.jdbc.Driver</driverClass>-->
+                <!--<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>-->
+                <!--<user>root</user>-->
+                <!--<password>root</password>-->
+            <!--</dataSource>-->
+        <!--</connectionSource>-->
+    <!--</appender>-->
+</configuration>

+ 12 - 0
backstage-service/src/main/resources/mapper/MytestMapper.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.medipath.backstage.dao.MytestMapper">
+  <resultMap id="BaseResultMap" type="com.medipath.backstage.model.Mytest">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" jdbcType="INTEGER" property="id" />
+    <result column="content" jdbcType="VARCHAR" property="content" />
+    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+  </resultMap>
+</mapper>

+ 64 - 0
backstage-service/src/main/resources/mapper/PermissionMapper.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.medipath.backstage.dao.PermissionMapper">
+    <resultMap id="BaseResultMap" type="com.medipath.backstage.model.Permission">
+        <!--
+          WARNING - @mbg.generated
+        -->
+        <id column="id" jdbcType="INTEGER" property="id"/>
+        <result column="name" jdbcType="VARCHAR" property="name"/>
+        <result column="e_name" jdbcType="VARCHAR" property="eName"/>
+        <result column="logo" jdbcType="VARCHAR" property="logo"/>
+        <result column="type" jdbcType="VARCHAR" property="type"/>
+        <result column="is_action" jdbcType="VARCHAR" property="isAction"/>
+        <result column="status" jdbcType="INTEGER" property="status"/>
+        <result column="url" jdbcType="VARCHAR" property="url"/>
+        <result column="composing_key" jdbcType="VARCHAR" property="composingKey"/>
+        <result column="seq" jdbcType="INTEGER" property="seq"/>
+        <result column="parent_id" jdbcType="VARCHAR" property="parentId"/>
+        <result column="create_user_id" jdbcType="VARCHAR" property="createUserId"/>
+        <result column="update_user_id" jdbcType="VARCHAR" property="updateUserId"/>
+        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+    </resultMap>
+
+    <select id="selectEenu" parameterType="string" resultMap="BaseResultMap">
+        select distinct p.*
+        from b_permission p,
+             b_user_role ur,
+             b_role r,
+             b_role_permission rp
+        where p.id = rp.permission_id
+          and rp.role_id = ur.role_id
+          and ur.role_id = r.id
+          and ur.user_id = #{userId}
+          and p.status = 0
+          and r.status = 0
+          and p.type in (1, 2)
+        order by seq, id
+    </select>
+
+    <select id="selectPermissionByUserId" parameterType="string" resultMap="BaseResultMap">
+        select distinct p.*
+        from b_permission p,
+             b_user_role ur,
+             b_role r,
+             b_role_permission rp
+        where p.id = rp.permission_id
+          and rp.role_id = ur.role_id
+          and ur.role_id = r.id
+          and ur.user_id = #{userId}
+          and p.status = 0
+          and r.status = 0
+        order by seq, id
+    </select>
+
+    <select id="selectPermissionGroup" resultType="com.medipath.backstage.dto.PermissionGroupDto">
+        SELECT url                            AS url,
+               method                         AS method,
+               GROUP_CONCAT(permission_value) AS permissionValues
+        FROM b_permission
+        WHERE type = 4
+        GROUP BY url,method
+    </select>
+</mapper>

+ 17 - 0
backstage-service/src/main/resources/mapper/RoleMapper.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.medipath.backstage.dao.RoleMapper">
+  <resultMap id="BaseResultMap" type="com.medipath.backstage.model.Role">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" jdbcType="INTEGER" property="id" />
+    <result column="name" jdbcType="VARCHAR" property="name" />
+    <result column="type" jdbcType="VARCHAR" property="type" />
+    <result column="status" jdbcType="VARCHAR" property="status" />
+    <result column="create_user_id" jdbcType="VARCHAR" property="createUserId" />
+    <result column="update_user_id" jdbcType="VARCHAR" property="updateUserId" />
+    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
+  </resultMap>
+</mapper>

+ 12 - 0
backstage-service/src/main/resources/mapper/RolePermissionMapper.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.medipath.backstage.dao.RolePermissionMapper">
+  <resultMap id="BaseResultMap" type="com.medipath.backstage.model.RolePermission">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" jdbcType="INTEGER" property="id" />
+    <result column="role_id" jdbcType="VARCHAR" property="roleId" />
+    <result column="permission_id" jdbcType="VARCHAR" property="permissionId" />
+  </resultMap>
+</mapper>

+ 22 - 0
backstage-service/src/main/resources/mapper/UserMapper.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.medipath.backstage.dao.UserMapper">
+  <resultMap id="BaseResultMap" type="com.medipath.backstage.model.User">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" jdbcType="INTEGER" property="id" />
+    <result column="name" jdbcType="VARCHAR" property="name" />
+    <result column="login_account" jdbcType="VARCHAR" property="loginAccount" />
+    <result column="password" jdbcType="VARCHAR" property="password" />
+    <result column="salt" jdbcType="VARCHAR" property="salt" />
+    <result column="phone_no" jdbcType="VARCHAR" property="phoneNo" />
+    <result column="email" jdbcType="VARCHAR" property="email" />
+    <result column="status" jdbcType="VARCHAR" property="status" />
+    <result column="company_id" jdbcType="VARCHAR" property="companyId" />
+    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
+    <result column="create_user_id" jdbcType="VARCHAR" property="createUserId" />
+    <result column="update_user_id" jdbcType="VARCHAR" property="updateUserId" />
+  </resultMap>
+</mapper>

+ 12 - 0
backstage-service/src/main/resources/mapper/UserRoleMapper.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.medipath.backstage.dao.UserRoleMapper">
+  <resultMap id="BaseResultMap" type="com.medipath.backstage.model.UserRole">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" jdbcType="INTEGER" property="id" />
+    <result column="user_id" jdbcType="INTEGER" property="userId" />
+    <result column="role_id" jdbcType="INTEGER" property="roleId" />
+  </resultMap>
+</mapper>

+ 26 - 0
backstage-service/src/main/resources/templates/uploadimg.html

@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>uploadimg.html</title>
+
+    <meta name="keywords" content="keyword1,keyword2,keyword3"></meta>
+    <meta name="description" content="this is my page"></meta>
+    <meta name="content-type" content="text/html; charset=UTF-8"></meta>
+
+    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
+
+  </head>
+
+  <body>
+  <form enctype="multipart/form-data" method="post" action="/upload/testuploadimg">
+    图片<input type="file" name="file"/>
+    <input type="submit" value="上传"/>
+    </form>
+    <div>
+    	11111111
+    	<img alt="" src="/upload/getUrl?id=AD8E77C3-0DF9-4A6A-A04F-73BAB85A84CB.jpg"/>
+    </div>
+    
+    
+      </body>
+</html>

+ 437 - 0
backstage-service/src/test/java/CodeGenerator.java

@@ -0,0 +1,437 @@
+import static com.medipath.backstage.core.ProjectConstant.BASE_PACKAGE;
+import static com.medipath.backstage.core.ProjectConstant.CONTROLLER_PACKAGE;
+import static com.medipath.backstage.core.ProjectConstant.MAPPER_INTERFACE_REFERENCE;
+import static com.medipath.backstage.core.ProjectConstant.MAPPER_PACKAGE;
+import static com.medipath.backstage.core.ProjectConstant.MODEL_PACKAGE;
+import static com.medipath.backstage.core.ProjectConstant.SERVICE_IMPL_PACKAGE;
+import static com.medipath.backstage.core.ProjectConstant.SERVICE_PACKAGE;
+
+import static com.medipath.backstage.core.ProjectConstant.SERVICE_DTO_PACKAGE;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.mybatis.generator.api.MyBatisGenerator;
+import org.mybatis.generator.config.*;
+import org.mybatis.generator.internal.DefaultShellCallback;
+
+import com.google.common.base.CaseFormat;
+
+import freemarker.template.TemplateExceptionHandler;
+
+/**
+ * 代码生成器,根据数据表名称生成对应的Model、Mapper、Service、Controller简化开发。
+ */
+public class CodeGenerator {
+	// JDBC配置,请修改为你项目的实际配置
+	private static final String JDBC_URL = "jdbc:mysql://nj-cdb-9dj4cs2z.sql.tencentcdb.com:63883/backstage";
+	private static final String JDBC_USERNAME = "root";
+	private static final String JDBC_PASSWORD = "wukong000";
+	private static final String JDBC_DIVER_CLASS_NAME = "com.mysql.jdbc.Driver";
+
+	private static final String APPLICATION = "backstage";
+
+	private static final String PROJECT_PATH = System.getProperty("user.dir")+"\\"+APPLICATION+"-service";// 项目在硬盘上的基础路径
+	private static final String PROJECT_INTERFACE_PATH = System.getProperty("user.dir")+"\\"+APPLICATION+"-interface";// 项目在硬盘上的基础路径
+	private static final String PROJECT_API_PATH = System.getProperty("user.dir")+"\\"+APPLICATION+"-api";// 项目在硬盘上的基础路径
+	private static final String TEMPLATE_FILE_PATH = PROJECT_PATH + "/src/test/resources/generator/template";// 模板位置
+
+	private static final String JAVA_PATH = "/src/main/java"; // java文件路径
+	private static final String RESOURCES_PATH = "/src/main/resources";// 资源文件路径
+
+	private static final String PACKAGE_PATH_SERVICE = packageConvertPath(SERVICE_PACKAGE);// 生成的Service存放路径
+	private static final String PACKAGE_PATH_SERVICE_IMPL = packageConvertPath(SERVICE_IMPL_PACKAGE);// 生成的Service实现存放路径
+	private static final String PACKAGE_PATH_CONTROLLER = packageConvertPath(CONTROLLER_PACKAGE);// 生成的Controller存放路径
+	private static final String PACKAGE_PATH_DTO = packageConvertPath(SERVICE_DTO_PACKAGE);// 生成的Service实现存放路径
+
+
+	private static final String AUTHOR = "CodeGenerator";// @author
+	private static final String DATE = new SimpleDateFormat("yyyy/MM/dd").format(new Date());// @date
+
+	public static void main(String[] args) {
+		//genCode("c_customer","c_customer_protocol","c_customer_address","c_user","c_user_bank_card","c_user_operator","c_bcard_list");
+		// genCode("输入表名","输入自定义Model名称");
+		 genCode("m_mytest");
+		//genCode("c_member_coupon");
+	}
+
+	/**
+	 * 通过数据表名称生成代码,Model 名称通过解析数据表名称获得,下划线转大驼峰的形式。 如输入表名称 "t_user_detail" 将生成
+	 * TUserDetail、TUserDetailMapper、TUserDetailService ...
+	 *
+	 * @param tableNames 数据表名称...
+	 */
+	public static void genCode(String... tableNames) {
+		for (String tableName : tableNames) {
+			// System.out.println(tableNameConvertUpperCamel(tableName.substring(2,tableName.length())));
+			genCode2(tableName, tableNameConvertUpperCamel(tableName.substring(2, tableName.length())));
+		}
+	}
+
+	// 首字母大写
+	public static String captureName(String name) {
+		name = name.substring(0, 1).toUpperCase() + name.substring(1);
+		return name;
+
+	}
+
+	/**
+	 * 通过数据表名称,和自定义的 Model 名称生成代码 如输入表名称 "t_user_detail" 和自定义的 Model 名称 "User"
+	 * 将生成 User、UserMapper、UserService ...
+	 *
+	 * @param tableName 数据表名称
+	 * @param modelName 自定义的 Model 名称
+	 */
+	public static void genCode2(String tableName, String modelName) {
+		genModelAndMapper(tableName, modelName);
+		genService(tableName, modelName);
+		genController(tableName, modelName);
+		//genClient(tableName, modelName);
+	}
+
+	public static void genModelAndMapper(String tableName, String modelName) {
+		Context context = new Context(ModelType.FLAT);
+		context.setId("Potato");
+		context.setTargetRuntime("MyBatis3Simple");
+		context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
+		context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
+
+		JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration();
+		jdbcConnectionConfiguration.setConnectionURL(JDBC_URL);
+		jdbcConnectionConfiguration.setUserId(JDBC_USERNAME);
+		jdbcConnectionConfiguration.setPassword(JDBC_PASSWORD);
+		jdbcConnectionConfiguration.setDriverClass(JDBC_DIVER_CLASS_NAME);
+		context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
+
+		PluginConfiguration pluginConfiguration = new PluginConfiguration();
+		pluginConfiguration.setConfigurationType("tk.mybatis.mapper.generator.MapperPlugin");
+		pluginConfiguration.addProperty("mappers", MAPPER_INTERFACE_REFERENCE);
+		context.addPluginConfiguration(pluginConfiguration);
+
+		JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
+		javaModelGeneratorConfiguration.setTargetProject(PROJECT_PATH + JAVA_PATH);
+		javaModelGeneratorConfiguration.setTargetPackage(MODEL_PACKAGE);
+		context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
+
+		SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration();
+		sqlMapGeneratorConfiguration.setTargetProject(PROJECT_PATH + RESOURCES_PATH);
+		sqlMapGeneratorConfiguration.setTargetPackage("mapper");
+		context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration);
+
+		JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
+		javaClientGeneratorConfiguration.setTargetProject(PROJECT_PATH + JAVA_PATH);
+		javaClientGeneratorConfiguration.setTargetPackage(MAPPER_PACKAGE);
+		javaClientGeneratorConfiguration.setConfigurationType("XMLMAPPER");
+		context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);
+
+		TableConfiguration tableConfiguration = new TableConfiguration(context);
+		tableConfiguration.setTableName(tableName);
+		tableConfiguration.setDomainObjectName(modelName);
+		tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));
+		context.addTableConfiguration(tableConfiguration);
+
+		List<String> warnings;
+		MyBatisGenerator generator;
+		try {
+			Configuration config = new Configuration();
+			config.addContext(context);
+			config.validate();
+
+			boolean overwrite = true;
+			DefaultShellCallback callback = new DefaultShellCallback(overwrite);
+			warnings = new ArrayList<String>();
+			generator = new MyBatisGenerator(config, callback, warnings);
+			generator.generate(null);
+		} catch (Exception e) {
+			throw new RuntimeException("生成Model和Mapper失败", e);
+		}
+
+		if (generator.getGeneratedJavaFiles().isEmpty() || generator.getGeneratedXmlFiles().isEmpty()) {
+			throw new RuntimeException("生成Model和Mapper失败:" + warnings);
+		}
+		if (StringUtils.isEmpty(modelName))
+			modelName = tableNameConvertUpperCamel(tableName);
+		System.out.println(modelName + ".java 生成成功");
+		System.out.println(modelName + "Mapper.java 生成成功");
+		System.out.println(modelName + "Mapper.xml 生成成功");
+		System.out.println(modelName + "开始生成interface----------main-----------");
+//		context = new Context(ModelType.FLAT);
+//		context.setId("Potato");
+//		context.setTargetRuntime("MyBatis3Simple");
+//		context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
+//		context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
+//
+//		context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
+//
+//		CommentGeneratorConfiguration myComment = new CommentGeneratorConfiguration();
+//		myComment.setConfigurationType("com.conpany.project.MyCommentGenerator");
+//		context.setCommentGeneratorConfiguration(myComment);
+//
+//		javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
+//		javaModelGeneratorConfiguration.setTargetProject(PROJECT_INTERFACE_PATH + JAVA_PATH);
+//		javaModelGeneratorConfiguration.setTargetPackage(SERVICE_DTO_PACKAGE);
+//		context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
+//
+//		tableConfiguration = new TableConfiguration(context);
+//		tableConfiguration.setTableName(tableName);
+//		tableConfiguration.setDomainObjectName(modelName+"DPO");
+//		tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));
+//		context.addTableConfiguration(tableConfiguration);
+//
+//
+//		try {
+//			Configuration config = new Configuration();
+//			config.addContext(context);
+//			config.validate();
+//
+//			boolean overwrite = true;
+//			DefaultShellCallback callback = new DefaultShellCallback(overwrite);
+//			warnings = new ArrayList<String>();
+//			generator = new MyBatisGenerator(config, callback, warnings);
+//			generator.generate(null);
+//		} catch (Exception e) {
+//			throw new RuntimeException("生成DPO失败", e);
+//		}
+//
+//		if (StringUtils.isEmpty(modelName))
+//			modelName = tableNameConvertUpperCamel(tableName);
+//		System.out.println(modelName + ".java 生成成功 --------DPO------");
+
+		context = new Context(ModelType.FLAT);
+		context.setId("Potato");
+		context.setTargetRuntime("MyBatis3Simple");
+		context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
+		context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
+
+		context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
+
+		CommentGeneratorConfiguration myComment2 = new CommentGeneratorConfiguration();
+		myComment2.setConfigurationType("com.conpany.project.MyCommentGenerator");
+		context.setCommentGeneratorConfiguration(myComment2);
+
+		PluginConfiguration serializablePlugin2 = new PluginConfiguration();
+		serializablePlugin2.setConfigurationType("com.conpany.project.SerializablePlugin");
+		context.addPluginConfiguration(serializablePlugin2);
+
+		javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
+		javaModelGeneratorConfiguration.setTargetProject(PROJECT_API_PATH + JAVA_PATH);
+		javaModelGeneratorConfiguration.setTargetPackage(SERVICE_DTO_PACKAGE);
+		context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
+
+		tableConfiguration = new TableConfiguration(context);
+		tableConfiguration.setTableName(tableName);
+		tableConfiguration.setDomainObjectName(modelName+"DTO");
+		tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));
+		context.addTableConfiguration(tableConfiguration);
+
+
+		try {
+			Configuration config = new Configuration();
+			config.addContext(context);
+			config.validate();
+
+			boolean overwrite = true;
+			DefaultShellCallback callback = new DefaultShellCallback(overwrite);
+			warnings = new ArrayList<String>();
+			generator = new MyBatisGenerator(config, callback, warnings);
+			generator.generate(null);
+		} catch (Exception e) {
+			throw new RuntimeException("生成DTO失败", e);
+		}
+
+		if (StringUtils.isEmpty(modelName))
+			modelName = tableNameConvertUpperCamel(tableName);
+		System.out.println(modelName + ".java 生成成功 --------DTO------");
+	}
+
+	/**
+	 * 生成请求客户端
+	 * @param tableName
+	 * @param modelName
+	 */
+	public static void genClient(String tableName, String modelName) {
+		try {
+			freemarker.template.Configuration cfg = getConfiguration();
+
+			Map<String, Object> data = new HashMap<>();
+			data.put("date", DATE);
+			data.put("author", AUTHOR);
+			String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName)
+					: modelName;
+			data.put("baseRequestMapping", modelNameConvertMappingPath(modelNameUpperCamel));
+			data.put("modelNameUpperCamel", modelNameUpperCamel);
+			data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel));
+			data.put("basePackage", BASE_PACKAGE);
+			data.put("application", APPLICATION);
+
+			File file = new File(
+					PROJECT_INTERFACE_PATH + JAVA_PATH + PACKAGE_PATH_SERVICE + modelNameUpperCamel + "ServiceClient.java");
+			if (!file.getParentFile().exists()) {
+				file.getParentFile().mkdirs();
+			}
+			cfg.getTemplate("client.ftl").process(data, new FileWriter(file));
+			System.out.println(modelNameUpperCamel + "Client.java 生成成功");
+
+//			File file1 = new File(
+//					PROJECT_INTERFACE_PATH + JAVA_PATH + PACKAGE_PATH_DTO + modelNameUpperCamel + "Dto.java");
+//			if (!file1.getParentFile().exists()) {
+//				file1.getParentFile().mkdirs();
+//			}
+//			cfg.getTemplate("dto.ftl").process(data, new FileWriter(file1));
+//			System.out.println(modelNameUpperCamel + "Dto.java 生成成功");
+
+//			Context context = new Context(ModelType.FLAT);
+//			context.setId("Potato");
+//			context.setTargetRuntime("MyBatis3Simple");
+//			context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
+//			context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
+//
+//			JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration();
+//			jdbcConnectionConfiguration.setConnectionURL(JDBC_URL);
+//			jdbcConnectionConfiguration.setUserId(JDBC_USERNAME);
+//			jdbcConnectionConfiguration.setPassword(JDBC_PASSWORD);
+//			jdbcConnectionConfiguration.setDriverClass(JDBC_DIVER_CLASS_NAME);
+//			context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
+//
+//			JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
+//			javaModelGeneratorConfiguration.setTargetProject(PROJECT_INTERFACE_PATH + JAVA_PATH);
+//			javaModelGeneratorConfiguration.setTargetPackage(SERVICE_DTO_PACKAGE);
+//			context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
+//
+//			TableConfiguration tableConfiguration = new TableConfiguration(context);
+//			tableConfiguration.setTableName(tableName);
+//			tableConfiguration.setDomainObjectName(modelName);
+//			tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));
+//			context.addTableConfiguration(tableConfiguration);
+//
+//			List<String> warnings;
+//			MyBatisGenerator generator;
+//			try {
+//				Configuration config = new Configuration();
+//				config.addContext(context);
+//				config.validate();
+//
+//				boolean overwrite = true;
+//				DefaultShellCallback callback = new DefaultShellCallback(overwrite);
+//				warnings = new ArrayList<String>();
+//				generator = new MyBatisGenerator(config, callback, warnings);
+//				generator.generate(null);
+//			} catch (Exception e) {
+//				throw new RuntimeException("生成Model失败", e);
+//			}
+//
+//			if (generator.getGeneratedJavaFiles().isEmpty() || generator.getGeneratedXmlFiles().isEmpty()) {
+//				throw new RuntimeException("生成Model失败:" + warnings);
+//			}
+//			if (StringUtils.isEmpty(modelName))
+//				modelName = tableNameConvertUpperCamel(tableName);
+//			System.out.println(modelName + ".java 生成成功");
+		} catch (Exception e) {
+			throw new RuntimeException("生成interface失败", e);
+		}
+	}
+
+	public static void genService(String tableName, String modelName) {
+		try {
+			freemarker.template.Configuration cfg = getConfiguration();
+
+			Map<String, Object> data = new HashMap<>();
+			data.put("date", DATE);
+			data.put("author", AUTHOR);
+			String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName)
+					: modelName;
+			data.put("modelNameUpperCamel", modelNameUpperCamel);
+			data.put("modelNameLowerCamel", tableNameConvertLowerCamel(tableName));
+			data.put("basePackage", BASE_PACKAGE);
+
+			File file = new File(
+					PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_SERVICE + modelNameUpperCamel + "Service.java");
+			if (!file.getParentFile().exists()) {
+				file.getParentFile().mkdirs();
+			}
+			cfg.getTemplate("service.ftl").process(data, new FileWriter(file));
+			System.out.println(modelNameUpperCamel + "Service.java 生成成功");
+
+			File file1 = new File(
+					PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_SERVICE_IMPL + modelNameUpperCamel + "ServiceImpl.java");
+			if (!file1.getParentFile().exists()) {
+				file1.getParentFile().mkdirs();
+			}
+			cfg.getTemplate("service-impl.ftl").process(data, new FileWriter(file1));
+			System.out.println(modelNameUpperCamel + "ServiceImpl.java 生成成功");
+		} catch (Exception e) {
+			throw new RuntimeException("生成Service失败", e);
+		}
+	}
+
+	public static void genController(String tableName, String modelName) {
+		try {
+			freemarker.template.Configuration cfg = getConfiguration();
+
+			Map<String, Object> data = new HashMap<>();
+			data.put("date", DATE);
+			data.put("author", AUTHOR);
+			String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName)
+					: modelName;
+			data.put("baseRequestMapping", modelNameConvertMappingPath(modelNameUpperCamel));
+			data.put("modelNameUpperCamel", modelNameUpperCamel);
+			data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel));
+			data.put("basePackage", BASE_PACKAGE);
+
+			File file = new File(
+					PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_CONTROLLER + modelNameUpperCamel + "Controller.java");
+			if (!file.getParentFile().exists()) {
+				file.getParentFile().mkdirs();
+			}
+			// cfg.getTemplate("controller-restful.ftl").process(data, new
+			// FileWriter(file));
+			cfg.getTemplate("controller.ftl").process(data, new FileWriter(file));
+
+			System.out.println(modelNameUpperCamel + "Controller.java 生成成功");
+		} catch (Exception e) {
+			throw new RuntimeException("生成Controller失败", e);
+		}
+
+	}
+
+	private static freemarker.template.Configuration getConfiguration() throws IOException {
+		freemarker.template.Configuration cfg = new freemarker.template.Configuration(
+				freemarker.template.Configuration.VERSION_2_3_23);
+		cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_FILE_PATH));
+		cfg.setDefaultEncoding("UTF-8");
+		cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
+		return cfg;
+	}
+
+	private static String tableNameConvertLowerCamel(String tableName) {
+		return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName.toLowerCase());
+	}
+
+	private static String tableNameConvertUpperCamel(String tableName) {
+		return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName.toLowerCase());
+
+	}
+
+	private static String tableNameConvertMappingPath(String tableName) {
+		tableName = tableName.toLowerCase();// 兼容使用大写的表名
+		return "/" + (tableName.contains("_") ? tableName.replaceAll("_", "/") : tableName);
+	}
+
+	private static String modelNameConvertMappingPath(String modelName) {
+		String tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, modelName);
+		return tableNameConvertMappingPath(tableName);
+	}
+
+	private static String packageConvertPath(String packageName) {
+		return String.format("/%s/", packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName);
+	}
+
+}

+ 313 - 0
backstage-service/src/test/java/com/conpany/project/MyCommentGenerator.java

@@ -0,0 +1,313 @@
+package com.conpany.project;
+
+import org.mybatis.generator.api.CommentGenerator;
+import org.mybatis.generator.api.IntrospectedColumn;
+import org.mybatis.generator.api.IntrospectedTable;
+import org.mybatis.generator.api.dom.java.*;
+import org.mybatis.generator.api.dom.xml.XmlElement;
+import org.mybatis.generator.config.MergeConstants;
+import org.mybatis.generator.config.PropertyRegistry;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Properties;
+
+import static org.mybatis.generator.internal.util.StringUtility.isTrue;
+
+/**   
+ * @Title: MyCommentGenerator.java 
+ * @Package com.fendo.mybatis_generator_plus 
+ * @Description:  mybatis generator 自定义comment生成器.
+ *                基于MBG 1.3.5
+ * @author fendo
+ * @date 2017年10月5日 下午3:07:26 
+ * @version V1.0   
+*/
+public class MyCommentGenerator implements CommentGenerator{
+ 
+    /**
+      * properties配置文件
+     */
+    private Properties properties;
+    /**
+      * properties配置文件
+     */
+    private Properties systemPro;
+    
+    /*
+     * 父类时间
+     */
+    private boolean suppressDate;
+    
+    /**
+     * 父类所有注释
+     */
+    private boolean suppressAllComments;
+    
+    /**
+     * 当前时间
+     */
+    private String currentDateStr;
+    
+    public MyCommentGenerator() {
+        super();
+        properties = new Properties();
+        systemPro = System.getProperties();
+        suppressDate = false;
+        suppressAllComments = false;
+        currentDateStr = (new SimpleDateFormat("yyyy-MM-dd")).format(new Date());
+    }
+    
+    /**
+     * Java类的类注释
+     */
+	@Override
+	public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
+        if (suppressAllComments) {
+            return;
+        }
+ 
+        StringBuilder sb = new StringBuilder();
+        innerClass.addJavaDocLine("/**");
+        sb.append(" * ");
+        sb.append(introspectedTable.getFullyQualifiedTable());
+        sb.append(" ");
+        sb.append(getDateString());
+        innerClass.addJavaDocLine(sb.toString().replace("\n", " "));
+        innerClass.addJavaDocLine(" */");
+	}
+ 
+	/**
+	 * 为类添加注释
+	 */
+	@Override
+	public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
+		if (suppressAllComments) {
+            return;
+        }
+        StringBuilder sb = new StringBuilder();
+        innerClass.addJavaDocLine("/**");
+        sb.append(" * ");
+        sb.append(" * ");
+        sb.append(introspectedTable.getFullyQualifiedTable());
+        innerClass.addJavaDocLine(sb.toString().replace("\n", " "));
+        sb.setLength(0);
+        sb.append(" * @author ");
+        sb.append(systemPro.getProperty("user.name"));
+        sb.append(" ");
+        sb.append(currentDateStr);
+        innerClass.addJavaDocLine(" */");
+	}
+ 
+	
+	/**
+	 * Mybatis的Mapper.xml文件里面的注释
+	 */
+	@Override
+	public void addComment(XmlElement xmlElement) {
+		
+	}
+ 
+	/**
+	 * 
+	 *@Title addConfigurationProperties 
+	 *@Description: 从该配置中的任何属性添加此实例的属性CommentGenerator配置。
+	 *              这个方法将在任何其他方法之前被调用。
+	 *@Author fendo
+	 *@Date 2017年10月5日 下午3:45:58
+	 *@return
+	 *@throws
+	 */
+	@Override
+	public void addConfigurationProperties(Properties properties) {
+		this.properties.putAll(properties);
+        suppressDate = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
+        suppressAllComments = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
+	}
+ 
+	/**
+	 * 
+	 *@Title getDateString 
+	 *@Description: 此方法返回格式化的日期字符串以包含在Javadoc标记中和XML注释。 如果您不想要日期,则可以返回null在这些文档元素中。
+	 *@Author fendo
+	 *@Date 2017年10月5日 下午3:45:58
+	 *@return
+	 *@throws
+	 */
+    protected String getDateString() {
+        String result = null;
+        if (!suppressDate) {
+            result = currentDateStr;
+        }
+        return result;
+    }
+    
+    /**
+     * 
+     *@Title addJavadocTag 
+     *@Description: 此方法为其添加了自定义javadoc标签。
+     *@Author fendo
+     *@Date 2017年10月5日 下午3:49:05
+     *@param javaElement
+     *@param markAsDoNotDelete
+     *@throws
+     */
+	protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {
+        javaElement.addJavaDocLine(" *");
+        StringBuilder sb = new StringBuilder();
+        sb.append(" * ");
+        sb.append(MergeConstants.NEW_ELEMENT_TAG);
+        if (markAsDoNotDelete) {
+            sb.append(" do_not_delete_during_merge");
+        }
+        String s = getDateString();
+        if (s != null) {
+            sb.append(' ');
+            sb.append(s);
+        }
+        javaElement.addJavaDocLine(sb.toString());
+    }
+	
+	
+	/**
+	 * 为枚举添加注释
+	 */
+	@Override
+	public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
+		if (suppressAllComments) {
+            return;
+        }
+        StringBuilder sb = new StringBuilder();
+        innerEnum.addJavaDocLine("/**");
+        sb.append(" * ");
+        sb.append(introspectedTable.getFullyQualifiedTable());
+        innerEnum.addJavaDocLine(sb.toString().replace("\n", " "));
+        innerEnum.addJavaDocLine(" */");
+	}
+ 
+	/**
+	 * Java属性注释
+	 */
+	@Override
+	public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
+		if (suppressAllComments) {
+            return;
+        }
+        StringBuilder sb = new StringBuilder();
+        field.addJavaDocLine("/**");
+        sb.append(" * ");
+        sb.append(introspectedTable.getFullyQualifiedTable());
+        field.addJavaDocLine(sb.toString().replace("\n", " "));
+        field.addJavaDocLine(" */");
+        
+        
+        
+	}
+ 
+	/**
+	 * 为字段添加注释
+	 */
+	@Override
+	public void addFieldComment(Field field, IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn) {
+		if (suppressAllComments) {
+            return;
+        }
+        StringBuilder sb = new StringBuilder();
+        field.addJavaDocLine("/**");
+        sb.append(" * ");
+        sb.append(introspectedColumn.getRemarks());
+        field.addJavaDocLine(sb.toString().replace("\n", " "));
+        field.addJavaDocLine(" */");
+	}
+ 
+	/**
+	 * 普通方法的注释,这里主要是XXXMapper.java里面的接口方法的注释
+	 */
+	@Override
+	public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
+	  if (suppressAllComments) {
+        return;
+      }
+      method.addJavaDocLine("/**");
+      addJavadocTag(method, false);
+      method.addJavaDocLine(" */");
+	}
+ 
+	
+	/**
+	 * 给getter方法加注释
+	 */
+	@Override
+	public void addGetterComment(Method method, IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn) {
+	    if (suppressAllComments) {
+            return;
+        }
+        method.addJavaDocLine("/**");
+        StringBuilder sb = new StringBuilder();
+        sb.append(" * ");
+        sb.append(introspectedColumn.getRemarks());
+        method.addJavaDocLine(sb.toString().replace("\n", " "));
+        sb.setLength(0);
+        sb.append(" * @return ");
+        sb.append(introspectedColumn.getActualColumnName());
+        sb.append(" ");
+        sb.append(introspectedColumn.getRemarks());
+        method.addJavaDocLine(sb.toString().replace("\n", " "));
+        method.addJavaDocLine(" */");
+	}
+ 
+	/**
+	 * 给Java文件加注释,这个注释是在文件的顶部,也就是package上面。
+	 */
+	@Override
+	public void addJavaFileComment(CompilationUnit compilationUnit) {
+    	SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
+    	compilationUnit.addFileCommentLine("/*");
+    	compilationUnit.addFileCommentLine("*");
+    	compilationUnit.addFileCommentLine("* "+compilationUnit.getType().getShortName()+".java");
+    	compilationUnit.addFileCommentLine("* Copyright(C) 2017-2020 fendo公司");
+    	compilationUnit.addFileCommentLine("* @date "+sdf.format(new Date())+"");
+    	compilationUnit.addFileCommentLine("*/");
+	}
+ 
+	/**
+	 * 为模型类添加注释
+	 */
+	@Override
+	public void addModelClassComment(TopLevelClass arg0, IntrospectedTable arg1) {
+		
+	}
+ 
+	/**
+	 * 为调用此方法作为根元素的第一个子节点添加注释。
+	 */
+	@Override
+	public void addRootComment(XmlElement arg0) {
+		
+	}
+ 
+	
+	/**
+	 * 给setter方法加注释
+	 */
+	@Override
+	public void addSetterComment(Method method, IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn) {
+		if (suppressAllComments) {
+            return;
+        }
+        method.addJavaDocLine("/**");
+        StringBuilder sb = new StringBuilder();
+        sb.append(" * ");
+        sb.append(introspectedColumn.getRemarks());
+        method.addJavaDocLine(sb.toString().replace("\n", " "));
+        Parameter parm = method.getParameters().get(0);
+        sb.setLength(0);
+        sb.append(" * @param ");
+        sb.append(parm.getName());
+        sb.append(" ");
+        sb.append(introspectedColumn.getRemarks());
+        method.addJavaDocLine(sb.toString().replace("\n", " "));
+        method.addJavaDocLine(" */");
+	}
+ 
+}

+ 110 - 0
backstage-service/src/test/java/com/conpany/project/SerializablePlugin.java

@@ -0,0 +1,110 @@
+package com.conpany.project;
+
+import org.mybatis.generator.api.IntrospectedTable;
+import org.mybatis.generator.api.PluginAdapter;  
+import org.mybatis.generator.api.dom.java.*;  
+  
+import java.util.List;  
+import java.util.Properties;  
+
+/**
+ * 分布式开发的话,Example对象也必须要序列化
+ * 扩展一个 mybatis generator 插件,用于不仅仅在生成的实体类 还有 *Example 类都序列化
+ * @author alexgaoyh
+ *
+ */
+public class SerializablePlugin extends PluginAdapter {  
+  
+    private FullyQualifiedJavaType serializable;  
+    private FullyQualifiedJavaType gwtSerializable;  
+    private boolean addGWTInterface;  
+    private boolean suppressJavaInterface;  
+  
+    public SerializablePlugin() {  
+        super();  
+        serializable = new FullyQualifiedJavaType("java.io.Serializable"); //$NON-NLS-1$  
+        gwtSerializable = new FullyQualifiedJavaType("com.google.gwt.user.client.rpc.IsSerializable"); //$NON-NLS-1$  
+    }  
+  
+    public boolean validate(List<String> warnings) {  
+        // this plugin is always valid  
+        return true;  
+    }  
+  
+    @Override  
+    public void setProperties(Properties properties) {  
+        super.setProperties(properties);  
+        addGWTInterface = Boolean.valueOf(properties.getProperty("addGWTInterface")); //$NON-NLS-1$  
+        suppressJavaInterface = Boolean.valueOf(properties.getProperty("suppressJavaInterface")); //$NON-NLS-1$  
+    }  
+  
+    @Override  
+    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass,  
+                                                 IntrospectedTable introspectedTable) {  
+        makeSerializable(topLevelClass, introspectedTable);  
+        return true;  
+    }  
+  
+    @Override  
+    public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass,  
+                                                 IntrospectedTable introspectedTable) {  
+        makeSerializable(topLevelClass, introspectedTable);  
+        return true;  
+    }  
+  
+    @Override  
+    public boolean modelRecordWithBLOBsClassGenerated(  
+            TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {  
+        makeSerializable(topLevelClass, introspectedTable);  
+        return true;  
+    }  
+  
+    /** 
+     * 添加给Example类序列化的方法 
+     * @param topLevelClass 
+     * @param introspectedTable 
+     * @return 
+     */  
+    @Override  
+    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,IntrospectedTable introspectedTable){  
+        makeSerializable(topLevelClass, introspectedTable);  
+  
+        for (InnerClass innerClass : topLevelClass.getInnerClasses()) {  
+            if ("GeneratedCriteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$  
+                innerClass.addSuperInterface(serializable);  
+            }  
+            if ("Criteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$  
+                innerClass.addSuperInterface(serializable);  
+            }  
+            if ("Criterion".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$  
+                innerClass.addSuperInterface(serializable);  
+            }  
+        }  
+  
+        return true;  
+    }  
+  
+    protected void makeSerializable(TopLevelClass topLevelClass,  
+                                    IntrospectedTable introspectedTable) {  
+        if (addGWTInterface) {  
+            topLevelClass.addImportedType(gwtSerializable);  
+            topLevelClass.addSuperInterface(gwtSerializable);  
+        }  
+  
+        if (!suppressJavaInterface) {  
+            topLevelClass.addImportedType(serializable);  
+            topLevelClass.addSuperInterface(serializable);  
+  
+            Field field = new Field();  
+            field.setFinal(true);  
+            field.setInitializationString("1L"); //$NON-NLS-1$  
+            field.setName("serialVersionUID"); //$NON-NLS-1$  
+            field.setStatic(true);  
+            field.setType(new FullyQualifiedJavaType("long")); //$NON-NLS-1$  
+            field.setVisibility(JavaVisibility.PRIVATE);  
+            context.getCommentGenerator().addFieldComment(field, introspectedTable);  
+  
+            topLevelClass.addField(field);  
+        }  
+    }  
+}

+ 52 - 0
backstage-service/src/test/java/com/conpany/project/TestRedis.java

@@ -0,0 +1,52 @@
+package com.conpany.project;
+
+import javax.annotation.Resource;
+
+import cn.hutool.crypto.SecureUtil;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+
+public class TestRedis extends Tester{
+
+	@Resource
+    private StringRedisTemplate stringRedisTemplate;
+    
+    @Resource
+    private RedisTemplate redisTemplate;
+
+    @Test
+    public void test() throws Exception {
+        stringRedisTemplate.opsForValue().set("aaa", "111");
+        Assert.assertEquals("111", stringRedisTemplate.opsForValue().get("aaa"));
+    }
+    
+    @Test
+    public void testObj() throws Exception {
+//        User user=new User();
+//        user.setName("222");
+//        ValueOperations<String, User> operations= redisTemplate.opsForValue();
+//        operations.set("com.neox", user);
+//        operations.set("com.neo.f", user,30000,TimeUnit.SECONDS);
+        Thread.sleep(1000);
+        //redisTemplate.delete("com.neo.f");
+        boolean exists=redisTemplate.hasKey("com.neo.f");
+        if(exists){
+            System.out.println("exists is true");
+        }else{
+            System.out.println("exists is false");
+        }
+//        System.out.println(operations.get("com.neo.f").getName());
+//        Assert.assertEquals("aa", operations.get("com.neo.f").getName());
+    }
+    
+    
+    @Test
+    public void testPwd() throws Exception {
+        String salt = "Fn3i";
+        String pwd = SecureUtil.md5(("2"+salt.toUpperCase()));
+        System.out.println(pwd);
+    }
+}

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