diff --git a/README.md b/README.md index 461d81c..3251531 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## 项目介绍 -`mall-swarm`是一套微服务商城系统,采用了 Spring Cloud Greenwich、Spring Boot 2、MyBatis、Docker、Elasticsearch等核心技术,同时提供了基于Vue的管理后台方便快速搭建系统。`mall-swarm`在电商业务的基础集成了注册中心、配置中心、监控中心、网关等系统功能。 文档齐全,附带全套Spring Cloud教程。 +`mall-swarm`是一套微服务商城系统,采用了 Spring Cloud Hoxton & Alibaba、Spring Boot 2.3、Oauth2、MyBatis、Docker、Elasticsearch等核心技术,同时提供了基于Vue的管理后台方便快速搭建系统。`mall-swarm`在电商业务的基础集成了注册中心、配置中心、监控中心、网关等系统功能。 文档齐全,附带全套Spring Cloud教程。 ## 系统架构图 @@ -22,15 +22,14 @@ mall ├── mall-common -- 工具类及通用代码模块 ├── mall-mbg -- MyBatisGenerator生成的数据库操作代码模块 -├── mall-security -- 封装SpringSecurity+JWT的安全认证的模块 -├── mall-registry -- 基于Eureka的微服务注册中心 -├── mall-config -- 基于Spring Cloud Config的微服务配置中心 +├── mall-auth -- 基于Spring Security Oauth2的统一的认证中心 ├── mall-gateway -- 基于Spring Cloud Gateway的微服务API网关服务 ├── mall-monitor -- 基于Spring Boot Admin的微服务监控中心 ├── mall-admin -- 后台管理系统服务 ├── mall-search -- 基于Elasticsearch的商品搜索系统服务 ├── mall-portal -- 移动端商城系统服务 -└── mall-demo -- 微服务远程调用测试服务 +├── mall-demo -- 微服务远程调用测试服务 +└── config -- 配置中心存储的配置 ``` ## 项目文档 @@ -47,29 +46,30 @@ mall ### 后端技术 -| 技术 | 说明 | 官网 | -| ---------------- | -------------------- | ---------------------------------------------------- | -| Spring Cloud | 微服务框架 | https://spring.io/projects/spring-cloud | -| Spring Boot | 容器+MVC框架 | https://spring.io/projects/spring-boot | -| Spring Security | 认证和授权框架 | https://spring.io/projects/spring-security | -| MyBatis | ORM框架 | http://www.mybatis.org/mybatis-3/zh/index.html | -| MyBatisGenerator | 数据层代码生成 | http://www.mybatis.org/generator/index.html | -| PageHelper | MyBatis物理分页插件 | http://git.oschina.net/free/Mybatis_PageHelper | -| Swagger-UI | 文档生产工具 | https://github.com/swagger-api/swagger-ui | -| Elasticsearch | 搜索引擎 | https://github.com/elastic/elasticsearch | -| RabbitMq | 消息队列 | https://www.rabbitmq.com/ | -| Redis | 分布式缓存 | https://redis.io/ | -| MongoDb | NoSql数据库 | https://www.mongodb.com/ | -| Docker | 应用容器引擎 | https://www.docker.com/ | -| Druid | 数据库连接池 | https://github.com/alibaba/druid | -| OSS | 对象存储 | https://github.com/aliyun/aliyun-oss-java-sdk | -| MinIO | 对象存储 | https://github.com/minio/minio | -| JWT | JWT登录支持 | https://github.com/jwtk/jjwt | -| LogStash | 日志收集 | https://github.com/logstash/logstash-logback-encoder | -| Lombok | 简化对象封装工具 | https://github.com/rzwitserloot/lombok | -| Seata | 全局事务管理框架 | https://github.com/seata/seata | -| Portainer | 可视化Docker容器管理 | https://github.com/portainer/portainer | -| Jenkins | 自动化部署工具 | https://github.com/jenkinsci/jenkins | +| 技术 | 说明 | 官网 | +| ---------------------- | -------------------- | ---------------------------------------------------- | +| Spring Cloud | 微服务框架 | https://spring.io/projects/spring-cloud | +| Spring Cloud Alibaba | 微服务框架 | https://github.com/alibaba/spring-cloud-alibaba | +| Spring Boot | 容器+MVC框架 | https://spring.io/projects/spring-boot | +| Spring Security Oauth2 | 认证和授权框架 | https://spring.io/projects/spring-security-oauth | +| MyBatis | ORM框架 | http://www.mybatis.org/mybatis-3/zh/index.html | +| MyBatisGenerator | 数据层代码生成 | http://www.mybatis.org/generator/index.html | +| PageHelper | MyBatis物理分页插件 | http://git.oschina.net/free/Mybatis_PageHelper | +| Knife4j | 文档生产工具 | https://github.com/xiaoymin/swagger-bootstrap-ui | +| Elasticsearch | 搜索引擎 | https://github.com/elastic/elasticsearch | +| RabbitMq | 消息队列 | https://www.rabbitmq.com/ | +| Redis | 分布式缓存 | https://redis.io/ | +| MongoDb | NoSql数据库 | https://www.mongodb.com/ | +| Docker | 应用容器引擎 | https://www.docker.com/ | +| Druid | 数据库连接池 | https://github.com/alibaba/druid | +| OSS | 对象存储 | https://github.com/aliyun/aliyun-oss-java-sdk | +| MinIO | 对象存储 | https://github.com/minio/minio | +| JWT | JWT登录支持 | https://github.com/jwtk/jjwt | +| LogStash | 日志收集 | https://github.com/logstash/logstash-logback-encoder | +| Lombok | 简化对象封装工具 | https://github.com/rzwitserloot/lombok | +| Seata | 全局事务管理框架 | https://github.com/seata/seata | +| Portainer | 可视化Docker容器管理 | https://github.com/portainer/portainer | +| Jenkins | 自动化部署工具 | https://github.com/jenkinsci/jenkins | ### 前端技术 @@ -87,15 +87,17 @@ mall ### 开发环境 -工具 | 版本号 | 下载 -----|----|---- -JDK | 1.8 | https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html -Mysql | 5.7 | https://www.mysql.com/ -Redis | 3.2 | https://redis.io/download -Elasticsearch | 6.2.2 | https://www.elastic.co/downloads -MongoDb | 3.2 | https://www.mongodb.com/download-center -RabbitMq | 3.7.14 | http://www.rabbitmq.com/download.html -nginx | 1.10 | http://nginx.org/en/download.html +| 工具 | 版本号 | 下载 | +| ------------- | ------ | ------------------------------------------------------------ | +| JDK | 1.8 | https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html | +| Mysql | 5.7 | https://www.mysql.com/ | +| Redis | 5.0 | https://redis.io/download | +| Elasticsearch | 7.6.2 | https://www.elastic.co/cn/downloads/elasticsearch | +| Kibana | 7.6.2 | https://www.elastic.co/cn/downloads/kibana | +| Logstash | 7.6.2 | https://www.elastic.co/cn/downloads/logstash | +| MongoDb | 4.2.5 | https://www.mongodb.com/download-center | +| RabbitMq | 3.7.14 | http://www.rabbitmq.com/download.html | +| nginx | 1.10 | http://nginx.org/en/download.html | ### 搭建步骤 @@ -106,8 +108,6 @@ nginx | 1.10 | http://nginx.org/en/download.html - `ELK`日志收集系统的搭建请参考:[SpringBoot应用整合ELK实现日志收集](http://www.macrozheng.com/#/technology/mall_tiny_elk); - 使用MinIO存储文件请参考:[前后端分离项目,如何优雅实现文件存储](http://www.macrozheng.com/#/technology/minio_use); - 读写分离解决方案请参考:[你还在代码里做读写分离么,试试这个中间件吧](http://www.macrozheng.com/#/reference/gaea); -- 如果想使用`Consul`作为注册及配置中心的话请参考:[Spring Cloud Consul:服务治理与配置中心](http://www.macrozheng.com/#/cloud/consul); -- 如果想使用`Nacos`作为注册及配置中心的话请参考:[Spring Cloud Alibaba:Nacos 作为注册中心和配置中心使用](http://www.macrozheng.com/#/cloud/nacos); - `分布式事务`解决方案请参考:[使用Seata彻底解决Spring Cloud中的分布式事务问题!](http://www.macrozheng.com/#/cloud/seata)。 > Docker环境部署 @@ -120,21 +120,31 @@ nginx | 1.10 | http://nginx.org/en/download.html ## 运行效果展示 -- 注册中心控制台信息: +- 查看注册中心注册服务信息,访问地址:http://192.168.3.101:8848/nacos/ -![](http://img.macrozheng.com/mall/project/mall_swarm_linux_07.png) +![](/document/resource/mall_swarm_run_01.png) -- 监控中心应用信息: +- 监控中心应用信息,访问地址:http://192.168.3.101:8101 -![](http://img.macrozheng.com/mall/project/mall_swarm_linux_08.png) +![](/document/resource/mall_swarm_run_02.png) -![](http://img.macrozheng.com/mall/project/mall_swarm_linux_09.png) +![](/document/resource/mall_swarm_run_03.png) -- 可视化容器管理: +![](/document/resource/mall_swarm_run_04.png) -![](http://img.macrozheng.com/mall/project/mall_swarm_linux_02.png) +- API文档信息,访问地址:http://192.168.3.101:8201 -![](http://img.macrozheng.com/mall/project/mall_swarm_linux_04.png) +![](/document/resource/mall_swarm_run_05.png) + +- 日志收集系统信息,访问地址:http://192.168.3.101:5601 + +![](/document/resource/mall_swarm_run_06.png) + +- 可视化容器管理,访问地址:http://192.168.3.101:9000 + +![](/document/resource/mall_swarm_run_07.png) + +![](/document/resource/mall_swarm_run_08.png) ## 公众号 diff --git a/mall-config/src/main/resources/config/admin/admin-dev.yml b/config/admin/mall-admin-dev.yaml similarity index 69% rename from mall-config/src/main/resources/config/admin/admin-dev.yml rename to config/admin/mall-admin-dev.yaml index 3395943..8762958 100644 --- a/mall-config/src/main/resources/config/admin/admin-dev.yml +++ b/config/admin/mall-admin-dev.yaml @@ -15,7 +15,15 @@ spring: url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: root + redis: + host: localhost # Redis服务器地址 + database: 0 # Redis数据库索引(默认为0) + port: 6379 # Redis服务器连接端口 + password: # Redis服务器连接密码(默认为空) + timeout: 3000ms # 连接超时时间(毫秒) logging: level: - root: info #日志配置DEBUG,INFO,WARN,ERROR - com.macro.mall: debug \ No newline at end of file + root: info + com.macro.mall: debug +logstash: + host: localhost \ No newline at end of file diff --git a/mall-config/src/main/resources/config/admin/admin-prod.yml b/config/admin/mall-admin-prod.yaml similarity index 72% rename from mall-config/src/main/resources/config/admin/admin-prod.yml rename to config/admin/mall-admin-prod.yaml index a0002db..52e3f79 100644 --- a/mall-config/src/main/resources/config/admin/admin-prod.yml +++ b/config/admin/mall-admin-prod.yaml @@ -15,5 +15,16 @@ spring: url: jdbc:mysql://db:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: reader password: 123456 + redis: + host: redis # Redis服务器地址 + database: 0 # Redis数据库索引(默认为0) + port: 6379 # Redis服务器连接端口 + password: #不设置密码 logging: - path: /var/logs #配置日志生成路径 \ No newline at end of file + file: + path: /var/logs + level: + root: info + com.macro.mall: info +logstash: + host: logstash \ No newline at end of file diff --git a/mall-config/src/main/resources/config/demo/demo-dev.yml b/config/demo/mall-demo-dev.yaml similarity index 66% rename from mall-config/src/main/resources/config/demo/demo-dev.yml rename to config/demo/mall-demo-dev.yaml index 6f0240f..53e977f 100644 --- a/mall-config/src/main/resources/config/demo/demo-dev.yml +++ b/config/demo/mall-demo-dev.yaml @@ -5,6 +5,7 @@ spring: password: root logging: level: - root: info #日志配置DEBUG,INFO,WARN,ERROR + root: info com.macro.mall: debug - com.macro.mall.demo.service.FeignAdminService: debug \ No newline at end of file +logstash: + host: localhost \ No newline at end of file diff --git a/mall-config/src/main/resources/config/demo/demo-prod.yml b/config/demo/mall-demo-prod.yaml similarity index 63% rename from mall-config/src/main/resources/config/demo/demo-prod.yml rename to config/demo/mall-demo-prod.yaml index 4e49a5f..1f6e91d 100644 --- a/mall-config/src/main/resources/config/demo/demo-prod.yml +++ b/config/demo/mall-demo-prod.yaml @@ -4,4 +4,10 @@ spring: username: reader password: 123456 logging: - path: /var/logs #配置日志生成路径 \ No newline at end of file + file: + path: /var/logs + level: + root: info + com.macro.mall: info +logstash: + host: logstash \ No newline at end of file diff --git a/config/gateway/mall-gateway-dev.yaml b/config/gateway/mall-gateway-dev.yaml new file mode 100644 index 0000000..38661e4 --- /dev/null +++ b/config/gateway/mall-gateway-dev.yaml @@ -0,0 +1,18 @@ +spring: + redis: + host: localhost # Redis服务器地址 + database: 0 # Redis数据库索引(默认为0) + port: 6379 # Redis服务器连接端口 + password: # Redis服务器连接密码(默认为空) + timeout: 3000ms # 连接超时时间(毫秒) + security: + oauth2: + resourceserver: + jwt: + jwk-set-uri: 'http://localhost:8201/mall-auth/rsa/publicKey' +logging: + level: + root: info + com.macro.mall: debug +logstash: + host: localhost \ No newline at end of file diff --git a/config/gateway/mall-gateway-prod.yaml b/config/gateway/mall-gateway-prod.yaml new file mode 100644 index 0000000..0a5f108 --- /dev/null +++ b/config/gateway/mall-gateway-prod.yaml @@ -0,0 +1,19 @@ +spring: + redis: + host: redis # Redis服务器地址 + database: 0 # Redis数据库索引(默认为0) + port: 6379 # Redis服务器连接端口 + password: #不设置密码 + security: + oauth2: + resourceserver: + jwt: + jwk-set-uri: 'http://mall-gateway:8201/mall-auth/rsa/publicKey' +logging: + file: + path: /var/logs + level: + root: info + com.macro.mall: info +logstash: + host: logstash \ No newline at end of file diff --git a/mall-config/src/main/resources/config/portal/portal-dev.yml b/config/portal/mall-portal-dev.yaml similarity index 75% rename from mall-config/src/main/resources/config/portal/portal-dev.yml rename to config/portal/mall-portal-dev.yaml index 75c292b..6b8d6df 100644 --- a/mall-config/src/main/resources/config/portal/portal-dev.yml +++ b/config/portal/mall-portal-dev.yaml @@ -19,10 +19,10 @@ spring: virtual-host: /mall username: mall password: mall - publisher-confirms: true #如果对异步消息需要回调必须设置为true # 日志配置 logging: level: - org.springframework.data.mongodb.core: debug - com.macro.mall.mapper: debug - com.macro.mall.portal.dao: debug \ No newline at end of file + root: info + com.macro.mall: debug +logstash: + host: localhost \ No newline at end of file diff --git a/mall-config/src/main/resources/config/portal/portal-prod.yml b/config/portal/mall-portal-prod.yaml similarity index 84% rename from mall-config/src/main/resources/config/portal/portal-prod.yml rename to config/portal/mall-portal-prod.yaml index accb7f9..2a898d9 100644 --- a/mall-config/src/main/resources/config/portal/portal-prod.yml +++ b/config/portal/mall-portal-prod.yaml @@ -20,4 +20,12 @@ spring: username: mall password: mall publisher-confirms: true #如果对异步消息需要回调必须设置为true +logging: + file: + path: /var/logs + level: + root: info + com.macro.mall: info +logstash: + host: logstash diff --git a/mall-config/src/main/resources/config/search/search-dev.yml b/config/search/mall-search-dev.yaml similarity index 59% rename from mall-config/src/main/resources/config/search/search-dev.yml rename to config/search/mall-search-dev.yaml index 38ee08e..1507e16 100644 --- a/mall-config/src/main/resources/config/search/search-dev.yml +++ b/config/search/mall-search-dev.yaml @@ -3,14 +3,12 @@ spring: url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: root - data: - elasticsearch: - cluster-nodes: 127.0.0.1:9300 - cluster-name: elasticsearch elasticsearch: rest: uris: http://localhost:9200 logging: level: - root: info #日志配置DEBUG,INFO,WARN,ERROR - com.macro.mall: debug \ No newline at end of file + root: info + com.macro.mall: debug +logstash: + host: localhost \ No newline at end of file diff --git a/mall-config/src/main/resources/config/search/search-prod.yml b/config/search/mall-search-prod.yaml similarity index 58% rename from mall-config/src/main/resources/config/search/search-prod.yml rename to config/search/mall-search-prod.yaml index 3496b41..b7c1d48 100644 --- a/mall-config/src/main/resources/config/search/search-prod.yml +++ b/config/search/mall-search-prod.yaml @@ -3,16 +3,18 @@ spring: url: jdbc:mysql://db:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: reader password: 123456 - data: - elasticsearch: - cluster-nodes: es:9300 - cluster-name: elasticsearch elasticsearch: rest: uris: http://es:9200 -logging: - path: /var/logs #配置日志生成路径 management: health: elasticsearch: - response-timeout: 1000ms #加大健康检查超时时间 \ No newline at end of file + response-timeout: 1000ms #加大健康检查超时时间 +logging: + file: + path: /var/logs + level: + root: info + com.macro.mall: info +logstash: + host: logstash \ No newline at end of file diff --git a/document/docker/docker-compose-app.yml b/document/docker/docker-compose-app.yml index 42c9381..6eaf166 100644 --- a/document/docker/docker-compose-app.yml +++ b/document/docker/docker-compose-app.yml @@ -5,23 +5,78 @@ services: container_name: mall-admin ports: - 8080:8080 + volumes: + - /mydata/app/mall-admin/logs:/var/logs + - /etc/localtime:/etc/localtime + environment: + - 'TZ="Asia/Shanghai"' external_links: - mysql:db #可以用db这个域名访问mysql服务 + - nacos-registry:nacos-registry #可以用nacos-registry这个域名访问nacos服务 mall-search: image: mall/mall-search:1.0-SNAPSHOT container_name: mall-search ports: - 8081:8081 + volumes: + - /mydata/app/mall-search/logs:/var/logs + - /etc/localtime:/etc/localtime + environment: + - 'TZ="Asia/Shanghai"' external_links: - elasticsearch:es #可以用es这个域名访问elasticsearch服务 - mysql:db #可以用db这个域名访问mysql服务 + - nacos-registry:nacos-registry #可以用nacos-registry这个域名访问nacos服务 mall-portal: image: mall/mall-portal:1.0-SNAPSHOT container_name: mall-portal ports: - 8085:8085 + volumes: + - /mydata/app/mall-portal/logs:/var/logs + - /etc/localtime:/etc/localtime + environment: + - 'TZ="Asia/Shanghai"' external_links: - redis:redis #可以用redis这个域名访问redis服务 - mongo:mongo #可以用mongo这个域名访问mongo服务 - mysql:db #可以用db这个域名访问mysql服务 - - rabbitmq:rabbit #可以用rabbit这个域名访问rabbitmq服务 \ No newline at end of file + - rabbitmq:rabbit #可以用rabbit这个域名访问rabbitmq服务 + - nacos-registry:nacos-registry #可以用nacos-registry这个域名访问nacos服务 + mall-auth: + image: mall/mall-auth:1.0-SNAPSHOT + container_name: mall-auth + ports: + - 8401:8401 + volumes: + - /mydata/app/mall-auth/logs:/var/logs + - /etc/localtime:/etc/localtime + environment: + - 'TZ="Asia/Shanghai"' + external_links: + - nacos-registry:nacos-registry #可以用nacos-registry这个域名访问nacos服务 + mall-gateway: + image: mall/mall-gateway:1.0-SNAPSHOT + container_name: mall-gateway + ports: + - 8201:8201 + volumes: + - /mydata/app/mall-gateway/logs:/var/logs + - /etc/localtime:/etc/localtime + environment: + - 'TZ="Asia/Shanghai"' + external_links: + - redis:redis #可以用redis这个域名访问redis服务 + - nacos-registry:nacos-registry #可以用nacos-registry这个域名访问nacos服务 + mall-monitor: + image: mall/mall-monitor:1.0-SNAPSHOT + container_name: mall-monitor + ports: + - 8101:8101 + volumes: + - /mydata/app/mall-monitor/logs:/var/logs + - /etc/localtime:/etc/localtime + environment: + - 'TZ="Asia/Shanghai"' + external_links: + - nacos-registry:nacos-registry #可以用nacos-registry这个域名访问nacos服务 \ No newline at end of file diff --git a/document/docker/docker-compose-env.yml b/document/docker/docker-compose-env.yml index b4e1f82..c292a83 100644 --- a/document/docker/docker-compose-env.yml +++ b/document/docker/docker-compose-env.yml @@ -14,7 +14,7 @@ services: - /mydata/mysql/data/conf:/etc/mysql/conf.d #配置文件挂载 - /mydata/mysql/log:/var/log/mysql #日志文件挂载 redis: - image: redis:3.2 + image: redis:5 container_name: redis command: redis-server --appendonly yes volumes: @@ -40,8 +40,9 @@ services: - 5672:5672 - 15672:15672 elasticsearch: - image: elasticsearch:6.4.0 + image: elasticsearch:7.6.2 container_name: elasticsearch + user: root environment: - "cluster.name=elasticsearch" #设置集群名称为elasticsearch - "discovery.type=single-node" #以单一节点模式启动 @@ -52,8 +53,24 @@ services: ports: - 9200:9200 - 9300:9300 + logstash: + image: logstash:7.6.2 + container_name: logstash + environment: + - TZ=Asia/Shanghai + volumes: + - /mydata/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf #挂载logstash的配置文件 + depends_on: + - elasticsearch #kibana在elasticsearch启动之后再启动 + links: + - elasticsearch:es #可以用es这个域名访问elasticsearch服务 + ports: + - 4560:4560 + - 4561:4561 + - 4562:4562 + - 4563:4563 kibana: - image: kibana:6.4.0 + image: kibana:7.6.2 container_name: kibana links: - elasticsearch:es #可以用es这个域名访问elasticsearch服务 @@ -64,9 +81,16 @@ services: ports: - 5601:5601 mongo: - image: mongo:3.2 + image: mongo:4.2.5 container_name: mongo volumes: - /mydata/mongo/db:/data/db #数据文件挂载 ports: - - 27017:27017 \ No newline at end of file + - 27017:27017 + nacos-registry: + image: nacos/nacos-server:1.3.0 + container_name: nacos-registry + environment: + - "MODE=standalone" + ports: + - 8848:8848 diff --git a/document/docker/docker-deploy.md b/document/docker/docker-deploy.md deleted file mode 100644 index 8cd872f..0000000 --- a/document/docker/docker-deploy.md +++ /dev/null @@ -1,149 +0,0 @@ -# docker环境部署 - -## docker环境安装 -### docker安装 -1. 安装yum-utils: -yum install -y yum-utils \ -device-mapper-persistent-data \ -lvm2 -2. 为yum源添加docker仓库位置: -yum-config-manager \ ---add-repo \ -https://download.docker.com/linux/centos/docker-ce.repo -3. 安装docker: -yum install docker-ce -4. 启动docker: -systemctl start docker -注:常见命令见document/reference文件夹中的docker.md -5. 安装上传下载插件: -yum -y install lrzsz -### docker compose安装 -1. 下载地址:https://github.com/docker/compose/releases -2. 安装地址:/usr/local/bin/docker-compose -3. 设置为可执行:sudo chmod +x /usr/local/bin/docker-compose -4. 测试是否安装成功:docker-compose --version - -## mysql安装 -### 下载镜像文件 -docker pull mysql:5.7 -### 创建实例并启动 -docker run -p 3306:3306 --name mysql \ --v /mydata/mysql/log:/var/log/mysql \ --v /mydata/mysql/data:/var/lib/mysql \ --v /mydata/mysql/conf:/etc/mysql \ --e MYSQL_ROOT_PASSWORD=root \ --d mysql:5.7 -> 参数说明 -- -p 3306:3306:将容器的3306端口映射到主机的3306端口 -- -v /mydata/mysql/conf:/etc/mysql:将配置文件夹挂在到主机 -- -v /mydata/mysql/log:/var/log/mysql:将日志文件夹挂载到主机 -- -v /mydata/mysql/data:/var/lib/mysql/:将配置文件夹挂载到主机 -- -e MYSQL_ROOT_PASSWORD=root:初始化root用户的密码 -### 通过容器的mysql命令行工具连接 -docker exec -it mysql mysql -uroot -proot -### 设置远程访问 -grant all privileges on *.* to 'root' @'%' identified by 'root'; -flush privileges; -### 进入容器文件系统 -docker exec -it mysql /bin/bash - -## redis安装 -### 下载镜像文件 -docker pull redis:3.2 -### 创建实例并启动 -docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data -d redis:3.2 redis-server --appendonly yes -### 使用redis镜像执行redis-cli命令连接 -docker exec -it redis redis-cli - -## nginx安装 -### 下载镜像文件 -docker pull nginx:1.10 -### 创建实例并启动 -docker run -p 80:80 --name nginx \ --v /mydata/nginx/html:/usr/share/nginx/html \ --v /mydata/nginx/logs:/var/log/nginx \ --d nginx:1.10 -### 修改nginx配置 -1. 将容器内的配置文件拷贝到当前目录:docker container cp nginx:/etc/nginx . -2. 修改文件名称:mv nginx conf -3. 终止容器:docker stop nginx -4. 执行命令删除原容器:docker rm $ContainerId -5. 执行以下命令: -docker run -p 80:80 --name nginx \ --v /mydata/nginx/html:/usr/share/nginx/html \ --v /mydata/nginx/logs:/var/log/nginx \ --v /mydata/nginx/conf:/etc/nginx \ --d nginx:1.10 - -## rabbitmq安装 -### 下载镜像文件 -docker pull rabbitmq:management -### 创建实例并启动 -docker run -d --name rabbitmq --publish 5671:5671 \ - --publish 5672:5672 --publish 4369:4369 --publish 25672:25672 --publish 15671:15671 --publish 15672:15672 \ -rabbitmq:management - -## elasticsearch安装 -### 下载镜像文件 -docker pull elasticsearch:6.4.0 -### 创建实例并运行 -docker run -p 9200:9200 -p 9300:9300 --name elasticsearch \ --v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \ --v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \ --d elasticsearch:6.4.0 -### 测试 -访问会返回版本信息:http://192.168.1.66:9200/ -### 安装目录位置 -/usr/share/elasticsearch -### 安装head插件(可以不安装,仅用于测试) -1. 进入docker内部bash:docker exec -it elasticsearch /bin/bash -2. 安装插件,具体参考:https://github.com/mobz/elasticsearch-head -3. 测试:http://192.168.1.66:9200/_plugin/head/ -### 安装中文分词器IKAnalyzer -1. 进入docker内部bash:docker exec -it elasticsearch /bin/bash -2. 安装中文分词插件,执行以下命令:elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.2.2/elasticsearch-analysis-ik-6.2.2.zip -3. 测试: - - 访问header插件:打开地址http://192.168.1.66:9200/_plugin/head/ - - 选择复合查询,输入地址:POST:http://192.168.1.66:9200/_analyze - - 输入参数:JSON:{"analyzer":"ik","text":"我们是大数据开发人员"} - -## mongodb安装 -### 下载镜像文件 -docker pull mongo:3.2 -### 创建实例并运行 -docker run -p 27017:27017 --name mongo -v /mydata/mongo/db:/data/db -d mongo:3.2 -### 使用mongo命令进入容器 -docker exec -it mongo mongo - -## SpringBoot应用命令部署 -**docker容器间进行连接才能互相访问** -### 部署mall-admin -docker run -p 8080:8080 --name mall-admin \ ---link mysql:db \ --v /etc/timezone:/etc/timezone \ --v /etc/localtime:/etc/localtime \ --v /mydata/app/admin/logs:/var/logs \ --d mall/mall-admin:1.0-SNAPSHOT -### 部署mall-search -docker run -p 8081:8081 --name mall-search \ ---link elasticsearch:es \ ---link mysql:db \ --v /etc/timezone:/etc/timezone \ --v /etc/localtime:/etc/localtime \ --v /mydata/app/search/logs:/var/logs \ --d mall/mall-search:1.0-SNAPSHOT -### 部署mall-port -docker run -p 8085:8085 --name mall-portal \ ---link mysql:db \ ---link redis:redis \ ---link mongo:mongo \ --v /etc/timezone:/etc/timezone \ --v /etc/localtime:/etc/localtime \ --v /mydata/app/portal/logs:/var/logs \ --d mall/mall-portal:1.0-SNAPSHOT - -## SpringBoot应用自动化部署 -### 部署文件 -document/docker/docker-compose.yml -### 部署命令 -docker-compose up -d \ No newline at end of file diff --git a/document/elk/logstash-springboot.conf b/document/elk/logstash-springboot.conf deleted file mode 100644 index a71e919..0000000 --- a/document/elk/logstash-springboot.conf +++ /dev/null @@ -1,14 +0,0 @@ -input { - tcp { - mode => "server" - host => "0.0.0.0" - port => 4560 - codec => json_lines - } -} -output { - elasticsearch { - hosts => "es:9200" - index => "springboot-logstash-%{+YYYY.MM.dd}" - } -} \ No newline at end of file diff --git a/document/elk/logstash.conf b/document/elk/logstash.conf new file mode 100644 index 0000000..953d054 --- /dev/null +++ b/document/elk/logstash.conf @@ -0,0 +1,49 @@ +input { + tcp { + mode => "server" + host => "0.0.0.0" + port => 4560 + codec => json_lines + type => "debug" + } + tcp { + mode => "server" + host => "0.0.0.0" + port => 4561 + codec => json_lines + type => "error" + } + tcp { + mode => "server" + host => "0.0.0.0" + port => 4562 + codec => json_lines + type => "business" + } + tcp { + mode => "server" + host => "0.0.0.0" + port => 4563 + codec => json_lines + type => "record" + } +} +filter{ + if [type] == "record" { + mutate { + remove_field => "port" + remove_field => "host" + remove_field => "@version" + } + json { + source => "message" + remove_field => ["message"] + } + } +} +output { + elasticsearch { + hosts => "es:9200" + index => "mall-%{type}-%{+YYYY.MM.dd}" + } +} \ No newline at end of file diff --git a/document/resource/mall_swarm_linux_02.png b/document/resource/mall_swarm_linux_02.png deleted file mode 100644 index 970955c..0000000 Binary files a/document/resource/mall_swarm_linux_02.png and /dev/null differ diff --git a/document/resource/mall_swarm_linux_04.png b/document/resource/mall_swarm_linux_04.png deleted file mode 100644 index 471974a..0000000 Binary files a/document/resource/mall_swarm_linux_04.png and /dev/null differ diff --git a/document/resource/mall_swarm_linux_07.png b/document/resource/mall_swarm_linux_07.png deleted file mode 100644 index 45bf959..0000000 Binary files a/document/resource/mall_swarm_linux_07.png and /dev/null differ diff --git a/document/resource/mall_swarm_linux_08.png b/document/resource/mall_swarm_linux_08.png deleted file mode 100644 index 6b7c8b1..0000000 Binary files a/document/resource/mall_swarm_linux_08.png and /dev/null differ diff --git a/document/resource/mall_swarm_linux_09.png b/document/resource/mall_swarm_linux_09.png deleted file mode 100644 index 14961fc..0000000 Binary files a/document/resource/mall_swarm_linux_09.png and /dev/null differ diff --git a/document/resource/mall_swarm_run_01.png b/document/resource/mall_swarm_run_01.png new file mode 100644 index 0000000..5254d49 Binary files /dev/null and b/document/resource/mall_swarm_run_01.png differ diff --git a/document/resource/mall_swarm_run_02.png b/document/resource/mall_swarm_run_02.png new file mode 100644 index 0000000..635d3e2 Binary files /dev/null and b/document/resource/mall_swarm_run_02.png differ diff --git a/document/resource/mall_swarm_run_03.png b/document/resource/mall_swarm_run_03.png new file mode 100644 index 0000000..74327bb Binary files /dev/null and b/document/resource/mall_swarm_run_03.png differ diff --git a/document/resource/mall_swarm_run_04.png b/document/resource/mall_swarm_run_04.png new file mode 100644 index 0000000..e3de4b9 Binary files /dev/null and b/document/resource/mall_swarm_run_04.png differ diff --git a/document/resource/mall_swarm_run_05.png b/document/resource/mall_swarm_run_05.png new file mode 100644 index 0000000..1bbfe3e Binary files /dev/null and b/document/resource/mall_swarm_run_05.png differ diff --git a/document/resource/mall_swarm_run_06.png b/document/resource/mall_swarm_run_06.png new file mode 100644 index 0000000..d5e4acc Binary files /dev/null and b/document/resource/mall_swarm_run_06.png differ diff --git a/document/resource/mall_swarm_run_07.png b/document/resource/mall_swarm_run_07.png new file mode 100644 index 0000000..07143a7 Binary files /dev/null and b/document/resource/mall_swarm_run_07.png differ diff --git a/document/resource/mall_swarm_run_08.png b/document/resource/mall_swarm_run_08.png new file mode 100644 index 0000000..53721a3 Binary files /dev/null and b/document/resource/mall_swarm_run_08.png differ diff --git a/document/resource/mall_swarm_run_09.png b/document/resource/mall_swarm_run_09.png new file mode 100644 index 0000000..819234d Binary files /dev/null and b/document/resource/mall_swarm_run_09.png differ diff --git a/document/resource/mall_swarm_run_10.png b/document/resource/mall_swarm_run_10.png new file mode 100644 index 0000000..64f5f98 Binary files /dev/null and b/document/resource/mall_swarm_run_10.png differ diff --git a/document/resource/mall_swarm_run_11.png b/document/resource/mall_swarm_run_11.png new file mode 100644 index 0000000..db31253 Binary files /dev/null and b/document/resource/mall_swarm_run_11.png differ diff --git a/document/resource/rabbitmq_install_1.png b/document/resource/rabbitmq_install_1.png deleted file mode 100644 index 73d4586..0000000 Binary files a/document/resource/rabbitmq_install_1.png and /dev/null differ diff --git a/document/resource/rabbitmq_install_2.png b/document/resource/rabbitmq_install_2.png deleted file mode 100644 index 89dee1b..0000000 Binary files a/document/resource/rabbitmq_install_2.png and /dev/null differ diff --git a/document/resource/rabbitmq_install_3.png b/document/resource/rabbitmq_install_3.png deleted file mode 100644 index d3fe850..0000000 Binary files a/document/resource/rabbitmq_install_3.png and /dev/null differ diff --git a/document/resource/rabbitmq_install_4.png b/document/resource/rabbitmq_install_4.png deleted file mode 100644 index 7426be6..0000000 Binary files a/document/resource/rabbitmq_install_4.png and /dev/null differ diff --git a/mall-admin/pom.xml b/mall-admin/pom.xml index 43902bf..5fb8c82 100644 --- a/mall-admin/pom.xml +++ b/mall-admin/pom.xml @@ -22,29 +22,37 @@ mall-mbg - com.macro.mall - mall-security + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config - org.springframework.cloud - spring-cloud-starter-config + org.springframework.boot + spring-boot-starter-data-redis com.aliyun.oss aliyun-sdk-oss - - net.logstash.logback - logstash-logback-encoder - io.minio minio + + jakarta.validation + jakarta.validation-api + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + io.github.openfeign + feign-okhttp + diff --git a/mall-admin/src/main/java/com/macro/mall/MallAdminApplication.java b/mall-admin/src/main/java/com/macro/mall/MallAdminApplication.java index 2f95822..8e1e27b 100644 --- a/mall-admin/src/main/java/com/macro/mall/MallAdminApplication.java +++ b/mall-admin/src/main/java/com/macro/mall/MallAdminApplication.java @@ -3,11 +3,13 @@ package com.macro.mall; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; /** * 应用启动入口 * Created by macro on 2018/4/26. */ +@EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class MallAdminApplication { diff --git a/mall-admin/src/main/java/com/macro/mall/bo/AdminUserDetails.java b/mall-admin/src/main/java/com/macro/mall/bo/AdminUserDetails.java deleted file mode 100644 index a46ab68..0000000 --- a/mall-admin/src/main/java/com/macro/mall/bo/AdminUserDetails.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.macro.mall.bo; - -import com.macro.mall.model.UmsAdmin; -import com.macro.mall.model.UmsResource; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; - -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -/** - * SpringSecurity需要的用户详情 - * Created by macro on 2018/4/26. - */ -public class AdminUserDetails implements UserDetails { - private UmsAdmin umsAdmin; - private List resourceList; - public AdminUserDetails(UmsAdmin umsAdmin,List resourceList) { - this.umsAdmin = umsAdmin; - this.resourceList = resourceList; - } - - @Override - public Collection getAuthorities() { - //返回当前用户的角色 - return resourceList.stream() - .map(role ->new SimpleGrantedAuthority(role.getId()+":"+role.getName())) - .collect(Collectors.toList()); - } - - @Override - public String getPassword() { - return umsAdmin.getPassword(); - } - - @Override - public String getUsername() { - return umsAdmin.getUsername(); - } - - @Override - public boolean isAccountNonExpired() { - return true; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @Override - public boolean isEnabled() { - return umsAdmin.getStatus().equals(1); - } -} diff --git a/mall-admin/src/main/java/com/macro/mall/bo/WebLog.java b/mall-admin/src/main/java/com/macro/mall/bo/WebLog.java deleted file mode 100644 index 98c51dd..0000000 --- a/mall-admin/src/main/java/com/macro/mall/bo/WebLog.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.macro.mall.bo; - -/** - * Controller层的日志封装类 - * Created by macro on 2018/4/26. - */ -public class WebLog { - /** - * 操作描述 - */ - private String description; - - /** - * 操作用户 - */ - private String username; - - /** - * 操作时间 - */ - private Long startTime; - - /** - * 消耗时间 - */ - private Integer spendTime; - - /** - * 根路径 - */ - private String basePath; - - /** - * URI - */ - private String uri; - - /** - * URL - */ - private String url; - - /** - * 请求类型 - */ - private String method; - - /** - * IP地址 - */ - private String ip; - - private Object parameter; - - private Object result; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public Long getStartTime() { - return startTime; - } - - public void setStartTime(Long startTime) { - this.startTime = startTime; - } - - public Integer getSpendTime() { - return spendTime; - } - - public void setSpendTime(Integer spendTime) { - this.spendTime = spendTime; - } - - public String getBasePath() { - return basePath; - } - - public void setBasePath(String basePath) { - this.basePath = basePath; - } - - public String getUri() { - return uri; - } - - public void setUri(String uri) { - this.uri = uri; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getMethod() { - return method; - } - - public void setMethod(String method) { - this.method = method; - } - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public Object getParameter() { - return parameter; - } - - public void setParameter(Object parameter) { - this.parameter = parameter; - } - - public Object getResult() { - return result; - } - - public void setResult(Object result) { - this.result = result; - } -} diff --git a/mall-admin/src/main/java/com/macro/mall/component/ResourceRoleRulesHolder.java b/mall-admin/src/main/java/com/macro/mall/component/ResourceRoleRulesHolder.java new file mode 100644 index 0000000..721094c --- /dev/null +++ b/mall-admin/src/main/java/com/macro/mall/component/ResourceRoleRulesHolder.java @@ -0,0 +1,23 @@ +package com.macro.mall.component; + +import com.macro.mall.service.UmsResourceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +/** + * 资源与角色访问对应关系操作组件 + * Created by macro on 2020/7/17. + */ +@Component +public class ResourceRoleRulesHolder { + + @Autowired + private UmsResourceService resourceService; + + @PostConstruct + public void initResourceRolesMap(){ + resourceService.initResourceRolesMap(); + } +} diff --git a/mall-admin/src/main/java/com/macro/mall/config/GlobalCorsConfig.java b/mall-admin/src/main/java/com/macro/mall/config/GlobalCorsConfig.java deleted file mode 100644 index f07d095..0000000 --- a/mall-admin/src/main/java/com/macro/mall/config/GlobalCorsConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.macro.mall.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.cors.UrlBasedCorsConfigurationSource; -import org.springframework.web.filter.CorsFilter; - -/** - * 全局跨域配置 - * 注意:前端从网关进行调用时不需要配置 - * Created by macro on 2019/7/27. - */ -//@Configuration -public class GlobalCorsConfig { - - /** - * 允许跨域调用的过滤器 - */ - @Bean - public CorsFilter corsFilter() { - CorsConfiguration config = new CorsConfiguration(); - //允许所有域名进行跨域调用 - config.addAllowedOrigin("*"); - //允许跨越发送cookie - config.setAllowCredentials(true); - //放行全部原始头信息 - config.addAllowedHeader("*"); - //允许所有请求方法跨域调用 - config.addAllowedMethod("*"); - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - source.registerCorsConfiguration("/**", config); - return new CorsFilter(source); - } -} diff --git a/mall-admin/src/main/java/com/macro/mall/config/MallSecurityConfig.java b/mall-admin/src/main/java/com/macro/mall/config/MallSecurityConfig.java deleted file mode 100644 index 23b6f15..0000000 --- a/mall-admin/src/main/java/com/macro/mall/config/MallSecurityConfig.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.macro.mall.config; - -import com.macro.mall.model.UmsResource; -import com.macro.mall.security.component.DynamicSecurityService; -import com.macro.mall.security.config.SecurityConfig; -import com.macro.mall.service.UmsAdminService; -import com.macro.mall.service.UmsResourceService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.ConfigAttribute; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.userdetails.UserDetailsService; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * mall-security模块相关配置 - * Created by macro on 2019/11/9. - */ -@Configuration -@EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class MallSecurityConfig extends SecurityConfig { - - @Autowired - private UmsAdminService adminService; - @Autowired - private UmsResourceService resourceService; - - @Bean - public UserDetailsService userDetailsService() { - //获取登录用户信息 - return username -> adminService.loadUserByUsername(username); - } - - @Bean - public DynamicSecurityService dynamicSecurityService() { - return new DynamicSecurityService() { - @Override - public Map loadDataSource() { - Map map = new ConcurrentHashMap<>(); - List resourceList = resourceService.listAll(); - for (UmsResource resource : resourceList) { - map.put(resource.getUrl(), new org.springframework.security.access.SecurityConfig(resource.getId() + ":" + resource.getName())); - } - return map; - } - }; - } -} diff --git a/mall-admin/src/main/java/com/macro/mall/config/MyBatisConfig.java b/mall-admin/src/main/java/com/macro/mall/config/MyBatisConfig.java index 4f0677a..1164256 100644 --- a/mall-admin/src/main/java/com/macro/mall/config/MyBatisConfig.java +++ b/mall-admin/src/main/java/com/macro/mall/config/MyBatisConfig.java @@ -5,7 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; /** - * MyBatis配置类 + * MyBatis相关配置 * Created by macro on 2019/4/8. */ @Configuration diff --git a/mall-admin/src/main/java/com/macro/mall/config/OssConfig.java b/mall-admin/src/main/java/com/macro/mall/config/OssConfig.java index d0112a9..9f7da2a 100644 --- a/mall-admin/src/main/java/com/macro/mall/config/OssConfig.java +++ b/mall-admin/src/main/java/com/macro/mall/config/OssConfig.java @@ -6,6 +6,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** + * OSS对象存储相关配置 * Created by macro on 2018/5/17. */ @Configuration diff --git a/mall-admin/src/main/java/com/macro/mall/config/RedisConfig.java b/mall-admin/src/main/java/com/macro/mall/config/RedisConfig.java new file mode 100644 index 0000000..90bba12 --- /dev/null +++ b/mall-admin/src/main/java/com/macro/mall/config/RedisConfig.java @@ -0,0 +1,19 @@ +package com.macro.mall.config; + +import com.macro.mall.common.config.BaseRedisConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * Redis相关配置 + * Created by macro on 2020/6/19. + */ +@Configuration +public class RedisConfig extends BaseRedisConfig { + +} diff --git a/mall-admin/src/main/java/com/macro/mall/config/Swagger2Config.java b/mall-admin/src/main/java/com/macro/mall/config/Swagger2Config.java deleted file mode 100644 index a3da046..0000000 --- a/mall-admin/src/main/java/com/macro/mall/config/Swagger2Config.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.macro.mall.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.ApiKey; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -import java.util.ArrayList; -import java.util.List; - -/** - * Swagger2API文档的配置 - * Created by macro on 2018/4/26. - */ -@Configuration -@EnableSwagger2 -public class Swagger2Config { - @Bean - public Docket createRestApi(){ - return new Docket(DocumentationType.SWAGGER_2) - .apiInfo(apiInfo()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.macro.mall.controller")) - .paths(PathSelectors.any()) - .build() - .securitySchemes(securitySchemes()) - .securityContexts(securityContexts()); - } - - private ApiInfo apiInfo() { - return new ApiInfoBuilder() - .title("mall后台系统") - .description("mall后台模块") - .contact("macro") - .version("1.0") - .build(); - } - - private List securitySchemes() { - //设置请求头信息 - List result = new ArrayList<>(); - ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header"); - result.add(apiKey); - return result; - } - - private List securityContexts() { - //设置需要登录认证的路径 - List result = new ArrayList<>(); - result.add(getContextByPath("/brand/.*")); - result.add(getContextByPath("/product/.*")); - result.add(getContextByPath("/productCategory/.*")); - return result; - } - - private SecurityContext getContextByPath(String pathRegex){ - return SecurityContext.builder() - .securityReferences(defaultAuth()) - .forPaths(PathSelectors.regex(pathRegex)) - .build(); - } - - private List defaultAuth() { - List result = new ArrayList<>(); - AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); - AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; - authorizationScopes[0] = authorizationScope; - result.add(new SecurityReference("Authorization", authorizationScopes)); - return result; - } -} diff --git a/mall-admin/src/main/java/com/macro/mall/config/SwaggerConfig.java b/mall-admin/src/main/java/com/macro/mall/config/SwaggerConfig.java new file mode 100644 index 0000000..37894e3 --- /dev/null +++ b/mall-admin/src/main/java/com/macro/mall/config/SwaggerConfig.java @@ -0,0 +1,41 @@ +package com.macro.mall.config; + +import com.macro.mall.common.config.BaseSwaggerConfig; +import com.macro.mall.common.domain.SwaggerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.ArrayList; +import java.util.List; + +/** + * Swagger API文档相关配置 + * Created by macro on 2018/4/26. + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig extends BaseSwaggerConfig { + + @Override + public SwaggerProperties swaggerProperties() { + return SwaggerProperties.builder() + .apiBasePackage("com.macro.mall.controller") + .title("mall后台系统") + .description("mall后台相关接口文档") + .contactName("macro") + .version("1.0") + .enableSecurity(true) + .build(); + } +} diff --git a/mall-admin/src/main/java/com/macro/mall/controller/MinioController.java b/mall-admin/src/main/java/com/macro/mall/controller/MinioController.java index 1958965..71e015b 100644 --- a/mall-admin/src/main/java/com/macro/mall/controller/MinioController.java +++ b/mall-admin/src/main/java/com/macro/mall/controller/MinioController.java @@ -1,9 +1,11 @@ package com.macro.mall.controller; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.json.JSONUtil; import com.macro.mall.common.api.CommonResult; +import com.macro.mall.dto.BucketPolicyConfigDto; import com.macro.mall.dto.MinioUploadDto; -import io.minio.MinioClient; -import io.minio.policy.PolicyType; +import io.minio.*; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; @@ -20,6 +22,7 @@ import java.text.SimpleDateFormat; import java.util.Date; /** + * MinIO对象存储管理 * Created by macro on 2019/12/25. */ @Api(tags = "MinioController", description = "MinIO对象存储管理") @@ -43,39 +46,68 @@ public class MinioController { public CommonResult upload(@RequestParam("file") MultipartFile file) { try { //创建一个MinIO的Java客户端 - MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY); - boolean isExist = minioClient.bucketExists(BUCKET_NAME); + MinioClient minioClient =MinioClient.builder() + .endpoint(ENDPOINT) + .credentials(ACCESS_KEY,SECRET_KEY) + .build(); + boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(BUCKET_NAME).build()); if (isExist) { LOGGER.info("存储桶已经存在!"); } else { //创建存储桶并设置只读权限 - minioClient.makeBucket(BUCKET_NAME); - minioClient.setBucketPolicy(BUCKET_NAME, "*.*", PolicyType.READ_ONLY); + minioClient.makeBucket(MakeBucketArgs.builder().bucket(BUCKET_NAME).build()); + BucketPolicyConfigDto bucketPolicyConfigDto = createBucketPolicyConfigDto(BUCKET_NAME); + SetBucketPolicyArgs setBucketPolicyArgs = SetBucketPolicyArgs.builder() + .bucket(BUCKET_NAME) + .config(JSONUtil.toJsonStr(bucketPolicyConfigDto)) + .build(); + minioClient.setBucketPolicy(setBucketPolicyArgs); } String filename = file.getOriginalFilename(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); // 设置存储对象名称 String objectName = sdf.format(new Date()) + "/" + filename; // 使用putObject上传一个文件到存储桶中 - minioClient.putObject(BUCKET_NAME, objectName, file.getInputStream(), file.getContentType()); + PutObjectArgs putObjectArgs = PutObjectArgs.builder() + .bucket(BUCKET_NAME) + .object(objectName) + .contentType(file.getContentType()) + .stream(file.getInputStream(), file.getSize(), ObjectWriteArgs.MIN_MULTIPART_SIZE).build(); + minioClient.putObject(putObjectArgs); LOGGER.info("文件上传成功!"); MinioUploadDto minioUploadDto = new MinioUploadDto(); minioUploadDto.setName(filename); minioUploadDto.setUrl(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName); return CommonResult.success(minioUploadDto); } catch (Exception e) { + e.printStackTrace(); LOGGER.info("上传发生错误: {}!", e.getMessage()); } return CommonResult.failed(); } + private BucketPolicyConfigDto createBucketPolicyConfigDto(String bucketName) { + BucketPolicyConfigDto.Statement statement = BucketPolicyConfigDto.Statement.builder() + .Effect("Allow") + .Principal("*") + .Action("s3:GetObject") + .Resource("arn:aws:s3:::"+bucketName+"/*.**").build(); + return BucketPolicyConfigDto.builder() + .Version("2012-10-17") + .Statement(CollUtil.toList(statement)) + .build(); + } + @ApiOperation("文件删除") @RequestMapping(value = "/delete", method = RequestMethod.POST) @ResponseBody public CommonResult delete(@RequestParam("objectName") String objectName) { try { - MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY); - minioClient.removeObject(BUCKET_NAME, objectName); + MinioClient minioClient = MinioClient.builder() + .endpoint(ENDPOINT) + .credentials(ACCESS_KEY,SECRET_KEY) + .build(); + minioClient.removeObject(RemoveObjectArgs.builder().bucket(BUCKET_NAME).object(objectName).build()); return CommonResult.success(null); } catch (Exception e) { e.printStackTrace(); diff --git a/mall-admin/src/main/java/com/macro/mall/controller/UmsAdminController.java b/mall-admin/src/main/java/com/macro/mall/controller/UmsAdminController.java index ee36dc7..5237008 100644 --- a/mall-admin/src/main/java/com/macro/mall/controller/UmsAdminController.java +++ b/mall-admin/src/main/java/com/macro/mall/controller/UmsAdminController.java @@ -1,7 +1,9 @@ package com.macro.mall.controller; +import cn.hutool.core.collection.CollUtil; import com.macro.mall.common.api.CommonPage; import com.macro.mall.common.api.CommonResult; +import com.macro.mall.common.domain.UserDto; import com.macro.mall.dto.UmsAdminLoginParam; import com.macro.mall.dto.UmsAdminParam; import com.macro.mall.dto.UpdateAdminPasswordParam; @@ -13,16 +15,14 @@ import com.macro.mall.service.UmsRoleService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; -import java.security.Principal; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * 后台用户管理 @@ -32,10 +32,6 @@ import java.util.Map; @Api(tags = "UmsAdminController", description = "后台用户管理") @RequestMapping("/admin") public class UmsAdminController { - @Value("${jwt.tokenHeader}") - private String tokenHeader; - @Value("${jwt.tokenHead}") - private String tokenHead; @Autowired private UmsAdminService adminService; @Autowired @@ -56,45 +52,23 @@ public class UmsAdminController { @RequestMapping(value = "/login", method = RequestMethod.POST) @ResponseBody public CommonResult login(@RequestBody UmsAdminLoginParam umsAdminLoginParam, BindingResult result) { - String token = adminService.login(umsAdminLoginParam.getUsername(), umsAdminLoginParam.getPassword()); - if (token == null) { - return CommonResult.validateFailed("用户名或密码错误"); - } - Map tokenMap = new HashMap<>(); - tokenMap.put("token", token); - tokenMap.put("tokenHead", tokenHead); - return CommonResult.success(tokenMap); - } - - @ApiOperation(value = "刷新token") - @RequestMapping(value = "/refreshToken", method = RequestMethod.GET) - @ResponseBody - public CommonResult refreshToken(HttpServletRequest request) { - String token = request.getHeader(tokenHeader); - String refreshToken = adminService.refreshToken(token); - if (refreshToken == null) { - return CommonResult.failed("token已经过期!"); - } - Map tokenMap = new HashMap<>(); - tokenMap.put("token", refreshToken); - tokenMap.put("tokenHead", tokenHead); - return CommonResult.success(tokenMap); + return adminService.login(umsAdminLoginParam.getUsername(),umsAdminLoginParam.getPassword()); } @ApiOperation(value = "获取当前登录用户信息") @RequestMapping(value = "/info", method = RequestMethod.GET) @ResponseBody - public CommonResult getAdminInfo(Principal principal) { - if(principal==null){ - return CommonResult.unauthorized(null); - } - String username = principal.getName(); - UmsAdmin umsAdmin = adminService.getAdminByUsername(username); + public CommonResult getAdminInfo() { + UmsAdmin umsAdmin = adminService.getCurrentAdmin(); Map data = new HashMap<>(); data.put("username", umsAdmin.getUsername()); - data.put("roles", new String[]{"TEST"}); data.put("menus", roleService.getMenuList(umsAdmin.getId())); data.put("icon", umsAdmin.getIcon()); + List roleList = adminService.getRoleList(umsAdmin.getId()); + if(CollUtil.isNotEmpty(roleList)){ + List roles = roleList.stream().map(UmsRole::getName).collect(Collectors.toList()); + data.put("roles",roles); + } return CommonResult.success(data); } @@ -215,4 +189,12 @@ public class UmsAdminController { List permissionList = adminService.getPermissionList(adminId); return CommonResult.success(permissionList); } + + @ApiOperation("根据用户名获取通用用户信息") + @RequestMapping(value = "/loadByUsername", method = RequestMethod.GET) + @ResponseBody + public UserDto loadUserByUsername(@RequestParam String username) { + UserDto userDTO = adminService.loadUserByUsername(username); + return userDTO; + } } diff --git a/mall-admin/src/main/java/com/macro/mall/controller/UmsResourceController.java b/mall-admin/src/main/java/com/macro/mall/controller/UmsResourceController.java index 09685e9..5261007 100644 --- a/mall-admin/src/main/java/com/macro/mall/controller/UmsResourceController.java +++ b/mall-admin/src/main/java/com/macro/mall/controller/UmsResourceController.java @@ -3,7 +3,6 @@ package com.macro.mall.controller; import com.macro.mall.common.api.CommonPage; import com.macro.mall.common.api.CommonResult; import com.macro.mall.model.UmsResource; -import com.macro.mall.security.component.DynamicSecurityMetadataSource; import com.macro.mall.service.UmsResourceService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -12,6 +11,7 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; /** * 后台资源管理Controller @@ -24,15 +24,12 @@ public class UmsResourceController { @Autowired private UmsResourceService resourceService; - @Autowired - private DynamicSecurityMetadataSource dynamicSecurityMetadataSource; @ApiOperation("添加后台资源") @RequestMapping(value = "/create", method = RequestMethod.POST) @ResponseBody public CommonResult create(@RequestBody UmsResource umsResource) { int count = resourceService.create(umsResource); - dynamicSecurityMetadataSource.clearDataSource(); if (count > 0) { return CommonResult.success(count); } else { @@ -46,7 +43,6 @@ public class UmsResourceController { public CommonResult update(@PathVariable Long id, @RequestBody UmsResource umsResource) { int count = resourceService.update(id, umsResource); - dynamicSecurityMetadataSource.clearDataSource(); if (count > 0) { return CommonResult.success(count); } else { @@ -67,7 +63,6 @@ public class UmsResourceController { @ResponseBody public CommonResult delete(@PathVariable Long id) { int count = resourceService.delete(id); - dynamicSecurityMetadataSource.clearDataSource(); if (count > 0) { return CommonResult.success(count); } else { @@ -94,4 +89,12 @@ public class UmsResourceController { List resourceList = resourceService.listAll(); return CommonResult.success(resourceList); } + + @ApiOperation("初始化资源角色关联数据") + @RequestMapping(value = "/initResourceRolesMap", method = RequestMethod.GET) + @ResponseBody + public CommonResult initResourceRolesMap() { + Map> resourceRolesMap = resourceService.initResourceRolesMap(); + return CommonResult.success(resourceRolesMap); + } } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/CmsPrefrenceAreaProductRelationDao.java b/mall-admin/src/main/java/com/macro/mall/dao/CmsPrefrenceAreaProductRelationDao.java index 6d2276f..9f8216f 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/CmsPrefrenceAreaProductRelationDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/CmsPrefrenceAreaProductRelationDao.java @@ -6,7 +6,7 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 自定义优选和商品关系操作 + * 自定义优选和商品关系操作Dao * Created by macro on 2018/4/26. */ public interface CmsPrefrenceAreaProductRelationDao { diff --git a/mall-admin/src/main/java/com/macro/mall/dao/CmsSubjectProductRelationDao.java b/mall-admin/src/main/java/com/macro/mall/dao/CmsSubjectProductRelationDao.java index df2d05b..749aee6 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/CmsSubjectProductRelationDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/CmsSubjectProductRelationDao.java @@ -6,7 +6,7 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 自定义商品和专题关系操作 + * 自定义商品和专题关系操作Dao * Created by macro on 2018/4/26. */ public interface CmsSubjectProductRelationDao { diff --git a/mall-admin/src/main/java/com/macro/mall/dao/PmsProductAttributeCategoryDao.java b/mall-admin/src/main/java/com/macro/mall/dao/PmsProductAttributeCategoryDao.java index cf1e27e..b126010 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/PmsProductAttributeCategoryDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/PmsProductAttributeCategoryDao.java @@ -10,7 +10,7 @@ import java.util.List; */ public interface PmsProductAttributeCategoryDao { /** - * 获取商品属性分类,包括属性 + * 获取包含属性的商品属性分类 */ List getListWithAttr(); } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/PmsProductCategoryDao.java b/mall-admin/src/main/java/com/macro/mall/dao/PmsProductCategoryDao.java index 3697f08..9ac86da 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/PmsProductCategoryDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/PmsProductCategoryDao.java @@ -10,7 +10,7 @@ import java.util.List; */ public interface PmsProductCategoryDao { /** - * 获取商品分类包括子分类 + * 获取商品分类及其子分类 */ List listWithChildren(); } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/PmsProductDao.java b/mall-admin/src/main/java/com/macro/mall/dao/PmsProductDao.java index 443adbc..982b482 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/PmsProductDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/PmsProductDao.java @@ -5,7 +5,7 @@ import org.apache.ibatis.annotations.Param; /** - * 商品自定义Dao + * 自定义商品管理Dao * Created by macro on 2018/4/26. */ public interface PmsProductDao { diff --git a/mall-admin/src/main/java/com/macro/mall/dao/PmsProductLadderDao.java b/mall-admin/src/main/java/com/macro/mall/dao/PmsProductLadderDao.java index 48b909f..ef95cb8 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/PmsProductLadderDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/PmsProductLadderDao.java @@ -10,5 +10,8 @@ import java.util.List; * Created by macro on 2018/4/26. */ public interface PmsProductLadderDao { + /** + * 批量创建 + */ int insertList(@Param("list") List productLadderList); } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/PmsProductVertifyRecordDao.java b/mall-admin/src/main/java/com/macro/mall/dao/PmsProductVertifyRecordDao.java index c17c172..71c6ce7 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/PmsProductVertifyRecordDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/PmsProductVertifyRecordDao.java @@ -6,9 +6,12 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 商品审核日志自定义Dao + * 自定义商品审核日志管理Dao * Created by macro on 2018/4/27. */ public interface PmsProductVertifyRecordDao { + /** + * 批量创建 + */ int insertList(@Param("list") List list); } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/PmsSkuStockDao.java b/mall-admin/src/main/java/com/macro/mall/dao/PmsSkuStockDao.java index 9ce1896..0568474 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/PmsSkuStockDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/PmsSkuStockDao.java @@ -6,7 +6,7 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 自定义商品sku库存Dao + * 自定义商品SKU管理Dao * Created by macro on 2018/4/26. */ public interface PmsSkuStockDao { diff --git a/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponDao.java b/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponDao.java index 3c57ad0..603c03d 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponDao.java @@ -4,9 +4,12 @@ import com.macro.mall.dto.SmsCouponParam; import org.apache.ibatis.annotations.Param; /** - * 优惠券管理自定义查询Dao + * 自定义优惠券管理Dao * Created by macro on 2018/8/29. */ public interface SmsCouponDao { + /** + * 获取优惠券详情包括绑定关系 + */ SmsCouponParam getItem(@Param("id") Long id); } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponProductCategoryRelationDao.java b/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponProductCategoryRelationDao.java index 78973ab..ae5054f 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponProductCategoryRelationDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponProductCategoryRelationDao.java @@ -6,9 +6,12 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 优惠券和商品分类关系自定义Dao + * 自定义优惠券和商品分类关系管理Dao * Created by macro on 2018/8/28. */ public interface SmsCouponProductCategoryRelationDao { + /** + * 批量创建 + */ int insertList(@Param("list")List productCategoryRelationList); } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponProductRelationDao.java b/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponProductRelationDao.java index f78531e..10d7e01 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponProductRelationDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/SmsCouponProductRelationDao.java @@ -6,9 +6,12 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 优惠券和产品关系自定义Dao + * 自定义优惠券和商品关系关系Dao * Created by macro on 2018/8/28. */ public interface SmsCouponProductRelationDao { + /** + * 批量创建 + */ int insertList(@Param("list")List productRelationList); } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/SmsFlashPromotionProductRelationDao.java b/mall-admin/src/main/java/com/macro/mall/dao/SmsFlashPromotionProductRelationDao.java index d574bcc..2e4b02d 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/SmsFlashPromotionProductRelationDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/SmsFlashPromotionProductRelationDao.java @@ -6,7 +6,7 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 限时购商品关联自定义Dao + * 自定义限时购商品关系管理Dao * Created by macro on 2018/11/16. */ public interface SmsFlashPromotionProductRelationDao { diff --git a/mall-admin/src/main/java/com/macro/mall/dao/UmsAdminPermissionRelationDao.java b/mall-admin/src/main/java/com/macro/mall/dao/UmsAdminPermissionRelationDao.java index b75bfe6..6493161 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/UmsAdminPermissionRelationDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/UmsAdminPermissionRelationDao.java @@ -6,9 +6,12 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 用户权限自定义Dao + * 自定义用户权限关系管理Dao * Created by macro on 2018/10/8. */ public interface UmsAdminPermissionRelationDao { + /** + * 批量创建 + */ int insertList(@Param("list") List list); } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/UmsAdminRoleRelationDao.java b/mall-admin/src/main/java/com/macro/mall/dao/UmsAdminRoleRelationDao.java index eba581d..fe55396 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/UmsAdminRoleRelationDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/UmsAdminRoleRelationDao.java @@ -9,7 +9,7 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 后台用户与角色管理自定义Dao + * 自定义后台用户与角色管理Dao * Created by macro on 2018/10/8. */ public interface UmsAdminRoleRelationDao { @@ -37,4 +37,9 @@ public interface UmsAdminRoleRelationDao { * 获取用户所有可访问资源 */ List getResourceList(@Param("adminId") Long adminId); + + /** + * 获取资源相关用户ID列表 + */ + List getAdminIdList(@Param("resourceId") Long resourceId); } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/UmsRoleDao.java b/mall-admin/src/main/java/com/macro/mall/dao/UmsRoleDao.java index d38ee0b..04873d8 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/UmsRoleDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/UmsRoleDao.java @@ -7,13 +7,20 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 后台用户角色自定义Dao + * 自定义后台角色管理Dao * Created by macro on 2020/2/2. */ public interface UmsRoleDao { + /** + * 根据后台用户ID获取菜单 + */ List getMenuList(@Param("adminId") Long adminId); - + /** + * 根据角色ID获取菜单 + */ List getMenuListByRoleId(@Param("roleId") Long roleId); - + /** + * 根据角色ID获取资源 + */ List getResourceListByRoleId(@Param("roleId") Long roleId); } diff --git a/mall-admin/src/main/java/com/macro/mall/dao/UmsRolePermissionRelationDao.java b/mall-admin/src/main/java/com/macro/mall/dao/UmsRolePermissionRelationDao.java index a09882d..795d573 100644 --- a/mall-admin/src/main/java/com/macro/mall/dao/UmsRolePermissionRelationDao.java +++ b/mall-admin/src/main/java/com/macro/mall/dao/UmsRolePermissionRelationDao.java @@ -7,7 +7,7 @@ import org.apache.ibatis.annotations.Param; import java.util.List; /** - * 后台用户角色管理自定义Dao + * 自定义角色权限关系管理Dao * Created by macro on 2018/9/30. */ public interface UmsRolePermissionRelationDao { diff --git a/mall-admin/src/main/java/com/macro/mall/dto/BucketPolicyConfigDto.java b/mall-admin/src/main/java/com/macro/mall/dto/BucketPolicyConfigDto.java new file mode 100644 index 0000000..c37f898 --- /dev/null +++ b/mall-admin/src/main/java/com/macro/mall/dto/BucketPolicyConfigDto.java @@ -0,0 +1,31 @@ +package com.macro.mall.dto; + +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * Minio Bucket访问策略配置 + * Created by macro on 2020/8/11. + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Builder +public class BucketPolicyConfigDto { + + private String Version; + private List Statement; + + @Data + @EqualsAndHashCode(callSuper = false) + @Builder + public static class Statement { + private String Effect; + private String Principal; + private String Action; + private String Resource; + + } +} diff --git a/mall-admin/src/main/java/com/macro/mall/dto/MinioUploadDto.java b/mall-admin/src/main/java/com/macro/mall/dto/MinioUploadDto.java index 1ce3980..a2769c9 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/MinioUploadDto.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/MinioUploadDto.java @@ -1,5 +1,6 @@ package com.macro.mall.dto; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; @@ -10,6 +11,8 @@ import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = false) public class MinioUploadDto { + @ApiModelProperty("文件访问URL") private String url; + @ApiModelProperty("文件名称") private String name; } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/OmsMoneyInfoParam.java b/mall-admin/src/main/java/com/macro/mall/dto/OmsMoneyInfoParam.java index 8d4125f..71ba001 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/OmsMoneyInfoParam.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/OmsMoneyInfoParam.java @@ -1,5 +1,6 @@ package com.macro.mall.dto; +import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; @@ -12,8 +13,12 @@ import java.math.BigDecimal; @Getter @Setter public class OmsMoneyInfoParam { + @ApiModelProperty("订单ID") private Long orderId; + @ApiModelProperty("运费金额") private BigDecimal freightAmount; + @ApiModelProperty("管理员后台调整订单使用的折扣金额") private BigDecimal discountAmount; + @ApiModelProperty("订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单") private Integer status; } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/OmsOrderDetail.java b/mall-admin/src/main/java/com/macro/mall/dto/OmsOrderDetail.java index 494fb0c..129c0f2 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/OmsOrderDetail.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/OmsOrderDetail.java @@ -3,6 +3,7 @@ package com.macro.mall.dto; import com.macro.mall.model.OmsOrder; import com.macro.mall.model.OmsOrderItem; import com.macro.mall.model.OmsOrderOperateHistory; +import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; @@ -15,8 +16,10 @@ import java.util.List; public class OmsOrderDetail extends OmsOrder { @Getter @Setter + @ApiModelProperty("订单商品列表") private List orderItemList; @Getter @Setter + @ApiModelProperty("订单操作记录列表") private List historyList; } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/OmsOrderReturnApplyResult.java b/mall-admin/src/main/java/com/macro/mall/dto/OmsOrderReturnApplyResult.java index 4d77fdd..8e43953 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/OmsOrderReturnApplyResult.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/OmsOrderReturnApplyResult.java @@ -2,6 +2,7 @@ package com.macro.mall.dto; import com.macro.mall.model.OmsCompanyAddress; import com.macro.mall.model.OmsOrderReturnApply; +import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; @@ -12,5 +13,6 @@ import lombok.Setter; public class OmsOrderReturnApplyResult extends OmsOrderReturnApply { @Getter @Setter + @ApiModelProperty(value = "公司收货地址") private OmsCompanyAddress companyAddress; } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/OmsReceiverInfoParam.java b/mall-admin/src/main/java/com/macro/mall/dto/OmsReceiverInfoParam.java index 773f314..5bd0351 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/OmsReceiverInfoParam.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/OmsReceiverInfoParam.java @@ -1,5 +1,6 @@ package com.macro.mall.dto; +import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; @@ -10,13 +11,22 @@ import lombok.Setter; @Getter @Setter public class OmsReceiverInfoParam { + @ApiModelProperty(value = "订单ID") private Long orderId; + @ApiModelProperty(value = "收货人姓名") private String receiverName; + @ApiModelProperty(value = "收货人电话") private String receiverPhone; + @ApiModelProperty(value = "收货人邮编") private String receiverPostCode; + @ApiModelProperty(value = "详细地址") private String receiverDetailAddress; + @ApiModelProperty(value = "省份/直辖市") private String receiverProvince; + @ApiModelProperty(value = "城市") private String receiverCity; + @ApiModelProperty(value = "区") private String receiverRegion; + @ApiModelProperty(value = "订单状态:0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单") private Integer status; } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/OssCallbackParam.java b/mall-admin/src/main/java/com/macro/mall/dto/OssCallbackParam.java index 202fd85..26134b8 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/OssCallbackParam.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/OssCallbackParam.java @@ -1,11 +1,15 @@ package com.macro.mall.dto; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; /** * oss上传成功后的回调参数 * Created by macro on 2018/5/17. */ +@Data +@EqualsAndHashCode(callSuper = false) public class OssCallbackParam { @ApiModelProperty("请求的回调地址") private String callbackUrl; @@ -13,28 +17,4 @@ public class OssCallbackParam { private String callbackBody; @ApiModelProperty("回调时传入参数的格式,比如表单提交形式") private String callbackBodyType; - - public String getCallbackUrl() { - return callbackUrl; - } - - public void setCallbackUrl(String callbackUrl) { - this.callbackUrl = callbackUrl; - } - - public String getCallbackBody() { - return callbackBody; - } - - public void setCallbackBody(String callbackBody) { - this.callbackBody = callbackBody; - } - - public String getCallbackBodyType() { - return callbackBodyType; - } - - public void setCallbackBodyType(String callbackBodyType) { - this.callbackBodyType = callbackBodyType; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/OssCallbackResult.java b/mall-admin/src/main/java/com/macro/mall/dto/OssCallbackResult.java index 3213dd0..6cf67d4 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/OssCallbackResult.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/OssCallbackResult.java @@ -1,11 +1,15 @@ package com.macro.mall.dto; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; /** * oss上传文件的回调结果 * Created by macro on 2018/5/17. */ +@Data +@EqualsAndHashCode(callSuper = false) public class OssCallbackResult { @ApiModelProperty("文件名称") private String filename; @@ -17,44 +21,4 @@ public class OssCallbackResult { private String width; @ApiModelProperty("图片文件的高") private String height; - - public String getFilename() { - return filename; - } - - public void setFilename(String filename) { - this.filename = filename; - } - - public String getSize() { - return size; - } - - public void setSize(String size) { - this.size = size; - } - - public String getMimeType() { - return mimeType; - } - - public void setMimeType(String mimeType) { - this.mimeType = mimeType; - } - - public String getWidth() { - return width; - } - - public void setWidth(String width) { - this.width = width; - } - - public String getHeight() { - return height; - } - - public void setHeight(String height) { - this.height = height; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/OssPolicyResult.java b/mall-admin/src/main/java/com/macro/mall/dto/OssPolicyResult.java index c42dc02..c24f780 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/OssPolicyResult.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/OssPolicyResult.java @@ -1,11 +1,15 @@ package com.macro.mall.dto; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; /** * 获取OSS上传文件授权返回结果 * Created by macro on 2018/5/17. */ +@Data +@EqualsAndHashCode(callSuper = false) public class OssPolicyResult { @ApiModelProperty("访问身份验证中用到用户标识") private String accessKeyId; @@ -19,52 +23,4 @@ public class OssPolicyResult { private String host; @ApiModelProperty("上传成功后的回调设置") private String callback; - - public String getAccessKeyId() { - return accessKeyId; - } - - public void setAccessKeyId(String accessKeyId) { - this.accessKeyId = accessKeyId; - } - - public String getPolicy() { - return policy; - } - - public void setPolicy(String policy) { - this.policy = policy; - } - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - - public String getDir() { - return dir; - } - - public void setDir(String dir) { - this.dir = dir; - } - - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - - public String getCallback() { - return callback; - } - - public void setCallback(String callback) { - this.callback = callback; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/PmsBrandParam.java b/mall-admin/src/main/java/com/macro/mall/dto/PmsBrandParam.java index 7b3df4a..e903476 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/PmsBrandParam.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/PmsBrandParam.java @@ -2,6 +2,8 @@ package com.macro.mall.dto; import com.macro.mall.validator.FlagValidator; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; import javax.validation.constraints.Min; import javax.validation.constraints.NotEmpty; @@ -10,6 +12,8 @@ import javax.validation.constraints.NotEmpty; * 品牌传递参数 * Created by macro on 2018/4/26. */ +@Data +@EqualsAndHashCode(callSuper = false) public class PmsBrandParam { @ApiModelProperty(value = "品牌名称",required = true) @NotEmpty(message = "名称不能为空") @@ -32,68 +36,4 @@ public class PmsBrandParam { private String bigPic; @ApiModelProperty(value = "品牌故事") private String brandStory; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getFirstLetter() { - return firstLetter; - } - - public void setFirstLetter(String firstLetter) { - this.firstLetter = firstLetter; - } - - public Integer getSort() { - return sort; - } - - public void setSort(Integer sort) { - this.sort = sort; - } - - public Integer getFactoryStatus() { - return factoryStatus; - } - - public void setFactoryStatus(Integer factoryStatus) { - this.factoryStatus = factoryStatus; - } - - public Integer getShowStatus() { - return showStatus; - } - - public void setShowStatus(Integer showStatus) { - this.showStatus = showStatus; - } - - public String getLogo() { - return logo; - } - - public void setLogo(String logo) { - this.logo = logo; - } - - public String getBigPic() { - return bigPic; - } - - public void setBigPic(String bigPic) { - this.bigPic = bigPic; - } - - public String getBrandStory() { - return brandStory; - } - - public void setBrandStory(String brandStory) { - this.brandStory = brandStory; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductAttributeCategoryItem.java b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductAttributeCategoryItem.java index 9109796..550596c 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductAttributeCategoryItem.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductAttributeCategoryItem.java @@ -2,6 +2,10 @@ package com.macro.mall.dto; import com.macro.mall.model.PmsProductAttribute; import com.macro.mall.model.PmsProductAttributeCategory; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; import java.util.List; @@ -10,13 +14,8 @@ import java.util.List; * Created by macro on 2018/5/24. */ public class PmsProductAttributeCategoryItem extends PmsProductAttributeCategory { + @Getter + @Setter + @ApiModelProperty(value = "商品属性列表") private List productAttributeList; - - public List getProductAttributeList() { - return productAttributeList; - } - - public void setProductAttributeList(List productAttributeList) { - this.productAttributeList = productAttributeList; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductAttributeParam.java b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductAttributeParam.java index 56279b2..28b6b8b 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductAttributeParam.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductAttributeParam.java @@ -2,6 +2,8 @@ package com.macro.mall.dto; import com.macro.mall.validator.FlagValidator; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; import javax.validation.constraints.NotEmpty; @@ -9,6 +11,8 @@ import javax.validation.constraints.NotEmpty; * 商品属性参数 * Created by macro on 2018/4/26. */ +@Data +@EqualsAndHashCode(callSuper = false) public class PmsProductAttributeParam { @ApiModelProperty("属性分类ID") @NotEmpty(message = "属性分类不能为空") @@ -41,92 +45,4 @@ public class PmsProductAttributeParam { @ApiModelProperty("属性的类型;0->规格;1->参数") @FlagValidator({"0","1"}) private Integer type; - - public Long getProductAttributeCategoryId() { - return productAttributeCategoryId; - } - - public void setProductAttributeCategoryId(Long productAttributeCategoryId) { - this.productAttributeCategoryId = productAttributeCategoryId; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer getSelectType() { - return selectType; - } - - public void setSelectType(Integer selectType) { - this.selectType = selectType; - } - - public Integer getInputType() { - return inputType; - } - - public void setInputType(Integer inputType) { - this.inputType = inputType; - } - - public String getInputList() { - return inputList; - } - - public void setInputList(String inputList) { - this.inputList = inputList; - } - - public Integer getSort() { - return sort; - } - - public void setSort(Integer sort) { - this.sort = sort; - } - - public Integer getFilterType() { - return filterType; - } - - public void setFilterType(Integer filterType) { - this.filterType = filterType; - } - - public Integer getSearchType() { - return searchType; - } - - public void setSearchType(Integer searchType) { - this.searchType = searchType; - } - - public Integer getRelatedStatus() { - return relatedStatus; - } - - public void setRelatedStatus(Integer relatedStatus) { - this.relatedStatus = relatedStatus; - } - - public Integer getHandAddStatus() { - return handAddStatus; - } - - public void setHandAddStatus(Integer handAddStatus) { - this.handAddStatus = handAddStatus; - } - - public Integer getType() { - return type; - } - - public void setType(Integer type) { - this.type = type; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductCategoryParam.java b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductCategoryParam.java index 4b0ea74..b560b18 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductCategoryParam.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductCategoryParam.java @@ -2,6 +2,8 @@ package com.macro.mall.dto; import com.macro.mall.validator.FlagValidator; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; import javax.validation.constraints.Min; import javax.validation.constraints.NotEmpty; @@ -11,6 +13,8 @@ import java.util.List; * 添加更新产品分类的参数 * Created by macro on 2018/4/26. */ +@Data +@EqualsAndHashCode(callSuper = false) public class PmsProductCategoryParam { @ApiModelProperty("父分类的编号") private Long parentId; @@ -36,84 +40,4 @@ public class PmsProductCategoryParam { private String description; @ApiModelProperty("产品相关筛选属性集合") private List productAttributeIdList; - - public Long getParentId() { - return parentId; - } - - public void setParentId(Long parentId) { - this.parentId = parentId; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getProductUnit() { - return productUnit; - } - - public void setProductUnit(String productUnit) { - this.productUnit = productUnit; - } - - public Integer getNavStatus() { - return navStatus; - } - - public void setNavStatus(Integer navStatus) { - this.navStatus = navStatus; - } - - public Integer getShowStatus() { - return showStatus; - } - - public void setShowStatus(Integer showStatus) { - this.showStatus = showStatus; - } - - public Integer getSort() { - return sort; - } - - public void setSort(Integer sort) { - this.sort = sort; - } - - public String getIcon() { - return icon; - } - - public void setIcon(String icon) { - this.icon = icon; - } - - public String getKeywords() { - return keywords; - } - - public void setKeywords(String keywords) { - this.keywords = keywords; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public List getProductAttributeIdList() { - return productAttributeIdList; - } - - public void setProductAttributeIdList(List productAttributeIdList) { - this.productAttributeIdList = productAttributeIdList; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductCategoryWithChildrenItem.java b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductCategoryWithChildrenItem.java index 7d5a990..f69f4b4 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductCategoryWithChildrenItem.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductCategoryWithChildrenItem.java @@ -1,6 +1,9 @@ package com.macro.mall.dto; import com.macro.mall.model.PmsProductCategory; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; import java.util.List; @@ -8,13 +11,8 @@ import java.util.List; * Created by macro on 2018/5/25. */ public class PmsProductCategoryWithChildrenItem extends PmsProductCategory { + @Getter + @Setter + @ApiModelProperty("子级分类") private List children; - - public List getChildren() { - return children; - } - - public void setChildren(List children) { - this.children = children; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductParam.java b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductParam.java index 371cb7a..1f29d1e 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductParam.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductParam.java @@ -2,6 +2,8 @@ package com.macro.mall.dto; import com.macro.mall.model.*; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; import java.util.List; @@ -9,6 +11,8 @@ import java.util.List; * 创建和修改商品时使用的参数 * Created by macro on 2018/4/26. */ +@Data +@EqualsAndHashCode(callSuper = false) public class PmsProductParam extends PmsProduct{ @ApiModelProperty("商品阶梯价格设置") private List productLadderList; @@ -24,60 +28,4 @@ public class PmsProductParam extends PmsProduct{ private List subjectProductRelationList; @ApiModelProperty("优选专区和商品的关系") private List prefrenceAreaProductRelationList; - - public List getProductLadderList() { - return productLadderList; - } - - public void setProductLadderList(List productLadderList) { - this.productLadderList = productLadderList; - } - - public List getProductFullReductionList() { - return productFullReductionList; - } - - public void setProductFullReductionList(List productFullReductionList) { - this.productFullReductionList = productFullReductionList; - } - - public List getMemberPriceList() { - return memberPriceList; - } - - public void setMemberPriceList(List memberPriceList) { - this.memberPriceList = memberPriceList; - } - - public List getSkuStockList() { - return skuStockList; - } - - public void setSkuStockList(List skuStockList) { - this.skuStockList = skuStockList; - } - - public List getProductAttributeValueList() { - return productAttributeValueList; - } - - public void setProductAttributeValueList(List productAttributeValueList) { - this.productAttributeValueList = productAttributeValueList; - } - - public List getSubjectProductRelationList() { - return subjectProductRelationList; - } - - public void setSubjectProductRelationList(List subjectProductRelationList) { - this.subjectProductRelationList = subjectProductRelationList; - } - - public List getPrefrenceAreaProductRelationList() { - return prefrenceAreaProductRelationList; - } - - public void setPrefrenceAreaProductRelationList(List prefrenceAreaProductRelationList) { - this.prefrenceAreaProductRelationList = prefrenceAreaProductRelationList; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductQueryParam.java b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductQueryParam.java index d24907c..ccba855 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductQueryParam.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductQueryParam.java @@ -1,11 +1,15 @@ package com.macro.mall.dto; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; /** * 产品查询参数 * Created by macro on 2018/4/27. */ +@Data +@EqualsAndHashCode(callSuper = false) public class PmsProductQueryParam { @ApiModelProperty("上架状态") private Integer publishStatus; @@ -19,52 +23,4 @@ public class PmsProductQueryParam { private Long productCategoryId; @ApiModelProperty("商品品牌编号") private Long brandId; - - public Integer getPublishStatus() { - return publishStatus; - } - - public void setPublishStatus(Integer publishStatus) { - this.publishStatus = publishStatus; - } - - public Integer getVerifyStatus() { - return verifyStatus; - } - - public void setVerifyStatus(Integer verifyStatus) { - this.verifyStatus = verifyStatus; - } - - public String getKeyword() { - return keyword; - } - - public void setKeyword(String keyword) { - this.keyword = keyword; - } - - public String getProductSn() { - return productSn; - } - - public void setProductSn(String productSn) { - this.productSn = productSn; - } - - public Long getProductCategoryId() { - return productCategoryId; - } - - public void setProductCategoryId(Long productCategoryId) { - this.productCategoryId = productCategoryId; - } - - public Long getBrandId() { - return brandId; - } - - public void setBrandId(Long brandId) { - this.brandId = brandId; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductResult.java b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductResult.java index 4db7f68..7ddeecc 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/PmsProductResult.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/PmsProductResult.java @@ -1,18 +1,16 @@ package com.macro.mall.dto; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + /** * 查询单个产品进行修改时返回的结果 * Created by macro on 2018/4/26. */ public class PmsProductResult extends PmsProductParam { - //商品所选分类的父id + @Getter + @Setter + @ApiModelProperty("商品所选分类的父id") private Long cateParentId; - - public Long getCateParentId() { - return cateParentId; - } - - public void setCateParentId(Long cateParentId) { - this.cateParentId = cateParentId; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/ProductAttrInfo.java b/mall-admin/src/main/java/com/macro/mall/dto/ProductAttrInfo.java index 6bed624..3d6218a 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/ProductAttrInfo.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/ProductAttrInfo.java @@ -1,27 +1,19 @@ package com.macro.mall.dto; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + /** * 商品分类对应属性信息 * Created by macro on 2018/5/23. */ +@Data +@EqualsAndHashCode(callSuper = false) public class ProductAttrInfo { + @ApiModelProperty("商品属性ID") private Long attributeId; + @ApiModelProperty("商品属性分类ID") private Long attributeCategoryId; - - public Long getAttributeId() { - return attributeId; - } - - public void setAttributeId(Long attributeId) { - this.attributeId = attributeId; - } - - public Long getAttributeCategoryId() { - return attributeCategoryId; - } - - public void setAttributeCategoryId(Long attributeCategoryId) { - this.attributeCategoryId = attributeCategoryId; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/SmsCouponParam.java b/mall-admin/src/main/java/com/macro/mall/dto/SmsCouponParam.java index 99643cb..bc974d9 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/SmsCouponParam.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/SmsCouponParam.java @@ -3,6 +3,9 @@ package com.macro.mall.dto; import com.macro.mall.model.SmsCoupon; import com.macro.mall.model.SmsCouponProductCategoryRelation; import com.macro.mall.model.SmsCouponProductRelation; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; import java.util.List; @@ -11,24 +14,12 @@ import java.util.List; * Created by macro on 2018/8/28. */ public class SmsCouponParam extends SmsCoupon { - //优惠券绑定的商品 + @Getter + @Setter + @ApiModelProperty("优惠券绑定的商品") private List productRelationList; - //优惠券绑定的商品分类 + @Getter + @Setter + @ApiModelProperty("优惠券绑定的商品分类") private List productCategoryRelationList; - - public List getProductRelationList() { - return productRelationList; - } - - public void setProductRelationList(List productRelationList) { - this.productRelationList = productRelationList; - } - - public List getProductCategoryRelationList() { - return productCategoryRelationList; - } - - public void setProductCategoryRelationList(List productCategoryRelationList) { - this.productCategoryRelationList = productCategoryRelationList; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/SmsFlashPromotionProduct.java b/mall-admin/src/main/java/com/macro/mall/dto/SmsFlashPromotionProduct.java index a3e5877..d9b5e7f 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/SmsFlashPromotionProduct.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/SmsFlashPromotionProduct.java @@ -2,6 +2,7 @@ package com.macro.mall.dto; import com.macro.mall.model.PmsProduct; import com.macro.mall.model.SmsFlashPromotionProductRelation; +import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; @@ -12,5 +13,6 @@ import lombok.Setter; public class SmsFlashPromotionProduct extends SmsFlashPromotionProductRelation{ @Getter @Setter + @ApiModelProperty("关联商品") private PmsProduct product; } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/SmsFlashPromotionSessionDetail.java b/mall-admin/src/main/java/com/macro/mall/dto/SmsFlashPromotionSessionDetail.java index 4d35c6d..d441f6c 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/SmsFlashPromotionSessionDetail.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/SmsFlashPromotionSessionDetail.java @@ -1,6 +1,7 @@ package com.macro.mall.dto; import com.macro.mall.model.SmsFlashPromotionSession; +import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; @@ -11,5 +12,6 @@ import lombok.Setter; public class SmsFlashPromotionSessionDetail extends SmsFlashPromotionSession { @Setter @Getter + @ApiModelProperty("商品数量") private Long productCount; } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/UmsAdminLoginParam.java b/mall-admin/src/main/java/com/macro/mall/dto/UmsAdminLoginParam.java index dc0595b..988f8a6 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/UmsAdminLoginParam.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/UmsAdminLoginParam.java @@ -1,6 +1,8 @@ package com.macro.mall.dto; import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; import javax.validation.constraints.NotEmpty; @@ -8,6 +10,8 @@ import javax.validation.constraints.NotEmpty; * 用户登录参数 * Created by macro on 2018/4/26. */ +@Data +@EqualsAndHashCode(callSuper = false) public class UmsAdminLoginParam { @ApiModelProperty(value = "用户名", required = true) @NotEmpty(message = "用户名不能为空") @@ -15,20 +19,4 @@ public class UmsAdminLoginParam { @ApiModelProperty(value = "密码", required = true) @NotEmpty(message = "密码不能为空") private String password; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/UmsMenuNode.java b/mall-admin/src/main/java/com/macro/mall/dto/UmsMenuNode.java index 8dcb13c..ec36ada 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/UmsMenuNode.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/UmsMenuNode.java @@ -1,6 +1,7 @@ package com.macro.mall.dto; import com.macro.mall.model.UmsMenu; +import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; @@ -13,5 +14,6 @@ import java.util.List; @Getter @Setter public class UmsMenuNode extends UmsMenu { + @ApiModelProperty(value = "子级菜单") private List children; } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/UmsPermissionNode.java b/mall-admin/src/main/java/com/macro/mall/dto/UmsPermissionNode.java index adb570d..d38fc65 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/UmsPermissionNode.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/UmsPermissionNode.java @@ -1,6 +1,7 @@ package com.macro.mall.dto; import com.macro.mall.model.UmsPermission; +import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; @@ -13,5 +14,6 @@ import java.util.List; public class UmsPermissionNode extends UmsPermission { @Getter @Setter + @ApiModelProperty(value = "子级权限") private List children; } diff --git a/mall-admin/src/main/java/com/macro/mall/service/AuthService.java b/mall-admin/src/main/java/com/macro/mall/service/AuthService.java new file mode 100644 index 0000000..e25c505 --- /dev/null +++ b/mall-admin/src/main/java/com/macro/mall/service/AuthService.java @@ -0,0 +1,20 @@ +package com.macro.mall.service; + +import com.macro.mall.common.api.CommonResult; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.Map; + +/** + * 认证服务远程调用 + * Created by macro on 2020/7/19. + */ +@FeignClient("mall-auth") +public interface AuthService { + + @PostMapping(value = "/oauth/token") + CommonResult getAccessToken(@RequestParam Map parameters); + +} diff --git a/mall-admin/src/main/java/com/macro/mall/service/PmsProductAttributeService.java b/mall-admin/src/main/java/com/macro/mall/service/PmsProductAttributeService.java index 76b6851..2f1b6b8 100644 --- a/mall-admin/src/main/java/com/macro/mall/service/PmsProductAttributeService.java +++ b/mall-admin/src/main/java/com/macro/mall/service/PmsProductAttributeService.java @@ -14,8 +14,7 @@ import java.util.List; public interface PmsProductAttributeService { /** * 根据分类分页获取商品属性 - * - * @param cid 分类id + * @param cid 分类id * @param type 0->属性;2->参数 */ List getList(Long cid, Integer type, Integer pageSize, Integer pageNum); @@ -36,14 +35,8 @@ public interface PmsProductAttributeService { */ PmsProductAttribute getItem(Long id); - /** - * 批量删除商品属性 - */ @Transactional int delete(List ids); - /** - * 获取和分类相关的商品属性 - */ List getProductAttrInfo(Long productCategoryId); } diff --git a/mall-admin/src/main/java/com/macro/mall/service/UmsAdminCacheService.java b/mall-admin/src/main/java/com/macro/mall/service/UmsAdminCacheService.java new file mode 100644 index 0000000..030fd8c --- /dev/null +++ b/mall-admin/src/main/java/com/macro/mall/service/UmsAdminCacheService.java @@ -0,0 +1,27 @@ +package com.macro.mall.service; + +import com.macro.mall.model.UmsAdmin; +import com.macro.mall.model.UmsResource; + +import java.util.List; + +/** + * 后台用户缓存操作类 + * Created by macro on 2020/3/13. + */ +public interface UmsAdminCacheService { + /** + * 删除后台用户缓存 + */ + void delAdmin(Long adminId); + + /** + * 获取缓存后台用户信息 + */ + UmsAdmin getAdmin(Long adminId); + + /** + * 设置缓存后台用户信息 + */ + void setAdmin(UmsAdmin admin); +} diff --git a/mall-admin/src/main/java/com/macro/mall/service/UmsAdminService.java b/mall-admin/src/main/java/com/macro/mall/service/UmsAdminService.java index fc241f6..cc42c38 100644 --- a/mall-admin/src/main/java/com/macro/mall/service/UmsAdminService.java +++ b/mall-admin/src/main/java/com/macro/mall/service/UmsAdminService.java @@ -1,12 +1,10 @@ package com.macro.mall.service; +import com.macro.mall.common.api.CommonResult; +import com.macro.mall.common.domain.UserDto; import com.macro.mall.dto.UmsAdminParam; import com.macro.mall.dto.UpdateAdminPasswordParam; -import com.macro.mall.model.UmsAdmin; -import com.macro.mall.model.UmsPermission; -import com.macro.mall.model.UmsResource; -import com.macro.mall.model.UmsRole; -import org.springframework.security.core.userdetails.UserDetails; +import com.macro.mall.model.*; import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -30,15 +28,9 @@ public interface UmsAdminService { * 登录功能 * @param username 用户名 * @param password 密码 - * @return 生成的JWT的token + * @return 调用认证中心返回结果 */ - String login(String username,String password); - - /** - * 刷新token的功能 - * @param oldToken 旧的token - */ - String refreshToken(String oldToken); + CommonResult login(String username, String password); /** * 根据用户id获取用户 @@ -95,5 +87,10 @@ public interface UmsAdminService { /** * 获取用户信息 */ - UserDetails loadUserByUsername(String username); + UserDto loadUserByUsername(String username); + + /** + * 获取当前登录后台用户 + */ + UmsAdmin getCurrentAdmin(); } diff --git a/mall-admin/src/main/java/com/macro/mall/service/UmsResourceService.java b/mall-admin/src/main/java/com/macro/mall/service/UmsResourceService.java index 131c555..33a1dc4 100644 --- a/mall-admin/src/main/java/com/macro/mall/service/UmsResourceService.java +++ b/mall-admin/src/main/java/com/macro/mall/service/UmsResourceService.java @@ -3,6 +3,7 @@ package com.macro.mall.service; import com.macro.mall.model.UmsResource; import java.util.List; +import java.util.Map; /** * 后台资源管理Service @@ -38,4 +39,9 @@ public interface UmsResourceService { * 查询全部资源 */ List listAll(); + + /** + * 初始化资源角色规则 + */ + Map> initResourceRolesMap(); } diff --git a/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminCacheServiceImpl.java b/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminCacheServiceImpl.java new file mode 100644 index 0000000..16b45ad --- /dev/null +++ b/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminCacheServiceImpl.java @@ -0,0 +1,45 @@ +package com.macro.mall.service.impl; + +import com.macro.mall.common.service.RedisService; +import com.macro.mall.model.UmsAdmin; +import com.macro.mall.service.UmsAdminCacheService; +import com.macro.mall.service.UmsAdminService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * UmsAdminCacheService实现类 + * Created by macro on 2020/3/13. + */ +@Service +public class UmsAdminCacheServiceImpl implements UmsAdminCacheService { + @Autowired + private UmsAdminService adminService; + @Autowired + private RedisService redisService; + @Value("${redis.database}") + private String REDIS_DATABASE; + @Value("${redis.expire.common}") + private Long REDIS_EXPIRE; + @Value("${redis.key.admin}") + private String REDIS_KEY_ADMIN; + + @Override + public void delAdmin(Long adminId) { + String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + adminId; + redisService.del(key); + } + + @Override + public UmsAdmin getAdmin(Long adminId) { + String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + adminId; + return (UmsAdmin) redisService.get(key); + } + + @Override + public void setAdmin(UmsAdmin admin) { + String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + admin.getId(); + redisService.set(key, admin, REDIS_EXPIRE); + } +} diff --git a/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminServiceImpl.java b/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminServiceImpl.java index 484a8f0..5f675f4 100644 --- a/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminServiceImpl.java +++ b/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminServiceImpl.java @@ -2,8 +2,14 @@ package com.macro.mall.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.BCrypt; +import cn.hutool.json.JSONUtil; import com.github.pagehelper.PageHelper; -import com.macro.mall.bo.AdminUserDetails; +import com.macro.mall.common.api.CommonResult; +import com.macro.mall.common.api.ResultCode; +import com.macro.mall.common.constant.AuthConstant; +import com.macro.mall.common.domain.UserDto; +import com.macro.mall.common.exception.Asserts; import com.macro.mall.dao.UmsAdminPermissionRelationDao; import com.macro.mall.dao.UmsAdminRoleRelationDao; import com.macro.mall.dto.UmsAdminParam; @@ -13,19 +19,13 @@ import com.macro.mall.mapper.UmsAdminMapper; import com.macro.mall.mapper.UmsAdminPermissionRelationMapper; import com.macro.mall.mapper.UmsAdminRoleRelationMapper; import com.macro.mall.model.*; -import com.macro.mall.security.util.JwtTokenUtil; +import com.macro.mall.service.AuthService; +import com.macro.mall.service.UmsAdminCacheService; import com.macro.mall.service.UmsAdminService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -33,9 +33,7 @@ import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; /** @@ -46,10 +44,6 @@ import java.util.stream.Collectors; public class UmsAdminServiceImpl implements UmsAdminService { private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class); @Autowired - private JwtTokenUtil jwtTokenUtil; - @Autowired - private PasswordEncoder passwordEncoder; - @Autowired private UmsAdminMapper adminMapper; @Autowired private UmsAdminRoleRelationMapper adminRoleRelationMapper; @@ -61,6 +55,12 @@ public class UmsAdminServiceImpl implements UmsAdminService { private UmsAdminPermissionRelationDao adminPermissionRelationDao; @Autowired private UmsAdminLoginLogMapper loginLogMapper; + @Autowired + private AuthService authService; + @Autowired + private UmsAdminCacheService adminCacheService; + @Autowired + private HttpServletRequest request; @Override public UmsAdmin getAdminByUsername(String username) { @@ -87,30 +87,29 @@ public class UmsAdminServiceImpl implements UmsAdminService { return null; } //将密码进行加密操作 - String encodePassword = passwordEncoder.encode(umsAdmin.getPassword()); + String encodePassword = BCrypt.hashpw(umsAdmin.getPassword()); umsAdmin.setPassword(encodePassword); adminMapper.insert(umsAdmin); return umsAdmin; } @Override - public String login(String username, String password) { - String token = null; - //密码需要客户端加密后传递 - try { - UserDetails userDetails = loadUserByUsername(username); - if(!passwordEncoder.matches(password,userDetails.getPassword())){ - throw new BadCredentialsException("密码不正确"); - } - UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); - SecurityContextHolder.getContext().setAuthentication(authentication); - token = jwtTokenUtil.generateToken(userDetails); + public CommonResult login(String username, String password) { + if(StrUtil.isEmpty(username)||StrUtil.isEmpty(password)){ + Asserts.fail("用户名或密码不能为空!"); + } + Map params = new HashMap<>(); + params.put("client_id", AuthConstant.ADMIN_CLIENT_ID); + params.put("client_secret","123456"); + params.put("grant_type","password"); + params.put("username",username); + params.put("password",password); + CommonResult restResult = authService.getAccessToken(params); + if(ResultCode.SUCCESS.getCode()==restResult.getCode()&&restResult.getData()!=null){ // updateLoginTimeByUsername(username); insertLoginLog(username); - } catch (AuthenticationException e) { - LOGGER.warn("登录异常:{}", e.getMessage()); } - return token; + return restResult; } /** @@ -119,6 +118,7 @@ public class UmsAdminServiceImpl implements UmsAdminService { */ private void insertLoginLog(String username) { UmsAdmin admin = getAdminByUsername(username); + if(admin==null) return; UmsAdminLoginLog loginLog = new UmsAdminLoginLog(); loginLog.setAdminId(admin.getId()); loginLog.setCreateTime(new Date()); @@ -139,11 +139,6 @@ public class UmsAdminServiceImpl implements UmsAdminService { adminMapper.updateByExampleSelective(record, example); } - @Override - public String refreshToken(String oldToken) { - return jwtTokenUtil.refreshHeadToken(oldToken); - } - @Override public UmsAdmin getItem(Long id) { return adminMapper.selectByPrimaryKey(id); @@ -173,15 +168,19 @@ public class UmsAdminServiceImpl implements UmsAdminService { if(StrUtil.isEmpty(admin.getPassword())){ admin.setPassword(null); }else{ - admin.setPassword(passwordEncoder.encode(admin.getPassword())); + admin.setPassword(BCrypt.hashpw(admin.getPassword())); } } - return adminMapper.updateByPrimaryKeySelective(admin); + int count = adminMapper.updateByPrimaryKeySelective(admin); + adminCacheService.delAdmin(id); + return count; } @Override public int delete(Long id) { - return adminMapper.deleteByPrimaryKey(id); + int count = adminMapper.deleteByPrimaryKey(id); + adminCacheService.delAdmin(id); + return count; } @Override @@ -271,22 +270,46 @@ public class UmsAdminServiceImpl implements UmsAdminService { return -2; } UmsAdmin umsAdmin = adminList.get(0); - if(!passwordEncoder.matches(param.getOldPassword(),umsAdmin.getPassword())){ + if(!BCrypt.checkpw(param.getOldPassword(),umsAdmin.getPassword())){ return -3; } - umsAdmin.setPassword(passwordEncoder.encode(param.getNewPassword())); + umsAdmin.setPassword(BCrypt.hashpw(param.getNewPassword())); adminMapper.updateByPrimaryKey(umsAdmin); + adminCacheService.delAdmin(umsAdmin.getId()); return 1; } @Override - public UserDetails loadUserByUsername(String username){ + public UserDto loadUserByUsername(String username){ //获取用户信息 UmsAdmin admin = getAdminByUsername(username); if (admin != null) { - List resourceList = getResourceList(admin.getId()); - return new AdminUserDetails(admin,resourceList); + List roleList = getRoleList(admin.getId()); + UserDto userDTO = new UserDto(); + BeanUtils.copyProperties(admin,userDTO); + if(CollUtil.isNotEmpty(roleList)){ + List roleStrList = roleList.stream().map(item -> item.getId() + "_" + item.getName()).collect(Collectors.toList()); + userDTO.setRoles(roleStrList); + } + return userDTO; + } + return null; + } + + @Override + public UmsAdmin getCurrentAdmin() { + String userStr = request.getHeader(AuthConstant.USER_TOKEN_HEADER); + if(StrUtil.isEmpty(userStr)){ + Asserts.fail(ResultCode.UNAUTHORIZED); + } + UserDto userDto = JSONUtil.toBean(userStr, UserDto.class); + UmsAdmin admin = adminCacheService.getAdmin(userDto.getId()); + if(admin!=null){ + return admin; + }else{ + admin = adminMapper.selectByPrimaryKey(userDto.getId()); + adminCacheService.setAdmin(admin); + return admin; } - throw new UsernameNotFoundException("用户名或密码错误"); } } diff --git a/mall-admin/src/main/java/com/macro/mall/service/impl/UmsResourceServiceImpl.java b/mall-admin/src/main/java/com/macro/mall/service/impl/UmsResourceServiceImpl.java index 4d866c0..44f517f 100644 --- a/mall-admin/src/main/java/com/macro/mall/service/impl/UmsResourceServiceImpl.java +++ b/mall-admin/src/main/java/com/macro/mall/service/impl/UmsResourceServiceImpl.java @@ -2,15 +2,20 @@ package com.macro.mall.service.impl; import cn.hutool.core.util.StrUtil; import com.github.pagehelper.PageHelper; +import com.macro.mall.common.constant.AuthConstant; +import com.macro.mall.common.service.RedisService; import com.macro.mall.mapper.UmsResourceMapper; -import com.macro.mall.model.UmsResource; -import com.macro.mall.model.UmsResourceExample; +import com.macro.mall.mapper.UmsRoleMapper; +import com.macro.mall.mapper.UmsRoleResourceRelationMapper; +import com.macro.mall.model.*; +import com.macro.mall.service.UmsAdminCacheService; import com.macro.mall.service.UmsResourceService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import java.util.Date; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; /** * 后台资源管理Service实现类 @@ -20,16 +25,28 @@ import java.util.List; public class UmsResourceServiceImpl implements UmsResourceService { @Autowired private UmsResourceMapper resourceMapper; + @Autowired + private UmsRoleMapper roleMapper; + @Autowired + private UmsRoleResourceRelationMapper roleResourceRelationMapper; + @Autowired + private RedisService redisService; + @Value("${spring.application.name}") + private String applicationName; @Override public int create(UmsResource umsResource) { umsResource.setCreateTime(new Date()); - return resourceMapper.insert(umsResource); + int count = resourceMapper.insert(umsResource); + initResourceRolesMap(); + return count; } @Override public int update(Long id, UmsResource umsResource) { umsResource.setId(id); - return resourceMapper.updateByPrimaryKeySelective(umsResource); + int count = resourceMapper.updateByPrimaryKeySelective(umsResource); + initResourceRolesMap(); + return count; } @Override @@ -39,7 +56,9 @@ public class UmsResourceServiceImpl implements UmsResourceService { @Override public int delete(Long id) { - return resourceMapper.deleteByPrimaryKey(id); + int count = resourceMapper.deleteByPrimaryKey(id); + initResourceRolesMap(); + return count; } @Override @@ -63,4 +82,21 @@ public class UmsResourceServiceImpl implements UmsResourceService { public List listAll() { return resourceMapper.selectByExample(new UmsResourceExample()); } + + @Override + public Map> initResourceRolesMap() { + Map> resourceRoleMap = new TreeMap<>(); + List resourceList = resourceMapper.selectByExample(new UmsResourceExample()); + List roleList = roleMapper.selectByExample(new UmsRoleExample()); + List relationList = roleResourceRelationMapper.selectByExample(new UmsRoleResourceRelationExample()); + for (UmsResource resource : resourceList) { + Set roleIds = relationList.stream().filter(item -> item.getResourceId().equals(resource.getId())).map(UmsRoleResourceRelation::getRoleId).collect(Collectors.toSet()); + List roleNames = roleList.stream().filter(item -> roleIds.contains(item.getId())).map(item -> item.getId() + "_" + item.getName()).collect(Collectors.toList()); + resourceRoleMap.put("/"+applicationName+resource.getUrl(),roleNames); + } + redisService.del(AuthConstant.RESOURCE_ROLES_MAP_KEY); + redisService.hSetAll(AuthConstant.RESOURCE_ROLES_MAP_KEY, resourceRoleMap); + return resourceRoleMap; + + } } diff --git a/mall-admin/src/main/java/com/macro/mall/service/impl/UmsRoleServiceImpl.java b/mall-admin/src/main/java/com/macro/mall/service/impl/UmsRoleServiceImpl.java index ddd9230..879099c 100644 --- a/mall-admin/src/main/java/com/macro/mall/service/impl/UmsRoleServiceImpl.java +++ b/mall-admin/src/main/java/com/macro/mall/service/impl/UmsRoleServiceImpl.java @@ -8,6 +8,8 @@ import com.macro.mall.mapper.UmsRoleMenuRelationMapper; import com.macro.mall.mapper.UmsRolePermissionRelationMapper; import com.macro.mall.mapper.UmsRoleResourceRelationMapper; import com.macro.mall.model.*; +import com.macro.mall.service.UmsAdminCacheService; +import com.macro.mall.service.UmsResourceService; import com.macro.mall.service.UmsRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -35,6 +37,8 @@ public class UmsRoleServiceImpl implements UmsRoleService { private UmsRolePermissionRelationDao rolePermissionRelationDao; @Autowired private UmsRoleDao roleDao; + @Autowired + private UmsResourceService resourceService; @Override public int create(UmsRole role) { role.setCreateTime(new Date()); @@ -53,7 +57,9 @@ public class UmsRoleServiceImpl implements UmsRoleService { public int delete(List ids) { UmsRoleExample example = new UmsRoleExample(); example.createCriteria().andIdIn(ids); - return roleMapper.deleteByExample(example); + int count = roleMapper.deleteByExample(example); + resourceService.initResourceRolesMap(); + return count; } @Override @@ -137,6 +143,7 @@ public class UmsRoleServiceImpl implements UmsRoleService { relation.setResourceId(resourceId); roleResourceRelationMapper.insert(relation); } + resourceService.initResourceRolesMap(); return resourceIds.size(); } } diff --git a/mall-admin/src/main/resources/application.yml b/mall-admin/src/main/resources/application.yml index 09139a7..93213fb 100644 --- a/mall-admin/src/main/resources/application.yml +++ b/mall-admin/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 8180 + port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai @@ -14,6 +14,12 @@ spring: stat-view-servlet: #访问监控网页的登录用户名和密码 login-username: druid login-password: druid + redis: + host: localhost # Redis服务器地址 + database: 0 # Redis数据库索引(默认为0) + port: 6379 # Redis服务器连接端口 + password: # Redis服务器连接密码(默认为空) + timeout: 3000ms # 连接超时时间(毫秒) rabbitmq: #rabbitmq相关配置 host: localhost port: 5672 @@ -35,30 +41,12 @@ management: #开启SpringBoot Admin的监控 endpoint: health: show-details: always -jwt: - tokenHeader: Authorization #JWT存储的请求头 - secret: mall-admin-secret #JWT加解密使用的密钥 - expiration: 604800 #JWT的超期限时间(60*60*24) - tokenHead: Bearer #JWT负载中拿到开头 -secure: - ignored: - urls: #安全路径白名单 - - /swagger-ui.html - - /swagger-resources/** - - /swagger/** - - /**/v2/api-docs - - /**/*.js - - /**/*.css - - /**/*.png - - /**/*.ico - - /webjars/springfox-swagger-ui/** - - /actuator/** - - /druid/** - - /admin/login - - /admin/register - - /admin/info - - /admin/logout - - /minio/upload +redis: + database: mall + key: + admin: 'ums:admin' + expire: + common: 86400 # 24小时 aliyun: oss: endpoint: oss-cn-shenzhen.aliyuncs.com # oss对外服务的访问域名 @@ -75,4 +63,10 @@ minio: endpoint: http://192.168.6.132:9090 #MinIO服务所在地址 bucketName: mall #存储桶名称 accessKey: minioadmin #访问的key - secretKey: minioadmin #访问的秘钥 \ No newline at end of file + secretKey: minioadmin #访问的秘钥 +feign: + okhttp: + enabled: true +ribbon: + ConnectTimeout: 3000 #服务请求连接超时时间(毫秒) + ReadTimeout: 3000 #服务请求处理超时时间(毫秒) \ No newline at end of file diff --git a/mall-admin/src/main/resources/bootstrap-dev.yml b/mall-admin/src/main/resources/bootstrap-dev.yml index d35a60c..365fbba 100644 --- a/mall-admin/src/main/resources/bootstrap-dev.yml +++ b/mall-admin/src/main/resources/bootstrap-dev.yml @@ -1,13 +1,8 @@ spring: cloud: - config: - profile: dev #启用环境名称 - label: master #分支名称 - name: admin #配置文件名称 + nacos: discovery: - enabled: true - service-id: mall-config -eureka: - client: - service-url: - defaultZone: http://localhost:8001/eureka/ \ No newline at end of file + server-addr: http://localhost:8848 + config: + server-addr: http://localhost:8848 + file-extension: yaml \ No newline at end of file diff --git a/mall-admin/src/main/resources/bootstrap-prod.yml b/mall-admin/src/main/resources/bootstrap-prod.yml index 14e897e..fc71e7a 100644 --- a/mall-admin/src/main/resources/bootstrap-prod.yml +++ b/mall-admin/src/main/resources/bootstrap-prod.yml @@ -1,15 +1,8 @@ spring: cloud: - config: - profile: prod #启用环境名称 - label: master #分支名称 - name: admin #配置文件名称 + nacos: discovery: - enabled: true - service-id: mall-config -eureka: - client: - service-url: - defaultZone: http://mall-registry:8001/eureka/ - instance: - prefer-ip-address: true \ No newline at end of file + server-addr: http://nacos-registry:8848 + config: + server-addr: http://nacos-registry:8848 + file-extension: yaml \ No newline at end of file diff --git a/mall-admin/src/main/resources/dao/UmsAdminRoleRelationDao.xml b/mall-admin/src/main/resources/dao/UmsAdminRoleRelationDao.xml index 6b1ec7d..badc580 100644 --- a/mall-admin/src/main/resources/dao/UmsAdminRoleRelationDao.xml +++ b/mall-admin/src/main/resources/dao/UmsAdminRoleRelationDao.xml @@ -71,4 +71,12 @@ GROUP BY ur.id + \ No newline at end of file diff --git a/mall-admin/src/main/resources/logback-spring.xml b/mall-admin/src/main/resources/logback-spring.xml deleted file mode 100644 index a86c84c..0000000 --- a/mall-admin/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - ${APP_NAME} - - - - ${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log - 30 - - - ${FILE_LOG_PATTERN} - - - - - localhost:4560 - - - - - - - - - diff --git a/mall-config/pom.xml b/mall-auth/pom.xml similarity index 54% rename from mall-config/pom.xml rename to mall-auth/pom.xml index b8db18b..cacc678 100644 --- a/mall-config/pom.xml +++ b/mall-auth/pom.xml @@ -1,13 +1,16 @@ - + 4.0.0 com.macro.mall - mall-config + mall-auth 1.0-SNAPSHOT - mall-config - mall-config project for mall + jar + + mall-auth + mall-auth project for mall com.macro.mall @@ -17,12 +20,46 @@ - org.springframework.cloud - spring-cloud-config-server + com.macro.mall + mall-common + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.springframework.boot + spring-boot-starter-web + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + org.springframework.boot + spring-boot-starter-security org.springframework.cloud - spring-cloud-starter-netflix-eureka-client + spring-cloud-starter-oauth2 + + + com.nimbusds + nimbus-jose-jwt + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + io.github.openfeign + feign-okhttp @@ -62,4 +99,4 @@ - + \ No newline at end of file diff --git a/mall-config/src/main/java/com/macro/mall/MallConfigApplication.java b/mall-auth/src/main/java/com/macro/mall/auth/MallAuthApplication.java similarity index 50% rename from mall-config/src/main/java/com/macro/mall/MallConfigApplication.java rename to mall-auth/src/main/java/com/macro/mall/auth/MallAuthApplication.java index 2c6c13d..8c6cda8 100644 --- a/mall-config/src/main/java/com/macro/mall/MallConfigApplication.java +++ b/mall-auth/src/main/java/com/macro/mall/auth/MallAuthApplication.java @@ -1,17 +1,17 @@ -package com.macro.mall; +package com.macro.mall.auth; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.cloud.config.server.EnableConfigServer; +import org.springframework.cloud.openfeign.EnableFeignClients; -@EnableConfigServer +@EnableFeignClients @EnableDiscoveryClient -@SpringBootApplication -public class MallConfigApplication { +@SpringBootApplication(scanBasePackages = "com.macro.mall") +public class MallAuthApplication { public static void main(String[] args) { - SpringApplication.run(MallConfigApplication.class, args); + SpringApplication.run(MallAuthApplication.class, args); } } diff --git a/mall-auth/src/main/java/com/macro/mall/auth/component/JwtTokenEnhancer.java b/mall-auth/src/main/java/com/macro/mall/auth/component/JwtTokenEnhancer.java new file mode 100644 index 0000000..c6b9e80 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/component/JwtTokenEnhancer.java @@ -0,0 +1,29 @@ +package com.macro.mall.auth.component; + +import com.macro.mall.auth.domain.SecurityUser; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.token.TokenEnhancer; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +/** + * JWT内容增强器 + * Created by macro on 2020/6/19. + */ +@Component +public class JwtTokenEnhancer implements TokenEnhancer { + @Override + public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { + SecurityUser securityUser = (SecurityUser) authentication.getPrincipal(); + Map info = new HashMap<>(); + //把用户ID设置到JWT中 + info.put("id", securityUser.getId()); + info.put("client_id",securityUser.getClientId()); + ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info); + return accessToken; + } +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/config/Oauth2ServerConfig.java b/mall-auth/src/main/java/com/macro/mall/auth/config/Oauth2ServerConfig.java new file mode 100644 index 0000000..ae90217 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/config/Oauth2ServerConfig.java @@ -0,0 +1,89 @@ +package com.macro.mall.auth.config; + +import com.macro.mall.auth.component.JwtTokenEnhancer; +import com.macro.mall.auth.service.impl.UserServiceImpl; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; +import org.springframework.security.oauth2.provider.token.TokenEnhancer; +import org.springframework.security.oauth2.provider.token.TokenEnhancerChain; +import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; +import org.springframework.security.rsa.crypto.KeyStoreKeyFactory; + +import java.security.KeyPair; +import java.util.ArrayList; +import java.util.List; + +/** + * 认证服务器配置 + * Created by macro on 2020/6/19. + */ +@AllArgsConstructor +@Configuration +@EnableAuthorizationServer +public class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter { + + private final PasswordEncoder passwordEncoder; + private final UserServiceImpl userDetailsService; + private final AuthenticationManager authenticationManager; + private final JwtTokenEnhancer jwtTokenEnhancer; + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + clients.inMemory() + .withClient("admin-app") + .secret(passwordEncoder.encode("123456")) + .scopes("all") + .authorizedGrantTypes("password", "refresh_token") + .accessTokenValiditySeconds(3600) + .refreshTokenValiditySeconds(86400) + .and() + .withClient("portal-app") + .secret(passwordEncoder.encode("123456")) + .scopes("all") + .authorizedGrantTypes("password", "refresh_token") + .accessTokenValiditySeconds(3600) + .refreshTokenValiditySeconds(86400); + } + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + TokenEnhancerChain enhancerChain = new TokenEnhancerChain(); + List delegates = new ArrayList<>(); + delegates.add(jwtTokenEnhancer); + delegates.add(accessTokenConverter()); + enhancerChain.setTokenEnhancers(delegates); //配置JWT的内容增强器 + endpoints.authenticationManager(authenticationManager) + .userDetailsService(userDetailsService) //配置加载用户信息的服务 + .accessTokenConverter(accessTokenConverter()) + .tokenEnhancer(enhancerChain); + } + + @Override + public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { + security.allowFormAuthenticationForClients(); + } + + @Bean + public JwtAccessTokenConverter accessTokenConverter() { + JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); + jwtAccessTokenConverter.setKeyPair(keyPair()); + return jwtAccessTokenConverter; + } + + @Bean + public KeyPair keyPair() { + //从classpath下的证书中获取秘钥对 + KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "123456".toCharArray()); + return keyStoreKeyFactory.getKeyPair("jwt", "123456".toCharArray()); + } + +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/config/SwaggerConfig.java b/mall-auth/src/main/java/com/macro/mall/auth/config/SwaggerConfig.java new file mode 100644 index 0000000..4de6626 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/config/SwaggerConfig.java @@ -0,0 +1,27 @@ +package com.macro.mall.auth.config; + +import com.macro.mall.common.config.BaseSwaggerConfig; +import com.macro.mall.common.domain.SwaggerProperties; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +/** + * Swagger API文档相关配置 + * Created by macro on 2018/4/26. + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig extends BaseSwaggerConfig { + + @Override + public SwaggerProperties swaggerProperties() { + return SwaggerProperties.builder() + .apiBasePackage("com.macro.mall.auth.controller") + .title("mall认证中心") + .description("mall认证中心相关接口文档") + .contactName("macro") + .version("1.0") + .enableSecurity(true) + .build(); + } +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/config/WebSecurityConfig.java b/mall-auth/src/main/java/com/macro/mall/auth/config/WebSecurityConfig.java new file mode 100644 index 0000000..537f831 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/config/WebSecurityConfig.java @@ -0,0 +1,41 @@ +package com.macro.mall.auth.config; + +import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +/** + * SpringSecurity配置 + * Created by macro on 2020/6/19. + */ +@Configuration +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll() + .antMatchers("/rsa/publicKey").permitAll() + .antMatchers("/v2/api-docs").permitAll() + .anyRequest().authenticated(); + } + + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/constant/MessageConstant.java b/mall-auth/src/main/java/com/macro/mall/auth/constant/MessageConstant.java new file mode 100644 index 0000000..a2f9738 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/constant/MessageConstant.java @@ -0,0 +1,23 @@ +package com.macro.mall.auth.constant; + +/** + * 消息常量 + * Created by macro on 2020/6/19. + */ +public class MessageConstant { + + public static final String LOGIN_SUCCESS = "登录成功!"; + + public static final String USERNAME_PASSWORD_ERROR = "用户名或密码错误!"; + + public static final String CREDENTIALS_EXPIRED = "该账户的登录凭证已过期,请重新登录!"; + + public static final String ACCOUNT_DISABLED = "该账户已被禁用,请联系管理员!"; + + public static final String ACCOUNT_LOCKED = "该账号已被锁定,请联系管理员!"; + + public static final String ACCOUNT_EXPIRED = "该账号已过期,请联系管理员!"; + + public static final String PERMISSION_DENIED = "没有访问权限,请联系管理员!"; + +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/controller/AuthController.java b/mall-auth/src/main/java/com/macro/mall/auth/controller/AuthController.java new file mode 100644 index 0000000..3aa8865 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/controller/AuthController.java @@ -0,0 +1,55 @@ +package com.macro.mall.auth.controller; + +import com.macro.mall.auth.domain.Oauth2TokenDto; +import com.macro.mall.common.api.CommonResult; +import com.macro.mall.common.constant.AuthConstant; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + +import java.security.Principal; +import java.util.Map; + +/** + * 自定义Oauth2获取令牌接口 + * Created by macro on 2020/7/17. + */ +@RestController +@Api(tags = "AuthController", description = "认证中心登录认证") +@RequestMapping("/oauth") +public class AuthController { + + @Autowired + private TokenEndpoint tokenEndpoint; + + @ApiOperation("Oauth2获取token") + @ApiImplicitParams({ + @ApiImplicitParam(name = "grant_type", value = "授权模式", required = true), + @ApiImplicitParam(name = "client_id", value = "Oauth2客户端ID", required = true), + @ApiImplicitParam(name = "client_secret", value = "Oauth2客户端秘钥", required = true), + @ApiImplicitParam(name = "refresh_token", value = "刷新token"), + @ApiImplicitParam(name = "username", value = "登录用户名"), + @ApiImplicitParam(name = "password", value = "登录密码") + }) + @RequestMapping(value = "/token", method = RequestMethod.POST) + public CommonResult postAccessToken(@ApiIgnore Principal principal, @ApiIgnore @RequestParam Map parameters) throws HttpRequestMethodNotSupportedException { + OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody(); + Oauth2TokenDto oauth2TokenDto = Oauth2TokenDto.builder() + .token(oAuth2AccessToken.getValue()) + .refreshToken(oAuth2AccessToken.getRefreshToken().getValue()) + .expiresIn(oAuth2AccessToken.getExpiresIn()) + .tokenHead(AuthConstant.JWT_TOKEN_PREFIX).build(); + + return CommonResult.success(oauth2TokenDto); + } +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/controller/KeyPairController.java b/mall-auth/src/main/java/com/macro/mall/auth/controller/KeyPairController.java new file mode 100644 index 0000000..c21c1a2 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/controller/KeyPairController.java @@ -0,0 +1,30 @@ +package com.macro.mall.auth.controller; + +import com.nimbusds.jose.jwk.JWKSet; +import com.nimbusds.jose.jwk.RSAKey; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.security.KeyPair; +import java.security.interfaces.RSAPublicKey; +import java.util.Map; + +/** + * 获取RSA公钥接口 + * Created by macro on 2020/6/19. + */ +@RestController +public class KeyPairController { + + @Autowired + private KeyPair keyPair; + + @GetMapping("/rsa/publicKey") + public Map getKey() { + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + RSAKey key = new RSAKey.Builder(publicKey).build(); + return new JWKSet(key).toJSONObject(); + } + +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/domain/Oauth2TokenDto.java b/mall-auth/src/main/java/com/macro/mall/auth/domain/Oauth2TokenDto.java new file mode 100644 index 0000000..8464b15 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/domain/Oauth2TokenDto.java @@ -0,0 +1,24 @@ +package com.macro.mall.auth.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * Oauth2获取Token返回信息封装 + * Created by macro on 2020/7/17. + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Builder +public class Oauth2TokenDto { + @ApiModelProperty("访问令牌") + private String token; + @ApiModelProperty("刷令牌") + private String refreshToken; + @ApiModelProperty("访问令牌头前缀") + private String tokenHead; + @ApiModelProperty("有效时间(秒)") + private int expiresIn; +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/domain/SecurityUser.java b/mall-auth/src/main/java/com/macro/mall/auth/domain/SecurityUser.java new file mode 100644 index 0000000..c07017e --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/domain/SecurityUser.java @@ -0,0 +1,95 @@ +package com.macro.mall.auth.domain; + +import com.macro.mall.common.domain.UserDto; +import lombok.Data; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * 登录用户信息 + * Created by macro on 2020/6/19. + */ +@Data +public class SecurityUser implements UserDetails { + + /** + * ID + */ + private Long id; + /** + * 用户名 + */ + private String username; + /** + * 用户密码 + */ + private String password; + /** + * 用户状态 + */ + private Boolean enabled; + /** + * 登录客户端ID + */ + private String clientId; + /** + * 权限数据 + */ + private Collection authorities; + + public SecurityUser() { + + } + + public SecurityUser(UserDto userDto) { + this.setId(userDto.getId()); + this.setUsername(userDto.getUsername()); + this.setPassword(userDto.getPassword()); + this.setEnabled(userDto.getStatus() == 1); + this.setClientId(userDto.getClientId()); + if (userDto.getRoles() != null) { + authorities = new ArrayList<>(); + userDto.getRoles().forEach(item -> authorities.add(new SimpleGrantedAuthority(item))); + } + } + + @Override + public Collection getAuthorities() { + return this.authorities; + } + + @Override + public String getPassword() { + return this.password; + } + + @Override + public String getUsername() { + return this.username; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return this.enabled; + } + +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/exception/Oauth2ExceptionHandler.java b/mall-auth/src/main/java/com/macro/mall/auth/exception/Oauth2ExceptionHandler.java new file mode 100644 index 0000000..f237a4d --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/exception/Oauth2ExceptionHandler.java @@ -0,0 +1,20 @@ +package com.macro.mall.auth.exception; + +import com.macro.mall.common.api.CommonResult; +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * 全局处理Oauth2抛出的异常 + * Created by macro on 2020/7/17. + */ +@ControllerAdvice +public class Oauth2ExceptionHandler { + @ResponseBody + @ExceptionHandler(value = OAuth2Exception.class) + public CommonResult handleOauth2(OAuth2Exception e) { + return CommonResult.failed(e.getMessage()); + } +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/service/UmsAdminService.java b/mall-auth/src/main/java/com/macro/mall/auth/service/UmsAdminService.java new file mode 100644 index 0000000..e386fb7 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/service/UmsAdminService.java @@ -0,0 +1,16 @@ +package com.macro.mall.auth.service; + +import com.macro.mall.common.domain.UserDto; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * Created by macro on 2019/10/18. + */ +@FeignClient("mall-admin") +public interface UmsAdminService { + + @GetMapping("/admin/loadByUsername") + UserDto loadUserByUsername(@RequestParam String username); +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/service/UmsMemberService.java b/mall-auth/src/main/java/com/macro/mall/auth/service/UmsMemberService.java new file mode 100644 index 0000000..25fb689 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/service/UmsMemberService.java @@ -0,0 +1,15 @@ +package com.macro.mall.auth.service; + +import com.macro.mall.common.domain.UserDto; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * Created by macro on 2020/7/16. + */ +@FeignClient("mall-portal") +public interface UmsMemberService { + @GetMapping("/sso/loadByUsername") + UserDto loadUserByUsername(@RequestParam String username); +} diff --git a/mall-auth/src/main/java/com/macro/mall/auth/service/impl/UserServiceImpl.java b/mall-auth/src/main/java/com/macro/mall/auth/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..4563988 --- /dev/null +++ b/mall-auth/src/main/java/com/macro/mall/auth/service/impl/UserServiceImpl.java @@ -0,0 +1,61 @@ +package com.macro.mall.auth.service.impl; + +import com.macro.mall.auth.domain.SecurityUser; +import com.macro.mall.auth.constant.MessageConstant; +import com.macro.mall.auth.service.UmsAdminService; +import com.macro.mall.auth.service.UmsMemberService; +import com.macro.mall.common.constant.AuthConstant; +import com.macro.mall.common.domain.UserDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AccountExpiredException; +import org.springframework.security.authentication.CredentialsExpiredException; +import org.springframework.security.authentication.DisabledException; +import org.springframework.security.authentication.LockedException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; + +/** + * 用户管理业务类 + * Created by macro on 2020/6/19. + */ +@Service +public class UserServiceImpl implements UserDetailsService { + + @Autowired + private UmsAdminService adminService; + @Autowired + private UmsMemberService memberService; + @Autowired + private HttpServletRequest request; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + String clientId = request.getParameter("client_id"); + UserDto userDto; + if(AuthConstant.ADMIN_CLIENT_ID.equals(clientId)){ + userDto = adminService.loadUserByUsername(username); + }else{ + userDto = memberService.loadUserByUsername(username); + } + if (userDto==null) { + throw new UsernameNotFoundException(MessageConstant.USERNAME_PASSWORD_ERROR); + } + userDto.setClientId(clientId); + SecurityUser securityUser = new SecurityUser(userDto); + if (!securityUser.isEnabled()) { + throw new DisabledException(MessageConstant.ACCOUNT_DISABLED); + } else if (!securityUser.isAccountNonLocked()) { + throw new LockedException(MessageConstant.ACCOUNT_LOCKED); + } else if (!securityUser.isAccountNonExpired()) { + throw new AccountExpiredException(MessageConstant.ACCOUNT_EXPIRED); + } else if (!securityUser.isCredentialsNonExpired()) { + throw new CredentialsExpiredException(MessageConstant.CREDENTIALS_EXPIRED); + } + return securityUser; + } + +} diff --git a/mall-auth/src/main/resources/application.yml b/mall-auth/src/main/resources/application.yml new file mode 100644 index 0000000..b66c00d --- /dev/null +++ b/mall-auth/src/main/resources/application.yml @@ -0,0 +1,13 @@ +server: + port: 8401 +management: + endpoints: + web: + exposure: + include: "*" +feign: + okhttp: + enabled: true +ribbon: + ConnectTimeout: 3000 #服务请求连接超时时间(毫秒) + ReadTimeout: 3000 #服务请求处理超时时间(毫秒) diff --git a/mall-auth/src/main/resources/bootstrap-dev.yml b/mall-auth/src/main/resources/bootstrap-dev.yml new file mode 100644 index 0000000..d9d496a --- /dev/null +++ b/mall-auth/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,11 @@ +spring: + cloud: + nacos: + discovery: + server-addr: http://localhost:8848 + config: + server-addr: http://localhost:8848 + file-extension: yaml +logging: + level: + root: debug \ No newline at end of file diff --git a/mall-auth/src/main/resources/bootstrap-prod.yml b/mall-auth/src/main/resources/bootstrap-prod.yml new file mode 100644 index 0000000..15564b9 --- /dev/null +++ b/mall-auth/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,11 @@ +spring: + cloud: + nacos: + discovery: + server-addr: http://nacos-registry:8848 + config: + server-addr: http://nacos-registry:8848 + file-extension: yaml +logging: + level: + root: info \ No newline at end of file diff --git a/mall-auth/src/main/resources/bootstrap.yml b/mall-auth/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..75e96d9 --- /dev/null +++ b/mall-auth/src/main/resources/bootstrap.yml @@ -0,0 +1,5 @@ +spring: + profiles: + active: dev + application: + name: mall-auth \ No newline at end of file diff --git a/mall-auth/src/main/resources/jwt.jks b/mall-auth/src/main/resources/jwt.jks new file mode 100644 index 0000000..af359ea Binary files /dev/null and b/mall-auth/src/main/resources/jwt.jks differ diff --git a/mall-common/pom.xml b/mall-common/pom.xml index 4ffe1c4..ee34b46 100644 --- a/mall-common/pom.xml +++ b/mall-common/pom.xml @@ -20,35 +20,27 @@ com.github.pagehelper - pagehelper-spring-boot-starter + pagehelper org.springframework.boot spring-boot-starter-web - com.alibaba - druid-spring-boot-starter - - - io.springfox - springfox-swagger2 - - - io.springfox - springfox-swagger-ui + org.springframework.boot + spring-boot-starter-data-redis org.springframework.data spring-data-commons - cn.hutool - hutool-all + com.github.xiaoymin + knife4j-micro-spring-boot-starter - org.projectlombok - lombok + net.logstash.logback + logstash-logback-encoder diff --git a/mall-common/src/main/java/com/macro/mall/common/annotation/CacheException.java b/mall-common/src/main/java/com/macro/mall/common/annotation/CacheException.java new file mode 100644 index 0000000..fc37d5c --- /dev/null +++ b/mall-common/src/main/java/com/macro/mall/common/annotation/CacheException.java @@ -0,0 +1,12 @@ +package com.macro.mall.common.annotation; + +import java.lang.annotation.*; + +/** + * 自定义注解,有该注解的缓存方法会抛出异常 + */ +@Documented +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface CacheException { +} diff --git a/mall-common/src/main/java/com/macro/mall/common/config/BaseRedisConfig.java b/mall-common/src/main/java/com/macro/mall/common/config/BaseRedisConfig.java new file mode 100644 index 0000000..27a137d --- /dev/null +++ b/mall-common/src/main/java/com/macro/mall/common/config/BaseRedisConfig.java @@ -0,0 +1,69 @@ +package com.macro.mall.common.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.macro.mall.common.service.RedisService; +import com.macro.mall.common.service.impl.RedisServiceImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.time.Duration; + +/** + * Redis基础配置 + * Created by macro on 2020/6/19. + */ +public class BaseRedisConfig { + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { + RedisSerializer serializer = redisSerializer(); + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(redisConnectionFactory); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(serializer); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashValueSerializer(serializer); + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } + + @Bean + public RedisSerializer redisSerializer() { + //创建JSON序列化器 + Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + //必须设置,否则无法将JSON转化为对象,会转化成Map类型 + objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL); + serializer.setObjectMapper(objectMapper); + return serializer; + } + + @Bean + public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) { + RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); + //设置Redis缓存有效期为1天 + RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() + .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer())).entryTtl(Duration.ofDays(1)); + return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration); + } + + + @Bean + public RedisService redisService(){ + return new RedisServiceImpl(); + } + +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/config/Swagger2Config.java b/mall-common/src/main/java/com/macro/mall/common/config/BaseSwaggerConfig.java similarity index 59% rename from mall-portal/src/main/java/com/macro/mall/portal/config/Swagger2Config.java rename to mall-common/src/main/java/com/macro/mall/common/config/BaseSwaggerConfig.java index 0a62e84..011af3e 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/config/Swagger2Config.java +++ b/mall-common/src/main/java/com/macro/mall/common/config/BaseSwaggerConfig.java @@ -1,47 +1,45 @@ -package com.macro.mall.portal.config; +package com.macro.mall.common.config; +import com.macro.mall.common.domain.SwaggerProperties; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.ApiKey; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.SecurityReference; +import springfox.documentation.service.*; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.util.ArrayList; import java.util.List; /** - * Swagger2API文档的配置 - * Created by macro on 2018/4/26. + * Swagger基础配置 + * Created by macro on 2020/7/16. */ -@Configuration -@EnableSwagger2 -public class Swagger2Config { +public abstract class BaseSwaggerConfig { + @Bean public Docket createRestApi() { - return new Docket(DocumentationType.SWAGGER_2) - .apiInfo(apiInfo()) + SwaggerProperties swaggerProperties = swaggerProperties(); + Docket docket = new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo(swaggerProperties)) .select() - .apis(RequestHandlerSelectors.basePackage("com.macro.mall.portal.controller")) + .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getApiBasePackage())) .paths(PathSelectors.any()) - .build() - .securitySchemes(securitySchemes()) - .securityContexts(securityContexts()); + .build(); + if (swaggerProperties.isEnableSecurity()) { + docket.securitySchemes(securitySchemes()).securityContexts(securityContexts()); + } + return docket; } - private ApiInfo apiInfo() { + private ApiInfo apiInfo(SwaggerProperties swaggerProperties) { return new ApiInfoBuilder() - .title("mall前台系统") - .description("mall前台模块") - .contact("macro") - .version("1.0") + .title(swaggerProperties.getTitle()) + .description(swaggerProperties.getDescription()) + .contact(new Contact(swaggerProperties.getContactName(), swaggerProperties.getContactUrl(), swaggerProperties.getContactEmail())) + .version(swaggerProperties.getVersion()) .build(); } @@ -56,10 +54,7 @@ public class Swagger2Config { private List securityContexts() { //设置需要登录认证的路径 List result = new ArrayList<>(); - result.add(getContextByPath("/member/.*")); - result.add(getContextByPath("/cart/.*")); - result.add(getContextByPath("/order/.*")); - result.add(getContextByPath("/returnApply/.*")); + result.add(getContextByPath("/*/.*")); return result; } @@ -78,4 +73,9 @@ public class Swagger2Config { result.add(new SecurityReference("Authorization", authorizationScopes)); return result; } + + /** + * 自定义Swagger配置 + */ + public abstract SwaggerProperties swaggerProperties(); } diff --git a/mall-common/src/main/java/com/macro/mall/common/constant/AuthConstant.java b/mall-common/src/main/java/com/macro/mall/common/constant/AuthConstant.java new file mode 100644 index 0000000..34ed033 --- /dev/null +++ b/mall-common/src/main/java/com/macro/mall/common/constant/AuthConstant.java @@ -0,0 +1,54 @@ +package com.macro.mall.common.constant; + +/** + * 权限相关常量定义 + * Created by macro on 2020/6/19. + */ +public interface AuthConstant { + + /** + * JWT存储权限前缀 + */ + String AUTHORITY_PREFIX = "ROLE_"; + + /** + * JWT存储权限属性 + */ + String AUTHORITY_CLAIM_NAME = "authorities"; + + /** + * 后台管理client_id + */ + String ADMIN_CLIENT_ID = "admin-app"; + + /** + * 前台商城client_id + */ + String PORTAL_CLIENT_ID = "portal-app"; + + /** + * 后台管理接口路径匹配 + */ + String ADMIN_URL_PATTERN = "/mall-admin/**"; + + /** + * Redis缓存权限规则key + */ + String RESOURCE_ROLES_MAP_KEY = "auth:resourceRolesMap"; + + /** + * 认证信息Http请求头 + */ + String JWT_TOKEN_HEADER = "Authorization"; + + /** + * JWT令牌前缀 + */ + String JWT_TOKEN_PREFIX = "Bearer "; + + /** + * 用户信息Http请求头 + */ + String USER_TOKEN_HEADER = "user"; + +} diff --git a/mall-common/src/main/java/com/macro/mall/common/domain/SwaggerProperties.java b/mall-common/src/main/java/com/macro/mall/common/domain/SwaggerProperties.java new file mode 100644 index 0000000..4043805 --- /dev/null +++ b/mall-common/src/main/java/com/macro/mall/common/domain/SwaggerProperties.java @@ -0,0 +1,47 @@ +package com.macro.mall.common.domain; + +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * Swagger自定义配置 + * Created by macro on 2020/7/16. + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Builder +public class SwaggerProperties { + /** + * API文档生成基础路径 + */ + private String apiBasePackage; + /** + * 是否要启用登录认证 + */ + private boolean enableSecurity; + /** + * 文档标题 + */ + private String title; + /** + * 文档描述 + */ + private String description; + /** + * 文档版本 + */ + private String version; + /** + * 文档联系人姓名 + */ + private String contactName; + /** + * 文档联系人网址 + */ + private String contactUrl; + /** + * 文档联系人邮箱 + */ + private String contactEmail; +} diff --git a/mall-common/src/main/java/com/macro/mall/common/domain/UserDto.java b/mall-common/src/main/java/com/macro/mall/common/domain/UserDto.java new file mode 100644 index 0000000..ce2a718 --- /dev/null +++ b/mall-common/src/main/java/com/macro/mall/common/domain/UserDto.java @@ -0,0 +1,24 @@ +package com.macro.mall.common.domain; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 登录用户信息 + * Created by macro on 2020/6/19. + */ +@Data +@EqualsAndHashCode(callSuper = false) +@NoArgsConstructor +public class UserDto { + private Long id; + private String username; + private String password; + private Integer status; + private String clientId; + private List roles; + +} diff --git a/mall-common/src/main/java/com/macro/mall/common/domain/WebLog.java b/mall-common/src/main/java/com/macro/mall/common/domain/WebLog.java new file mode 100644 index 0000000..e4faf97 --- /dev/null +++ b/mall-common/src/main/java/com/macro/mall/common/domain/WebLog.java @@ -0,0 +1,68 @@ +package com.macro.mall.common.domain; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * Controller层的日志封装类 + * Created by macro on 2018/4/26. + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WebLog { + /** + * 操作描述 + */ + private String description; + + /** + * 操作用户 + */ + private String username; + + /** + * 操作时间 + */ + private Long startTime; + + /** + * 消耗时间 + */ + private Integer spendTime; + + /** + * 根路径 + */ + private String basePath; + + /** + * URI + */ + private String uri; + + /** + * URL + */ + private String url; + + /** + * 请求类型 + */ + private String method; + + /** + * IP地址 + */ + private String ip; + + /** + * 请求参数 + */ + private Object parameter; + + /** + * 返回结果 + */ + private Object result; + +} diff --git a/mall-admin/src/main/java/com/macro/mall/component/WebLogAspect.java b/mall-common/src/main/java/com/macro/mall/common/log/WebLogAspect.java similarity index 97% rename from mall-admin/src/main/java/com/macro/mall/component/WebLogAspect.java rename to mall-common/src/main/java/com/macro/mall/common/log/WebLogAspect.java index 6e5bdf8..fb99c70 100644 --- a/mall-admin/src/main/java/com/macro/mall/component/WebLogAspect.java +++ b/mall-common/src/main/java/com/macro/mall/common/log/WebLogAspect.java @@ -1,10 +1,9 @@ -package com.macro.mall.component; +package com.macro.mall.common.log; import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.URLUtil; -import cn.hutool.json.JSON; import cn.hutool.json.JSONUtil; -import com.macro.mall.bo.WebLog; +import com.macro.mall.common.domain.WebLog; import io.swagger.annotations.ApiOperation; import net.logstash.logback.marker.Markers; import org.aspectj.lang.JoinPoint; @@ -40,7 +39,7 @@ import java.util.Map; public class WebLogAspect { private static final Logger LOGGER = LoggerFactory.getLogger(WebLogAspect.class); - @Pointcut("execution(public * com.macro.mall.controller.*.*(..))") + @Pointcut("execution(public * com.macro.mall.controller.*.*(..))||execution(public * com.macro.mall.*.controller.*.*(..))") public void webLog() { } diff --git a/mall-common/src/main/java/com/macro/mall/common/service/RedisService.java b/mall-common/src/main/java/com/macro/mall/common/service/RedisService.java new file mode 100644 index 0000000..9f2de5e --- /dev/null +++ b/mall-common/src/main/java/com/macro/mall/common/service/RedisService.java @@ -0,0 +1,182 @@ +package com.macro.mall.common.service; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * redis操作Service + * Created by macro on 2020/3/3. + */ +public interface RedisService { + + /** + * 保存属性 + */ + void set(String key, Object value, long time); + + /** + * 保存属性 + */ + void set(String key, Object value); + + /** + * 获取属性 + */ + Object get(String key); + + /** + * 删除属性 + */ + Boolean del(String key); + + /** + * 批量删除属性 + */ + Long del(List keys); + + /** + * 设置过期时间 + */ + Boolean expire(String key, long time); + + /** + * 获取过期时间 + */ + Long getExpire(String key); + + /** + * 判断是否有该属性 + */ + Boolean hasKey(String key); + + /** + * 按delta递增 + */ + Long incr(String key, long delta); + + /** + * 按delta递减 + */ + Long decr(String key, long delta); + + /** + * 获取Hash结构中的属性 + */ + Object hGet(String key, String hashKey); + + /** + * 向Hash结构中放入一个属性 + */ + Boolean hSet(String key, String hashKey, Object value, long time); + + /** + * 向Hash结构中放入一个属性 + */ + void hSet(String key, String hashKey, Object value); + + /** + * 直接获取整个Hash结构 + */ + Map hGetAll(String key); + + /** + * 直接设置整个Hash结构 + */ + Boolean hSetAll(String key, Map map, long time); + + /** + * 直接设置整个Hash结构 + */ + void hSetAll(String key, Map map); + + /** + * 删除Hash结构中的属性 + */ + void hDel(String key, Object... hashKey); + + /** + * 判断Hash结构中是否有该属性 + */ + Boolean hHasKey(String key, String hashKey); + + /** + * Hash结构中属性递增 + */ + Long hIncr(String key, String hashKey, Long delta); + + /** + * Hash结构中属性递减 + */ + Long hDecr(String key, String hashKey, Long delta); + + /** + * 获取Set结构 + */ + Set sMembers(String key); + + /** + * 向Set结构中添加属性 + */ + Long sAdd(String key, Object... values); + + /** + * 向Set结构中添加属性 + */ + Long sAdd(String key, long time, Object... values); + + /** + * 是否为Set中的属性 + */ + Boolean sIsMember(String key, Object value); + + /** + * 获取Set结构的长度 + */ + Long sSize(String key); + + /** + * 删除Set结构中的属性 + */ + Long sRemove(String key, Object... values); + + /** + * 获取List结构中的属性 + */ + List lRange(String key, long start, long end); + + /** + * 获取List结构的长度 + */ + Long lSize(String key); + + /** + * 根据索引获取List中的属性 + */ + Object lIndex(String key, long index); + + /** + * 向List结构中添加属性 + */ + Long lPush(String key, Object value); + + /** + * 向List结构中添加属性 + */ + Long lPush(String key, Object value, long time); + + /** + * 向List结构中批量添加属性 + */ + Long lPushAll(String key, Object... values); + + /** + * 向List结构中批量添加属性 + */ + Long lPushAll(String key, Long time, Object... values); + + /** + * 从List结构中移除属性 + */ + Long lRemove(String key, long count, Object value); +} \ No newline at end of file diff --git a/mall-common/src/main/java/com/macro/mall/common/service/impl/RedisServiceImpl.java b/mall-common/src/main/java/com/macro/mall/common/service/impl/RedisServiceImpl.java new file mode 100644 index 0000000..8720014 --- /dev/null +++ b/mall-common/src/main/java/com/macro/mall/common/service/impl/RedisServiceImpl.java @@ -0,0 +1,198 @@ +package com.macro.mall.common.service.impl; + +import com.macro.mall.common.service.RedisService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * redis操作实现类 + * Created by macro on 2020/3/3. + */ +public class RedisServiceImpl implements RedisService { + @Autowired + private RedisTemplate redisTemplate; + + @Override + public void set(String key, Object value, long time) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } + + @Override + public void set(String key, Object value) { + redisTemplate.opsForValue().set(key, value); + } + + @Override + public Object get(String key) { + return redisTemplate.opsForValue().get(key); + } + + @Override + public Boolean del(String key) { + return redisTemplate.delete(key); + } + + @Override + public Long del(List keys) { + return redisTemplate.delete(keys); + } + + @Override + public Boolean expire(String key, long time) { + return redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + + @Override + public Long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + @Override + public Boolean hasKey(String key) { + return redisTemplate.hasKey(key); + } + + @Override + public Long incr(String key, long delta) { + return redisTemplate.opsForValue().increment(key, delta); + } + + @Override + public Long decr(String key, long delta) { + return redisTemplate.opsForValue().increment(key, -delta); + } + + @Override + public Object hGet(String key, String hashKey) { + return redisTemplate.opsForHash().get(key, hashKey); + } + + @Override + public Boolean hSet(String key, String hashKey, Object value, long time) { + redisTemplate.opsForHash().put(key, hashKey, value); + return expire(key, time); + } + + @Override + public void hSet(String key, String hashKey, Object value) { + redisTemplate.opsForHash().put(key, hashKey, value); + } + + @Override + public Map hGetAll(String key) { + return redisTemplate.opsForHash().entries(key); + } + + @Override + public Boolean hSetAll(String key, Map map, long time) { + redisTemplate.opsForHash().putAll(key, map); + return expire(key, time); + } + + @Override + public void hSetAll(String key, Map map) { + redisTemplate.opsForHash().putAll(key, map); + } + + @Override + public void hDel(String key, Object... hashKey) { + redisTemplate.opsForHash().delete(key, hashKey); + } + + @Override + public Boolean hHasKey(String key, String hashKey) { + return redisTemplate.opsForHash().hasKey(key, hashKey); + } + + @Override + public Long hIncr(String key, String hashKey, Long delta) { + return redisTemplate.opsForHash().increment(key, hashKey, delta); + } + + @Override + public Long hDecr(String key, String hashKey, Long delta) { + return redisTemplate.opsForHash().increment(key, hashKey, -delta); + } + + @Override + public Set sMembers(String key) { + return redisTemplate.opsForSet().members(key); + } + + @Override + public Long sAdd(String key, Object... values) { + return redisTemplate.opsForSet().add(key, values); + } + + @Override + public Long sAdd(String key, long time, Object... values) { + Long count = redisTemplate.opsForSet().add(key, values); + expire(key, time); + return count; + } + + @Override + public Boolean sIsMember(String key, Object value) { + return redisTemplate.opsForSet().isMember(key, value); + } + + @Override + public Long sSize(String key) { + return redisTemplate.opsForSet().size(key); + } + + @Override + public Long sRemove(String key, Object... values) { + return redisTemplate.opsForSet().remove(key, values); + } + + @Override + public List lRange(String key, long start, long end) { + return redisTemplate.opsForList().range(key, start, end); + } + + @Override + public Long lSize(String key) { + return redisTemplate.opsForList().size(key); + } + + @Override + public Object lIndex(String key, long index) { + return redisTemplate.opsForList().index(key, index); + } + + @Override + public Long lPush(String key, Object value) { + return redisTemplate.opsForList().rightPush(key, value); + } + + @Override + public Long lPush(String key, Object value, long time) { + Long index = redisTemplate.opsForList().rightPush(key, value); + expire(key, time); + return index; + } + + @Override + public Long lPushAll(String key, Object... values) { + return redisTemplate.opsForList().rightPushAll(key, values); + } + + @Override + public Long lPushAll(String key, Long time, Object... values) { + Long count = redisTemplate.opsForList().rightPushAll(key, values); + expire(key, time); + return count; + } + + @Override + public Long lRemove(String key, long count, Object value) { + return redisTemplate.opsForList().remove(key, count, value); + } +} diff --git a/mall-common/src/main/resources/logback-spring.xml b/mall-common/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..51ef9da --- /dev/null +++ b/mall-common/src/main/resources/logback-spring.xml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + DEBUG + + + + ${FILE_LOG_PATTERN} + UTF-8 + + + + ${LOG_FILE_PATH}/debug/${APP_NAME}-%d{yyyy-MM-dd}-%i.log + + ${LOG_FILE_MAX_SIZE:-10MB} + + ${LOG_FILE_MAX_HISTORY:-30} + + + + + + + + ERROR + ACCEPT + DENY + + + + ${FILE_LOG_PATTERN} + UTF-8 + + + + ${LOG_FILE_PATH}/error/${APP_NAME}-%d{yyyy-MM-dd}-%i.log + + ${LOG_FILE_MAX_SIZE:-10MB} + + ${LOG_FILE_MAX_HISTORY:-30} + + + + + + + DEBUG + + ${LOG_STASH_HOST}:4560 + + + + Asia/Shanghai + + + + + { + "project": "mall-swarm", + "level": "%level", + "service": "${APP_NAME:-}", + "pid": "${PID:-}", + "thread": "%thread", + "class": "%logger", + "message": "%message", + "stack_trace": "%exception{20}" + } + + + + + + + + 5 minutes + + + + + + + + ERROR + ACCEPT + DENY + + ${LOG_STASH_HOST}:4561 + + + + Asia/Shanghai + + + + + { + "project": "mall-swarm", + "level": "%level", + "service": "${APP_NAME:-}", + "pid": "${PID:-}", + "thread": "%thread", + "class": "%logger", + "message": "%message", + "stack_trace": "%exception{20}" + } + + + + + + + + 5 minutes + + + + + + + ${LOG_STASH_HOST}:4562 + + + + Asia/Shanghai + + + + + { + "project": "mall-swarm", + "level": "%level", + "service": "${APP_NAME:-}", + "pid": "${PID:-}", + "thread": "%thread", + "class": "%logger", + "message": "%message", + "stack_trace": "%exception{20}" + } + + + + + + + + 5 minutes + + + + + + + ${LOG_STASH_HOST}:4563 + + + + Asia/Shanghai + + + + + { + "project": "mall-swarm", + "level": "%level", + "service": "${APP_NAME:-}", + "class": "%logger", + "message": "%message" + } + + + + + + + + 5 minutes + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mall-config/.gitignore b/mall-config/.gitignore deleted file mode 100644 index a2a3040..0000000 --- a/mall-config/.gitignore +++ /dev/null @@ -1,31 +0,0 @@ -HELP.md -target/ -!.mvn/wrapper/maven-wrapper.jar -!**/src/main/** -!**/src/test/** - -### 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/ - -### VS Code ### -.vscode/ diff --git a/mall-config/src/main/resources/application-dev.yml b/mall-config/src/main/resources/application-dev.yml deleted file mode 100644 index 5c884f5..0000000 --- a/mall-config/src/main/resources/application-dev.yml +++ /dev/null @@ -1,4 +0,0 @@ -eureka: - client: - service-url: - defaultZone: http://localhost:8001/eureka/ \ No newline at end of file diff --git a/mall-config/src/main/resources/application-native.yml b/mall-config/src/main/resources/application-native.yml deleted file mode 100644 index 5c884f5..0000000 --- a/mall-config/src/main/resources/application-native.yml +++ /dev/null @@ -1,4 +0,0 @@ -eureka: - client: - service-url: - defaultZone: http://localhost:8001/eureka/ \ No newline at end of file diff --git a/mall-config/src/main/resources/application-prod.yml b/mall-config/src/main/resources/application-prod.yml deleted file mode 100644 index 9b788df..0000000 --- a/mall-config/src/main/resources/application-prod.yml +++ /dev/null @@ -1,6 +0,0 @@ -eureka: - client: - service-url: - defaultZone: http://mall-registry:8001/eureka/ - instance: - prefer-ip-address: true \ No newline at end of file diff --git a/mall-config/src/main/resources/application.yml b/mall-config/src/main/resources/application.yml deleted file mode 100644 index 5b4c008..0000000 --- a/mall-config/src/main/resources/application.yml +++ /dev/null @@ -1,18 +0,0 @@ -server: - port: 8301 -spring: - application: - name: mall-config - profiles: - active: native #使用本地配置,要使用git存储改为git即可 - cloud: - config: - server: - native: #本地仓库存储 - search-locations: classpath:/config/{application} - git: #Git仓库存储 - uri: https://gitee.com/macrozheng/mall-config.git - username: macro - password: 123456 - clone-on-start: true - search-paths: '{application}' diff --git a/mall-config/src/test/java/com/macro/mall/MallConfigApplicationTests.java b/mall-config/src/test/java/com/macro/mall/MallConfigApplicationTests.java deleted file mode 100644 index ca7dcf2..0000000 --- a/mall-config/src/test/java/com/macro/mall/MallConfigApplicationTests.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.macro.mall; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class MallConfigApplicationTests { - - @Test - public void contextLoads() { - } - -} diff --git a/mall-demo/pom.xml b/mall-demo/pom.xml index 0b9ff53..3d570da 100644 --- a/mall-demo/pom.xml +++ b/mall-demo/pom.xml @@ -25,17 +25,25 @@ org.springframework.boot spring-boot-starter-web - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client - org.springframework.cloud spring-cloud-starter-openfeign - org.springframework.cloud - spring-cloud-starter-config + io.github.openfeign + feign-okhttp + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + jakarta.validation + jakarta.validation-api diff --git a/mall-demo/src/main/java/com/macro/mall/demo/config/Swagger2Config.java b/mall-demo/src/main/java/com/macro/mall/demo/config/Swagger2Config.java deleted file mode 100644 index 22b0fe4..0000000 --- a/mall-demo/src/main/java/com/macro/mall/demo/config/Swagger2Config.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.macro.mall.demo.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.ApiKey; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -import java.util.ArrayList; -import java.util.List; - -/** - * Swagger2API文档的配置 - */ -@Configuration -@EnableSwagger2 -public class Swagger2Config { - @Bean - public Docket createRestApi(){ - return new Docket(DocumentationType.SWAGGER_2) - .apiInfo(apiInfo()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.macro.mall.demo.controller")) - .paths(PathSelectors.any()) - .build() - .securitySchemes(securitySchemes()) - .securityContexts(securityContexts()); - } - - private ApiInfo apiInfo() { - return new ApiInfoBuilder() - .title("mall-demo系统") - .description("SpringCloud版本中的一些示例") - .contact("macro") - .version("1.0") - .build(); - } - - private List securitySchemes() { - //设置请求头信息 - List result = new ArrayList<>(); - ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header"); - result.add(apiKey); - return result; - } - - private List securityContexts() { - //设置需要登录认证的路径 - List result = new ArrayList<>(); - result.add(getContextByPath("/feign/admin/getBrandList")); - result.add(getContextByPath("/feign/portal/cartList")); - return result; - } - - private SecurityContext getContextByPath(String pathRegex){ - return SecurityContext.builder() - .securityReferences(defaultAuth()) - .forPaths(PathSelectors.regex(pathRegex)) - .build(); - } - - private List defaultAuth() { - List result = new ArrayList<>(); - AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); - AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; - authorizationScopes[0] = authorizationScope; - result.add(new SecurityReference("Authorization", authorizationScopes)); - return result; - } - -} diff --git a/mall-demo/src/main/java/com/macro/mall/demo/config/SwaggerConfig.java b/mall-demo/src/main/java/com/macro/mall/demo/config/SwaggerConfig.java new file mode 100644 index 0000000..f1159a2 --- /dev/null +++ b/mall-demo/src/main/java/com/macro/mall/demo/config/SwaggerConfig.java @@ -0,0 +1,42 @@ +package com.macro.mall.demo.config; + +import com.macro.mall.common.config.BaseSwaggerConfig; +import com.macro.mall.common.domain.SwaggerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.ArrayList; +import java.util.List; + +/** + * Swagger相关配置 + * Created by macro on 2019/4/8. + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig extends BaseSwaggerConfig { + + @Override + public SwaggerProperties swaggerProperties() { + return SwaggerProperties.builder() + .apiBasePackage("com.macro.mall.demo.controller") + .title("mall-demo系统") + .description("SpringCloud版本中的一些示例") + .contactName("macro") + .version("1.0") + .enableSecurity(true) + .build(); + } + +} diff --git a/mall-demo/src/main/java/com/macro/mall/demo/dto/UmsAdminLoginParam.java b/mall-demo/src/main/java/com/macro/mall/demo/dto/UmsAdminLoginParam.java index 98cd507..fbeb561 100644 --- a/mall-demo/src/main/java/com/macro/mall/demo/dto/UmsAdminLoginParam.java +++ b/mall-demo/src/main/java/com/macro/mall/demo/dto/UmsAdminLoginParam.java @@ -3,7 +3,6 @@ package com.macro.mall.demo.dto; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; -import org.hibernate.validator.constraints.NotEmpty; /** * 用户登录参数 diff --git a/mall-demo/src/main/resources/application.yml b/mall-demo/src/main/resources/application.yml index e31f536..a239517 100644 --- a/mall-demo/src/main/resources/application.yml +++ b/mall-demo/src/main/resources/application.yml @@ -17,3 +17,6 @@ management: #开启SpringBoot Admin的监控 endpoint: health: show-details: always +feign: + okhttp: + enabled: true diff --git a/mall-demo/src/main/resources/bootstrap-dev.yml b/mall-demo/src/main/resources/bootstrap-dev.yml index e36963e..365fbba 100644 --- a/mall-demo/src/main/resources/bootstrap-dev.yml +++ b/mall-demo/src/main/resources/bootstrap-dev.yml @@ -1,13 +1,8 @@ spring: cloud: - config: - profile: dev #启用环境名称 - label: master #分支名称 - name: demo #配置文件名称 + nacos: discovery: - enabled: true - service-id: mall-config -eureka: - client: - service-url: - defaultZone: http://localhost:8001/eureka/ \ No newline at end of file + server-addr: http://localhost:8848 + config: + server-addr: http://localhost:8848 + file-extension: yaml \ No newline at end of file diff --git a/mall-demo/src/main/resources/bootstrap-prod.yml b/mall-demo/src/main/resources/bootstrap-prod.yml index 77ba38c..fc71e7a 100644 --- a/mall-demo/src/main/resources/bootstrap-prod.yml +++ b/mall-demo/src/main/resources/bootstrap-prod.yml @@ -1,15 +1,8 @@ spring: cloud: - config: - profile: prod #启用环境名称 - label: master #分支名称 - name: demo #配置文件名称 + nacos: discovery: - enabled: true - service-id: mall-config -eureka: - client: - service-url: - defaultZone: http://mall-registry:8001/eureka/ - instance: - prefer-ip-address: true \ No newline at end of file + server-addr: http://nacos-registry:8848 + config: + server-addr: http://nacos-registry:8848 + file-extension: yaml \ No newline at end of file diff --git a/mall-gateway/pom.xml b/mall-gateway/pom.xml index fb3d61c..2dbea68 100644 --- a/mall-gateway/pom.xml +++ b/mall-gateway/pom.xml @@ -16,13 +16,55 @@ - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client + com.macro.mall + mall-common + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config org.springframework.cloud spring-cloud-starter-gateway + + com.github.xiaoymin + knife4j-spring-boot-starter + + + org.springframework.security + spring-security-config + + + org.springframework.security + spring-security-oauth2-resource-server + + + org.springframework.security + spring-security-oauth2-client + + + org.springframework.security + spring-security-oauth2-jose + + + com.nimbusds + nimbus-jose-jwt + + + org.springframework.boot + spring-boot-starter-data-redis + diff --git a/mall-gateway/src/main/java/com/macro/mall/authorization/AuthorizationManager.java b/mall-gateway/src/main/java/com/macro/mall/authorization/AuthorizationManager.java new file mode 100644 index 0000000..423ab49 --- /dev/null +++ b/mall-gateway/src/main/java/com/macro/mall/authorization/AuthorizationManager.java @@ -0,0 +1,104 @@ +package com.macro.mall.authorization; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.macro.mall.common.constant.AuthConstant; +import com.macro.mall.common.domain.UserDto; +import com.macro.mall.config.IgnoreUrlsConfig; +import com.nimbusds.jose.JWSObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.http.HttpMethod; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.ReactiveAuthorizationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.web.server.authorization.AuthorizationContext; +import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.PathMatcher; +import reactor.core.publisher.Mono; + +import java.net.URI; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 鉴权管理器,用于判断是否有资源的访问权限 + * Created by macro on 2020/6/19. + */ +@Component +public class AuthorizationManager implements ReactiveAuthorizationManager { + @Autowired + private RedisTemplate redisTemplate; + @Autowired + private IgnoreUrlsConfig ignoreUrlsConfig; + + @Override + public Mono check(Mono mono, AuthorizationContext authorizationContext) { + ServerHttpRequest request = authorizationContext.getExchange().getRequest(); + URI uri = request.getURI(); + PathMatcher pathMatcher = new AntPathMatcher(); + //白名单路径直接放行 + List ignoreUrls = ignoreUrlsConfig.getUrls(); + for (String ignoreUrl : ignoreUrls) { + if (pathMatcher.match(ignoreUrl, uri.getPath())) { + return Mono.just(new AuthorizationDecision(true)); + } + } + //对应跨域的预检请求直接放行 + if(request.getMethod()==HttpMethod.OPTIONS){ + return Mono.just(new AuthorizationDecision(true)); + } + //不同用户体系登录不允许互相访问 + try { + String token = request.getHeaders().getFirst(AuthConstant.JWT_TOKEN_HEADER); + if(StrUtil.isEmpty(token)){ + return Mono.just(new AuthorizationDecision(false)); + } + String realToken = token.replace(AuthConstant.JWT_TOKEN_PREFIX, ""); + JWSObject jwsObject = JWSObject.parse(realToken); + String userStr = jwsObject.getPayload().toString(); + UserDto userDto = JSONUtil.toBean(userStr, UserDto.class); + if (AuthConstant.ADMIN_CLIENT_ID.equals(userDto.getClientId()) && !pathMatcher.match(AuthConstant.ADMIN_URL_PATTERN, uri.getPath())) { + return Mono.just(new AuthorizationDecision(false)); + } + if (AuthConstant.PORTAL_CLIENT_ID.equals(userDto.getClientId()) && pathMatcher.match(AuthConstant.ADMIN_URL_PATTERN, uri.getPath())) { + return Mono.just(new AuthorizationDecision(false)); + } + } catch (ParseException e) { + e.printStackTrace(); + return Mono.just(new AuthorizationDecision(false)); + } + //非管理端路径直接放行 + if (!pathMatcher.match(AuthConstant.ADMIN_URL_PATTERN, uri.getPath())) { + return Mono.just(new AuthorizationDecision(true)); + } + //管理端路径需校验权限 + Map resourceRolesMap = redisTemplate.opsForHash().entries(AuthConstant.RESOURCE_ROLES_MAP_KEY); + Iterator iterator = resourceRolesMap.keySet().iterator(); + List authorities = new ArrayList<>(); + while (iterator.hasNext()) { + String pattern = (String) iterator.next(); + if (pathMatcher.match(pattern, uri.getPath())) { + authorities.addAll(Convert.toList(String.class, resourceRolesMap.get(pattern))); + } + } + authorities = authorities.stream().map(i -> i = AuthConstant.AUTHORITY_PREFIX + i).collect(Collectors.toList()); + //认证通过且角色匹配的用户可访问当前路径 + return mono + .filter(Authentication::isAuthenticated) + .flatMapIterable(Authentication::getAuthorities) + .map(GrantedAuthority::getAuthority) + .any(authorities::contains) + .map(AuthorizationDecision::new) + .defaultIfEmpty(new AuthorizationDecision(false)); + } + +} diff --git a/mall-gateway/src/main/java/com/macro/mall/component/RestAuthenticationEntryPoint.java b/mall-gateway/src/main/java/com/macro/mall/component/RestAuthenticationEntryPoint.java new file mode 100644 index 0000000..e3aef92 --- /dev/null +++ b/mall-gateway/src/main/java/com/macro/mall/component/RestAuthenticationEntryPoint.java @@ -0,0 +1,35 @@ +package com.macro.mall.component; + +import cn.hutool.json.JSONUtil; +import com.macro.mall.common.api.CommonResult; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.server.ServerAuthenticationEntryPoint; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +import java.nio.charset.Charset; + +/** + * 自定义返回结果:没有登录或token过期时 + * Created by macro on 2020/6/18. + */ +@Component +public class RestAuthenticationEntryPoint implements ServerAuthenticationEntryPoint { + @Override + public Mono commence(ServerWebExchange exchange, AuthenticationException e) { + ServerHttpResponse response = exchange.getResponse(); + response.setStatusCode(HttpStatus.OK); + response.getHeaders().set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + response.getHeaders().set("Access-Control-Allow-Origin","*"); + response.getHeaders().set("Cache-Control","no-cache"); + String body= JSONUtil.toJsonStr(CommonResult.unauthorized(e.getMessage())); + DataBuffer buffer = response.bufferFactory().wrap(body.getBytes(Charset.forName("UTF-8"))); + return response.writeWith(Mono.just(buffer)); + } +} diff --git a/mall-gateway/src/main/java/com/macro/mall/component/RestfulAccessDeniedHandler.java b/mall-gateway/src/main/java/com/macro/mall/component/RestfulAccessDeniedHandler.java new file mode 100644 index 0000000..81f425f --- /dev/null +++ b/mall-gateway/src/main/java/com/macro/mall/component/RestfulAccessDeniedHandler.java @@ -0,0 +1,36 @@ +package com.macro.mall.component; + +import cn.hutool.json.JSONUtil; +import com.macro.mall.common.api.CommonResult; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +import java.nio.charset.Charset; + + +/** + * 自定义返回结果:没有权限访问时 + * Created by macro on 2018/4/26. + */ +@Component +public class RestfulAccessDeniedHandler implements ServerAccessDeniedHandler { + @Override + public Mono handle(ServerWebExchange exchange, AccessDeniedException denied) { + ServerHttpResponse response = exchange.getResponse(); + response.setStatusCode(HttpStatus.OK); + response.getHeaders().set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + response.getHeaders().set("Access-Control-Allow-Origin","*"); + response.getHeaders().set("Cache-Control","no-cache"); + String body= JSONUtil.toJsonStr(CommonResult.forbidden(denied.getMessage())); + DataBuffer buffer = response.bufferFactory().wrap(body.getBytes(Charset.forName("UTF-8"))); + return response.writeWith(Mono.just(buffer)); + } +} diff --git a/mall-gateway/src/main/java/com/macro/mall/config/GlobalCorsConfig.java b/mall-gateway/src/main/java/com/macro/mall/config/GlobalCorsConfig.java index 4514bc5..cd7ac77 100644 --- a/mall-gateway/src/main/java/com/macro/mall/config/GlobalCorsConfig.java +++ b/mall-gateway/src/main/java/com/macro/mall/config/GlobalCorsConfig.java @@ -21,7 +21,7 @@ public class GlobalCorsConfig { config.addAllowedMethod("*"); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); - + config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser()); source.registerCorsConfiguration("/**", config); diff --git a/mall-gateway/src/main/java/com/macro/mall/config/IgnoreUrlsConfig.java b/mall-gateway/src/main/java/com/macro/mall/config/IgnoreUrlsConfig.java new file mode 100644 index 0000000..3e497d1 --- /dev/null +++ b/mall-gateway/src/main/java/com/macro/mall/config/IgnoreUrlsConfig.java @@ -0,0 +1,20 @@ +package com.macro.mall.config; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 网关白名单配置 + * Created by macro on 2020/6/17. + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Component +@ConfigurationProperties(prefix="secure.ignore") +public class IgnoreUrlsConfig { + private List urls; +} diff --git a/mall-gateway/src/main/java/com/macro/mall/config/RedisConfig.java b/mall-gateway/src/main/java/com/macro/mall/config/RedisConfig.java new file mode 100644 index 0000000..90bba12 --- /dev/null +++ b/mall-gateway/src/main/java/com/macro/mall/config/RedisConfig.java @@ -0,0 +1,19 @@ +package com.macro.mall.config; + +import com.macro.mall.common.config.BaseRedisConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * Redis相关配置 + * Created by macro on 2020/6/19. + */ +@Configuration +public class RedisConfig extends BaseRedisConfig { + +} diff --git a/mall-gateway/src/main/java/com/macro/mall/config/ResourceServerConfig.java b/mall-gateway/src/main/java/com/macro/mall/config/ResourceServerConfig.java new file mode 100644 index 0000000..bba28b5 --- /dev/null +++ b/mall-gateway/src/main/java/com/macro/mall/config/ResourceServerConfig.java @@ -0,0 +1,66 @@ +package com.macro.mall.config; + +import cn.hutool.core.util.ArrayUtil; +import com.macro.mall.authorization.AuthorizationManager; +import com.macro.mall.common.constant.AuthConstant; +import com.macro.mall.component.RestAuthenticationEntryPoint; +import com.macro.mall.component.RestfulAccessDeniedHandler; +import com.macro.mall.filter.IgnoreUrlsRemoveJwtFilter; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.SecurityWebFiltersOrder; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; +import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; +import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter; +import org.springframework.security.web.server.SecurityWebFilterChain; +import reactor.core.publisher.Mono; + +/** + * 资源服务器配置 + * Created by macro on 2020/6/19. + */ +@AllArgsConstructor +@Configuration +@EnableWebFluxSecurity +public class ResourceServerConfig { + private final AuthorizationManager authorizationManager; + private final IgnoreUrlsConfig ignoreUrlsConfig; + private final RestfulAccessDeniedHandler restfulAccessDeniedHandler; + private final RestAuthenticationEntryPoint restAuthenticationEntryPoint; + private final IgnoreUrlsRemoveJwtFilter ignoreUrlsRemoveJwtFilter; + + @Bean + public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { + http.oauth2ResourceServer().jwt() + .jwtAuthenticationConverter(jwtAuthenticationConverter()); + //自定义处理JWT请求头过期或签名错误的结果 + http.oauth2ResourceServer().authenticationEntryPoint(restAuthenticationEntryPoint); + //对白名单路径,直接移除JWT请求头 + http.addFilterBefore(ignoreUrlsRemoveJwtFilter,SecurityWebFiltersOrder.AUTHENTICATION); + http.authorizeExchange() + .pathMatchers(ArrayUtil.toArray(ignoreUrlsConfig.getUrls(),String.class)).permitAll()//白名单配置 + .anyExchange().access(authorizationManager)//鉴权管理器配置 + .and().exceptionHandling() + .accessDeniedHandler(restfulAccessDeniedHandler)//处理未授权 + .authenticationEntryPoint(restAuthenticationEntryPoint)//处理未认证 + .and().csrf().disable(); + return http.build(); + } + + @Bean + public Converter> jwtAuthenticationConverter() { + JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); + jwtGrantedAuthoritiesConverter.setAuthorityPrefix(AuthConstant.AUTHORITY_PREFIX); + jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName(AuthConstant.AUTHORITY_CLAIM_NAME); + JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter(); + jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter); + return new ReactiveJwtAuthenticationConverterAdapter(jwtAuthenticationConverter); + } + +} diff --git a/mall-gateway/src/main/java/com/macro/mall/config/SwaggerResourceConfig.java b/mall-gateway/src/main/java/com/macro/mall/config/SwaggerResourceConfig.java new file mode 100644 index 0000000..c66ad3b --- /dev/null +++ b/mall-gateway/src/main/java/com/macro/mall/config/SwaggerResourceConfig.java @@ -0,0 +1,55 @@ +package com.macro.mall.config; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.gateway.config.GatewayProperties; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.support.NameUtils; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; +import springfox.documentation.swagger.web.SwaggerResource; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; + +import java.util.ArrayList; +import java.util.List; + +/** + * Swagger资源配置 + * Created by macro on 2020/7/9. + */ +@Slf4j +@Component +@Primary +@AllArgsConstructor +public class SwaggerResourceConfig implements SwaggerResourcesProvider { + + private final RouteLocator routeLocator; + private final GatewayProperties gatewayProperties; + + @Override + public List get() { + List resources = new ArrayList<>(); + List routes = new ArrayList<>(); + //获取所有路由的ID + routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); + //过滤出配置文件中定义的路由->过滤出Path Route Predicate->根据路径拼接成api-docs路径->生成SwaggerResource + gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> { + route.getPredicates().stream() + .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName())) + .forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(), + predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") + .replace("**", "v2/api-docs")))); + }); + + return resources; + } + + private SwaggerResource swaggerResource(String name, String location) { + log.info("name:{},location:{}", name, location); + SwaggerResource swaggerResource = new SwaggerResource(); + swaggerResource.setName(name); + swaggerResource.setLocation(location); + swaggerResource.setSwaggerVersion("2.0"); + return swaggerResource; + } +} diff --git a/mall-gateway/src/main/java/com/macro/mall/filter/AuthGlobalFilter.java b/mall-gateway/src/main/java/com/macro/mall/filter/AuthGlobalFilter.java new file mode 100644 index 0000000..13a71f2 --- /dev/null +++ b/mall-gateway/src/main/java/com/macro/mall/filter/AuthGlobalFilter.java @@ -0,0 +1,51 @@ +package com.macro.mall.filter; + +import cn.hutool.core.util.StrUtil; +import com.macro.mall.common.constant.AuthConstant; +import com.nimbusds.jose.JWSObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +import java.text.ParseException; + +/** + * 将登录用户的JWT转化成用户信息的全局过滤器 + * Created by macro on 2020/6/17. + */ +@Component +public class AuthGlobalFilter implements GlobalFilter, Ordered { + + private static Logger LOGGER = LoggerFactory.getLogger(AuthGlobalFilter.class); + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + String token = exchange.getRequest().getHeaders().getFirst(AuthConstant.JWT_TOKEN_HEADER); + if (StrUtil.isEmpty(token)) { + return chain.filter(exchange); + } + try { + //从token中解析用户信息并设置到Header中去 + String realToken = token.replace(AuthConstant.JWT_TOKEN_PREFIX, ""); + JWSObject jwsObject = JWSObject.parse(realToken); + String userStr = jwsObject.getPayload().toString(); + LOGGER.info("AuthGlobalFilter.filter() user:{}",userStr); + ServerHttpRequest request = exchange.getRequest().mutate().header(AuthConstant.USER_TOKEN_HEADER, userStr).build(); + exchange = exchange.mutate().request(request).build(); + } catch (ParseException e) { + e.printStackTrace(); + } + return chain.filter(exchange); + } + + @Override + public int getOrder() { + return 0; + } +} diff --git a/mall-gateway/src/main/java/com/macro/mall/filter/IgnoreUrlsRemoveJwtFilter.java b/mall-gateway/src/main/java/com/macro/mall/filter/IgnoreUrlsRemoveJwtFilter.java new file mode 100644 index 0000000..05a708b --- /dev/null +++ b/mall-gateway/src/main/java/com/macro/mall/filter/IgnoreUrlsRemoveJwtFilter.java @@ -0,0 +1,43 @@ +package com.macro.mall.filter; + +import com.macro.mall.common.constant.AuthConstant; +import com.macro.mall.config.IgnoreUrlsConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.security.web.server.authentication.AuthenticationWebFilter; +import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.PathMatcher; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; +import reactor.core.publisher.Mono; + +import java.net.URI; +import java.util.List; + +/** + * 白名单路径访问时需要移除JWT请求头 + * Created by macro on 2020/7/24. + */ +@Component +public class IgnoreUrlsRemoveJwtFilter implements WebFilter { + @Autowired + private IgnoreUrlsConfig ignoreUrlsConfig; + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + ServerHttpRequest request = exchange.getRequest(); + URI uri = request.getURI(); + PathMatcher pathMatcher = new AntPathMatcher(); + //白名单路径移除JWT请求头 + List ignoreUrls = ignoreUrlsConfig.getUrls(); + for (String ignoreUrl : ignoreUrls) { + if (pathMatcher.match(ignoreUrl, uri.getPath())) { + request = exchange.getRequest().mutate().header(AuthConstant.JWT_TOKEN_HEADER, "").build(); + exchange = exchange.mutate().request(request).build(); + return chain.filter(exchange); + } + } + return chain.filter(exchange); + } +} diff --git a/mall-gateway/src/main/java/com/macro/mall/handler/SwaggerHandler.java b/mall-gateway/src/main/java/com/macro/mall/handler/SwaggerHandler.java new file mode 100644 index 0000000..5f5a29e --- /dev/null +++ b/mall-gateway/src/main/java/com/macro/mall/handler/SwaggerHandler.java @@ -0,0 +1,58 @@ +package com.macro.mall.handler; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; +import springfox.documentation.swagger.web.*; + +import java.util.Optional; + +/** + * 自定义Swagger的各个配置节点 + * Created by macro on 2020/7/9. + */ +@RestController +public class SwaggerHandler { + + @Autowired(required = false) + private SecurityConfiguration securityConfiguration; + + @Autowired(required = false) + private UiConfiguration uiConfiguration; + + private final SwaggerResourcesProvider swaggerResources; + + @Autowired + public SwaggerHandler(SwaggerResourcesProvider swaggerResources) { + this.swaggerResources = swaggerResources; + } + + /** + * Swagger安全配置,支持oauth和apiKey设置 + */ + @GetMapping("/swagger-resources/configuration/security") + public Mono> securityConfiguration() { + return Mono.just(new ResponseEntity<>( + Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK)); + } + + /** + * Swagger UI配置 + */ + @GetMapping("/swagger-resources/configuration/ui") + public Mono> uiConfiguration() { + return Mono.just(new ResponseEntity<>( + Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); + } + + /** + * Swagger资源配置,微服务中这各个服务的api-docs信息 + */ + @GetMapping("/swagger-resources") + public Mono swaggerResources() { + return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); + } +} diff --git a/mall-gateway/src/main/resources/application-dev.yml b/mall-gateway/src/main/resources/application-dev.yml deleted file mode 100644 index ee639c8..0000000 --- a/mall-gateway/src/main/resources/application-dev.yml +++ /dev/null @@ -1,5 +0,0 @@ -eureka: - client: - service-url: - defaultZone: http://localhost:8001/eureka/ - registry-fetch-interval-seconds: 10 diff --git a/mall-gateway/src/main/resources/application-prod.yml b/mall-gateway/src/main/resources/application-prod.yml deleted file mode 100644 index 2950ce4..0000000 --- a/mall-gateway/src/main/resources/application-prod.yml +++ /dev/null @@ -1,7 +0,0 @@ -eureka: - client: - service-url: - defaultZone: http://mall-registry:8001/eureka/ - registry-fetch-interval-seconds: 10 - instance: - prefer-ip-address: true diff --git a/mall-gateway/src/main/resources/application.yml b/mall-gateway/src/main/resources/application.yml index c8bb3df..a1c7903 100644 --- a/mall-gateway/src/main/resources/application.yml +++ b/mall-gateway/src/main/resources/application.yml @@ -1,16 +1,77 @@ server: port: 8201 spring: - application: - name: mall-gateway - profiles: - active: dev cloud: gateway: discovery: locator: enabled: true lower-case-service-id: true #使用小写service-id + routes: #配置路由路径 + - id: mall-auth + uri: lb://mall-auth + predicates: + - Path=/mall-auth/** + filters: + - StripPrefix=1 + - id: mall-admin + uri: lb://mall-admin + predicates: + - Path=/mall-admin/** + filters: + - StripPrefix=1 + - id: mall-portal + uri: lb://mall-portal + predicates: + - Path=/mall-portal/** + filters: + - StripPrefix=1 + - id: mall-search + uri: lb://mall-search + predicates: + - Path=/mall-search/** + filters: + - StripPrefix=1 + - id: mall-demo + uri: lb://mall-demo + predicates: + - Path=/mall-demo/** + filters: + - StripPrefix=1 + security: + oauth2: + resourceserver: + jwt: + jwk-set-uri: 'http://localhost:8201/mall-auth/rsa/publicKey' #配置RSA的公钥访问地址 + redis: + database: 0 + port: 6379 + host: localhost + password: +secure: + ignore: + urls: #配置白名单路径 + - "/doc.html" + - "/swagger-resources/**" + - "/swagger/**" + - "/**/v2/api-docs" + - "/**/*.js" + - "/**/*.css" + - "/**/*.png" + - "/**/*.ico" + - "/webjars/springfox-swagger-ui/**" + - "/actuator/**" + - "/mall-auth/oauth/token" + - "/mall-auth/rsa/publicKey" + - "/mall-search/**" + - "/mall-portal/sso/**" + - "/mall-portal/home/**" + - "/mall-portal/product/**" + - "/mall-portal/brand/**" + - "/mall-admin/admin/login" + - "/mall-admin/admin/register" + - "/mall-admin/admin/info" + - "/mall-admin/minio/upload" management: #开启SpringBoot Admin的监控 endpoints: web: @@ -19,6 +80,3 @@ management: #开启SpringBoot Admin的监控 endpoint: health: show-details: always -logging: - level: - org.springframework.cloud.gateway: debug diff --git a/mall-gateway/src/main/resources/bootstrap-dev.yml b/mall-gateway/src/main/resources/bootstrap-dev.yml new file mode 100644 index 0000000..365fbba --- /dev/null +++ b/mall-gateway/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,8 @@ +spring: + cloud: + nacos: + discovery: + server-addr: http://localhost:8848 + config: + server-addr: http://localhost:8848 + file-extension: yaml \ No newline at end of file diff --git a/mall-gateway/src/main/resources/bootstrap-prod.yml b/mall-gateway/src/main/resources/bootstrap-prod.yml new file mode 100644 index 0000000..fc71e7a --- /dev/null +++ b/mall-gateway/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,8 @@ +spring: + cloud: + nacos: + discovery: + server-addr: http://nacos-registry:8848 + config: + server-addr: http://nacos-registry:8848 + file-extension: yaml \ No newline at end of file diff --git a/mall-gateway/src/main/resources/bootstrap.yml b/mall-gateway/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..b3900a3 --- /dev/null +++ b/mall-gateway/src/main/resources/bootstrap.yml @@ -0,0 +1,5 @@ +spring: + profiles: + active: dev + application: + name: mall-gateway \ No newline at end of file diff --git a/mall-mbg/pom.xml b/mall-mbg/pom.xml index ac12150..216b043 100644 --- a/mall-mbg/pom.xml +++ b/mall-mbg/pom.xml @@ -23,6 +23,14 @@ com.macro.mall mall-common + + com.github.pagehelper + pagehelper-spring-boot-starter + + + com.alibaba + druid-spring-boot-starter + org.mybatis.generator mybatis-generator-core diff --git a/mall-monitor/pom.xml b/mall-monitor/pom.xml index 82efca1..a5a8950 100644 --- a/mall-monitor/pom.xml +++ b/mall-monitor/pom.xml @@ -20,8 +20,8 @@ spring-boot-starter-web - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery de.codecentric diff --git a/mall-monitor/src/main/resources/application-dev.yml b/mall-monitor/src/main/resources/application-dev.yml index 0cdc0aa..a7c40c6 100644 --- a/mall-monitor/src/main/resources/application-dev.yml +++ b/mall-monitor/src/main/resources/application-dev.yml @@ -1,4 +1,5 @@ -eureka: - client: - service-url: - defaultZone: http://localhost:8001/eureka/ +spring: + cloud: + nacos: + discovery: + server-addr: http://localhost:8848 diff --git a/mall-monitor/src/main/resources/application-prod.yml b/mall-monitor/src/main/resources/application-prod.yml index 321524e..17c0d7b 100644 --- a/mall-monitor/src/main/resources/application-prod.yml +++ b/mall-monitor/src/main/resources/application-prod.yml @@ -1,6 +1,5 @@ -eureka: - client: - service-url: - defaultZone: http://mall-registry:8001/eureka/ - instance: - prefer-ip-address: true +spring: + cloud: + nacos: + discovery: + server-addr: http://nacos-registry:8848 diff --git a/mall-monitor/src/main/resources/application.yml b/mall-monitor/src/main/resources/application.yml index 6490fa8..dade0d2 100644 --- a/mall-monitor/src/main/resources/application.yml +++ b/mall-monitor/src/main/resources/application.yml @@ -11,9 +11,3 @@ spring: ignored-services: ${spring.application.name} server: port: 8101 -eureka: - client: - register-with-eureka: true - fetch-registry: true - service-url: - defaultZone: http://localhost:8001/eureka/ diff --git a/mall-portal/pom.xml b/mall-portal/pom.xml index 5506137..7a424be 100644 --- a/mall-portal/pom.xml +++ b/mall-portal/pom.xml @@ -22,10 +22,6 @@ com.macro.mall mall-mbg - - com.macro.mall - mall-security - org.springframework.boot @@ -42,12 +38,20 @@ spring-boot-starter-amqp - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config org.springframework.cloud - spring-cloud-starter-config + spring-cloud-starter-openfeign + + + io.github.openfeign + feign-okhttp diff --git a/mall-portal/src/main/java/com/macro/mall/portal/MallPortalApplication.java b/mall-portal/src/main/java/com/macro/mall/portal/MallPortalApplication.java index 8c74689..4a1d40f 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/MallPortalApplication.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/MallPortalApplication.java @@ -3,7 +3,9 @@ package com.macro.mall.portal; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +@EnableFeignClients @EnableDiscoveryClient @SpringBootApplication(scanBasePackages = "com.macro.mall") public class MallPortalApplication { diff --git a/mall-portal/src/main/java/com/macro/mall/portal/config/MallSecurityConfig.java b/mall-portal/src/main/java/com/macro/mall/portal/config/MallSecurityConfig.java deleted file mode 100644 index 2a41f9c..0000000 --- a/mall-portal/src/main/java/com/macro/mall/portal/config/MallSecurityConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.macro.mall.portal.config; - -import com.macro.mall.portal.service.UmsMemberService; -import com.macro.mall.security.component.DynamicSecurityService; -import com.macro.mall.security.config.SecurityConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.ConfigAttribute; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.userdetails.UserDetailsService; - -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * mall-security模块相关配置 - * Created by macro on 2019/11/5. - */ -@Configuration -@EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class MallSecurityConfig extends SecurityConfig { - - @Autowired - private UmsMemberService memberService; - - @Bean - public UserDetailsService userDetailsService() { - //获取登录用户信息 - return username -> memberService.loadUserByUsername(username); - } -} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/config/RedisConfig.java b/mall-portal/src/main/java/com/macro/mall/portal/config/RedisConfig.java new file mode 100644 index 0000000..acc33d6 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/config/RedisConfig.java @@ -0,0 +1,15 @@ +package com.macro.mall.portal.config; + +import com.macro.mall.common.config.BaseRedisConfig; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Configuration; + +/** + * Redis配置类 + * Created by macro on 2020/3/2. + */ +@EnableCaching +@Configuration +public class RedisConfig extends BaseRedisConfig { + +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/config/SwaggerConfig.java b/mall-portal/src/main/java/com/macro/mall/portal/config/SwaggerConfig.java new file mode 100644 index 0000000..d340df8 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/config/SwaggerConfig.java @@ -0,0 +1,41 @@ +package com.macro.mall.portal.config; + +import com.macro.mall.common.config.BaseSwaggerConfig; +import com.macro.mall.common.domain.SwaggerProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.ArrayList; +import java.util.List; + +/** + * Swagger2API文档的配置 + * Created by macro on 2018/4/26. + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig extends BaseSwaggerConfig { + + @Override + public SwaggerProperties swaggerProperties() { + return SwaggerProperties.builder() + .apiBasePackage("com.macro.mall.portal.controller") + .title("mall前台系统") + .description("mall前台相关接口文档") + .contactName("macro") + .version("1.0") + .enableSecurity(true) + .build(); + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/HomeController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/HomeController.java index 4d9af1c..f78c16d 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/controller/HomeController.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/HomeController.java @@ -59,4 +59,22 @@ public class HomeController { List subjectList = homeService.getSubjectList(cateId,pageSize,pageNum); return CommonResult.success(subjectList); } + + @ApiOperation("分页获取人气推荐商品") + @RequestMapping(value = "/hotProductList", method = RequestMethod.GET) + @ResponseBody + public CommonResult> hotProductList(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(value = "pageSize", defaultValue = "6") Integer pageSize) { + List productList = homeService.hotProductList(pageNum,pageSize); + return CommonResult.success(productList); + } + + @ApiOperation("分页获取新品推荐商品") + @RequestMapping(value = "/newProductList", method = RequestMethod.GET) + @ResponseBody + public CommonResult> newProductList(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(value = "pageSize", defaultValue = "6") Integer pageSize) { + List productList = homeService.newProductList(pageNum,pageSize); + return CommonResult.success(productList); + } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberAttentionController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberAttentionController.java index c5947df..80ea510 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberAttentionController.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberAttentionController.java @@ -1,11 +1,14 @@ package com.macro.mall.portal.controller; +import com.macro.mall.common.api.CommonPage; import com.macro.mall.common.api.CommonResult; import com.macro.mall.portal.domain.MemberBrandAttention; +import com.macro.mall.portal.domain.MemberProductCollection; import com.macro.mall.portal.service.MemberAttentionService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @@ -36,8 +39,8 @@ public class MemberAttentionController { @ApiOperation("取消关注") @RequestMapping(value = "/delete", method = RequestMethod.POST) @ResponseBody - public CommonResult delete(Long memberId, Long brandId) { - int count = memberAttentionService.delete(memberId,brandId); + public CommonResult delete(Long brandId) { + int count = memberAttentionService.delete(brandId); if(count>0){ return CommonResult.success(count); }else{ @@ -46,10 +49,27 @@ public class MemberAttentionController { } @ApiOperation("显示关注列表") - @RequestMapping(value = "/list/{memberId}", method = RequestMethod.GET) + @RequestMapping(value = "/list", method = RequestMethod.GET) @ResponseBody - public CommonResult> list(@PathVariable Long memberId) { - List memberBrandAttentionList = memberAttentionService.list(memberId); - return CommonResult.success(memberBrandAttentionList); + public CommonResult> list(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize) { + Page page = memberAttentionService.list(pageNum,pageSize); + return CommonResult.success(CommonPage.restPage(page)); + } + + @ApiOperation("显示关注品牌详情") + @RequestMapping(value = "/detail", method = RequestMethod.GET) + @ResponseBody + public CommonResult detail(@RequestParam Long brandId) { + MemberBrandAttention memberBrandAttention = memberAttentionService.detail(brandId); + return CommonResult.success(memberBrandAttention); + } + + @ApiOperation("清空关注列表") + @RequestMapping(value = "/clear", method = RequestMethod.POST) + @ResponseBody + public CommonResult clear() { + memberAttentionService.clear(); + return CommonResult.success(null); } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberCollectionController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberCollectionController.java deleted file mode 100644 index 63d3fac..0000000 --- a/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberCollectionController.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.macro.mall.portal.controller; - -import com.macro.mall.common.api.CommonResult; -import com.macro.mall.portal.domain.MemberProductCollection; -import com.macro.mall.portal.service.MemberCollectionService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -/** - * 会员收藏管理Controller - * Created by macro on 2018/8/2. - */ -@Controller -@Api(tags = "MemberCollectionController", description = "会员收藏管理") -@RequestMapping("/member/collection") -public class MemberCollectionController { - @Autowired - private MemberCollectionService memberCollectionService; - - @ApiOperation("添加商品收藏") - @RequestMapping(value = "/addProduct", method = RequestMethod.POST) - @ResponseBody - public CommonResult addProduct(@RequestBody MemberProductCollection productCollection) { - int count = memberCollectionService.addProduct(productCollection); - if (count > 0) { - return CommonResult.success(count); - } else { - return CommonResult.failed(); - } - } - - @ApiOperation("删除收藏商品") - @RequestMapping(value = "/deleteProduct", method = RequestMethod.POST) - @ResponseBody - public CommonResult deleteProduct(Long memberId, Long productId) { - int count = memberCollectionService.deleteProduct(memberId, productId); - if (count > 0) { - return CommonResult.success(count); - } else { - return CommonResult.failed(); - } - } - - @ApiOperation("显示关注列表") - @RequestMapping(value = "/listProduct/{memberId}", method = RequestMethod.GET) - @ResponseBody - public CommonResult> listProduct(@PathVariable Long memberId) { - List memberProductCollectionList = memberCollectionService.listProduct(memberId); - return CommonResult.success(memberProductCollectionList); - } -} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberProductCollectionController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberProductCollectionController.java new file mode 100644 index 0000000..1c78787 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberProductCollectionController.java @@ -0,0 +1,75 @@ +package com.macro.mall.portal.controller; + +import com.macro.mall.common.api.CommonPage; +import com.macro.mall.common.api.CommonResult; +import com.macro.mall.portal.domain.MemberProductCollection; +import com.macro.mall.portal.service.MemberCollectionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 会员收藏管理Controller + * Created by macro on 2018/8/2. + */ +@Controller +@Api(tags = "MemberCollectionController", description = "会员收藏管理") +@RequestMapping("/member/productCollection") +public class MemberProductCollectionController { + @Autowired + private MemberCollectionService memberCollectionService; + + @ApiOperation("添加商品收藏") + @RequestMapping(value = "/add", method = RequestMethod.POST) + @ResponseBody + public CommonResult add(@RequestBody MemberProductCollection productCollection) { + int count = memberCollectionService.add(productCollection); + if (count > 0) { + return CommonResult.success(count); + } else { + return CommonResult.failed(); + } + } + + @ApiOperation("删除收藏商品") + @RequestMapping(value = "/delete", method = RequestMethod.POST) + @ResponseBody + public CommonResult delete(Long productId) { + int count = memberCollectionService.delete(productId); + if (count > 0) { + return CommonResult.success(count); + } else { + return CommonResult.failed(); + } + } + + @ApiOperation("显示收藏列表") + @RequestMapping(value = "/list", method = RequestMethod.GET) + @ResponseBody + public CommonResult> list(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize) { + Page page = memberCollectionService.list(pageNum,pageSize); + return CommonResult.success(CommonPage.restPage(page)); + } + + @ApiOperation("显示收藏商品详情") + @RequestMapping(value = "/detail", method = RequestMethod.GET) + @ResponseBody + public CommonResult detail(@RequestParam Long productId) { + MemberProductCollection memberProductCollection = memberCollectionService.detail(productId); + return CommonResult.success(memberProductCollection); + } + + @ApiOperation("清空收藏列表") + @RequestMapping(value = "/clear", method = RequestMethod.POST) + @ResponseBody + public CommonResult clear() { + memberCollectionService.clear(); + return CommonResult.success(null); + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberReadHistoryController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberReadHistoryController.java index 8393408..949897f 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberReadHistoryController.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/MemberReadHistoryController.java @@ -1,11 +1,13 @@ package com.macro.mall.portal.controller; +import com.macro.mall.common.api.CommonPage; import com.macro.mall.common.api.CommonResult; import com.macro.mall.portal.domain.MemberReadHistory; import com.macro.mall.portal.service.MemberReadHistoryService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @@ -46,11 +48,20 @@ public class MemberReadHistoryController { } } - @ApiOperation("展示浏览记录") + @ApiOperation("清空除浏览记录") + @RequestMapping(value = "/clear", method = RequestMethod.POST) + @ResponseBody + public CommonResult clear() { + memberReadHistoryService.clear(); + return CommonResult.success(null); + } + + @ApiOperation("分页获取用户浏览记录") @RequestMapping(value = "/list", method = RequestMethod.GET) @ResponseBody - public CommonResult> list(Long memberId) { - List memberReadHistoryList = memberReadHistoryService.list(memberId); - return CommonResult.success(memberReadHistoryList); + public CommonResult> list(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize) { + Page page = memberReadHistoryService.list(pageNum, pageSize); + return CommonResult.success(CommonPage.restPage(page)); } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsCartItemController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsCartItemController.java index 74af308..944e8a2 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsCartItemController.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsCartItemController.java @@ -49,8 +49,8 @@ public class OmsCartItemController { @ApiOperation("获取某个会员的购物车列表,包括促销信息") @RequestMapping(value = "/list/promotion", method = RequestMethod.GET) @ResponseBody - public CommonResult> listPromotion() { - List cartPromotionItemList = cartItemService.listPromotion(memberService.getCurrentMember().getId()); + public CommonResult> listPromotion(@RequestParam(required = false) List cartIds) { + List cartPromotionItemList = cartItemService.listPromotion(memberService.getCurrentMember().getId(), cartIds); return CommonResult.success(cartPromotionItemList); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsPortalOrderController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsPortalOrderController.java index 6251704..80ab3f7 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsPortalOrderController.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/OmsPortalOrderController.java @@ -1,15 +1,19 @@ package com.macro.mall.portal.controller; +import com.macro.mall.common.api.CommonPage; import com.macro.mall.common.api.CommonResult; import com.macro.mall.portal.domain.ConfirmOrderResult; +import com.macro.mall.portal.domain.OmsOrderDetail; import com.macro.mall.portal.domain.OrderParam; import com.macro.mall.portal.service.OmsPortalOrderService; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; +import java.util.List; import java.util.Map; /** @@ -26,8 +30,8 @@ public class OmsPortalOrderController { @ApiOperation("根据购物车信息生成确认单信息") @RequestMapping(value = "/generateConfirmOrder", method = RequestMethod.POST) @ResponseBody - public CommonResult generateConfirmOrder() { - ConfirmOrderResult confirmOrderResult = portalOrderService.generateConfirmOrder(); + public CommonResult generateConfirmOrder(@RequestBody List cartIds) { + ConfirmOrderResult confirmOrderResult = portalOrderService.generateConfirmOrder(cartIds); return CommonResult.success(confirmOrderResult); } @@ -39,11 +43,11 @@ public class OmsPortalOrderController { return CommonResult.success(result, "下单成功"); } - @ApiOperation("支付成功的回调") + @ApiOperation("用户支付成功的回调") @RequestMapping(value = "/paySuccess", method = RequestMethod.POST) @ResponseBody - public CommonResult paySuccess(@RequestParam Long orderId) { - Integer count = portalOrderService.paySuccess(orderId); + public CommonResult paySuccess(@RequestParam Long orderId,@RequestParam Integer payType) { + Integer count = portalOrderService.paySuccess(orderId,payType); return CommonResult.success(count, "支付成功"); } @@ -62,4 +66,48 @@ public class OmsPortalOrderController { portalOrderService.sendDelayMessageCancelOrder(orderId); return CommonResult.success(null); } + + @ApiOperation("按状态分页获取用户订单列表") + @ApiImplicitParam(name = "status", value = "订单状态:-1->全部;0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭", + defaultValue = "-1", allowableValues = "-1,0,1,2,3,4", paramType = "query", dataType = "int") + @RequestMapping(value = "/list", method = RequestMethod.GET) + @ResponseBody + public CommonResult> list(@RequestParam Integer status, + @RequestParam(required = false, defaultValue = "1") Integer pageNum, + @RequestParam(required = false, defaultValue = "5") Integer pageSize) { + CommonPage orderPage = portalOrderService.list(status,pageNum,pageSize); + return CommonResult.success(orderPage); + } + + @ApiOperation("根据ID获取订单详情") + @RequestMapping(value = "/detail/{orderId}", method = RequestMethod.GET) + @ResponseBody + public CommonResult detail(@PathVariable Long orderId) { + OmsOrderDetail orderDetail = portalOrderService.detail(orderId); + return CommonResult.success(orderDetail); + } + + @ApiOperation("用户取消订单") + @RequestMapping(value = "/cancelUserOrder", method = RequestMethod.POST) + @ResponseBody + public CommonResult cancelUserOrder(Long orderId) { + portalOrderService.cancelOrder(orderId); + return CommonResult.success(null); + } + + @ApiOperation("用户确认收货") + @RequestMapping(value = "/confirmReceiveOrder", method = RequestMethod.POST) + @ResponseBody + public CommonResult confirmReceiveOrder(Long orderId) { + portalOrderService.confirmReceiveOrder(orderId); + return CommonResult.success(null); + } + + @ApiOperation("用户删除订单") + @RequestMapping(value = "/deleteOrder", method = RequestMethod.POST) + @ResponseBody + public CommonResult deleteOrder(Long orderId) { + portalOrderService.deleteOrder(orderId); + return CommonResult.success(null); + } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/PmsPortalProductController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/PmsPortalProductController.java new file mode 100644 index 0000000..0d173a8 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/PmsPortalProductController.java @@ -0,0 +1,60 @@ +package com.macro.mall.portal.controller; + +import com.macro.mall.common.api.CommonPage; +import com.macro.mall.common.api.CommonResult; +import com.macro.mall.model.PmsProduct; +import com.macro.mall.portal.domain.PmsPortalProductDetail; +import com.macro.mall.portal.domain.PmsProductCategoryNode; +import com.macro.mall.portal.service.PmsPortalProductService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 前台商品管理Controller + * Created by macro on 2020/4/6. + */ +@Controller +@Api(tags = "PmsPortalProductController", description = "前台商品管理") +@RequestMapping("/product") +public class PmsPortalProductController { + + @Autowired + private PmsPortalProductService portalProductService; + + @ApiOperation(value = "综合搜索、筛选、排序") + @ApiImplicitParam(name = "sort", value = "排序字段:0->按相关度;1->按新品;2->按销量;3->价格从低到高;4->价格从高到低", + defaultValue = "0", allowableValues = "0,1,2,3,4", paramType = "query", dataType = "integer") + @RequestMapping(value = "/search", method = RequestMethod.GET) + @ResponseBody + public CommonResult> search(@RequestParam(required = false) String keyword, + @RequestParam(required = false) Long brandId, + @RequestParam(required = false) Long productCategoryId, + @RequestParam(required = false, defaultValue = "0") Integer pageNum, + @RequestParam(required = false, defaultValue = "5") Integer pageSize, + @RequestParam(required = false, defaultValue = "0") Integer sort) { + List productList = portalProductService.search(keyword, brandId, productCategoryId, pageNum, pageSize, sort); + return CommonResult.success(CommonPage.restPage(productList)); + } + + @ApiOperation("以树形结构获取所有商品分类") + @RequestMapping(value = "/categoryTreeList", method = RequestMethod.GET) + @ResponseBody + public CommonResult> categoryTreeList() { + List list = portalProductService.categoryTreeList(); + return CommonResult.success(list); + } + + @ApiOperation("获取前台商品详情") + @RequestMapping(value = "/detail/{id}", method = RequestMethod.GET) + @ResponseBody + public CommonResult detail(@PathVariable Long id) { + PmsPortalProductDetail productDetail = portalProductService.detail(id); + return CommonResult.success(productDetail); + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/PortalBrandController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/PortalBrandController.java new file mode 100644 index 0000000..5f976ce --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/PortalBrandController.java @@ -0,0 +1,54 @@ +package com.macro.mall.portal.controller; + +import com.macro.mall.common.api.CommonPage; +import com.macro.mall.common.api.CommonResult; +import com.macro.mall.model.PmsBrand; +import com.macro.mall.model.PmsProduct; +import com.macro.mall.portal.service.PortalBrandService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 首页品牌推荐管理Controller + * Created by macro on 2020/5/15. + */ +@Controller +@Api(tags = "PortalBrandController", description = "前台品牌管理") +@RequestMapping("/brand") +public class PortalBrandController { + + @Autowired + private PortalBrandService homeBrandService; + + @ApiOperation("分页获取推荐品牌") + @RequestMapping(value = "/recommendList", method = RequestMethod.GET) + @ResponseBody + public CommonResult> recommendList(@RequestParam(value = "pageSize", defaultValue = "6") Integer pageSize, + @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) { + List brandList = homeBrandService.recommendList(pageNum, pageSize); + return CommonResult.success(brandList); + } + + @ApiOperation("获取品牌详情") + @RequestMapping(value = "/detail/{brandId}", method = RequestMethod.GET) + @ResponseBody + public CommonResult detail(@PathVariable Long brandId) { + PmsBrand brand = homeBrandService.detail(brandId); + return CommonResult.success(brand); + } + + @ApiOperation("分页获取品牌相关商品") + @RequestMapping(value = "/productList", method = RequestMethod.GET) + @ResponseBody + public CommonResult> productList(@RequestParam Long brandId, + @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(value = "pageSize", defaultValue = "6") Integer pageSize) { + CommonPage result = homeBrandService.productList(brandId,pageNum, pageSize); + return CommonResult.success(result); + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java index 843870e..661bd67 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java @@ -1,21 +1,18 @@ package com.macro.mall.portal.controller; import com.macro.mall.common.api.CommonResult; +import com.macro.mall.common.domain.UserDto; +import com.macro.mall.model.UmsMember; import com.macro.mall.portal.service.UmsMemberService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; -import javax.servlet.http.HttpServletRequest; -import java.util.HashMap; -import java.util.Map; - /** * 会员登录注册管理Controller * Created by macro on 2018/8/3. @@ -24,10 +21,6 @@ import java.util.Map; @Api(tags = "UmsMemberController", description = "会员登录注册管理") @RequestMapping("/sso") public class UmsMemberController { - @Value("${jwt.tokenHeader}") - private String tokenHeader; - @Value("${jwt.tokenHead}") - private String tokenHead; @Autowired private UmsMemberService memberService; @@ -47,14 +40,15 @@ public class UmsMemberController { @ResponseBody public CommonResult login(@RequestParam String username, @RequestParam String password) { - String token = memberService.login(username, password); - if (token == null) { - return CommonResult.validateFailed("用户名或密码错误"); - } - Map tokenMap = new HashMap<>(); - tokenMap.put("token", token); - tokenMap.put("tokenHead", tokenHead); - return CommonResult.success(tokenMap); + return memberService.login(username, password); + } + + @ApiOperation("获取会员信息") + @RequestMapping(value = "/info", method = RequestMethod.GET) + @ResponseBody + public CommonResult info() { + UmsMember member = memberService.getCurrentMember(); + return CommonResult.success(member); } @ApiOperation("获取验证码") @@ -75,19 +69,10 @@ public class UmsMemberController { return CommonResult.success(null,"密码修改成功"); } - - @ApiOperation(value = "刷新token") - @RequestMapping(value = "/refreshToken", method = RequestMethod.GET) + @ApiOperation("根据用户名获取通用用户信息") + @RequestMapping(value = "/loadByUsername", method = RequestMethod.GET) @ResponseBody - public CommonResult refreshToken(HttpServletRequest request) { - String token = request.getHeader(tokenHeader); - String refreshToken = memberService.refreshToken(token); - if (refreshToken == null) { - return CommonResult.failed("token已经过期!"); - } - Map tokenMap = new HashMap<>(); - tokenMap.put("token", refreshToken); - tokenMap.put("tokenHead", tokenHead); - return CommonResult.success(tokenMap); + public UserDto loadUserByUsername(@RequestParam String username) { + return memberService.loadUserByUsername(username); } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberCouponController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberCouponController.java index c76c5d5..f28c7d7 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberCouponController.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberCouponController.java @@ -1,6 +1,7 @@ package com.macro.mall.portal.controller; import com.macro.mall.common.api.CommonResult; +import com.macro.mall.model.SmsCoupon; import com.macro.mall.model.SmsCouponHistory; import com.macro.mall.portal.domain.CartPromotionItem; import com.macro.mall.portal.domain.SmsCouponHistoryDetail; @@ -39,14 +40,24 @@ public class UmsMemberCouponController { return CommonResult.success(null,"领取成功"); } + @ApiOperation("获取用户优惠券历史列表") + @ApiImplicitParam(name = "useStatus", value = "优惠券筛选类型:0->未使用;1->已使用;2->已过期", + allowableValues = "0,1,2", paramType = "query", dataType = "integer") + @RequestMapping(value = "/listHistory", method = RequestMethod.GET) + @ResponseBody + public CommonResult> listHistory(@RequestParam(value = "useStatus", required = false) Integer useStatus) { + List couponHistoryList = memberCouponService.listHistory(useStatus); + return CommonResult.success(couponHistoryList); + } + @ApiOperation("获取用户优惠券列表") @ApiImplicitParam(name = "useStatus", value = "优惠券筛选类型:0->未使用;1->已使用;2->已过期", allowableValues = "0,1,2", paramType = "query", dataType = "integer") @RequestMapping(value = "/list", method = RequestMethod.GET) @ResponseBody - public CommonResult> list(@RequestParam(value = "useStatus", required = false) Integer useStatus) { - List couponHistoryList = memberCouponService.list(useStatus); - return CommonResult.success(couponHistoryList); + public CommonResult> list(@RequestParam(value = "useStatus", required = false) Integer useStatus) { + List couponList = memberCouponService.list(useStatus); + return CommonResult.success(couponList); } @ApiOperation("获取登录会员购物车的相关优惠券") @@ -55,8 +66,16 @@ public class UmsMemberCouponController { @RequestMapping(value = "/list/cart/{type}", method = RequestMethod.GET) @ResponseBody public CommonResult> listCart(@PathVariable Integer type) { - List cartPromotionItemList = cartItemService.listPromotion(memberService.getCurrentMember().getId()); + List cartPromotionItemList = cartItemService.listPromotion(memberService.getCurrentMember().getId(), null); List couponHistoryList = memberCouponService.listCart(cartPromotionItemList, type); return CommonResult.success(couponHistoryList); } + + @ApiOperation("获取当前商品相关优惠券") + @RequestMapping(value = "/listByProduct/{productId}", method = RequestMethod.GET) + @ResponseBody + public CommonResult> listByProduct(@PathVariable Long productId) { + List couponHistoryList = memberCouponService.listByProduct(productId); + return CommonResult.success(couponHistoryList); + } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberReceiveAddressController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberReceiveAddressController.java index 76cfb33..27470be 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberReceiveAddressController.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberReceiveAddressController.java @@ -63,7 +63,7 @@ public class UmsMemberReceiveAddressController { return CommonResult.success(addressList); } - @ApiOperation("显示所有收货地址") + @ApiOperation("获取收货地址详情") @RequestMapping(value = "/{id}", method = RequestMethod.GET) @ResponseBody public CommonResult getItem(@PathVariable Long id) { diff --git a/mall-portal/src/main/java/com/macro/mall/portal/dao/PortalProductDao.java b/mall-portal/src/main/java/com/macro/mall/portal/dao/PortalProductDao.java index 0e3a296..9a68d3a 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/dao/PortalProductDao.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/dao/PortalProductDao.java @@ -1,5 +1,6 @@ package com.macro.mall.portal.dao; +import com.macro.mall.model.SmsCoupon; import com.macro.mall.portal.domain.CartProduct; import com.macro.mall.portal.domain.PromotionProduct; import org.apache.ibatis.annotations.Param; @@ -13,4 +14,5 @@ import java.util.List; public interface PortalProductDao { CartProduct getCartProduct(@Param("id") Long id); List getPromotionProductList(@Param("ids") List ids); + List getAvailableCouponList(@Param("productId") Long productId,@Param("productCategoryId")Long productCategoryId); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/dao/SmsCouponHistoryDao.java b/mall-portal/src/main/java/com/macro/mall/portal/dao/SmsCouponHistoryDao.java index 06b687c..238010e 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/dao/SmsCouponHistoryDao.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/dao/SmsCouponHistoryDao.java @@ -1,6 +1,8 @@ package com.macro.mall.portal.dao; +import com.macro.mall.model.SmsCoupon; import com.macro.mall.portal.domain.SmsCouponHistoryDetail; +import io.swagger.models.auth.In; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -11,4 +13,5 @@ import java.util.List; */ public interface SmsCouponHistoryDao { List getDetailList(@Param("memberId") Long memberId); + List getCouponList(@Param("memberId") Long memberId, @Param("useStatus")Integer useStatus); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberBrandAttention.java b/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberBrandAttention.java index c8f4fbe..9b2f5d6 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberBrandAttention.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberBrandAttention.java @@ -23,7 +23,6 @@ public class MemberBrandAttention { private String brandName; private String brandLogo; private String brandCity; - private Integer brandAttentionCount; private Date createTime; public String getId() { @@ -90,14 +89,6 @@ public class MemberBrandAttention { this.brandCity = brandCity; } - public Integer getBrandAttentionCount() { - return brandAttentionCount; - } - - public void setBrandAttentionCount(Integer brandAttentionCount) { - this.brandAttentionCount = brandAttentionCount; - } - public Date getCreateTime() { return createTime; } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberDetails.java b/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberDetails.java index ffca0d7..2d6f663 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberDetails.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberDetails.java @@ -1,61 +1,61 @@ -package com.macro.mall.portal.domain; - -import com.macro.mall.model.UmsMember; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; - -import java.util.Arrays; -import java.util.Collection; - -/** - * 会员详情封装 - * Created by macro on 2018/8/3. - */ -public class MemberDetails implements UserDetails { - private UmsMember umsMember; - - public MemberDetails(UmsMember umsMember) { - this.umsMember = umsMember; - } - - @Override - public Collection getAuthorities() { - //返回当前用户的权限 - return Arrays.asList(new SimpleGrantedAuthority("TEST")); - } - - @Override - public String getPassword() { - return umsMember.getPassword(); - } - - @Override - public String getUsername() { - return umsMember.getUsername(); - } - - @Override - public boolean isAccountNonExpired() { - return true; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @Override - public boolean isEnabled() { - return umsMember.getStatus()==1; - } - - public UmsMember getUmsMember() { - return umsMember; - } -} +//package com.macro.mall.portal.domain; +// +//import com.macro.mall.model.UmsMember; +//import org.springframework.security.core.GrantedAuthority; +//import org.springframework.security.core.authority.SimpleGrantedAuthority; +//import org.springframework.security.core.userdetails.UserDetails; +// +//import java.util.Arrays; +//import java.util.Collection; +// +///** +// * 会员详情封装 +// * Created by macro on 2018/8/3. +// */ +//public class MemberDetails implements UserDetails { +// private UmsMember umsMember; +// +// public MemberDetails(UmsMember umsMember) { +// this.umsMember = umsMember; +// } +// +// @Override +// public Collection getAuthorities() { +// //返回当前用户的权限 +// return Arrays.asList(new SimpleGrantedAuthority("TEST")); +// } +// +// @Override +// public String getPassword() { +// return umsMember.getPassword(); +// } +// +// @Override +// public String getUsername() { +// return umsMember.getUsername(); +// } +// +// @Override +// public boolean isAccountNonExpired() { +// return true; +// } +// +// @Override +// public boolean isAccountNonLocked() { +// return true; +// } +// +// @Override +// public boolean isCredentialsNonExpired() { +// return true; +// } +// +// @Override +// public boolean isEnabled() { +// return umsMember.getStatus()==1; +// } +// +// public UmsMember getUmsMember() { +// return umsMember; +// } +//} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/domain/OrderParam.java b/mall-portal/src/main/java/com/macro/mall/portal/domain/OrderParam.java index c5abbd8..9ffdab0 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/domain/OrderParam.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/domain/OrderParam.java @@ -1,48 +1,26 @@ package com.macro.mall.portal.domain; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + /** * 生成订单时传入的参数 * Created by macro on 2018/8/30. */ +@Data +@EqualsAndHashCode(callSuper = false) public class OrderParam { - //收货地址id + @ApiModelProperty("收货地址ID") private Long memberReceiveAddressId; - //优惠券id + @ApiModelProperty("优惠券ID") private Long couponId; - //使用的积分数 + @ApiModelProperty("使用的积分数") private Integer useIntegration; - //支付方式 + @ApiModelProperty("支付方式") private Integer payType; - - public Long getMemberReceiveAddressId() { - return memberReceiveAddressId; - } - - public void setMemberReceiveAddressId(Long memberReceiveAddressId) { - this.memberReceiveAddressId = memberReceiveAddressId; - } - - public Long getCouponId() { - return couponId; - } - - public void setCouponId(Long couponId) { - this.couponId = couponId; - } - - public Integer getPayType() { - return payType; - } - - public void setPayType(Integer payType) { - this.payType = payType; - } - - public Integer getUseIntegration() { - return useIntegration; - } - - public void setUseIntegration(Integer useIntegration) { - this.useIntegration = useIntegration; - } + @ApiModelProperty("被选中的购物车商品ID") + private List cartIds; } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/domain/PmsPortalProductDetail.java b/mall-portal/src/main/java/com/macro/mall/portal/domain/PmsPortalProductDetail.java new file mode 100644 index 0000000..10eeb20 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/domain/PmsPortalProductDetail.java @@ -0,0 +1,33 @@ +package com.macro.mall.portal.domain; + +import com.macro.mall.model.*; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * 前台商品详情 + * Created by macro on 2020/4/6. + */ +@Getter +@Setter +public class PmsPortalProductDetail{ + @ApiModelProperty("商品信息") + private PmsProduct product; + @ApiModelProperty("商品品牌") + private PmsBrand brand; + @ApiModelProperty("商品属性与参数") + private List productAttributeList; + @ApiModelProperty("手动录入的商品属性与参数值") + private List productAttributeValueList; + @ApiModelProperty("商品的sku库存信息") + private List skuStockList; + @ApiModelProperty("商品阶梯价格设置") + private List productLadderList; + @ApiModelProperty("商品满减价格设置") + private List productFullReductionList; + @ApiModelProperty("商品可用优惠券") + private List couponList; +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/domain/PmsProductCategoryNode.java b/mall-portal/src/main/java/com/macro/mall/portal/domain/PmsProductCategoryNode.java new file mode 100644 index 0000000..053009e --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/domain/PmsProductCategoryNode.java @@ -0,0 +1,17 @@ +package com.macro.mall.portal.domain; + +import com.macro.mall.model.PmsProductCategory; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * 商品分类,包含子分类 + * Created by macro on 2020/4/6. + */ +@Getter +@Setter +public class PmsProductCategoryNode extends PmsProductCategory { + private List children; +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberBrandAttentionRepository.java b/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberBrandAttentionRepository.java index 0339017..afb92b4 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberBrandAttentionRepository.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberBrandAttentionRepository.java @@ -1,6 +1,8 @@ package com.macro.mall.portal.repository; import com.macro.mall.portal.domain.MemberBrandAttention; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.List; @@ -12,5 +14,6 @@ import java.util.List; public interface MemberBrandAttentionRepository extends MongoRepository { MemberBrandAttention findByMemberIdAndBrandId(Long memberId, Long brandId); int deleteByMemberIdAndBrandId(Long memberId,Long brandId); - List findByMemberId(Long memberId); + Page findByMemberId(Long memberId, Pageable pageable); + void deleteAllByMemberId(Long memberId); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberProductCollectionRepository.java b/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberProductCollectionRepository.java index 1a2abdd..d4fe60e 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberProductCollectionRepository.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberProductCollectionRepository.java @@ -1,6 +1,8 @@ package com.macro.mall.portal.repository; import com.macro.mall.portal.domain.MemberProductCollection; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.List; @@ -12,5 +14,6 @@ import java.util.List; public interface MemberProductCollectionRepository extends MongoRepository { MemberProductCollection findByMemberIdAndProductId(Long memberId, Long productId); int deleteByMemberIdAndProductId(Long memberId,Long productId); - List findByMemberId(Long memberId); + Page findByMemberId(Long memberId, Pageable pageable); + void deleteAllByMemberId(Long memberId); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberReadHistoryRepository.java b/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberReadHistoryRepository.java index edd8f2b..7629e8d 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberReadHistoryRepository.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberReadHistoryRepository.java @@ -1,6 +1,8 @@ package com.macro.mall.portal.repository; import com.macro.mall.portal.domain.MemberReadHistory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.List; @@ -10,5 +12,6 @@ import java.util.List; * Created by macro on 2018/8/3. */ public interface MemberReadHistoryRepository extends MongoRepository { - List findByMemberIdOrderByCreateTimeDesc(Long memberId); + Page findByMemberIdOrderByCreateTimeDesc(Long memberId, Pageable pageable); + void deleteAllByMemberId(Long memberId); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/AuthService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/AuthService.java new file mode 100644 index 0000000..a382e68 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/AuthService.java @@ -0,0 +1,20 @@ +package com.macro.mall.portal.service; + +import com.macro.mall.common.api.CommonResult; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.Map; + +/** + * 认证服务远程调用 + * Created by macro on 2020/7/19. + */ +@FeignClient("mall-auth") +public interface AuthService { + + @PostMapping(value = "/oauth/token") + CommonResult getAccessToken(@RequestParam Map parameters); + +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/HomeService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/HomeService.java index 762c6f0..d502e42 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/HomeService.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/HomeService.java @@ -34,4 +34,14 @@ public interface HomeService { * @param cateId 专题分类id */ List getSubjectList(Long cateId, Integer pageSize, Integer pageNum); + + /** + * 分页获取人气推荐商品 + */ + List hotProductList(Integer pageNum, Integer pageSize); + + /** + * 分页获取新品推荐商品 + */ + List newProductList(Integer pageNum, Integer pageSize); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/MemberAttentionService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/MemberAttentionService.java index 977fd3b..6a64917 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/MemberAttentionService.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/MemberAttentionService.java @@ -1,6 +1,7 @@ package com.macro.mall.portal.service; import com.macro.mall.portal.domain.MemberBrandAttention; +import org.springframework.data.domain.Page; import java.util.List; @@ -17,10 +18,20 @@ public interface MemberAttentionService { /** * 取消关注 */ - int delete(Long memberId, Long brandId); + int delete(Long brandId); /** * 获取用户关注列表 */ - List list(Long memberId); + Page list(Integer pageNum, Integer pageSize); + + /** + * 获取用户关注详情 + */ + MemberBrandAttention detail(Long brandId); + + /** + * 清空关注列表 + */ + void clear(); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/MemberCollectionService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/MemberCollectionService.java index 5b2d080..6bb7812 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/MemberCollectionService.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/MemberCollectionService.java @@ -1,6 +1,7 @@ package com.macro.mall.portal.service; import com.macro.mall.portal.domain.MemberProductCollection; +import org.springframework.data.domain.Page; import java.util.List; @@ -9,9 +10,13 @@ import java.util.List; * Created by macro on 2018/8/2. */ public interface MemberCollectionService { - int addProduct(MemberProductCollection productCollection); + int add(MemberProductCollection productCollection); - int deleteProduct(Long memberId, Long productId); + int delete(Long productId); - List listProduct(Long memberId); + Page list(Integer pageNum, Integer pageSize); + + MemberProductCollection detail(Long productId); + + void clear(); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/MemberReadHistoryService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/MemberReadHistoryService.java index 66f38f2..f3fcc81 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/MemberReadHistoryService.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/MemberReadHistoryService.java @@ -1,6 +1,7 @@ package com.macro.mall.portal.service; import com.macro.mall.portal.domain.MemberReadHistory; +import org.springframework.data.domain.Page; import java.util.List; @@ -20,7 +21,12 @@ public interface MemberReadHistoryService { int delete(List ids); /** - * 获取用户浏览历史记录 + * 分页获取用户浏览历史记录 */ - List list(Long memberId); + Page list(Integer pageNum, Integer pageSize); + + /** + * 清空浏览记录 + */ + void clear(); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/OmsCartItemService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/OmsCartItemService.java index ef401df..96da5dd 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/OmsCartItemService.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/OmsCartItemService.java @@ -26,7 +26,7 @@ public interface OmsCartItemService { /** * 获取包含促销活动信息的购物车列表 */ - List listPromotion(Long memberId); + List listPromotion(Long memberId, List cartIds); /** * 修改某个购物车商品的数量 diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/OmsPortalOrderService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/OmsPortalOrderService.java index 46048f5..9aa3e19 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/OmsPortalOrderService.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/OmsPortalOrderService.java @@ -1,9 +1,12 @@ package com.macro.mall.portal.service; +import com.macro.mall.common.api.CommonPage; import com.macro.mall.portal.domain.ConfirmOrderResult; +import com.macro.mall.portal.domain.OmsOrderDetail; import com.macro.mall.portal.domain.OrderParam; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.Map; /** @@ -13,8 +16,9 @@ import java.util.Map; public interface OmsPortalOrderService { /** * 根据用户购物车信息生成确认单信息 + * @param cartIds */ - ConfirmOrderResult generateConfirmOrder(); + ConfirmOrderResult generateConfirmOrder(List cartIds); /** * 根据提交信息生成订单 @@ -26,7 +30,7 @@ public interface OmsPortalOrderService { * 支付成功后的回调 */ @Transactional - Integer paySuccess(Long orderId); + Integer paySuccess(Long orderId, Integer payType); /** * 自动取消超时订单 @@ -44,4 +48,24 @@ public interface OmsPortalOrderService { * 发送延迟消息取消订单 */ void sendDelayMessageCancelOrder(Long orderId); + + /** + * 确认收货 + */ + void confirmReceiveOrder(Long orderId); + + /** + * 分页获取用户订单 + */ + CommonPage list(Integer status, Integer pageNum, Integer pageSize); + + /** + * 根据订单ID获取订单详情 + */ + OmsOrderDetail detail(Long orderId); + + /** + * 用户根据订单ID删除订单 + */ + void deleteOrder(Long orderId); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/PmsPortalProductService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/PmsPortalProductService.java new file mode 100644 index 0000000..fdf3dea --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/PmsPortalProductService.java @@ -0,0 +1,28 @@ +package com.macro.mall.portal.service; + +import com.macro.mall.model.PmsProduct; +import com.macro.mall.portal.domain.PmsPortalProductDetail; +import com.macro.mall.portal.domain.PmsProductCategoryNode; + +import java.util.List; + +/** + * 前台商品管理Service + * Created by macro on 2020/4/6. + */ +public interface PmsPortalProductService { + /** + * 综合搜索商品 + */ + List search(String keyword, Long brandId, Long productCategoryId, Integer pageNum, Integer pageSize, Integer sort); + + /** + * 以树形结构获取所有商品分类 + */ + List categoryTreeList(); + + /** + * 获取前台商品详情 + */ + PmsPortalProductDetail detail(Long id); +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/PortalBrandService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/PortalBrandService.java new file mode 100644 index 0000000..256db28 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/PortalBrandService.java @@ -0,0 +1,28 @@ +package com.macro.mall.portal.service; + +import com.macro.mall.common.api.CommonPage; +import com.macro.mall.model.PmsBrand; +import com.macro.mall.model.PmsProduct; + +import java.util.List; + +/** + * 前台品牌管理Service + * Created by macro on 2020/5/15. + */ +public interface PortalBrandService { + /** + * 分页获取推荐品牌 + */ + List recommendList(Integer pageNum, Integer pageSize); + + /** + * 获取品牌详情 + */ + PmsBrand detail(Long brandId); + + /** + * 分页获取品牌关联商品 + */ + CommonPage productList(Long brandId, Integer pageNum, Integer pageSize); +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/RedisService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/RedisService.java deleted file mode 100644 index bc1bf81..0000000 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/RedisService.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.macro.mall.portal.service; - -/** - * redis操作Service, - * 对象和数组都以json形式进行存储 - * Created by macro on 2018/8/7. - */ -public interface RedisService { - /** - * 存储数据 - */ - void set(String key, String value); - - /** - * 获取数据 - */ - String get(String key); - - /** - * 设置超期时间 - */ - boolean expire(String key, long expire); - - /** - * 删除数据 - */ - void remove(String key); - - /** - * 自增操作 - * @param delta 自增步长 - */ - Long increment(String key, long delta); - -} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberCacheService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberCacheService.java new file mode 100644 index 0000000..f5c0dd7 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberCacheService.java @@ -0,0 +1,34 @@ +package com.macro.mall.portal.service; + +import com.macro.mall.model.UmsMember; + +/** + * 会员信息缓存业务类 + * Created by macro on 2020/3/14. + */ +public interface UmsMemberCacheService { + /** + * 删除会员用户缓存 + */ + void delMember(Long memberId); + + /** + * 获取会员用户缓存 + */ + UmsMember getMember(Long memberId); + + /** + * 设置会员用户缓存 + */ + void setMember(UmsMember member); + + /** + * 设置验证码 + */ + void setAuthCode(String telephone, String authCode); + + /** + * 获取验证码 + */ + String getAuthCode(String telephone); +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberCouponService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberCouponService.java index a34a1db..44ada98 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberCouponService.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberCouponService.java @@ -1,5 +1,6 @@ package com.macro.mall.portal.service; +import com.macro.mall.model.SmsCoupon; import com.macro.mall.model.SmsCouponHistory; import com.macro.mall.portal.domain.CartPromotionItem; import com.macro.mall.portal.domain.SmsCouponHistoryDetail; @@ -19,13 +20,22 @@ public interface UmsMemberCouponService { void add(Long couponId); /** - * 获取优惠券列表 - * @param useStatus 优惠券的使用状态 + * 获取优惠券历史列表 */ - List list(Integer useStatus); + List listHistory(Integer useStatus); /** * 根据购物车信息获取可用优惠券 */ List listCart(List cartItemList, Integer type); + + /** + * 获取当前商品相关优惠券 + */ + List listByProduct(Long productId); + + /** + * 获取用户优惠券列表 + */ + List list(Integer useStatus); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberReceiveAddressService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberReceiveAddressService.java index dcfab7b..3c70c8d 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberReceiveAddressService.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberReceiveAddressService.java @@ -1,6 +1,7 @@ package com.macro.mall.portal.service; import com.macro.mall.model.UmsMemberReceiveAddress; +import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -25,6 +26,7 @@ public interface UmsMemberReceiveAddressService { * @param id 地址表的id * @param address 修改的收货地址信息 */ + @Transactional int update(Long id, UmsMemberReceiveAddress address); /** diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberService.java index 0dfc499..42199f4 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberService.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberService.java @@ -1,8 +1,8 @@ package com.macro.mall.portal.service; import com.macro.mall.common.api.CommonResult; +import com.macro.mall.common.domain.UserDto; import com.macro.mall.model.UmsMember; -import org.springframework.security.core.userdetails.UserDetails; import org.springframework.transaction.annotation.Transactional; /** @@ -51,15 +51,10 @@ public interface UmsMemberService { /** * 获取用户信息 */ - UserDetails loadUserByUsername(String username); + UserDto loadUserByUsername(String username); /** * 登录后获取token */ - String login(String username, String password); - - /** - * 刷新token - */ - String refreshToken(String token); + CommonResult login(String username, String password); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/HomeServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/HomeServiceImpl.java index 16d3d74..0f98a0a 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/HomeServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/HomeServiceImpl.java @@ -43,7 +43,7 @@ public class HomeServiceImpl implements HomeService { //获取首页广告 result.setAdvertiseList(getHomeAdvertiseList()); //获取推荐品牌 - result.setBrandList(homeDao.getRecommendBrandList(0,4)); + result.setBrandList(homeDao.getRecommendBrandList(0,6)); //获取秒杀信息 result.setHomeFlashPromotion(getHomeFlashPromotion()); //获取新品推荐 @@ -88,6 +88,18 @@ public class HomeServiceImpl implements HomeService { return subjectMapper.selectByExample(example); } + @Override + public List hotProductList(Integer pageNum, Integer pageSize) { + int offset = pageSize * (pageNum - 1); + return homeDao.getHotProductList(offset, pageSize); + } + + @Override + public List newProductList(Integer pageNum, Integer pageSize) { + int offset = pageSize * (pageNum - 1); + return homeDao.getNewProductList(offset, pageSize); + } + private HomeFlashPromotion getHomeFlashPromotion() { HomeFlashPromotion homeFlashPromotion = new HomeFlashPromotion(); //获取当前秒杀活动 diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberAttentionServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberAttentionServiceImpl.java index 42038ff..1a05d18 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberAttentionServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberAttentionServiceImpl.java @@ -1,11 +1,17 @@ package com.macro.mall.portal.service.impl; +import com.macro.mall.model.UmsMember; import com.macro.mall.portal.domain.MemberBrandAttention; import com.macro.mall.portal.repository.MemberBrandAttentionRepository; import com.macro.mall.portal.service.MemberAttentionService; +import com.macro.mall.portal.service.UmsMemberService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import java.util.Date; import java.util.List; /** @@ -16,10 +22,17 @@ import java.util.List; public class MemberAttentionServiceImpl implements MemberAttentionService { @Autowired private MemberBrandAttentionRepository memberBrandAttentionRepository; + @Autowired + private UmsMemberService memberService; @Override public int add(MemberBrandAttention memberBrandAttention) { int count = 0; + UmsMember member = memberService.getCurrentMember(); + memberBrandAttention.setMemberId(member.getId()); + memberBrandAttention.setMemberNickname(member.getNickname()); + memberBrandAttention.setMemberIcon(member.getIcon()); + memberBrandAttention.setCreateTime(new Date()); MemberBrandAttention findAttention = memberBrandAttentionRepository.findByMemberIdAndBrandId(memberBrandAttention.getMemberId(), memberBrandAttention.getBrandId()); if (findAttention == null) { memberBrandAttentionRepository.save(memberBrandAttention); @@ -29,12 +42,27 @@ public class MemberAttentionServiceImpl implements MemberAttentionService { } @Override - public int delete(Long memberId, Long brandId) { - return memberBrandAttentionRepository.deleteByMemberIdAndBrandId(memberId,brandId); + public int delete(Long brandId) { + UmsMember member = memberService.getCurrentMember(); + return memberBrandAttentionRepository.deleteByMemberIdAndBrandId(member.getId(),brandId); } @Override - public List list(Long memberId) { - return memberBrandAttentionRepository.findByMemberId(memberId); + public Page list(Integer pageNum, Integer pageSize) { + UmsMember member = memberService.getCurrentMember(); + Pageable pageable = PageRequest.of(pageNum-1,pageSize); + return memberBrandAttentionRepository.findByMemberId(member.getId(),pageable); + } + + @Override + public MemberBrandAttention detail(Long brandId) { + UmsMember member = memberService.getCurrentMember(); + return memberBrandAttentionRepository.findByMemberIdAndBrandId(member.getId(), brandId); + } + + @Override + public void clear() { + UmsMember member = memberService.getCurrentMember(); + memberBrandAttentionRepository.deleteAllByMemberId(member.getId()); } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberCollectionServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberCollectionServiceImpl.java index 7c02ecc..e79b3fd 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberCollectionServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberCollectionServiceImpl.java @@ -1,9 +1,14 @@ package com.macro.mall.portal.service.impl; +import com.macro.mall.model.UmsMember; import com.macro.mall.portal.domain.MemberProductCollection; import com.macro.mall.portal.repository.MemberProductCollectionRepository; import com.macro.mall.portal.service.MemberCollectionService; +import com.macro.mall.portal.service.UmsMemberService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.List; @@ -16,10 +21,16 @@ import java.util.List; public class MemberCollectionServiceImpl implements MemberCollectionService { @Autowired private MemberProductCollectionRepository productCollectionRepository; + @Autowired + private UmsMemberService memberService; @Override - public int addProduct(MemberProductCollection productCollection) { + public int add(MemberProductCollection productCollection) { int count = 0; + UmsMember member = memberService.getCurrentMember(); + productCollection.setMemberId(member.getId()); + productCollection.setMemberNickname(member.getNickname()); + productCollection.setMemberIcon(member.getIcon()); MemberProductCollection findCollection = productCollectionRepository.findByMemberIdAndProductId(productCollection.getMemberId(), productCollection.getProductId()); if (findCollection == null) { productCollectionRepository.save(productCollection); @@ -29,12 +40,27 @@ public class MemberCollectionServiceImpl implements MemberCollectionService { } @Override - public int deleteProduct(Long memberId, Long productId) { - return productCollectionRepository.deleteByMemberIdAndProductId(memberId, productId); + public int delete(Long productId) { + UmsMember member = memberService.getCurrentMember(); + return productCollectionRepository.deleteByMemberIdAndProductId(member.getId(), productId); } @Override - public List listProduct(Long memberId) { - return productCollectionRepository.findByMemberId(memberId); + public Page list(Integer pageNum, Integer pageSize) { + UmsMember member = memberService.getCurrentMember(); + Pageable pageable = PageRequest.of(pageNum - 1, pageSize); + return productCollectionRepository.findByMemberId(member.getId(), pageable); + } + + @Override + public MemberProductCollection detail(Long productId) { + UmsMember member = memberService.getCurrentMember(); + return productCollectionRepository.findByMemberIdAndProductId(member.getId(), productId); + } + + @Override + public void clear() { + UmsMember member = memberService.getCurrentMember(); + productCollectionRepository.deleteAllByMemberId(member.getId()); } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberReadHistoryServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberReadHistoryServiceImpl.java index d8ed9f5..7b5e884 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberReadHistoryServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberReadHistoryServiceImpl.java @@ -1,9 +1,14 @@ package com.macro.mall.portal.service.impl; +import com.macro.mall.model.UmsMember; import com.macro.mall.portal.domain.MemberReadHistory; import com.macro.mall.portal.repository.MemberReadHistoryRepository; import com.macro.mall.portal.service.MemberReadHistoryService; +import com.macro.mall.portal.service.UmsMemberService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -18,8 +23,14 @@ import java.util.List; public class MemberReadHistoryServiceImpl implements MemberReadHistoryService { @Autowired private MemberReadHistoryRepository memberReadHistoryRepository; + @Autowired + private UmsMemberService memberService; @Override public int create(MemberReadHistory memberReadHistory) { + UmsMember member = memberService.getCurrentMember(); + memberReadHistory.setMemberId(member.getId()); + memberReadHistory.setMemberNickname(member.getNickname()); + memberReadHistory.setMemberIcon(member.getIcon()); memberReadHistory.setId(null); memberReadHistory.setCreateTime(new Date()); memberReadHistoryRepository.save(memberReadHistory); @@ -39,7 +50,15 @@ public class MemberReadHistoryServiceImpl implements MemberReadHistoryService { } @Override - public List list(Long memberId) { - return memberReadHistoryRepository.findByMemberIdOrderByCreateTimeDesc(memberId); + public Page list(Integer pageNum, Integer pageSize) { + UmsMember member = memberService.getCurrentMember(); + Pageable pageable = PageRequest.of(pageNum-1, pageSize); + return memberReadHistoryRepository.findByMemberIdOrderByCreateTimeDesc(member.getId(),pageable); + } + + @Override + public void clear() { + UmsMember member = memberService.getCurrentMember(); + memberReadHistoryRepository.deleteAllByMemberId(member.getId()); } } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsCartItemServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsCartItemServiceImpl.java index 1f818e9..869678c 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsCartItemServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsCartItemServiceImpl.java @@ -1,5 +1,6 @@ package com.macro.mall.portal.service.impl; +import cn.hutool.core.collection.CollUtil; import com.macro.mall.mapper.OmsCartItemMapper; import com.macro.mall.model.OmsCartItem; import com.macro.mall.model.OmsCartItemExample; @@ -18,6 +19,7 @@ import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; /** * 购物车管理Service实现类 @@ -78,8 +80,11 @@ public class OmsCartItemServiceImpl implements OmsCartItemService { } @Override - public List listPromotion(Long memberId) { + public List listPromotion(Long memberId, List cartIds) { List cartItemList = list(memberId); + if(CollUtil.isNotEmpty(cartIds)){ + cartItemList = cartItemList.stream().filter(item->cartIds.contains(item.getId())).collect(Collectors.toList()); + } List cartPromotionItemList = new ArrayList<>(); if(!CollectionUtils.isEmpty(cartItemList)){ cartPromotionItemList = promotionService.calcCartPromotion(cartItemList); diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPortalOrderServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPortalOrderServiceImpl.java index 6c7a33b..bc021e6 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPortalOrderServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPortalOrderServiceImpl.java @@ -1,6 +1,11 @@ package com.macro.mall.portal.service.impl; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import com.github.pagehelper.PageHelper; +import com.macro.mall.common.api.CommonPage; import com.macro.mall.common.exception.Asserts; +import com.macro.mall.common.service.RedisService; import com.macro.mall.mapper.*; import com.macro.mall.model.*; import com.macro.mall.portal.component.CancelOrderSender; @@ -18,6 +23,7 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.util.*; +import java.util.stream.Collectors; /** * 前台订单管理Service @@ -47,8 +53,10 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService { private SmsCouponHistoryMapper couponHistoryMapper; @Autowired private RedisService redisService; - @Value("${redis.key.prefix.orderId}") - private String REDIS_KEY_PREFIX_ORDER_ID; + @Value("${redis.key.orderId}") + private String REDIS_KEY_ORDER_ID; + @Value("${redis.database}") + private String REDIS_DATABASE; @Autowired private PortalOrderDao portalOrderDao; @Autowired @@ -59,11 +67,11 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService { private CancelOrderSender cancelOrderSender; @Override - public ConfirmOrderResult generateConfirmOrder() { + public ConfirmOrderResult generateConfirmOrder(List cartIds) { ConfirmOrderResult result = new ConfirmOrderResult(); //获取购物车信息 UmsMember currentMember = memberService.getCurrentMember(); - List cartPromotionItemList = cartItemService.listPromotion(currentMember.getId()); + List cartPromotionItemList = cartItemService.listPromotion(currentMember.getId(),cartIds); result.setCartPromotionItemList(cartPromotionItemList); //获取用户收货地址列表 List memberReceiveAddressList = memberReceiveAddressService.list(); @@ -87,7 +95,7 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService { List orderItemList = new ArrayList<>(); //获取购物车及优惠信息 UmsMember currentMember = memberService.getCurrentMember(); - List cartPromotionItemList = cartItemService.listPromotion(currentMember.getId()); + List cartPromotionItemList = cartItemService.listPromotion(currentMember.getId(), orderParam.getCartIds()); for (CartPromotionItem cartPromotionItem : cartPromotionItemList) { //生成下单商品信息 OmsOrderItem orderItem = new OmsOrderItem(); @@ -128,7 +136,7 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService { handleCouponAmount(orderItemList, couponHistoryDetail); } //判断是否使用积分 - if (orderParam.getUseIntegration() == null) { + if (orderParam.getUseIntegration() == null||orderParam.getUseIntegration().equals(0)) { //不使用积分 for (OmsOrderItem orderItem : orderItemList) { orderItem.setIntegrationAmount(new BigDecimal(0)); @@ -202,6 +210,11 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService { order.setGrowth(calcGiftGrowth(orderItemList)); //生成订单号 order.setOrderSn(generateOrderSn(order)); + //设置自动收货天数 + List orderSettings = orderSettingMapper.selectByExample(new OmsOrderSettingExample()); + if(CollUtil.isNotEmpty(orderSettings)){ + order.setAutoConfirmDay(orderSettings.get(0).getConfirmOvertime()); + } // TODO: 2018/9/3 bill_*,delivery_* //插入order表和order_item表 orderMapper.insert(order); @@ -230,12 +243,13 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService { } @Override - public Integer paySuccess(Long orderId) { + public Integer paySuccess(Long orderId, Integer payType) { //修改订单支付状态 OmsOrder order = new OmsOrder(); order.setId(orderId); order.setStatus(1); order.setPaymentTime(new Date()); + order.setPayType(payType); orderMapper.updateByPrimaryKeySelective(order); //恢复所有下单商品的锁定库存,扣减真实库存 OmsOrderDetail orderDetail = portalOrderDao.getDetail(orderId); @@ -274,7 +288,7 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService { @Override public void cancelOrder(Long orderId) { - //查询为付款的取消订单 + //查询未付款的取消订单 OmsOrderExample example = new OmsOrderExample(); example.createCriteria().andIdEqualTo(orderId).andStatusEqualTo(0).andDeleteStatusEqualTo(0); List cancelOrderList = orderMapper.selectByExample(example); @@ -312,14 +326,100 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService { cancelOrderSender.sendMessage(orderId, delayTimes); } + @Override + public void confirmReceiveOrder(Long orderId) { + UmsMember member = memberService.getCurrentMember(); + OmsOrder order = orderMapper.selectByPrimaryKey(orderId); + if(!member.getId().equals(order.getMemberId())){ + Asserts.fail("不能确认他人订单!"); + } + if(order.getStatus()!=2){ + Asserts.fail("该订单还未发货!"); + } + order.setStatus(3); + order.setConfirmStatus(1); + order.setReceiveTime(new Date()); + orderMapper.updateByPrimaryKey(order); + } + + @Override + public CommonPage list(Integer status, Integer pageNum, Integer pageSize) { + if(status==-1){ + status = null; + } + UmsMember member = memberService.getCurrentMember(); + PageHelper.startPage(pageNum,pageSize); + OmsOrderExample orderExample = new OmsOrderExample(); + OmsOrderExample.Criteria criteria = orderExample.createCriteria(); + criteria.andDeleteStatusEqualTo(0) + .andMemberIdEqualTo(member.getId()); + if(status!=null){ + criteria.andStatusEqualTo(status); + } + orderExample.setOrderByClause("create_time desc"); + List orderList = orderMapper.selectByExample(orderExample); + CommonPage orderPage = CommonPage.restPage(orderList); + //设置分页信息 + CommonPage resultPage = new CommonPage<>(); + resultPage.setPageNum(orderPage.getPageNum()); + resultPage.setPageSize(orderPage.getPageSize()); + resultPage.setTotal(orderPage.getTotal()); + resultPage.setTotalPage(orderPage.getTotalPage()); + if(CollUtil.isEmpty(orderList)){ + return resultPage; + } + //设置数据信息 + List orderIds = orderList.stream().map(OmsOrder::getId).collect(Collectors.toList()); + OmsOrderItemExample orderItemExample = new OmsOrderItemExample(); + orderItemExample.createCriteria().andOrderIdIn(orderIds); + List orderItemList = orderItemMapper.selectByExample(orderItemExample); + List orderDetailList = new ArrayList<>(); + for (OmsOrder omsOrder : orderList) { + OmsOrderDetail orderDetail = new OmsOrderDetail(); + BeanUtil.copyProperties(omsOrder,orderDetail); + List relatedItemList = orderItemList.stream().filter(item -> item.getOrderId().equals(orderDetail.getId())).collect(Collectors.toList()); + orderDetail.setOrderItemList(relatedItemList); + orderDetailList.add(orderDetail); + } + resultPage.setList(orderDetailList); + return resultPage; + } + + @Override + public OmsOrderDetail detail(Long orderId) { + OmsOrder omsOrder = orderMapper.selectByPrimaryKey(orderId); + OmsOrderItemExample example = new OmsOrderItemExample(); + example.createCriteria().andOrderIdEqualTo(orderId); + List orderItemList = orderItemMapper.selectByExample(example); + OmsOrderDetail orderDetail = new OmsOrderDetail(); + BeanUtil.copyProperties(omsOrder,orderDetail); + orderDetail.setOrderItemList(orderItemList); + return orderDetail; + } + + @Override + public void deleteOrder(Long orderId) { + UmsMember member = memberService.getCurrentMember(); + OmsOrder order = orderMapper.selectByPrimaryKey(orderId); + if(!member.getId().equals(order.getMemberId())){ + Asserts.fail("不能删除他人订单!"); + } + if(order.getStatus()==3||order.getStatus()==4){ + order.setDeleteStatus(1); + orderMapper.updateByPrimaryKey(order); + }else{ + Asserts.fail("只能删除已完成或已关闭的订单!"); + } + } + /** * 生成18位订单编号:8位日期+2位平台号码+2位支付方式+6位以上自增id */ private String generateOrderSn(OmsOrder order) { StringBuilder sb = new StringBuilder(); String date = new SimpleDateFormat("yyyyMMdd").format(new Date()); - String key = REDIS_KEY_PREFIX_ORDER_ID + date; - Long increment = redisService.increment(key, 1); + String key = REDIS_DATABASE+":"+ REDIS_KEY_ORDER_ID + date; + Long increment = redisService.incr(key, 1); sb.append(date); sb.append(String.format("%02d", order.getSourceType())); sb.append(String.format("%02d", order.getPayType())); @@ -405,10 +505,10 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService { StringBuilder sb = new StringBuilder(); for (OmsOrderItem orderItem : orderItemList) { sb.append(orderItem.getPromotionName()); - sb.append(","); + sb.append(";"); } String result = sb.toString(); - if (result.endsWith(",")) { + if (result.endsWith(";")) { result = result.substring(0, result.length() - 1); } return result; diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPromotionServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPromotionServiceImpl.java index 72657df..0be2dce 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPromotionServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/OmsPromotionServiceImpl.java @@ -48,6 +48,8 @@ public class OmsPromotionServiceImpl implements OmsPromotionService { //商品原价-促销价 PmsSkuStock skuStock = getOriginalPrice(promotionProduct, item.getProductSkuId()); BigDecimal originalPrice = skuStock.getPrice(); + //单品促销使用原价 + cartPromotionItem.setPrice(originalPrice); cartPromotionItem.setReduceAmount(originalPrice.subtract(skuStock.getPromotionPrice())); cartPromotionItem.setRealStock(skuStock.getStock()-skuStock.getLockStock()); cartPromotionItem.setIntegration(promotionProduct.getGiftPoint()); diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/PmsPortalProductServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/PmsPortalProductServiceImpl.java new file mode 100644 index 0000000..d29eaa0 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/PmsPortalProductServiceImpl.java @@ -0,0 +1,142 @@ +package com.macro.mall.portal.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.github.pagehelper.PageHelper; +import com.macro.mall.mapper.*; +import com.macro.mall.model.*; +import com.macro.mall.portal.dao.PortalProductDao; +import com.macro.mall.portal.domain.PmsPortalProductDetail; +import com.macro.mall.portal.domain.PmsProductCategoryNode; +import com.macro.mall.portal.service.PmsPortalProductService; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 前台订单管理Service实现类 + * Created by macro on 2020/4/6. + */ +@Service +public class PmsPortalProductServiceImpl implements PmsPortalProductService { + @Autowired + private PmsProductMapper productMapper; + @Autowired + private PmsProductCategoryMapper productCategoryMapper; + @Autowired + private PmsBrandMapper brandMapper; + @Autowired + private PmsProductAttributeMapper productAttributeMapper; + @Autowired + private PmsProductAttributeValueMapper productAttributeValueMapper; + @Autowired + private PmsSkuStockMapper skuStockMapper; + @Autowired + private PmsProductLadderMapper productLadderMapper; + @Autowired + private PmsProductFullReductionMapper productFullReductionMapper; + @Autowired + private PortalProductDao portalProductDao; + + @Override + public List search(String keyword, Long brandId, Long productCategoryId, Integer pageNum, Integer pageSize, Integer sort) { + PageHelper.startPage(pageNum, pageSize); + PmsProductExample example = new PmsProductExample(); + PmsProductExample.Criteria criteria = example.createCriteria(); + criteria.andDeleteStatusEqualTo(0); + if (StrUtil.isNotEmpty(keyword)) { + criteria.andNameLike("%" + keyword + "%"); + } + if (brandId != null) { + criteria.andBrandIdEqualTo(brandId); + } + if (productCategoryId != null) { + criteria.andProductCategoryIdEqualTo(productCategoryId); + } + //1->按新品;2->按销量;3->价格从低到高;4->价格从高到低 + if (sort == 1) { + example.setOrderByClause("id desc"); + } else if (sort == 2) { + example.setOrderByClause("sale desc"); + } else if (sort == 3) { + example.setOrderByClause("price asc"); + } else if (sort == 4) { + example.setOrderByClause("price desc"); + } + return productMapper.selectByExample(example); + } + + @Override + public List categoryTreeList() { + PmsProductCategoryExample example = new PmsProductCategoryExample(); + List allList = productCategoryMapper.selectByExample(example); + List result = allList.stream() + .filter(item -> item.getParentId().equals(0L)) + .map(item -> covert(item, allList)).collect(Collectors.toList()); + return result; + } + + @Override + public PmsPortalProductDetail detail(Long id) { + PmsPortalProductDetail result = new PmsPortalProductDetail(); + //获取商品信息 + PmsProduct product = productMapper.selectByPrimaryKey(id); + result.setProduct(product); + //获取品牌信息 + PmsBrand brand = brandMapper.selectByPrimaryKey(product.getBrandId()); + result.setBrand(brand); + //获取商品属性信息 + PmsProductAttributeExample attributeExample = new PmsProductAttributeExample(); + attributeExample.createCriteria().andProductAttributeCategoryIdEqualTo(product.getProductAttributeCategoryId()); + List productAttributeList = productAttributeMapper.selectByExample(attributeExample); + result.setProductAttributeList(productAttributeList); + //获取商品属性值信息 + if(CollUtil.isNotEmpty(productAttributeList)){ + List attributeIds = productAttributeList.stream().map(PmsProductAttribute::getId).collect(Collectors.toList()); + PmsProductAttributeValueExample attributeValueExample = new PmsProductAttributeValueExample(); + attributeValueExample.createCriteria().andProductIdEqualTo(product.getId()) + .andProductAttributeIdIn(attributeIds); + List productAttributeValueList = productAttributeValueMapper.selectByExample(attributeValueExample); + result.setProductAttributeValueList(productAttributeValueList); + } + //获取商品SKU库存信息 + PmsSkuStockExample skuExample = new PmsSkuStockExample(); + skuExample.createCriteria().andProductIdEqualTo(product.getId()); + List skuStockList = skuStockMapper.selectByExample(skuExample); + result.setSkuStockList(skuStockList); + //商品阶梯价格设置 + if(product.getPromotionType()==3){ + PmsProductLadderExample ladderExample = new PmsProductLadderExample(); + ladderExample.createCriteria().andProductIdEqualTo(product.getId()); + List productLadderList = productLadderMapper.selectByExample(ladderExample); + result.setProductLadderList(productLadderList); + } + //商品满减价格设置 + if(product.getPromotionType()==4){ + PmsProductFullReductionExample fullReductionExample = new PmsProductFullReductionExample(); + fullReductionExample.createCriteria().andProductIdEqualTo(product.getId()); + List productFullReductionList = productFullReductionMapper.selectByExample(fullReductionExample); + result.setProductFullReductionList(productFullReductionList); + } + //商品可用优惠券 + result.setCouponList(portalProductDao.getAvailableCouponList(product.getId(),product.getProductCategoryId())); + return result; + } + + + /** + * 初始对象转化为节点对象 + */ + private PmsProductCategoryNode covert(PmsProductCategory item, List allList) { + PmsProductCategoryNode node = new PmsProductCategoryNode(); + BeanUtils.copyProperties(item, node); + List children = allList.stream() + .filter(subItem -> subItem.getParentId().equals(item.getId())) + .map(subItem -> covert(subItem, allList)).collect(Collectors.toList()); + node.setChildren(children); + return node; + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/PortalBrandServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/PortalBrandServiceImpl.java new file mode 100644 index 0000000..a95bebf --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/PortalBrandServiceImpl.java @@ -0,0 +1,50 @@ +package com.macro.mall.portal.service.impl; + +import com.github.pagehelper.PageHelper; +import com.macro.mall.common.api.CommonPage; +import com.macro.mall.mapper.PmsBrandMapper; +import com.macro.mall.mapper.PmsProductMapper; +import com.macro.mall.model.PmsBrand; +import com.macro.mall.model.PmsProduct; +import com.macro.mall.model.PmsProductExample; +import com.macro.mall.portal.dao.HomeDao; +import com.macro.mall.portal.service.PortalBrandService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 前台品牌管理Service实现类 + * Created by macro on 2020/5/15. + */ +@Service +public class PortalBrandServiceImpl implements PortalBrandService { + @Autowired + private HomeDao homeDao; + @Autowired + private PmsBrandMapper brandMapper; + @Autowired + private PmsProductMapper productMapper; + + @Override + public List recommendList(Integer pageNum, Integer pageSize) { + int offset = (pageNum - 1) * pageSize; + return homeDao.getRecommendBrandList(offset, pageSize); + } + + @Override + public PmsBrand detail(Long brandId) { + return brandMapper.selectByPrimaryKey(brandId); + } + + @Override + public CommonPage productList(Long brandId, Integer pageNum, Integer pageSize) { + PageHelper.startPage(pageNum,pageSize); + PmsProductExample example = new PmsProductExample(); + example.createCriteria().andDeleteStatusEqualTo(0) + .andBrandIdEqualTo(brandId); + List productList = productMapper.selectByExample(example); + return CommonPage.restPage(productList); + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/RedisServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/RedisServiceImpl.java deleted file mode 100644 index 8426397..0000000 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/RedisServiceImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.macro.mall.portal.service.impl; - -import com.macro.mall.portal.service.RedisService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.StringRedisTemplate; -import org.springframework.stereotype.Service; - -import java.util.concurrent.TimeUnit; - -/** - * redis操作Service的实现类 - * Created by macro on 2018/8/7. - */ -@Service -public class RedisServiceImpl implements RedisService { - @Autowired - private StringRedisTemplate stringRedisTemplate; - - @Override - public void set(String key, String value) { - stringRedisTemplate.opsForValue().set(key, value); - } - - @Override - public String get(String key) { - return stringRedisTemplate.opsForValue().get(key); - } - - @Override - public boolean expire(String key, long expire) { - return stringRedisTemplate.expire(key, expire, TimeUnit.SECONDS); - } - - @Override - public void remove(String key) { - stringRedisTemplate.delete(key); - } - - @Override - public Long increment(String key, long delta) { - return stringRedisTemplate.opsForValue().increment(key,delta); - } -} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberCacheServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberCacheServiceImpl.java new file mode 100644 index 0000000..42812fe --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberCacheServiceImpl.java @@ -0,0 +1,62 @@ +package com.macro.mall.portal.service.impl; + +import com.macro.mall.common.annotation.CacheException; +import com.macro.mall.common.service.RedisService; +import com.macro.mall.mapper.UmsMemberMapper; +import com.macro.mall.model.UmsMember; +import com.macro.mall.portal.service.UmsMemberCacheService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * UmsMemberCacheService实现类 + * Created by macro on 2020/3/14. + */ +@Service +public class UmsMemberCacheServiceImpl implements UmsMemberCacheService { + @Autowired + private RedisService redisService; + @Value("${redis.database}") + private String REDIS_DATABASE; + @Value("${redis.expire.common}") + private Long REDIS_EXPIRE; + @Value("${redis.expire.authCode}") + private Long REDIS_EXPIRE_AUTH_CODE; + @Value("${redis.key.member}") + private String REDIS_KEY_MEMBER; + @Value("${redis.key.authCode}") + private String REDIS_KEY_AUTH_CODE; + + @Override + public void delMember(Long memberId) { + String key = REDIS_DATABASE + ":" + REDIS_KEY_MEMBER + ":" + memberId; + redisService.del(key); + } + + @Override + public UmsMember getMember(Long memberId) { + String key = REDIS_DATABASE + ":" + REDIS_KEY_MEMBER + ":" + memberId; + return (UmsMember) redisService.get(key); + } + + @Override + public void setMember(UmsMember member) { + String key = REDIS_DATABASE + ":" + REDIS_KEY_MEMBER + ":" + member.getId(); + redisService.set(key, member, REDIS_EXPIRE); + } + + @CacheException + @Override + public void setAuthCode(String telephone, String authCode) { + String key = REDIS_DATABASE + ":" + REDIS_KEY_AUTH_CODE + ":" + telephone; + redisService.set(key, authCode, REDIS_EXPIRE_AUTH_CODE); + } + + @CacheException + @Override + public String getAuthCode(String telephone) { + String key = REDIS_DATABASE + ":" + REDIS_KEY_AUTH_CODE + ":" + telephone; + return (String) redisService.get(key); + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberCouponServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberCouponServiceImpl.java index d38c872..19c05c8 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberCouponServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberCouponServiceImpl.java @@ -1,8 +1,8 @@ package com.macro.mall.portal.service.impl; +import cn.hutool.core.collection.CollUtil; import com.macro.mall.common.exception.Asserts; -import com.macro.mall.mapper.SmsCouponHistoryMapper; -import com.macro.mall.mapper.SmsCouponMapper; +import com.macro.mall.mapper.*; import com.macro.mall.model.*; import com.macro.mall.portal.dao.SmsCouponHistoryDao; import com.macro.mall.portal.domain.CartPromotionItem; @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Random; +import java.util.stream.Collectors; /** * 会员优惠券管理Service实现类 @@ -32,6 +33,12 @@ public class UmsMemberCouponServiceImpl implements UmsMemberCouponService { private SmsCouponHistoryMapper couponHistoryMapper; @Autowired private SmsCouponHistoryDao couponHistoryDao; + @Autowired + private SmsCouponProductRelationMapper couponProductRelationMapper; + @Autowired + private SmsCouponProductCategoryRelationMapper couponProductCategoryRelationMapper; + @Autowired + private PmsProductMapper productMapper; @Override public void add(Long couponId) { UmsMember currentMember = memberService.getCurrentMember(); @@ -93,7 +100,7 @@ public class UmsMemberCouponServiceImpl implements UmsMemberCouponService { } @Override - public List list(Integer useStatus) { + public List listHistory(Integer useStatus) { UmsMember currentMember = memberService.getCurrentMember(); SmsCouponHistoryExample couponHistoryExample=new SmsCouponHistoryExample(); SmsCouponHistoryExample.Criteria criteria = couponHistoryExample.createCriteria(); @@ -162,6 +169,48 @@ public class UmsMemberCouponServiceImpl implements UmsMemberCouponService { } } + @Override + public List listByProduct(Long productId) { + List allCouponIds = new ArrayList<>(); + //获取指定商品优惠券 + SmsCouponProductRelationExample cprExample = new SmsCouponProductRelationExample(); + cprExample.createCriteria().andProductIdEqualTo(productId); + List cprList = couponProductRelationMapper.selectByExample(cprExample); + if(CollUtil.isNotEmpty(cprList)){ + List couponIds = cprList.stream().map(SmsCouponProductRelation::getCouponId).collect(Collectors.toList()); + allCouponIds.addAll(couponIds); + } + //获取指定分类优惠券 + PmsProduct product = productMapper.selectByPrimaryKey(productId); + SmsCouponProductCategoryRelationExample cpcrExample = new SmsCouponProductCategoryRelationExample(); + cpcrExample.createCriteria().andProductCategoryIdEqualTo(product.getProductCategoryId()); + List cpcrList = couponProductCategoryRelationMapper.selectByExample(cpcrExample); + if(CollUtil.isNotEmpty(cpcrList)){ + List couponIds = cpcrList.stream().map(SmsCouponProductCategoryRelation::getCouponId).collect(Collectors.toList()); + allCouponIds.addAll(couponIds); + } + if(CollUtil.isEmpty(allCouponIds)){ + return new ArrayList<>(); + } + //所有优惠券 + SmsCouponExample couponExample = new SmsCouponExample(); + couponExample.createCriteria().andEndTimeGreaterThan(new Date()) + .andStartTimeLessThan(new Date()) + .andUseTypeEqualTo(0); + couponExample.or(couponExample.createCriteria() + .andEndTimeGreaterThan(new Date()) + .andStartTimeLessThan(new Date()) + .andUseTypeNotEqualTo(0) + .andIdIn(allCouponIds)); + return couponMapper.selectByExample(couponExample); + } + + @Override + public List list(Integer useStatus) { + UmsMember member = memberService.getCurrentMember(); + return couponHistoryDao.getCouponList(member.getId(),useStatus); + } + private BigDecimal calcTotalAmount(List cartItemList) { BigDecimal total = new BigDecimal("0"); for (CartPromotionItem item : cartItemList) { diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberReceiveAddressServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberReceiveAddressServiceImpl.java index e7bafda..29c6c14 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberReceiveAddressServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberReceiveAddressServiceImpl.java @@ -43,6 +43,16 @@ public class UmsMemberReceiveAddressServiceImpl implements UmsMemberReceiveAddre UmsMember currentMember = memberService.getCurrentMember(); UmsMemberReceiveAddressExample example = new UmsMemberReceiveAddressExample(); example.createCriteria().andMemberIdEqualTo(currentMember.getId()).andIdEqualTo(id); + if(address.getDefaultStatus()==1){ + //先将原来的默认地址去除 + UmsMemberReceiveAddress record= new UmsMemberReceiveAddress(); + record.setDefaultStatus(0); + UmsMemberReceiveAddressExample updateExample = new UmsMemberReceiveAddressExample(); + updateExample.createCriteria() + .andMemberIdEqualTo(currentMember.getId()) + .andDefaultStatusEqualTo(1); + addressMapper.updateByExampleSelective(record,updateExample); + } return addressMapper.updateByExampleSelective(address,example); } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberServiceImpl.java index 49ee902..bb67824 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberServiceImpl.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberServiceImpl.java @@ -1,5 +1,14 @@ package com.macro.mall.portal.service.impl; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.BCrypt; +import cn.hutool.json.JSONUtil; +import com.macro.mall.common.api.CommonResult; +import com.macro.mall.common.api.ResultCode; +import com.macro.mall.common.constant.AuthConstant; +import com.macro.mall.common.domain.UserDto; import com.macro.mall.common.exception.Asserts; import com.macro.mall.mapper.UmsMemberLevelMapper; import com.macro.mall.mapper.UmsMemberMapper; @@ -7,30 +16,20 @@ import com.macro.mall.model.UmsMember; import com.macro.mall.model.UmsMemberExample; import com.macro.mall.model.UmsMemberLevel; import com.macro.mall.model.UmsMemberLevelExample; -import com.macro.mall.portal.domain.MemberDetails; -import com.macro.mall.portal.service.RedisService; +import com.macro.mall.portal.service.AuthService; +import com.macro.mall.portal.service.UmsMemberCacheService; import com.macro.mall.portal.service.UmsMemberService; -import com.macro.mall.security.util.JwtTokenUtil; +import org.apache.catalina.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import java.util.Date; -import java.util.List; -import java.util.Random; +import javax.servlet.http.HttpServletRequest; +import java.util.*; /** * 会员管理Service实现类 @@ -40,19 +39,19 @@ import java.util.Random; public class UmsMemberServiceImpl implements UmsMemberService { private static final Logger LOGGER = LoggerFactory.getLogger(UmsMemberServiceImpl.class); @Autowired - private PasswordEncoder passwordEncoder; - @Autowired - private JwtTokenUtil jwtTokenUtil; - @Autowired private UmsMemberMapper memberMapper; @Autowired private UmsMemberLevelMapper memberLevelMapper; @Autowired - private RedisService redisService; - @Value("${redis.key.prefix.authCode}") + private UmsMemberCacheService memberCacheService; + @Value("${redis.key.authCode}") private String REDIS_KEY_PREFIX_AUTH_CODE; - @Value("${redis.key.expire.authCode}") + @Value("${redis.expire.authCode}") private Long AUTH_CODE_EXPIRE_SECONDS; + @Autowired + private AuthService authService; + @Autowired + private HttpServletRequest request; @Override public UmsMember getByUsername(String username) { @@ -88,7 +87,7 @@ public class UmsMemberServiceImpl implements UmsMemberService { UmsMember umsMember = new UmsMember(); umsMember.setUsername(username); umsMember.setPhone(telephone); - umsMember.setPassword(passwordEncoder.encode(password)); + umsMember.setPassword(BCrypt.hashpw(password)); umsMember.setCreateTime(new Date()); umsMember.setStatus(1); //获取默认会员等级并设置 @@ -109,9 +108,7 @@ public class UmsMemberServiceImpl implements UmsMemberService { for(int i=0;i<6;i++){ sb.append(random.nextInt(10)); } - //验证码绑定手机号并存储到redis - redisService.set(REDIS_KEY_PREFIX_AUTH_CODE+telephone,sb.toString()); - redisService.expire(REDIS_KEY_PREFIX_AUTH_CODE+telephone,AUTH_CODE_EXPIRE_SECONDS); + memberCacheService.setAuthCode(telephone,sb.toString()); return sb.toString(); } @@ -128,16 +125,26 @@ public class UmsMemberServiceImpl implements UmsMemberService { Asserts.fail("验证码错误"); } UmsMember umsMember = memberList.get(0); - umsMember.setPassword(passwordEncoder.encode(password)); + umsMember.setPassword(BCrypt.hashpw(password)); memberMapper.updateByPrimaryKeySelective(umsMember); + memberCacheService.delMember(umsMember.getId()); } @Override public UmsMember getCurrentMember() { - SecurityContext ctx = SecurityContextHolder.getContext(); - Authentication auth = ctx.getAuthentication(); - MemberDetails memberDetails = (MemberDetails) auth.getPrincipal(); - return memberDetails.getUmsMember(); + String userStr = request.getHeader(AuthConstant.USER_TOKEN_HEADER); + if(StrUtil.isEmpty(userStr)){ + Asserts.fail(ResultCode.UNAUTHORIZED); + } + UserDto userDto = JSONUtil.toBean(userStr, UserDto.class); + UmsMember member = memberCacheService.getMember(userDto.getId()); + if(member!=null){ + return member; + }else{ + member = getById(userDto.getId()); + memberCacheService.setMember(member); + return member; + } } @Override @@ -146,38 +153,33 @@ public class UmsMemberServiceImpl implements UmsMemberService { record.setId(id); record.setIntegration(integration); memberMapper.updateByPrimaryKeySelective(record); + memberCacheService.delMember(id); } @Override - public UserDetails loadUserByUsername(String username) { + public UserDto loadUserByUsername(String username) { UmsMember member = getByUsername(username); if(member!=null){ - return new MemberDetails(member); + UserDto userDto = new UserDto(); + BeanUtil.copyProperties(member,userDto); + userDto.setRoles(CollUtil.toList("前台会员")); + return userDto; } - throw new UsernameNotFoundException("用户名或密码错误"); + return null; } @Override - public String login(String username, String password) { - String token = null; - //密码需要客户端加密后传递 - try { - UserDetails userDetails = loadUserByUsername(username); - if(!passwordEncoder.matches(password,userDetails.getPassword())){ - throw new BadCredentialsException("密码不正确"); - } - UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); - SecurityContextHolder.getContext().setAuthentication(authentication); - token = jwtTokenUtil.generateToken(userDetails); - } catch (AuthenticationException e) { - LOGGER.warn("登录异常:{}", e.getMessage()); + public CommonResult login(String username, String password) { + if(StrUtil.isEmpty(username)||StrUtil.isEmpty(password)){ + Asserts.fail("用户名或密码不能为空!"); } - return token; - } - - @Override - public String refreshToken(String token) { - return jwtTokenUtil.refreshHeadToken(token); + Map params = new HashMap<>(); + params.put("client_id", AuthConstant.PORTAL_CLIENT_ID); + params.put("client_secret","123456"); + params.put("grant_type","password"); + params.put("username",username); + params.put("password",password); + return authService.getAccessToken(params); } //对输入的验证码进行校验 @@ -185,7 +187,7 @@ public class UmsMemberServiceImpl implements UmsMemberService { if(StringUtils.isEmpty(authCode)){ return false; } - String realAuthCode = redisService.get(REDIS_KEY_PREFIX_AUTH_CODE + telephone); + String realAuthCode = memberCacheService.getAuthCode(telephone); return authCode.equals(realAuthCode); } diff --git a/mall-portal/src/main/resources/application.yml b/mall-portal/src/main/resources/application.yml index 1bab897..03b5955 100644 --- a/mall-portal/src/main/resources/application.yml +++ b/mall-portal/src/main/resources/application.yml @@ -24,12 +24,6 @@ spring: database: 0 # Redis数据库索引(默认为0) port: 6379 # Redis服务器连接端口 password: # Redis服务器连接密码(默认为空) - jedis: - pool: - max-active: 8 # 连接池最大连接数(使用负值表示没有限制) - max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) - max-idle: 8 # 连接池中的最大空闲连接 - min-idle: 0 # 连接池中的最小空闲连接 timeout: 3000ms # 连接超时时间(毫秒) rabbitmq: host: localhost @@ -37,7 +31,6 @@ spring: virtual-host: /mall username: mall password: mall - publisher-confirms: true #如果对异步消息需要回调必须设置为true mybatis: mapper-locations: - classpath:dao/*.xml @@ -50,38 +43,26 @@ management: #开启SpringBoot Admin的监控 endpoint: health: show-details: always -jwt: - tokenHeader: Authorization #JWT存储的请求头 - secret: mall-portal-secret #JWT加解密使用的密钥 - expiration: 604800 #JWT的超期限时间(60*60*24) - tokenHead: Bearer #JWT负载中拿到开头 -secure: - ignored: - urls: #安全路径白名单 - - /swagger-ui.html - - /swagger-resources/** - - /swagger/** - - /**/v2/api-docs - - /**/*.js - - /**/*.css - - /**/*.png - - /**/*.ico - - /webjars/springfox-swagger-ui/** - - /druid/** - - /actuator/** - - /sso/** - - /home/** -# 自定义redis键值 + +# 自定义redis key redis: + database: mall key: - prefix: - authCode: "portal:authCode:" - orderId: "portal:orderId:" - expire: - authCode: 90 # 验证码超期时间 -# 自定义消息队列名称 + authCode: 'ums:authCode' + orderId: 'oms:orderId' + member: 'ums:member' + expire: + authCode: 90 # 验证码超期时间 + common: 86400 # 24小时 + +# 消息队列定义 rabbitmq: queue: name: cancelOrder: cancelOrderQueue - +feign: + okhttp: + enabled: true +ribbon: + ConnectTimeout: 3000 #服务请求连接超时时间(毫秒) + ReadTimeout: 3000 #服务请求处理超时时间(毫秒) diff --git a/mall-portal/src/main/resources/bootstrap-dev.yml b/mall-portal/src/main/resources/bootstrap-dev.yml index 6f75d09..365fbba 100644 --- a/mall-portal/src/main/resources/bootstrap-dev.yml +++ b/mall-portal/src/main/resources/bootstrap-dev.yml @@ -1,13 +1,8 @@ spring: cloud: - config: - profile: dev #启用环境名称 - label: master #分支名称 - name: portal #配置文件名称 + nacos: discovery: - enabled: true - service-id: mall-config -eureka: - client: - service-url: - defaultZone: http://localhost:8001/eureka/ \ No newline at end of file + server-addr: http://localhost:8848 + config: + server-addr: http://localhost:8848 + file-extension: yaml \ No newline at end of file diff --git a/mall-portal/src/main/resources/bootstrap-prod.yml b/mall-portal/src/main/resources/bootstrap-prod.yml index 9ef2dde..fc71e7a 100644 --- a/mall-portal/src/main/resources/bootstrap-prod.yml +++ b/mall-portal/src/main/resources/bootstrap-prod.yml @@ -1,15 +1,8 @@ spring: cloud: - config: - profile: prod #启用环境名称 - label: master #分支名称 - name: portal #配置文件名称 + nacos: discovery: - enabled: true - service-id: mall-config -eureka: - client: - service-url: - defaultZone: http://mall-registry:8001/eureka/ - instance: - prefer-ip-address: true \ No newline at end of file + server-addr: http://nacos-registry:8848 + config: + server-addr: http://nacos-registry:8848 + file-extension: yaml \ No newline at end of file diff --git a/mall-portal/src/main/resources/dao/PortalProductDao.xml b/mall-portal/src/main/resources/dao/PortalProductDao.xml index c5d4607..6ba886a 100644 --- a/mall-portal/src/main/resources/dao/PortalProductDao.xml +++ b/mall-portal/src/main/resources/dao/PortalProductDao.xml @@ -72,4 +72,31 @@ #{id} + \ No newline at end of file diff --git a/mall-portal/src/main/resources/dao/SmsCouponHistoryDao.xml b/mall-portal/src/main/resources/dao/SmsCouponHistoryDao.xml index 895f22f..28c19a4 100644 --- a/mall-portal/src/main/resources/dao/SmsCouponHistoryDao.xml +++ b/mall-portal/src/main/resources/dao/SmsCouponHistoryDao.xml @@ -33,4 +33,21 @@ WHERE ch.member_id = #{memberId} AND ch.use_status = 0 + + \ No newline at end of file diff --git a/mall-registry/.gitignore b/mall-registry/.gitignore deleted file mode 100644 index a2a3040..0000000 --- a/mall-registry/.gitignore +++ /dev/null @@ -1,31 +0,0 @@ -HELP.md -target/ -!.mvn/wrapper/maven-wrapper.jar -!**/src/main/** -!**/src/test/** - -### 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/ - -### VS Code ### -.vscode/ diff --git a/mall-registry/pom.xml b/mall-registry/pom.xml deleted file mode 100644 index 4bd37d7..0000000 --- a/mall-registry/pom.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - 4.0.0 - com.macro.mall - mall-registry - 1.0-SNAPSHOT - mall-registry - mall-registry project for mall - - - com.macro.mall - mall-swarm - 1.0-SNAPSHOT - - - - - org.springframework.cloud - spring-cloud-starter-netflix-eureka-server - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - com.spotify - docker-maven-plugin - ${docker.maven.plugin.version} - - - build-image - package - - build - - - - - mall/${project.artifactId}:${project.version} - ${docker.host} - java:8 - ["java", "-jar", "-Dspring.profiles.active=prod","/${project.build.finalName}.jar"] - - - / - ${project.build.directory} - ${project.build.finalName}.jar - - - - - - - - diff --git a/mall-registry/src/main/java/com/macro/mall/MallRegistryApplication.java b/mall-registry/src/main/java/com/macro/mall/MallRegistryApplication.java deleted file mode 100644 index 1139c8c..0000000 --- a/mall-registry/src/main/java/com/macro/mall/MallRegistryApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.macro.mall; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; - -@EnableEurekaServer -@SpringBootApplication -public class MallRegistryApplication { - - public static void main(String[] args) { - SpringApplication.run(MallRegistryApplication.class, args); - } - -} diff --git a/mall-registry/src/main/resources/application.yml b/mall-registry/src/main/resources/application.yml deleted file mode 100644 index 1c16d1c..0000000 --- a/mall-registry/src/main/resources/application.yml +++ /dev/null @@ -1,13 +0,0 @@ -server: - port: 8001 -spring: - application: - name: mall-registry -eureka: - instance: - hostname: localhost - client: - fetch-registry: false - register-with-eureka: false - server: - enable-self-preservation: false diff --git a/mall-registry/src/test/java/com/macro/mall/MallRegistryApplicationTests.java b/mall-registry/src/test/java/com/macro/mall/MallRegistryApplicationTests.java deleted file mode 100644 index dc59b8e..0000000 --- a/mall-registry/src/test/java/com/macro/mall/MallRegistryApplicationTests.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.macro.mall; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -class MallRegistryApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/mall-search/pom.xml b/mall-search/pom.xml index 37cde16..e05e15a 100644 --- a/mall-search/pom.xml +++ b/mall-search/pom.xml @@ -21,6 +21,12 @@ com.macro.mall mall-mbg + + + org.springframework.boot + spring-boot-starter-data-redis + + org.springframework.boot @@ -31,12 +37,12 @@ spring-boot-starter-data-elasticsearch - org.springframework.cloud - spring-cloud-starter-netflix-eureka-client + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery - org.springframework.cloud - spring-cloud-starter-config + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config diff --git a/mall-search/src/main/java/com/macro/mall/search/config/Swagger2Config.java b/mall-search/src/main/java/com/macro/mall/search/config/SwaggerConfig.java similarity index 59% rename from mall-search/src/main/java/com/macro/mall/search/config/Swagger2Config.java rename to mall-search/src/main/java/com/macro/mall/search/config/SwaggerConfig.java index a89caeb..670535a 100644 --- a/mall-search/src/main/java/com/macro/mall/search/config/Swagger2Config.java +++ b/mall-search/src/main/java/com/macro/mall/search/config/SwaggerConfig.java @@ -1,5 +1,7 @@ package com.macro.mall.search.config; +import com.macro.mall.common.config.BaseSwaggerConfig; +import com.macro.mall.common.domain.SwaggerProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; @@ -16,23 +18,17 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; */ @Configuration @EnableSwagger2 -public class Swagger2Config { - @Bean - public Docket createRestApi(){ - return new Docket(DocumentationType.SWAGGER_2) - .apiInfo(apiInfo()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.macro.mall.search.controller")) - .paths(PathSelectors.any()) - .build(); - } +public class SwaggerConfig extends BaseSwaggerConfig { - private ApiInfo apiInfo() { - return new ApiInfoBuilder() + @Override + public SwaggerProperties swaggerProperties() { + return SwaggerProperties.builder() + .apiBasePackage("com.macro.mall.search.controller") .title("mall搜索系统") - .description("mall搜索模块") - .contact("macro") + .description("mall搜索相关接口文档") + .contactName("macro") .version("1.0") + .enableSecurity(false) .build(); } } diff --git a/mall-search/src/main/java/com/macro/mall/search/service/impl/EsProductServiceImpl.java b/mall-search/src/main/java/com/macro/mall/search/service/impl/EsProductServiceImpl.java index 0008749..004fb94 100644 --- a/mall-search/src/main/java/com/macro/mall/search/service/impl/EsProductServiceImpl.java +++ b/mall-search/src/main/java/com/macro/mall/search/service/impl/EsProductServiceImpl.java @@ -5,7 +5,6 @@ import com.macro.mall.search.domain.EsProduct; import com.macro.mall.search.domain.EsProductRelatedInfo; import com.macro.mall.search.repository.EsProductRepository; import com.macro.mall.search.service.EsProductService; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; @@ -14,10 +13,10 @@ import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders; import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.AggregationBuilders; -import org.elasticsearch.search.aggregations.bucket.filter.InternalFilter; -import org.elasticsearch.search.aggregations.bucket.nested.InternalNested; -import org.elasticsearch.search.aggregations.bucket.terms.LongTerms; -import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; +import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilter; +import org.elasticsearch.search.aggregations.bucket.nested.ParsedNested; +import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms; +import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; @@ -28,7 +27,10 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; +import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHits; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service; @@ -39,6 +41,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** @@ -53,7 +56,7 @@ public class EsProductServiceImpl implements EsProductService { @Autowired private EsProductRepository productRepository; @Autowired - private ElasticsearchTemplate elasticsearchTemplate; + private ElasticsearchRestTemplate elasticsearchRestTemplate; @Override public int importAll() { List esProductList = productDao.getAllEsProductList(null); @@ -157,7 +160,12 @@ public class EsProductServiceImpl implements EsProductService { nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC)); NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build(); LOGGER.info("DSL:{}", searchQuery.getQuery().toString()); - return productRepository.search(searchQuery); + SearchHits searchHits = elasticsearchRestTemplate.search(searchQuery, EsProduct.class); + if(searchHits.getTotalHits()<=0){ + return new PageImpl<>(null,pageable,0); + } + List searchProductList = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList()); + return new PageImpl<>(searchProductList,pageable,searchHits.getTotalHits()); } @Override @@ -178,20 +186,30 @@ public class EsProductServiceImpl implements EsProductService { filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("keywords", keyword), ScoreFunctionBuilders.weightFactorFunction(2))); filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("brandId", brandId), - ScoreFunctionBuilders.weightFactorFunction(10))); + ScoreFunctionBuilders.weightFactorFunction(5))); filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("productCategoryId", productCategoryId), - ScoreFunctionBuilders.weightFactorFunction(6))); + ScoreFunctionBuilders.weightFactorFunction(3))); FunctionScoreQueryBuilder.FilterFunctionBuilder[] builders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[filterFunctionBuilders.size()]; filterFunctionBuilders.toArray(builders); FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(builders) .scoreMode(FunctionScoreQuery.ScoreMode.SUM) .setMinScore(2); + //用于过滤掉相同的商品 + BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); + boolQueryBuilder.mustNot(QueryBuilders.termQuery("id",id)); + //构建查询条件 NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder(); builder.withQuery(functionScoreQueryBuilder); + builder.withFilter(boolQueryBuilder); builder.withPageable(pageable); NativeSearchQuery searchQuery = builder.build(); LOGGER.info("DSL:{}", searchQuery.getQuery().toString()); - return productRepository.search(searchQuery); + SearchHits searchHits = elasticsearchRestTemplate.search(searchQuery, EsProduct.class); + if(searchHits.getTotalHits()<=0){ + return new PageImpl<>(null,pageable,0); + } + List searchProductList = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList()); + return new PageImpl<>(searchProductList,pageable,searchHits.getTotalHits()); } return new PageImpl<>(null); } @@ -220,16 +238,14 @@ public class EsProductServiceImpl implements EsProductService { .field("attrValueList.name")))); builder.addAggregation(aggregationBuilder); NativeSearchQuery searchQuery = builder.build(); - return elasticsearchTemplate.query(searchQuery, response -> { - LOGGER.info("DSL:{}",searchQuery.getQuery().toString()); - return convertProductRelatedInfo(response); - }); + SearchHits searchHits = elasticsearchRestTemplate.search(searchQuery, EsProduct.class); + return convertProductRelatedInfo(searchHits); } /** * 将返回结果转换为对象 */ - private EsProductRelatedInfo convertProductRelatedInfo(SearchResponse response) { + private EsProductRelatedInfo convertProductRelatedInfo(SearchHits response) { EsProductRelatedInfo productRelatedInfo = new EsProductRelatedInfo(); Map aggregationMap = response.getAggregations().getAsMap(); //设置品牌 @@ -248,14 +264,14 @@ public class EsProductServiceImpl implements EsProductService { productRelatedInfo.setProductCategoryNames(productCategoryNameList); //设置参数 Aggregation productAttrs = aggregationMap.get("allAttrValues"); - List attrIds = ((LongTerms) ((InternalFilter) ((InternalNested) productAttrs).getProperty("productAttrs")).getProperty("attrIds")).getBuckets(); + List attrIds = ((ParsedLongTerms) ((ParsedFilter) ((ParsedNested) productAttrs).getAggregations().get("productAttrs")).getAggregations().get("attrIds")).getBuckets(); List attrList = new ArrayList<>(); for (Terms.Bucket attrId : attrIds) { EsProductRelatedInfo.ProductAttr attr = new EsProductRelatedInfo.ProductAttr(); attr.setAttrId((Long) attrId.getKey()); List attrValueList = new ArrayList<>(); - List attrValues = ((StringTerms) attrId.getAggregations().get("attrValues")).getBuckets(); - List attrNames = ((StringTerms) attrId.getAggregations().get("attrNames")).getBuckets(); + List attrValues = ((ParsedStringTerms) attrId.getAggregations().get("attrValues")).getBuckets(); + List attrNames = ((ParsedStringTerms) attrId.getAggregations().get("attrNames")).getBuckets(); for (Terms.Bucket attrValue : attrValues) { attrValueList.add(attrValue.getKeyAsString()); } diff --git a/mall-search/src/main/resources/application.yml b/mall-search/src/main/resources/application.yml index e732a8d..91f581c 100644 --- a/mall-search/src/main/resources/application.yml +++ b/mall-search/src/main/resources/application.yml @@ -18,8 +18,9 @@ spring: elasticsearch: repositories: enabled: true - cluster-nodes: 127.0.0.1:9300 - cluster-name: elasticsearch + elasticsearch: + rest: + uris: 127.0.0.1:9200 mybatis: mapper-locations: - classpath:dao/*.xml diff --git a/mall-search/src/main/resources/bootstrap-dev.yml b/mall-search/src/main/resources/bootstrap-dev.yml index aa84ef6..365fbba 100644 --- a/mall-search/src/main/resources/bootstrap-dev.yml +++ b/mall-search/src/main/resources/bootstrap-dev.yml @@ -1,13 +1,8 @@ spring: cloud: - config: - profile: dev #启用环境名称 - label: master #分支名称 - name: search #配置文件名称 + nacos: discovery: - enabled: true - service-id: mall-config -eureka: - client: - service-url: - defaultZone: http://localhost:8001/eureka/ \ No newline at end of file + server-addr: http://localhost:8848 + config: + server-addr: http://localhost:8848 + file-extension: yaml \ No newline at end of file diff --git a/mall-search/src/main/resources/bootstrap-prod.yml b/mall-search/src/main/resources/bootstrap-prod.yml index 3ddb957..fc71e7a 100644 --- a/mall-search/src/main/resources/bootstrap-prod.yml +++ b/mall-search/src/main/resources/bootstrap-prod.yml @@ -1,15 +1,8 @@ spring: cloud: - config: - profile: prod #启用环境名称 - label: master #分支名称 - name: search #配置文件名称 + nacos: discovery: - enabled: true - service-id: mall-config -eureka: - client: - service-url: - defaultZone: http://mall-registry:8001/eureka/ - instance: - prefer-ip-address: true \ No newline at end of file + server-addr: http://nacos-registry:8848 + config: + server-addr: http://nacos-registry:8848 + file-extension: yaml \ No newline at end of file diff --git a/mall-search/src/test/java/com/macro/mall/search/MallSearchApplicationTests.java b/mall-search/src/test/java/com/macro/mall/search/MallSearchApplicationTests.java index ab1f90e..7de5d73 100644 --- a/mall-search/src/test/java/com/macro/mall/search/MallSearchApplicationTests.java +++ b/mall-search/src/test/java/com/macro/mall/search/MallSearchApplicationTests.java @@ -2,14 +2,13 @@ package com.macro.mall.search; import com.macro.mall.search.dao.EsProductDao; import com.macro.mall.search.domain.EsProduct; -import com.macro.mall.search.repository.EsProductRepository; -import org.elasticsearch.action.search.SearchResponse; + import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; -import org.springframework.data.elasticsearch.core.ResultsExtractor; +import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @@ -21,7 +20,7 @@ public class MallSearchApplicationTests { @Autowired private EsProductDao productDao; @Autowired - private ElasticsearchTemplate elasticsearchTemplate; + private ElasticsearchRestTemplate elasticsearchTemplate; @Test public void contextLoads() { } @@ -32,8 +31,9 @@ public class MallSearchApplicationTests { } @Test public void testEsProductMapping(){ - elasticsearchTemplate.putMapping(EsProduct.class); - Map mapping = elasticsearchTemplate.getMapping(EsProduct.class); + IndexOperations indexOperations = elasticsearchTemplate.indexOps(EsProduct.class); + indexOperations.putMapping(indexOperations.createMapping(EsProduct.class)); + Map mapping = indexOperations.getMapping(); System.out.println(mapping); } diff --git a/mall-security/.gitignore b/mall-security/.gitignore deleted file mode 100644 index a2a3040..0000000 --- a/mall-security/.gitignore +++ /dev/null @@ -1,31 +0,0 @@ -HELP.md -target/ -!.mvn/wrapper/maven-wrapper.jar -!**/src/main/** -!**/src/test/** - -### 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/ - -### VS Code ### -.vscode/ diff --git a/mall-security/pom.xml b/mall-security/pom.xml deleted file mode 100644 index c74d8b7..0000000 --- a/mall-security/pom.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - 4.0.0 - com.macro.mall - mall-security - 1.0-SNAPSHOT - jar - - mall-security - mall-security project for mall - - - com.macro.mall - mall-swarm - 1.0-SNAPSHOT - - - - - com.macro.mall - mall-common - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-security - - - io.jsonwebtoken - jjwt - - - - diff --git a/mall-security/src/main/java/com/macro/mall/security/component/DynamicAccessDecisionManager.java b/mall-security/src/main/java/com/macro/mall/security/component/DynamicAccessDecisionManager.java deleted file mode 100644 index 36dfec2..0000000 --- a/mall-security/src/main/java/com/macro/mall/security/component/DynamicAccessDecisionManager.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.macro.mall.security.component; - -import cn.hutool.core.collection.CollUtil; -import org.springframework.security.access.AccessDecisionManager; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.access.ConfigAttribute; -import org.springframework.security.authentication.InsufficientAuthenticationException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; - -import java.util.Collection; -import java.util.Iterator; - -/** - * 动态权限决策管理器,用于判断用户是否有访问权限 - * Created by macro on 2020/2/7. - */ -public class DynamicAccessDecisionManager implements AccessDecisionManager { - - @Override - public void decide(Authentication authentication, Object object, - Collection configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { - // 当接口未被配置资源时直接放行 - if (CollUtil.isEmpty(configAttributes)) { - return; - } - Iterator iterator = configAttributes.iterator(); - while (iterator.hasNext()) { - ConfigAttribute configAttribute = iterator.next(); - //将访问所需资源或用户拥有资源进行比对 - String needAuthority = configAttribute.getAttribute(); - for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) { - if (needAuthority.trim().equals(grantedAuthority.getAuthority())) { - return; - } - } - } - throw new AccessDeniedException("抱歉,您没有访问权限"); - } - - @Override - public boolean supports(ConfigAttribute configAttribute) { - return true; - } - - @Override - public boolean supports(Class aClass) { - return true; - } - -} diff --git a/mall-security/src/main/java/com/macro/mall/security/component/DynamicSecurityFilter.java b/mall-security/src/main/java/com/macro/mall/security/component/DynamicSecurityFilter.java deleted file mode 100644 index ae49b8b..0000000 --- a/mall-security/src/main/java/com/macro/mall/security/component/DynamicSecurityFilter.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.macro.mall.security.component; - -import com.macro.mall.security.config.IgnoreUrlsConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpMethod; -import org.springframework.security.access.SecurityMetadataSource; -import org.springframework.security.access.intercept.AbstractSecurityInterceptor; -import org.springframework.security.access.intercept.InterceptorStatusToken; -import org.springframework.security.web.FilterInvocation; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.PathMatcher; - -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; - -/** - * 动态权限过滤器,用于实现基于路径的动态权限过滤 - * Created by macro on 2020/2/7. - */ -public class DynamicSecurityFilter extends AbstractSecurityInterceptor implements Filter { - - @Autowired - private DynamicSecurityMetadataSource dynamicSecurityMetadataSource; - @Autowired - private IgnoreUrlsConfig ignoreUrlsConfig; - - @Autowired - public void setMyAccessDecisionManager(DynamicAccessDecisionManager dynamicAccessDecisionManager) { - super.setAccessDecisionManager(dynamicAccessDecisionManager); - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - } - - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { - HttpServletRequest request = (HttpServletRequest) servletRequest; - FilterInvocation fi = new FilterInvocation(servletRequest, servletResponse, filterChain); - //OPTIONS请求直接放行 - if(request.getMethod().equals(HttpMethod.OPTIONS.toString())){ - fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); - return; - } - //白名单请求直接放行 - PathMatcher pathMatcher = new AntPathMatcher(); - for (String path : ignoreUrlsConfig.getUrls()) { - if(pathMatcher.match(path,request.getRequestURI())){ - fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); - return; - } - } - //此处会调用AccessDecisionManager中的decide方法进行鉴权操作 - InterceptorStatusToken token = super.beforeInvocation(fi); - try { - fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); - } finally { - super.afterInvocation(token, null); - } - } - - @Override - public void destroy() { - } - - @Override - public Class getSecureObjectClass() { - return FilterInvocation.class; - } - - @Override - public SecurityMetadataSource obtainSecurityMetadataSource() { - return dynamicSecurityMetadataSource; - } - -} diff --git a/mall-security/src/main/java/com/macro/mall/security/component/DynamicSecurityMetadataSource.java b/mall-security/src/main/java/com/macro/mall/security/component/DynamicSecurityMetadataSource.java deleted file mode 100644 index 7bae7ef..0000000 --- a/mall-security/src/main/java/com/macro/mall/security/component/DynamicSecurityMetadataSource.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.macro.mall.security.component; - -import cn.hutool.core.util.URLUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.ConfigAttribute; -import org.springframework.security.web.FilterInvocation; -import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.PathMatcher; - -import javax.annotation.PostConstruct; -import java.util.*; - -/** - * 动态权限数据源,用于获取动态权限规则 - * Created by macro on 2020/2/7. - */ -public class DynamicSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { - - private static Map configAttributeMap = null; - @Autowired - private DynamicSecurityService dynamicSecurityService; - - @PostConstruct - public void loadDataSource() { - configAttributeMap = dynamicSecurityService.loadDataSource(); - } - - public void clearDataSource() { - configAttributeMap.clear(); - configAttributeMap = null; - } - - @Override - public Collection getAttributes(Object o) throws IllegalArgumentException { - if (configAttributeMap == null) this.loadDataSource(); - List configAttributes = new ArrayList<>(); - //获取当前访问的路径 - String url = ((FilterInvocation) o).getRequestUrl(); - String path = URLUtil.getPath(url); - PathMatcher pathMatcher = new AntPathMatcher(); - Iterator iterator = configAttributeMap.keySet().iterator(); - //获取访问该路径所需资源 - while (iterator.hasNext()) { - String pattern = iterator.next(); - if (pathMatcher.match(pattern, path)) { - configAttributes.add(configAttributeMap.get(pattern)); - } - } - // 未设置操作请求权限,返回空集合 - return configAttributes; - } - - @Override - public Collection getAllConfigAttributes() { - return null; - } - - @Override - public boolean supports(Class aClass) { - return true; - } - -} diff --git a/mall-security/src/main/java/com/macro/mall/security/component/DynamicSecurityService.java b/mall-security/src/main/java/com/macro/mall/security/component/DynamicSecurityService.java deleted file mode 100644 index 1246672..0000000 --- a/mall-security/src/main/java/com/macro/mall/security/component/DynamicSecurityService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.macro.mall.security.component; - -import org.springframework.security.access.ConfigAttribute; - -import java.util.Map; - -/** - * 动态权限相关业务类 - * Created by macro on 2020/2/7. - */ -public interface DynamicSecurityService { - /** - * 加载资源ANT通配符和资源对应MAP - */ - Map loadDataSource(); -} diff --git a/mall-security/src/main/java/com/macro/mall/security/component/JwtAuthenticationTokenFilter.java b/mall-security/src/main/java/com/macro/mall/security/component/JwtAuthenticationTokenFilter.java deleted file mode 100644 index bddd916..0000000 --- a/mall-security/src/main/java/com/macro/mall/security/component/JwtAuthenticationTokenFilter.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.macro.mall.security.component; - -import com.macro.mall.security.util.JwtTokenUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; -import org.springframework.web.filter.OncePerRequestFilter; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * JWT登录授权过滤器 - * Created by macro on 2018/4/26. - */ -public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { - private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class); - @Autowired - private UserDetailsService userDetailsService; - @Autowired - private JwtTokenUtil jwtTokenUtil; - @Value("${jwt.tokenHeader}") - private String tokenHeader; - @Value("${jwt.tokenHead}") - private String tokenHead; - - @Override - protected void doFilterInternal(HttpServletRequest request, - HttpServletResponse response, - FilterChain chain) throws ServletException, IOException { - String authHeader = request.getHeader(this.tokenHeader); - if (authHeader != null && authHeader.startsWith(this.tokenHead)) { - String authToken = authHeader.substring(this.tokenHead.length());// The part after "Bearer " - String username = jwtTokenUtil.getUserNameFromToken(authToken); - LOGGER.info("checking username:{}", username); - if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { - UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); - if (jwtTokenUtil.validateToken(authToken, userDetails)) { - UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); - authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - LOGGER.info("authenticated user:{}", username); - SecurityContextHolder.getContext().setAuthentication(authentication); - } - } - } - chain.doFilter(request, response); - } -} diff --git a/mall-security/src/main/java/com/macro/mall/security/component/RestAuthenticationEntryPoint.java b/mall-security/src/main/java/com/macro/mall/security/component/RestAuthenticationEntryPoint.java deleted file mode 100644 index 5bd8536..0000000 --- a/mall-security/src/main/java/com/macro/mall/security/component/RestAuthenticationEntryPoint.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.macro.mall.security.component; - -import cn.hutool.json.JSONUtil; -import com.macro.mall.common.api.CommonResult; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * 自定义返回结果:未登录或登录过期 - * Created by macro on 2018/5/14. - */ -public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { - @Override - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { - response.setHeader("Access-Control-Allow-Origin", "*"); - response.setHeader("Cache-Control","no-cache"); - response.setCharacterEncoding("UTF-8"); - response.setContentType("application/json"); - response.getWriter().println(JSONUtil.parse(CommonResult.unauthorized(authException.getMessage()))); - response.getWriter().flush(); - } -} diff --git a/mall-security/src/main/java/com/macro/mall/security/component/RestfulAccessDeniedHandler.java b/mall-security/src/main/java/com/macro/mall/security/component/RestfulAccessDeniedHandler.java deleted file mode 100644 index 1d0795d..0000000 --- a/mall-security/src/main/java/com/macro/mall/security/component/RestfulAccessDeniedHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.macro.mall.security.component; - -import cn.hutool.json.JSONUtil; -import com.macro.mall.common.api.CommonResult; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.web.access.AccessDeniedHandler; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * 自定义返回结果:没有权限访问时 - * Created by macro on 2018/4/26. - */ -public class RestfulAccessDeniedHandler implements AccessDeniedHandler{ - @Override - public void handle(HttpServletRequest request, - HttpServletResponse response, - AccessDeniedException e) throws IOException, ServletException { - response.setHeader("Access-Control-Allow-Origin", "*"); - response.setHeader("Cache-Control","no-cache"); - response.setCharacterEncoding("UTF-8"); - response.setContentType("application/json"); - response.getWriter().println(JSONUtil.parse(CommonResult.forbidden(e.getMessage()))); - response.getWriter().flush(); - } -} diff --git a/mall-security/src/main/java/com/macro/mall/security/config/IgnoreUrlsConfig.java b/mall-security/src/main/java/com/macro/mall/security/config/IgnoreUrlsConfig.java deleted file mode 100644 index a380184..0000000 --- a/mall-security/src/main/java/com/macro/mall/security/config/IgnoreUrlsConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.macro.mall.security.config; - -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.context.properties.ConfigurationProperties; - -import java.util.ArrayList; -import java.util.List; - -/** - * 用于配置不需要保护的资源路径 - * Created by macro on 2018/11/5. - */ -@Getter -@Setter -@ConfigurationProperties(prefix = "secure.ignored") -public class IgnoreUrlsConfig { - - private List urls = new ArrayList<>(); - -} diff --git a/mall-security/src/main/java/com/macro/mall/security/config/SecurityConfig.java b/mall-security/src/main/java/com/macro/mall/security/config/SecurityConfig.java deleted file mode 100644 index a16d7fe..0000000 --- a/mall-security/src/main/java/com/macro/mall/security/config/SecurityConfig.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.macro.mall.security.config; - -import com.macro.mall.security.component.*; -import com.macro.mall.security.util.JwtTokenUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.context.annotation.Bean; -import org.springframework.http.HttpMethod; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - - -/** - * 对SpringSecurity的配置的扩展,支持自定义白名单资源路径和查询用户逻辑 - * Created by macro on 2019/11/5. - */ -public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired(required = false) - private DynamicSecurityService dynamicSecurityService; - - @Override - protected void configure(HttpSecurity httpSecurity) throws Exception { - ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry = httpSecurity - .authorizeRequests(); - //不需要保护的资源路径允许访问 - for (String url : ignoreUrlsConfig().getUrls()) { - registry.antMatchers(url).permitAll(); - } - //允许跨域请求的OPTIONS请求 - registry.antMatchers(HttpMethod.OPTIONS) - .permitAll(); - // 任何请求需要身份认证 - registry.and() - .authorizeRequests() - .anyRequest() - .authenticated() - // 关闭跨站请求防护及不使用session - .and() - .csrf() - .disable() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - // 自定义权限拒绝处理类 - .and() - .exceptionHandling() - .accessDeniedHandler(restfulAccessDeniedHandler()) - .authenticationEntryPoint(restAuthenticationEntryPoint()) - // 自定义权限拦截器JWT过滤器 - .and() - .addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class); - //有动态权限配置时添加动态权限校验过滤器 - if(dynamicSecurityService!=null){ - registry.and().addFilterBefore(dynamicSecurityFilter(), FilterSecurityInterceptor.class); - } - } - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userDetailsService()) - .passwordEncoder(passwordEncoder()); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - - @Bean - public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() { - return new JwtAuthenticationTokenFilter(); - } - - @Bean - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); - } - - @Bean - public RestfulAccessDeniedHandler restfulAccessDeniedHandler() { - return new RestfulAccessDeniedHandler(); - } - - @Bean - public RestAuthenticationEntryPoint restAuthenticationEntryPoint() { - return new RestAuthenticationEntryPoint(); - } - - @Bean - public IgnoreUrlsConfig ignoreUrlsConfig() { - return new IgnoreUrlsConfig(); - } - - @Bean - public JwtTokenUtil jwtTokenUtil() { - return new JwtTokenUtil(); - } - - @ConditionalOnBean(name = "dynamicSecurityService") - @Bean - public DynamicAccessDecisionManager dynamicAccessDecisionManager() { - return new DynamicAccessDecisionManager(); - } - - - @ConditionalOnBean(name = "dynamicSecurityService") - @Bean - public DynamicSecurityFilter dynamicSecurityFilter() { - return new DynamicSecurityFilter(); - } - - @ConditionalOnBean(name = "dynamicSecurityService") - @Bean - public DynamicSecurityMetadataSource dynamicSecurityMetadataSource() { - return new DynamicSecurityMetadataSource(); - } - -} diff --git a/mall-security/src/main/java/com/macro/mall/security/util/JwtTokenUtil.java b/mall-security/src/main/java/com/macro/mall/security/util/JwtTokenUtil.java deleted file mode 100644 index 81eb969..0000000 --- a/mall-security/src/main/java/com/macro/mall/security/util/JwtTokenUtil.java +++ /dev/null @@ -1,170 +0,0 @@ -package com.macro.mall.security.util; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.StrUtil; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.core.userdetails.UserDetails; - -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -/** - * JwtToken生成的工具类 - * JWT token的格式:header.payload.signature - * header的格式(算法、token的类型): - * {"alg": "HS512","typ": "JWT"} - * payload的格式(用户名、创建时间、生成时间): - * {"sub":"wang","created":1489079981393,"exp":1489684781} - * signature的生成算法: - * HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret) - * Created by macro on 2018/4/26. - */ -public class JwtTokenUtil { - private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class); - private static final String CLAIM_KEY_USERNAME = "sub"; - private static final String CLAIM_KEY_CREATED = "created"; - @Value("${jwt.secret}") - private String secret; - @Value("${jwt.expiration}") - private Long expiration; - @Value("${jwt.tokenHead}") - private String tokenHead; - - /** - * 根据负责生成JWT的token - */ - private String generateToken(Map claims) { - return Jwts.builder() - .setClaims(claims) - .setExpiration(generateExpirationDate()) - .signWith(SignatureAlgorithm.HS512, secret) - .compact(); - } - - /** - * 从token中获取JWT中的负载 - */ - private Claims getClaimsFromToken(String token) { - Claims claims = null; - try { - claims = Jwts.parser() - .setSigningKey(secret) - .parseClaimsJws(token) - .getBody(); - } catch (Exception e) { - LOGGER.info("JWT格式验证失败:{}", token); - } - return claims; - } - - /** - * 生成token的过期时间 - */ - private Date generateExpirationDate() { - return new Date(System.currentTimeMillis() + expiration * 1000); - } - - /** - * 从token中获取登录用户名 - */ - public String getUserNameFromToken(String token) { - String username; - try { - Claims claims = getClaimsFromToken(token); - username = claims.getSubject(); - } catch (Exception e) { - username = null; - } - return username; - } - - /** - * 验证token是否还有效 - * - * @param token 客户端传入的token - * @param userDetails 从数据库中查询出来的用户信息 - */ - public boolean validateToken(String token, UserDetails userDetails) { - String username = getUserNameFromToken(token); - return username.equals(userDetails.getUsername()) && !isTokenExpired(token); - } - - /** - * 判断token是否已经失效 - */ - private boolean isTokenExpired(String token) { - Date expiredDate = getExpiredDateFromToken(token); - return expiredDate.before(new Date()); - } - - /** - * 从token中获取过期时间 - */ - private Date getExpiredDateFromToken(String token) { - Claims claims = getClaimsFromToken(token); - return claims.getExpiration(); - } - - /** - * 根据用户信息生成token - */ - public String generateToken(UserDetails userDetails) { - Map claims = new HashMap<>(); - claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername()); - claims.put(CLAIM_KEY_CREATED, new Date()); - return generateToken(claims); - } - - /** - * 当原来的token没过期时是可以刷新的 - * - * @param oldToken 带tokenHead的token - */ - public String refreshHeadToken(String oldToken) { - if(StrUtil.isEmpty(oldToken)){ - return null; - } - String token = oldToken.substring(tokenHead.length()); - if(StrUtil.isEmpty(token)){ - return null; - } - //token校验不通过 - Claims claims = getClaimsFromToken(token); - if(claims==null){ - return null; - } - //如果token已经过期,不支持刷新 - if(isTokenExpired(token)){ - return null; - } - //如果token在30分钟之内刚刷新过,返回原token - if(tokenRefreshJustBefore(token,30*60)){ - return token; - }else{ - claims.put(CLAIM_KEY_CREATED, new Date()); - return generateToken(claims); - } - } - - /** - * 判断token在指定时间内是否刚刚刷新过 - * @param token 原token - * @param time 指定时间(秒) - */ - private boolean tokenRefreshJustBefore(String token, int time) { - Claims claims = getClaimsFromToken(token); - Date created = claims.get(CLAIM_KEY_CREATED, Date.class); - Date refreshDate = new Date(); - //刷新时间在创建时间的指定时间内 - if(refreshDate.after(created)&&refreshDate.before(DateUtil.offsetSecond(created,time))){ - return true; - } - return false; - } -} diff --git a/pom.xml b/pom.xml index 4c0a5c9..3fd67c1 100644 --- a/pom.xml +++ b/pom.xml @@ -12,47 +12,46 @@ mall-common mall-mbg - mall-security mall-demo mall-admin mall-search mall-portal - mall-registry mall-monitor mall-gateway - mall-config + mall-auth org.springframework.boot spring-boot-starter-parent - 2.1.7.RELEASE + 2.3.0.RELEASE UTF-8 UTF-8 - 1.8 true - http://192.168.6.132:2375 + http://192.168.3.101:2375 1.1.0 1.8 - Greenwich.SR2 + Hoxton.SR5 + 2.2.0.RELEASE 1.2.10 5.1.8 1.1.10 4.5.7 - 2.7.0 1.3.7 3.4.6 - 8.0.15 - 2.1.5.RELEASE + 8.0.16 + 2.3.0.RELEASE 0.9.0 2.5.0 5.3 - 2.1.5 - 3.0.10 + 2.2.3 + 7.1.0 + 2.0.4 + 8.16 1.0-SNAPSHOT 1.0-SNAPSHOT 1.0-SNAPSHOT @@ -72,6 +71,19 @@ spring-boot-starter-test test + + cn.hutool + hutool-all + + + org.projectlombok + lombok + + + org.springframework.boot + spring-boot-configuration-processor + true + @@ -84,6 +96,14 @@ pom import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring-cloud-alibaba.version} + pom + import + com.macro.mall @@ -126,16 +146,16 @@ hutool-all ${hutool.version} - + - io.springfox - springfox-swagger2 - ${swagger2.version} + com.github.xiaoymin + knife4j-micro-spring-boot-starter + ${knife4j.version} - io.springfox - springfox-swagger-ui - ${swagger2.version} + com.github.xiaoymin + knife4j-spring-boot-starter + ${knife4j.version} @@ -167,6 +187,12 @@ jjwt ${jjwt.version} + + + com.nimbusds + nimbus-jose-jwt + ${nimbus-jose-jwt.version} + com.aliyun.oss