Pre Merge pull request !380 from 鲸落/master_zhp
commit
47b9563ddf
|
|
@ -1 +0,0 @@
|
|||
custom: http://doc.ruoyi.vip/ruoyi-cloud/other/donate.html
|
||||
21
LICENSE
21
LICENSE
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 若依
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
## 平台简介
|
||||
|
||||
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
|
||||
租研舍是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
|
||||
|
||||
* 采用前后端分离的模式,微服务版本前端(基于 [RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue))。
|
||||
* 后端采用Spring Boot、Spring Cloud & Alibaba。
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)
|
||||
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)
|
||||
|
||||
#### 友情链接 [若依/RuoYi-Cloud](https://gitee.com/zhangmrit/ruoyi-cloud) Ant Design版本。
|
||||
#### 友情链接 [租研舍/RuoYi-Cloud](https://gitee.com/zhangmrit/ruoyi-cloud) Ant Design版本。
|
||||
|
||||
## 系统模块
|
||||
|
||||
|
|
@ -126,6 +126,6 @@ com.ruoyi
|
|||
</table>
|
||||
|
||||
|
||||
## 若依微服务交流群
|
||||
## 租研舍微服务交流群
|
||||
|
||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) [](https://jq.qq.com/?_wv=1027&k=kiU5WDls) [](https://jq.qq.com/?_wv=1027&k=MtBy6YfT) [](https://jq.qq.com/?_wv=1027&k=FqImHgH2) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G4jZ4EtdT50PhnMBudTnEwgonxkXOscJ&authKey=FkGHYfoTKlGE6wHdKdjH9bVoOgQjtLP9WM%2Fj7pqGY1msoqw9uxDiBo39E2mLgzYg&noverify=0&group_code=128355254) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=irnwcXhbLOQEv1g-TwGifjNTA_f4wZiA&authKey=4bpzEwhcUY%2FvsPDHvzYn6xfoS%2FtOArvZ%2BGXzfr7O0%2FEqLfkKA%2BuCDXlzHIFg8t93&noverify=0&group_code=179219821) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=lx1uEdEDuxeM7rUvF3qmlFdqKqdJ5Z-R&authKey=rgyPW9yhhh4IIURKVFa6NgP3qiqH04WAzrJ0trsgkr3pjzm6sKIOGyA58oOjoj%2FJ&noverify=0&group_code=158753145) 点击按钮入群。
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# 复制项目的文件到对应docker路径,便于一键生成镜像。
|
||||
usage() {
|
||||
echo "Usage: sh copy.sh"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
# copy sql
|
||||
echo "begin copy sql "
|
||||
cp ../sql/ry_20240629.sql ./mysql/db
|
||||
cp ../sql/ry_config_20240902.sql ./mysql/db
|
||||
|
||||
# copy html
|
||||
echo "begin copy html "
|
||||
cp -r ../ruoyi-ui/dist/** ./nginx/html/dist
|
||||
|
||||
|
||||
# copy jar
|
||||
echo "begin copy ruoyi-gateway "
|
||||
cp ../ruoyi-gateway/target/ruoyi-gateway.jar ./ruoyi/gateway/jar
|
||||
|
||||
echo "begin copy ruoyi-auth "
|
||||
cp ../ruoyi-auth/target/ruoyi-auth.jar ./ruoyi/auth/jar
|
||||
|
||||
echo "begin copy ruoyi-visual "
|
||||
cp ../ruoyi-visual/ruoyi-monitor/target/ruoyi-visual-monitor.jar ./ruoyi/visual/monitor/jar
|
||||
|
||||
echo "begin copy ruoyi-modules-system "
|
||||
cp ../ruoyi-modules/ruoyi-system/target/ruoyi-modules-system.jar ./ruoyi/modules/system/jar
|
||||
|
||||
echo "begin copy ruoyi-modules-file "
|
||||
cp ../ruoyi-modules/ruoyi-file/target/ruoyi-modules-file.jar ./ruoyi/modules/file/jar
|
||||
|
||||
echo "begin copy ruoyi-modules-job "
|
||||
cp ../ruoyi-modules/ruoyi-job/target/ruoyi-modules-job.jar ./ruoyi/modules/job/jar
|
||||
|
||||
echo "begin copy ruoyi-modules-gen "
|
||||
cp ../ruoyi-modules/ruoyi-gen/target/ruoyi-modules-gen.jar ./ruoyi/modules/gen/jar
|
||||
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# 使用说明,用来提示输入参数
|
||||
usage() {
|
||||
echo "Usage: sh 执行脚本.sh [port|base|modules|stop|rm]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 开启所需端口
|
||||
port(){
|
||||
firewall-cmd --add-port=80/tcp --permanent
|
||||
firewall-cmd --add-port=8080/tcp --permanent
|
||||
firewall-cmd --add-port=8848/tcp --permanent
|
||||
firewall-cmd --add-port=9848/tcp --permanent
|
||||
firewall-cmd --add-port=9849/tcp --permanent
|
||||
firewall-cmd --add-port=6379/tcp --permanent
|
||||
firewall-cmd --add-port=3306/tcp --permanent
|
||||
firewall-cmd --add-port=9100/tcp --permanent
|
||||
firewall-cmd --add-port=9200/tcp --permanent
|
||||
firewall-cmd --add-port=9201/tcp --permanent
|
||||
firewall-cmd --add-port=9202/tcp --permanent
|
||||
firewall-cmd --add-port=9203/tcp --permanent
|
||||
firewall-cmd --add-port=9300/tcp --permanent
|
||||
service firewalld restart
|
||||
}
|
||||
|
||||
# 启动基础环境(必须)
|
||||
base(){
|
||||
docker-compose up -d ruoyi-mysql ruoyi-redis ruoyi-nacos
|
||||
}
|
||||
|
||||
# 启动程序模块(必须)
|
||||
modules(){
|
||||
docker-compose up -d ruoyi-nginx ruoyi-gateway ruoyi-auth ruoyi-modules-system
|
||||
}
|
||||
|
||||
# 关闭所有环境/模块
|
||||
stop(){
|
||||
docker-compose stop
|
||||
}
|
||||
|
||||
# 删除所有环境/模块
|
||||
rm(){
|
||||
docker-compose rm
|
||||
}
|
||||
|
||||
# 根据输入参数,选择执行对应方法,不输入则执行使用说明
|
||||
case "$1" in
|
||||
"port")
|
||||
port
|
||||
;;
|
||||
"base")
|
||||
base
|
||||
;;
|
||||
"modules")
|
||||
modules
|
||||
;;
|
||||
"stop")
|
||||
stop
|
||||
;;
|
||||
"rm")
|
||||
rm
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
version : '3.8'
|
||||
services:
|
||||
ruoyi-nacos:
|
||||
container_name: ruoyi-nacos
|
||||
image: nacos/nacos-server
|
||||
build:
|
||||
context: ./nacos
|
||||
environment:
|
||||
- MODE=standalone
|
||||
volumes:
|
||||
- ./nacos/logs/:/home/nacos/logs
|
||||
- ./nacos/conf/application.properties:/home/nacos/conf/application.properties
|
||||
ports:
|
||||
- "8848:8848"
|
||||
- "9848:9848"
|
||||
- "9849:9849"
|
||||
depends_on:
|
||||
- ruoyi-mysql
|
||||
ruoyi-mysql:
|
||||
container_name: ruoyi-mysql
|
||||
image: mysql:5.7
|
||||
build:
|
||||
context: ./mysql
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- ./mysql/conf:/etc/mysql/conf.d
|
||||
- ./mysql/logs:/logs
|
||||
- ./mysql/data:/var/lib/mysql
|
||||
command: [
|
||||
'mysqld',
|
||||
'--innodb-buffer-pool-size=80M',
|
||||
'--character-set-server=utf8mb4',
|
||||
'--collation-server=utf8mb4_unicode_ci',
|
||||
'--default-time-zone=+8:00',
|
||||
'--lower-case-table-names=1'
|
||||
]
|
||||
environment:
|
||||
MYSQL_DATABASE: 'ry-cloud'
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
ruoyi-redis:
|
||||
container_name: ruoyi-redis
|
||||
image: redis
|
||||
build:
|
||||
context: ./redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- ./redis/conf/redis.conf:/home/ruoyi/redis/redis.conf
|
||||
- ./redis/data:/data
|
||||
command: redis-server /home/ruoyi/redis/redis.conf
|
||||
ruoyi-nginx:
|
||||
container_name: ruoyi-nginx
|
||||
image: nginx
|
||||
build:
|
||||
context: ./nginx
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./nginx/html/dist:/home/ruoyi/projects/ruoyi-ui
|
||||
- ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./nginx/logs:/var/log/nginx
|
||||
- ./nginx/conf.d:/etc/nginx/conf.d
|
||||
depends_on:
|
||||
- ruoyi-gateway
|
||||
links:
|
||||
- ruoyi-gateway
|
||||
ruoyi-gateway:
|
||||
container_name: ruoyi-gateway
|
||||
build:
|
||||
context: ./ruoyi/gateway
|
||||
dockerfile: dockerfile
|
||||
ports:
|
||||
- "8080:8080"
|
||||
depends_on:
|
||||
- ruoyi-redis
|
||||
links:
|
||||
- ruoyi-redis
|
||||
ruoyi-auth:
|
||||
container_name: ruoyi-auth
|
||||
build:
|
||||
context: ./ruoyi/auth
|
||||
dockerfile: dockerfile
|
||||
ports:
|
||||
- "9200:9200"
|
||||
depends_on:
|
||||
- ruoyi-redis
|
||||
links:
|
||||
- ruoyi-redis
|
||||
ruoyi-modules-system:
|
||||
container_name: ruoyi-modules-system
|
||||
build:
|
||||
context: ./ruoyi/modules/system
|
||||
dockerfile: dockerfile
|
||||
ports:
|
||||
- "9201:9201"
|
||||
depends_on:
|
||||
- ruoyi-redis
|
||||
- ruoyi-mysql
|
||||
links:
|
||||
- ruoyi-redis
|
||||
- ruoyi-mysql
|
||||
ruoyi-modules-gen:
|
||||
container_name: ruoyi-modules-gen
|
||||
build:
|
||||
context: ./ruoyi/modules/gen
|
||||
dockerfile: dockerfile
|
||||
ports:
|
||||
- "9202:9202"
|
||||
depends_on:
|
||||
- ruoyi-mysql
|
||||
links:
|
||||
- ruoyi-mysql
|
||||
ruoyi-modules-job:
|
||||
container_name: ruoyi-modules-job
|
||||
build:
|
||||
context: ./ruoyi/modules/job
|
||||
dockerfile: dockerfile
|
||||
ports:
|
||||
- "9203:9203"
|
||||
depends_on:
|
||||
- ruoyi-mysql
|
||||
links:
|
||||
- ruoyi-mysql
|
||||
ruoyi-modules-file:
|
||||
container_name: ruoyi-modules-file
|
||||
build:
|
||||
context: ./ruoyi/modules/file
|
||||
dockerfile: dockerfile
|
||||
ports:
|
||||
- "9300:9300"
|
||||
volumes:
|
||||
- ./ruoyi/uploadPath:/home/ruoyi/uploadPath
|
||||
ruoyi-visual-monitor:
|
||||
container_name: ruoyi-visual-monitor
|
||||
build:
|
||||
context: ./ruoyi/visual/monitor
|
||||
dockerfile: dockerfile
|
||||
ports:
|
||||
- "9100:9100"
|
||||
|
|
@ -1 +0,0 @@
|
|||
存放sql目录下的所有脚本,用于docker自动执行。
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM mysql:5.7
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 执行sql脚本
|
||||
ADD ./db/*.sql /docker-entrypoint-initdb.d/
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
spring.datasource.platform=mysql
|
||||
db.num=1
|
||||
db.url.0=jdbc:mysql://ruoyi-mysql:3306/ry-config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
|
||||
db.user=root
|
||||
db.password=password
|
||||
|
||||
nacos.naming.empty-service.auto-clean=true
|
||||
nacos.naming.empty-service.clean.initial-delay-ms=50000
|
||||
nacos.naming.empty-service.clean.period-time-ms=30000
|
||||
|
||||
management.endpoints.web.exposure.include=*
|
||||
|
||||
management.metrics.export.elastic.enabled=false
|
||||
management.metrics.export.influx.enabled=false
|
||||
|
||||
server.tomcat.accesslog.enabled=true
|
||||
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i
|
||||
|
||||
server.tomcat.basedir=/home/ruoyi/nacos/tomcat/logs
|
||||
|
||||
nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
|
||||
|
||||
nacos.core.auth.system.type=nacos
|
||||
nacos.core.auth.enabled=false
|
||||
nacos.core.auth.default.token.expire.seconds=18000
|
||||
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||
nacos.core.auth.caching.enabled=true
|
||||
nacos.core.auth.enable.userAgentAuthWhite=false
|
||||
nacos.core.auth.server.identity.key=serverIdentity
|
||||
nacos.core.auth.server.identity.value=security
|
||||
|
||||
nacos.istio.mcp.server.enabled=false
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM nacos/nacos-server
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 复制conf文件到路径
|
||||
COPY ./conf/application.properties /home/nacos/conf/application.properties
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
worker_processes 1;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
root /home/ruoyi/projects/ruoyi-ui;
|
||||
try_files $uri $uri/ /index.html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
location /prod-api/{
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header REMOTE-HOST $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_pass http://ruoyi-gateway:8080/;
|
||||
}
|
||||
|
||||
# 避免actuator暴露
|
||||
if ($request_uri ~ "/actuator") {
|
||||
return 403;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root html;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM nginx
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 挂载目录
|
||||
VOLUME /home/ruoyi/projects/ruoyi-ui
|
||||
# 创建目录
|
||||
RUN mkdir -p /home/ruoyi/projects/ruoyi-ui
|
||||
# 指定路径
|
||||
WORKDIR /home/ruoyi/projects/ruoyi-ui
|
||||
# 复制conf文件到路径
|
||||
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
|
||||
# 复制html文件到路径
|
||||
COPY ./html/dist /home/ruoyi/projects/ruoyi-ui
|
||||
|
|
@ -1 +0,0 @@
|
|||
存放前端ruoyi-ui构建好的静态文件,用于nginx请求访问。
|
||||
|
|
@ -1 +0,0 @@
|
|||
# requirepass 123456
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM redis
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 挂载目录
|
||||
VOLUME /home/ruoyi/redis
|
||||
# 创建目录
|
||||
RUN mkdir -p /home/ruoyi/redis
|
||||
# 指定路径
|
||||
WORKDIR /home/ruoyi/redis
|
||||
# 复制conf文件到路径
|
||||
COPY ./conf/redis.conf /home/ruoyi/redis/redis.conf
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM openjdk:8-jre
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 挂载目录
|
||||
VOLUME /home/ruoyi
|
||||
# 创建目录
|
||||
RUN mkdir -p /home/ruoyi
|
||||
# 指定路径
|
||||
WORKDIR /home/ruoyi
|
||||
# 复制jar文件到路径
|
||||
COPY ./jar/ruoyi-auth.jar /home/ruoyi/ruoyi-auth.jar
|
||||
# 启动认证服务
|
||||
ENTRYPOINT ["java","-jar","ruoyi-auth.jar"]
|
||||
|
|
@ -1 +0,0 @@
|
|||
存放认证中心打包好的jar文件,用于docker启动应用。
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM openjdk:8-jre
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 挂载目录
|
||||
VOLUME /home/ruoyi
|
||||
# 创建目录
|
||||
RUN mkdir -p /home/ruoyi
|
||||
# 指定路径
|
||||
WORKDIR /home/ruoyi
|
||||
# 复制jar文件到路径
|
||||
COPY ./jar/ruoyi-gateway.jar /home/ruoyi/ruoyi-gateway.jar
|
||||
# 启动网关服务
|
||||
ENTRYPOINT ["java","-jar","ruoyi-gateway.jar"]
|
||||
|
|
@ -1 +0,0 @@
|
|||
存放网关模块打包好的jar文件,用于docker启动应用。
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM openjdk:8-jre
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 挂载目录
|
||||
VOLUME /home/ruoyi
|
||||
# 创建目录
|
||||
RUN mkdir -p /home/ruoyi
|
||||
# 指定路径
|
||||
WORKDIR /home/ruoyi
|
||||
# 复制jar文件到路径
|
||||
COPY ./jar/ruoyi-modules-file.jar /home/ruoyi/ruoyi-modules-file.jar
|
||||
# 启动文件服务
|
||||
ENTRYPOINT ["java","-jar","ruoyi-modules-file.jar"]
|
||||
|
|
@ -1 +0,0 @@
|
|||
存放文件服务打包好的jar文件,用于docker启动应用。
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM openjdk:8-jre
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 挂载目录
|
||||
VOLUME /home/ruoyi
|
||||
# 创建目录
|
||||
RUN mkdir -p /home/ruoyi
|
||||
# 指定路径
|
||||
WORKDIR /home/ruoyi
|
||||
# 复制jar文件到路径
|
||||
COPY ./jar/ruoyi-modules-gen.jar /home/ruoyi/ruoyi-modules-gen.jar
|
||||
# 启动代码生成服务
|
||||
ENTRYPOINT ["java","-jar","ruoyi-modules-gen.jar"]
|
||||
|
|
@ -1 +0,0 @@
|
|||
存放代码生成打包好的jar文件,用于docker启动应用。
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM openjdk:8-jre
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 挂载目录
|
||||
VOLUME /home/ruoyi
|
||||
# 创建目录
|
||||
RUN mkdir -p /home/ruoyi
|
||||
# 指定路径
|
||||
WORKDIR /home/ruoyi
|
||||
# 复制jar文件到路径
|
||||
COPY ./jar/ruoyi-modules-job.jar /home/ruoyi/ruoyi-modules-job.jar
|
||||
# 启动定时任务服务
|
||||
ENTRYPOINT ["java","-jar","ruoyi-modules-job.jar"]
|
||||
|
|
@ -1 +0,0 @@
|
|||
存放定时任务打包好的jar文件,用于docker启动应用。
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM openjdk:8-jre
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 挂载目录
|
||||
VOLUME /home/ruoyi
|
||||
# 创建目录
|
||||
RUN mkdir -p /home/ruoyi
|
||||
# 指定路径
|
||||
WORKDIR /home/ruoyi
|
||||
# 复制jar文件到路径
|
||||
COPY ./jar/ruoyi-modules-system.jar /home/ruoyi/ruoyi-modules-system.jar
|
||||
# 启动系统服务
|
||||
ENTRYPOINT ["java","-jar","ruoyi-modules-system.jar"]
|
||||
|
|
@ -1 +0,0 @@
|
|||
存放系统模块打包好的jar文件,用于docker启动应用。
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# 基础镜像
|
||||
FROM openjdk:8-jre
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 挂载目录
|
||||
VOLUME /home/ruoyi
|
||||
# 创建目录
|
||||
RUN mkdir -p /home/ruoyi
|
||||
# 指定路径
|
||||
WORKDIR /home/ruoyi
|
||||
# 复制jar文件到路径
|
||||
COPY ./jar/ruoyi-visual-monitor.jar /home/ruoyi/ruoyi-visual-monitor.jar
|
||||
# 启动系统服务
|
||||
ENTRYPOINT ["java","-jar","ruoyi-visual-monitor.jar"]
|
||||
|
|
@ -1 +0,0 @@
|
|||
存放监控中心打包好的jar文件,用于docker启动应用。
|
||||
20
pom.xml
20
pom.xml
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<name>ruoyi</name>
|
||||
<url>http://www.ruoyi.vip</url>
|
||||
<description>若依微服务系统</description>
|
||||
<description>租研舍微服务系统</description>
|
||||
|
||||
<properties>
|
||||
<ruoyi.version>3.6.4</ruoyi.version>
|
||||
|
|
@ -35,6 +35,9 @@
|
|||
<poi.version>4.1.2</poi.version>
|
||||
<springdoc.version>1.6.9</springdoc.version>
|
||||
<transmittable-thread-local.version>2.14.4</transmittable-thread-local.version>
|
||||
<mybatis-plus.version>3.5.2</mybatis-plus.version>
|
||||
<lombok.version>1.18.30</lombok.version>
|
||||
<hutools.version>5.8.26</hutools.version>
|
||||
</properties>
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
|
|
@ -216,6 +219,21 @@
|
|||
<artifactId>ruoyi-api-system</artifactId>
|
||||
<version>${ruoyi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutools.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package com.ruoyi.system.api;
|
||||
|
||||
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
|
||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||
import com.ruoyi.system.api.factory.RemoteChannelFallbackFactory;
|
||||
import com.ruoyi.system.api.factory.RemoteCustomerApplyLogFallbackFactory;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 用户服务
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@FeignClient(contextId = "remoteChannelService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteChannelFallbackFactory.class)
|
||||
public interface RemoteChannelService
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.ruoyi.system.api;
|
||||
|
||||
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||
import com.ruoyi.common.core.domain.GetSumDto;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
|
||||
import com.ruoyi.common.core.domain.http.Merchant;
|
||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||
import com.ruoyi.system.api.factory.RemoteCustomerApplyLogFallbackFactory;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户服务
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@FeignClient(contextId = "remoteCustomerApplyLogService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteCustomerApplyLogFallbackFactory.class)
|
||||
public interface RemoteCustomerApplyLogService
|
||||
{
|
||||
/**
|
||||
* 获取商户今日已申请数
|
||||
*
|
||||
*
|
||||
* @param getSumDto
|
||||
* @param source 请求来源
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/log/sum")
|
||||
public R<Integer> sum(@RequestBody GetSumDto getSumDto, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
|
||||
/**
|
||||
* 获取用户今日是否是否已申请
|
||||
*
|
||||
*
|
||||
* @param customerID
|
||||
* @param source 请求来源
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/log/customerApply")
|
||||
public R<Boolean> customerApply(@RequestParam("customerID") Long customerID,@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
|
||||
/**
|
||||
* 新增用户
|
||||
* @param customerApplyLog
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/log")
|
||||
public AjaxResult add(@RequestBody CustomerApplyLog customerApplyLog);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package com.ruoyi.system.api;
|
||||
|
||||
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.domain.http.Customer;
|
||||
import com.ruoyi.system.api.factory.RemoteCustomerFallbackFactory;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 用户服务
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@FeignClient(contextId = "remoteCustomerService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteCustomerFallbackFactory.class)
|
||||
public interface RemoteCustomerService
|
||||
{
|
||||
/**
|
||||
* 通过用户名查询用户信息
|
||||
*
|
||||
* @param id 用户名
|
||||
* @param source 请求来源
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/customer/{id}")
|
||||
public R<Customer> getCustomerInfoById(@PathVariable("id") Long id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
|
||||
/**
|
||||
* 通过手机号MD5查询用户信息
|
||||
*
|
||||
* @param phoneMD5 用户名
|
||||
* @param source 请求来源
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/customer/getByMd5")
|
||||
public R<Customer> getCustomerInfoByPhoneMd5(@RequestParam("phoneMD5")String phoneMD5, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
|
||||
/**
|
||||
* 通过手机号MD5更新用户信息
|
||||
*
|
||||
* @param customer 用户
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/customer/updateByPhoneMd5")
|
||||
public R updateByPhoneMd5(Customer customer ,@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
|
||||
/**
|
||||
* 新增客户信息
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/customer/addNewCustomer")
|
||||
public R add(@RequestBody Customer customer,@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
|
||||
/**
|
||||
* 获取用户token
|
||||
* @param phone
|
||||
* @param channelId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/customer/getCustomerToken")
|
||||
public String getCustomerToken(@RequestParam("phone") String phone,@RequestParam("channelId")Long channelId);
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.ruoyi.system.api;
|
||||
|
||||
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.domain.http.Merchant;
|
||||
import com.ruoyi.system.api.domain.SysUser;
|
||||
import com.ruoyi.system.api.factory.RemoteMerChantFallbackFactory;
|
||||
import com.ruoyi.system.api.factory.RemoteUserFallbackFactory;
|
||||
import com.ruoyi.system.api.model.LoginUser;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户服务
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@FeignClient(contextId = "remoteMerchantService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteMerChantFallbackFactory.class)
|
||||
public interface RemoteMerchantService
|
||||
{
|
||||
/**
|
||||
* 获取合适的产品 前筛
|
||||
*
|
||||
* @param source 请求来源
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/merchant/merchantList")
|
||||
public R<List<Merchant>> merchantList(@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.ruoyi.system.api.factory;
|
||||
|
||||
|
||||
import com.ruoyi.system.api.RemoteChannelService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
/**
|
||||
* 用户服务降级处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RemoteChannelFallbackFactory implements FallbackFactory<RemoteChannelService>
|
||||
{
|
||||
|
||||
@Override
|
||||
public RemoteChannelService create(Throwable throwable)
|
||||
{
|
||||
log.error("用户服务调用失败:{}", throwable.getMessage());
|
||||
return new RemoteChannelService()
|
||||
{
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.ruoyi.system.api.factory;
|
||||
|
||||
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||
import com.ruoyi.common.core.domain.GetSumDto;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
|
||||
import com.ruoyi.common.core.domain.http.Merchant;
|
||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||
import com.ruoyi.system.api.RemoteCustomerApplyLogService;
|
||||
import com.ruoyi.system.api.RemoteMerchantService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户服务降级处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RemoteCustomerApplyLogFallbackFactory implements FallbackFactory<RemoteCustomerApplyLogService>
|
||||
{
|
||||
|
||||
@Override
|
||||
public RemoteCustomerApplyLogService create(Throwable throwable)
|
||||
{
|
||||
log.error("用户服务调用失败:{}", throwable.getMessage());
|
||||
return new RemoteCustomerApplyLogService()
|
||||
{
|
||||
@Override
|
||||
public R<Integer> sum(GetSumDto getSumDto, @RequestHeader(SecurityConstants.FROM_SOURCE) String source)
|
||||
{
|
||||
return R.fail("获取商户已申请数失败:" + throwable.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<Boolean> customerApply(Long customerID, String source) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult add(CustomerApplyLog customerApplyLog) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.ruoyi.system.api.factory;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.domain.http.Customer;
|
||||
import com.ruoyi.system.api.RemoteCustomerService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 用户服务降级处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RemoteCustomerFallbackFactory implements FallbackFactory<RemoteCustomerService>
|
||||
{
|
||||
@Override
|
||||
public RemoteCustomerService create(Throwable throwable)
|
||||
{
|
||||
log.error("用户服务调用失败:{}", throwable.getMessage());
|
||||
return new RemoteCustomerService()
|
||||
{
|
||||
@Override
|
||||
public R<Customer> getCustomerInfoById(Long id, String source)
|
||||
{
|
||||
return R.fail("获取用户失败:" + throwable.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<Customer> getCustomerInfoByPhoneMd5(String phoneMD5, String source) {
|
||||
log.info("查询用户失败:{}",throwable.getMessage());
|
||||
return R.fail("查询用户失败:" + throwable.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public R updateByPhoneMd5(Customer customer, String source) {
|
||||
return R.fail("更新用户失败:" + throwable.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public R add(Customer customer, String source) {
|
||||
log.info("新增用户失败:{}",throwable.getMessage());
|
||||
return R.fail("新增用户失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomerToken(String phone, Long channelId) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.ruoyi.system.api.factory;
|
||||
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.domain.http.Merchant;
|
||||
import com.ruoyi.system.api.RemoteMerchantService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户服务降级处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class RemoteMerChantFallbackFactory implements FallbackFactory<RemoteMerchantService>
|
||||
{
|
||||
|
||||
@Override
|
||||
public RemoteMerchantService create(Throwable throwable)
|
||||
{
|
||||
log.error("用户服务调用失败:{}", throwable.getMessage());
|
||||
return new RemoteMerchantService()
|
||||
{
|
||||
@Override
|
||||
public R<List<Merchant>> merchantList(String source)
|
||||
{
|
||||
return R.fail("获取用户失败:" + throwable.getMessage());
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
com.ruoyi.system.api.factory.RemoteUserFallbackFactory
|
||||
com.ruoyi.system.api.factory.RemoteLogFallbackFactory
|
||||
com.ruoyi.system.api.factory.RemoteFileFallbackFactory
|
||||
com.ruoyi.system.api.factory.RemoteCustomerFallbackFactory
|
||||
com.ruoyi.system.api.factory.RemoteMerChantFallbackFactory
|
||||
com.ruoyi.system.api.factory.RemoteCustomerApplyLogFallbackFactory
|
||||
|
|
@ -17,15 +17,6 @@ public class RuoYiAuthApplication
|
|||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(RuoYiAuthApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ 认证授权中心启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||
" .-------. ____ __ \n" +
|
||||
" | _ _ \\ \\ \\ / / \n" +
|
||||
" | ( ' ) | \\ _. / ' \n" +
|
||||
" |(_ o _) / _( )_ .' \n" +
|
||||
" | (_,_).' __ ___(_ o _)' \n" +
|
||||
" | |\\ \\ | || |(_,_)' \n" +
|
||||
" | | \\ `' /| `-' / \n" +
|
||||
" | | \\ / \\ / \n" +
|
||||
" ''-' `'-' `-..-' ");
|
||||
System.out.println("(♥◠‿◠)ノ゙ 认证授权中心启动成功 ლ(´ڡ`ლ)゙ ");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@ spring:
|
|||
nacos:
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 127.0.0.1:8848
|
||||
server-addr: 47.109.135.151:8848
|
||||
namespace: b8ad3fd2-18ea-4cdf-a82c-4ce483392b1a
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 127.0.0.1:8848
|
||||
server-addr: 47.109.135.151:8848
|
||||
namespace: b8ad3fd2-18ea-4cdf-a82c-4ce483392b1a
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
</root>
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<root level="INFO">
|
||||
<appender-ref ref="file_info" />
|
||||
<appender-ref ref="file_error" />
|
||||
</root>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
<module>ruoyi-common-sensitive</module>
|
||||
<module>ruoyi-common-datascope</module>
|
||||
<module>ruoyi-common-datasource</module>
|
||||
<module>ruoyi-common-sms</module>
|
||||
</modules>
|
||||
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
|
|
|
|||
|
|
@ -106,7 +106,21 @@
|
|||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-annotation</artifactId>
|
||||
<version>3.5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -56,4 +56,20 @@ public class CacheConstants
|
|||
* 登录IP黑名单 cache key
|
||||
*/
|
||||
public static final String SYS_LOGIN_BLACKIPLIST = SYS_CONFIG_KEY + "sys.login.blackIPList";
|
||||
|
||||
|
||||
public static final String PROJET = "xymz:";
|
||||
/**
|
||||
* 渠道redis缓存键
|
||||
*/
|
||||
public static final String CHANNEL_ID = PROJET + "channel:id:";
|
||||
/**
|
||||
* 渠道redis缓存键
|
||||
*/
|
||||
public static final String CHANNEL_SIGN = PROJET + "channel:sign:";
|
||||
|
||||
/**
|
||||
* 商户redis缓存键
|
||||
*/
|
||||
public static final String MERCHANT = PROJET + "merchant:key:";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
package com.ruoyi.common.core.constant;
|
||||
|
||||
public class RedisConstant {
|
||||
|
||||
/**
|
||||
* 用户登录缓存
|
||||
*/
|
||||
public final static String APP_CUSTOMER_KEY = CacheConstants.PROJET + ":customer:key:";
|
||||
|
||||
/**
|
||||
* 用户名缓存
|
||||
*/
|
||||
public final static String APP_CUSTOMER_USERNAME_KEY = CacheConstants.PROJET + ":app:customer:username:key:";
|
||||
/**
|
||||
* 渠道ID缓存
|
||||
*/
|
||||
public final static String APP_CUSTOMER_CHANNEL_KEY = CacheConstants.PROJET + ":app:customer:channel:key:";
|
||||
/**
|
||||
* 用户登录缓存
|
||||
*/
|
||||
public final static String APP_CUSTOMER_TOKEN_KEY = CacheConstants.PROJET + ":app:customer:token:key:";
|
||||
|
||||
/**
|
||||
* app用户设备标识
|
||||
*/
|
||||
public final static String APP_DEVICE_IDENTIFICATION = CacheConstants.PROJET + ":app:app:device:identification:";
|
||||
|
||||
/**
|
||||
* H5登录验证码
|
||||
*/
|
||||
public final static String H5_LOGIN_CACHE = CacheConstants.PROJET+"H5:login:cache:";
|
||||
|
||||
/**
|
||||
* H5申请幂等校验
|
||||
*/
|
||||
public final static String H5_APPLY_CHECK = CacheConstants.PROJET+"H5:apply:check:";
|
||||
|
||||
/**
|
||||
* 撞库幂等校验
|
||||
*/
|
||||
public final static String HIT_CHECK_CACHE = CacheConstants.PROJET+"hit:check:cache:";
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class GetSumDto {
|
||||
|
||||
private Long merchantId;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.ruoyi.common.core.domain;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 概率计算
|
||||
* @Author: daisi
|
||||
* @Date: 2022/4/2 9:49
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class GuestProbabilityReq implements Serializable {
|
||||
private static final long serialVersionUID = -9096451963988288187L;
|
||||
|
||||
/**
|
||||
* 计划Id
|
||||
*/
|
||||
private Long planId;
|
||||
/**
|
||||
* 排序价格
|
||||
*/
|
||||
private BigDecimal orderPrice;
|
||||
/**
|
||||
* 概率
|
||||
*/
|
||||
private Double guestProbability;
|
||||
/**
|
||||
* 计算结果概率
|
||||
*/
|
||||
private Integer resultGuestProbability;
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package com.ruoyi.common.core.domain.http;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import com.ruoyi.common.core.annotation.Excel;
|
||||
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 渠道配置对象 channel
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2024-09-15
|
||||
*/
|
||||
@Data
|
||||
public class Channel extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** */
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 渠道名称 */
|
||||
@Excel(name = "渠道名称")
|
||||
private String channelName;
|
||||
|
||||
/** 渠道签名 */
|
||||
@Excel(name = "渠道签名")
|
||||
private String channelSign;
|
||||
|
||||
/** 渠道类型 1H5 2连登 3半流程 4全流程*/
|
||||
@Excel(name = "渠道类型")
|
||||
private String channelType;
|
||||
|
||||
/** 扣量比 */
|
||||
@Excel(name = "扣量比")
|
||||
private Long score;
|
||||
|
||||
/** 推广页名称 */
|
||||
@Excel(name = "推广页名称")
|
||||
private String htmlName;
|
||||
|
||||
/** 推广页地址 */
|
||||
@Excel(name = "推广页地址")
|
||||
private String htmlLocation;
|
||||
|
||||
/** 可访问IP */
|
||||
@Excel(name = "可访问IP")
|
||||
private String ips;
|
||||
|
||||
/** 开启关闭时段 */
|
||||
@Excel(name = "开启关闭时段")
|
||||
private String period;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package com.ruoyi.common.core.domain.http;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.core.annotation.Excel;
|
||||
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 客户信息对象 customer
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2024-09-15
|
||||
*/
|
||||
@Data
|
||||
public class Customer extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** $column.columnComment */
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**渠道ID**/
|
||||
@Excel(name = "渠道ID")
|
||||
private Long channelId;
|
||||
|
||||
/** 年龄 */
|
||||
@Excel(name = "年龄")
|
||||
private Integer age;
|
||||
|
||||
/** 0 男 1 女 */
|
||||
@Excel(name = "0 男 1 女")
|
||||
private Integer sex;
|
||||
|
||||
@Excel(name="身份证号")
|
||||
private String idCard;
|
||||
|
||||
/** 昵称 */
|
||||
@Excel(name = "昵称")
|
||||
private String name;
|
||||
|
||||
/** 真实姓名 */
|
||||
@Excel(name = "真实姓名")
|
||||
private String acturlName;
|
||||
|
||||
/** 手机号 */
|
||||
@Excel(name = "手机号")
|
||||
private String phone;
|
||||
|
||||
/** 手机号MD5 */
|
||||
@Excel(name = "手机号MD5")
|
||||
private String phoneMd5;
|
||||
|
||||
/** 0 未实名 1已实名 */
|
||||
@Excel(name = "0 未实名 1已实名")
|
||||
private Boolean isAuth;
|
||||
|
||||
/** 城市 */
|
||||
@Excel(name = "城市")
|
||||
private String city;
|
||||
|
||||
/** 城市编码 */
|
||||
@Excel(name = "城市编码")
|
||||
private Integer cityCode;
|
||||
|
||||
/** 首次登录时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "首次登录时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
private Date firstLoginTime;
|
||||
|
||||
/** 最后登录时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
private Date lastLoginTime;
|
||||
|
||||
/** 最后登录IP */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "最后登录IP", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
private Date lastLoginIp;
|
||||
|
||||
/** 用户状态 1正常 2异常 可继续扩展 */
|
||||
@Excel(name = "用户状态 1正常 2异常 可继续扩展")
|
||||
private Integer status;
|
||||
|
||||
/** 无社保 */
|
||||
@Excel(name = "社保")
|
||||
private Integer socialSecurity;
|
||||
|
||||
/** 无车 */
|
||||
@Excel(name = "车")
|
||||
private Integer car;
|
||||
|
||||
/** 保单缴纳不满一年 */
|
||||
@Excel(name = "保单")
|
||||
private Integer guaranteeSlip;
|
||||
|
||||
/** 初中 */
|
||||
@Excel(name = "学历")
|
||||
private Integer education;
|
||||
|
||||
/** 公积金未满6个月 */
|
||||
@Excel(name = "公积金")
|
||||
private Integer accumulationFund;
|
||||
|
||||
/** 本地无房 */
|
||||
@Excel(name = "房")
|
||||
private Integer hourse;
|
||||
|
||||
/** 上班族 */
|
||||
@Excel(name = "职业")
|
||||
private Integer career;
|
||||
|
||||
|
||||
/** 花呗5000以下 */
|
||||
@Excel(name = "花呗")
|
||||
private Integer huaBei;
|
||||
|
||||
/** 白条5000以下 */
|
||||
@Excel(name = "白条")
|
||||
private Integer baiTiao;
|
||||
|
||||
/** 芝麻分 */
|
||||
@Excel(name = "芝麻分")
|
||||
private Integer zhiMa;
|
||||
|
||||
|
||||
/** 月收入 */
|
||||
@Excel(name = "月收入")
|
||||
private Integer income;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.ruoyi.common.core.domain.http;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.core.annotation.Excel;
|
||||
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 客户申请记录对象 customer_apply_log
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2024-09-15
|
||||
*/
|
||||
@Data
|
||||
public class CustomerApplyLog extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** $column.columnComment */
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 用户id */
|
||||
@Excel(name = "用户id")
|
||||
private Long customerId;
|
||||
|
||||
/** 商户ID */
|
||||
@Excel(name = "商户ID")
|
||||
private Long merchantId;
|
||||
|
||||
/** $column.columnComment */
|
||||
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
|
||||
private Long channelId;
|
||||
|
||||
/** 订单状态 0 已申请 1 注册中 2风控中 3下单中 4 下单成功 5已成交 */
|
||||
@Excel(name = "订单状态 0 已申请 1 注册中 2风控中 3下单中 4 下单成功 5已成交 ")
|
||||
private Long orderStatus;
|
||||
|
||||
/** 成交金额 分 */
|
||||
@Excel(name = "成交金额 分")
|
||||
private BigDecimal price;
|
||||
|
||||
@Excel(name = "订单号")
|
||||
private String orderNo;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
package com.ruoyi.common.core.domain.http;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.core.annotation.Excel;
|
||||
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 商户对象 merchant
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2024-09-15
|
||||
*/
|
||||
@Data
|
||||
public class Merchant extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** $column.columnComment */
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/** 商户类型 1H5 2连登 3半流程 4全流程 */
|
||||
@Excel(name = "商户类型 1H5 2连登 3半流程 4全流程")
|
||||
private Long merchantType;
|
||||
|
||||
/** 商户名称 */
|
||||
@Excel(name = "商户名称")
|
||||
private String merchantName;
|
||||
|
||||
/** 商户描述 */
|
||||
@Excel(name = "商户描述")
|
||||
private String merchantDescribe;
|
||||
|
||||
/** 商户主体 */
|
||||
@Excel(name = "商户主体")
|
||||
private String merchantCompany;
|
||||
|
||||
/** logo文件地址 */
|
||||
@Excel(name = "logo文件地址")
|
||||
private String logo;
|
||||
|
||||
/** 是否上下架 */
|
||||
@Excel(name = "是否上下架")
|
||||
private Integer status;
|
||||
|
||||
/** 定量数 */
|
||||
@Excel(name = "定量数")
|
||||
private Integer limitNum;
|
||||
|
||||
/** 是否定量 0否 1是 */
|
||||
@Excel(name = "是否定量 0否 1是")
|
||||
private Integer limitType;
|
||||
|
||||
|
||||
/** 是否开启余额监控 0否 1是 */
|
||||
@Excel(name = " 是否开启余额监控 0否 1是")
|
||||
private Integer isBalanceMonitoring;
|
||||
|
||||
/** 余额监控余额 */
|
||||
@Excel(name = "余额")
|
||||
private Integer balanceMonitoring ;
|
||||
|
||||
|
||||
/** 渠道限制ID */
|
||||
@Excel(name = "渠道限制ID")
|
||||
private String channelLimit;
|
||||
|
||||
/** 是否通过 0否 1是 */
|
||||
@Excel(name = "是否通过 0否 1是")
|
||||
private Integer ispass;
|
||||
|
||||
/** 渠道限制类型 0不限 1满足其一 2满足全部 */
|
||||
@Excel(name = "渠道限制类型 0不限 1满足其一 2满足全部")
|
||||
private Integer customerInfoFilterType;
|
||||
|
||||
/** 渠道限制类型 0不限 1准入 2禁入 */
|
||||
@Excel(name = "渠道限制类型 0不限 1准入 2禁入")
|
||||
private Integer channelLimitType;
|
||||
|
||||
/** 执行时段 */
|
||||
@Excel(name = "执行时段")
|
||||
private String period;
|
||||
|
||||
/**撞库地址**/
|
||||
@Excel(name = "撞库地址")
|
||||
private String hitUrl;
|
||||
|
||||
/**注册地址**/
|
||||
@Excel(name = "注册地址")
|
||||
private String registUrl;
|
||||
|
||||
/** 年龄限制开始 */
|
||||
@Excel(name = "年龄限制开始")
|
||||
private Integer ageLimitStart;
|
||||
|
||||
/** 年龄限制结束 */
|
||||
@Excel(name = "年龄限制结束")
|
||||
private Integer ageLimitEnd;
|
||||
|
||||
/** 手机号禁入号段英文逗号分隔 */
|
||||
@Excel(name = "手机号禁入号段英文逗号分隔")
|
||||
private String phoneLimit;
|
||||
|
||||
/** 标签 */
|
||||
@Excel(name = "标签")
|
||||
private String label;
|
||||
|
||||
/** 商户是否开启二要素 0 否 1 是 */
|
||||
@Excel(name = "商户是否开启二要素")
|
||||
private Boolean merchantAuth;
|
||||
|
||||
@Excel(name = "下游渠道标识")
|
||||
private String channelSign;
|
||||
|
||||
/** 无社保 */
|
||||
@Excel(name = "无社保")
|
||||
private Boolean socialSecurityNo;
|
||||
|
||||
/** 社保未满6个月 */
|
||||
@Excel(name = "社保未满6个月")
|
||||
private Boolean socialSecurityLow;
|
||||
|
||||
/** 社保6个月以上 */
|
||||
@Excel(name = "社保6个月以上")
|
||||
private Boolean socialSecurityHigh;
|
||||
|
||||
/** 无车 */
|
||||
@Excel(name = "无车")
|
||||
private Boolean carNo;
|
||||
|
||||
/** 有车 */
|
||||
@Excel(name = "有车")
|
||||
private Boolean carHave;
|
||||
|
||||
/** 保单缴纳不满一年 */
|
||||
@Excel(name = "保单缴纳不满一年")
|
||||
private Boolean guaranteeSlipLow;
|
||||
|
||||
/** 保单缴纳一年以上 */
|
||||
@Excel(name = "保单缴纳一年以上")
|
||||
private Boolean guaranteeSlipCentre;
|
||||
|
||||
/** 保单缴纳2年以上 */
|
||||
@Excel(name = "保单缴纳2年以上")
|
||||
private Boolean guaranteeSlipHigh;
|
||||
|
||||
/** 初中 */
|
||||
@Excel(name = "初中")
|
||||
private Boolean educationMiddle;
|
||||
|
||||
/** 高中 */
|
||||
@Excel(name = "高中")
|
||||
private Boolean educationHighSchool;
|
||||
|
||||
/** 中专 */
|
||||
@Excel(name = "中专")
|
||||
private Boolean educationPolytechnic;
|
||||
|
||||
/** 大专 */
|
||||
@Excel(name = "大专")
|
||||
private Boolean educationJuniorCollege;
|
||||
|
||||
/** 本科 */
|
||||
@Excel(name = "本科")
|
||||
private Boolean educationUndergraduateCourse;
|
||||
|
||||
/** 研究生及以上 */
|
||||
@Excel(name = "研究生及以上")
|
||||
private Boolean educationPostgraduate;
|
||||
|
||||
/** 公积金未满6个月 */
|
||||
@Excel(name = "公积金未满6个月")
|
||||
private Boolean accumulationFundLow;
|
||||
|
||||
/** 公积金满6个月以上 */
|
||||
@Excel(name = "公积金满6个月以上")
|
||||
private Boolean accumulationFundHigh;
|
||||
|
||||
/** 本地无房 */
|
||||
@Excel(name = "本地无房")
|
||||
private Boolean hourseNo;
|
||||
|
||||
/** 本地全款房 */
|
||||
@Excel(name = "本地全款房")
|
||||
private Boolean hourseFullPayment;
|
||||
|
||||
/** 本地按揭 */
|
||||
@Excel(name = "本地按揭")
|
||||
private Boolean hourseMortgaging;
|
||||
|
||||
/** 上班族 */
|
||||
@Excel(name = "上班族")
|
||||
private Boolean officeWorker;
|
||||
|
||||
/** 公务员 */
|
||||
@Excel(name = "公务员")
|
||||
private Boolean civilServant;
|
||||
|
||||
/** 私营业主 */
|
||||
@Excel(name = "私营业主")
|
||||
private Boolean privatePropertyOwners;
|
||||
|
||||
/** 个体户 */
|
||||
@Excel(name = "个体户")
|
||||
private Boolean selfEmployedPerson;
|
||||
|
||||
/** 其他职业 */
|
||||
@Excel(name = "其他职业")
|
||||
private Boolean otherOccupations;
|
||||
|
||||
/** 花呗5000以下 */
|
||||
@Excel(name = "花呗5000以下")
|
||||
private Boolean huaBeiLow;
|
||||
|
||||
/** 花呗5000-10000 */
|
||||
@Excel(name = "花呗5000-10000")
|
||||
private Boolean huaBeiMiddle;
|
||||
|
||||
/** 花呗10000以上 */
|
||||
@Excel(name = "花呗10000以上")
|
||||
private Boolean huaBeiHigh;
|
||||
|
||||
/** 白条5000以下 */
|
||||
@Excel(name = "白条5000以下")
|
||||
private Boolean baiTiaoLow;
|
||||
|
||||
/** 白条5000-10000 */
|
||||
@Excel(name = "白条5000-10000")
|
||||
private Boolean baiTiaoMiddle;
|
||||
|
||||
/** 白条10000以上 */
|
||||
@Excel(name = "白条10000以上")
|
||||
private Boolean baiTiaoHigh;
|
||||
|
||||
/** 芝麻分 */
|
||||
@Excel(name = "芝麻分")
|
||||
private Integer zhiMa;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,636 @@
|
|||
package com.ruoyi.common.core.utils;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.springframework.stereotype.Component;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @program: JieYiHua-Cloud
|
||||
* @description: 加密解密
|
||||
* @author: LiYu
|
||||
* @create: 2021-07-23 17:02
|
||||
**/
|
||||
@Component
|
||||
public class EncryptUtil {
|
||||
|
||||
public static final String MD5 = "MD5";
|
||||
public static final String SHA1 = "SHA1";
|
||||
public static final String HmacMD5 = "HmacMD5";
|
||||
public static final String HmacSHA1 = "HmacSHA1";
|
||||
public static final String DES = "DES";
|
||||
public static final String AES = "AES";
|
||||
public static final Charset CHARSET = StandardCharsets.UTF_8;
|
||||
|
||||
public static final byte keyStrSize = 16;
|
||||
|
||||
|
||||
public static final byte ivStrSize = 16;
|
||||
|
||||
public static final String AES_CBC_NOPADDING = "AES/CBC/NoPadding";
|
||||
public static final String DES_ECB_PKCS7PADDING = "DES/ECB/PKCS7Padding";
|
||||
public static final String AES_ECB_PKCS5PADDING = "AES/ECB/PKCS5Padding";
|
||||
|
||||
/**
|
||||
* 编码格式;默认使用uft-8
|
||||
*/
|
||||
public static String charset = "utf-8";
|
||||
/**
|
||||
* DES
|
||||
*/
|
||||
public static int keysizeDES = 0;
|
||||
/**
|
||||
* AES
|
||||
*/
|
||||
public static int keysizeAES = 128;
|
||||
|
||||
public static EncryptUtil me;
|
||||
|
||||
private EncryptUtil() {
|
||||
//单例
|
||||
}
|
||||
|
||||
//双重锁
|
||||
public static EncryptUtil getInstance() {
|
||||
if (me == null) {
|
||||
synchronized (EncryptUtil.class) {
|
||||
if (me == null) {
|
||||
me = new EncryptUtil();
|
||||
}
|
||||
}
|
||||
}
|
||||
return me;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用MessageDigest进行单向加密(无密码)
|
||||
*
|
||||
* @param res 被加密的文本
|
||||
* @param algorithm 加密算法名称
|
||||
* @return
|
||||
*/
|
||||
private static String messageDigest(String res, String algorithm) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance(algorithm);
|
||||
byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
|
||||
return base64(md.digest(resBytes));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用KeyGenerator进行单向/双向加密(可设密码)
|
||||
*
|
||||
* @param res 被加密的原文
|
||||
* @param algorithm 加密使用的算法名称
|
||||
* @param key 加密使用的秘钥
|
||||
* @return
|
||||
*/
|
||||
private String keyGeneratorMac(String res, String algorithm, String key) {
|
||||
try {
|
||||
SecretKey sk = null;
|
||||
if (key == null) {
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algorithm);
|
||||
sk = kg.generateKey();
|
||||
} else {
|
||||
byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
|
||||
sk = new SecretKeySpec(keyBytes, algorithm);
|
||||
}
|
||||
Mac mac = Mac.getInstance(algorithm);
|
||||
mac.init(sk);
|
||||
byte[] result = mac.doFinal(res.getBytes());
|
||||
return base64(result);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用KeyGenerator双向加密,DES/AES,注意这里转化为字符串的时候是将2进制转为16进制格式的字符串,不是直接转,因为会出错
|
||||
*
|
||||
* @param res 加密的原文
|
||||
* @param algorithm 加密使用的算法名称
|
||||
* @param key 加密的秘钥
|
||||
* @param keysize
|
||||
* @param isEncode
|
||||
* @return
|
||||
*/
|
||||
private static String keyGeneratorES(String res, String algorithm, String key, int keysize, boolean isEncode) {
|
||||
try {
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algorithm);
|
||||
if (keysize == 0) {
|
||||
byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
|
||||
kg.init(new SecureRandom(keyBytes));
|
||||
} else if (key == null) {
|
||||
kg.init(keysize);
|
||||
} else {
|
||||
byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
|
||||
kg.init(keysize, new SecureRandom(keyBytes));
|
||||
}
|
||||
SecretKey sk = kg.generateKey();
|
||||
SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm);
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
if (isEncode) {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, sks);
|
||||
byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
|
||||
return parseByte2HexStr(cipher.doFinal(resBytes));
|
||||
} else {
|
||||
cipher.init(Cipher.DECRYPT_MODE, sks);
|
||||
return new String(cipher.doFinal(parseHexStr2Byte(res)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Deprecated
|
||||
private static String base64(byte[] res) {
|
||||
return Base64.encode(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将二进制转换成16进制
|
||||
*/
|
||||
public static String parseByte2HexStr(byte buf[]) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < buf.length; i++) {
|
||||
String hex = Integer.toHexString(buf[i] & 0xFF);
|
||||
if (hex.length() == 1) {
|
||||
hex = '0' + hex;
|
||||
}
|
||||
sb.append(hex.toUpperCase());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将16进制转换为二进制
|
||||
*/
|
||||
public static byte[] parseHexStr2Byte(String hexStr) {
|
||||
if (hexStr.length() < 1) {
|
||||
return null;
|
||||
}
|
||||
byte[] result = new byte[hexStr.length() / 2];
|
||||
for (int i = 0; i < hexStr.length() / 2; i++) {
|
||||
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
|
||||
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
|
||||
result[i] = (byte) (high * 16 + low);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* md5加密算法进行加密(不可逆)
|
||||
*
|
||||
* @param res 需要加密的原文
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public String MD5(String res) {
|
||||
return messageDigest(res, MD5);
|
||||
}
|
||||
|
||||
/**
|
||||
* md5加密算法进行加密(不可逆)
|
||||
*
|
||||
* @param res 需要加密的原文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public String MD5(String res, String key) {
|
||||
return keyGeneratorMac(res, HmacMD5, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用SHA1加密算法进行加密(不可逆)
|
||||
*
|
||||
* @param res 需要加密的原文
|
||||
* @return
|
||||
*/
|
||||
public static String SHA1(String res) {
|
||||
return messageDigest(res, SHA1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用SHA1加密算法进行加密(不可逆)
|
||||
*
|
||||
* @param res 需要加密的原文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String SHA1(String res, String key) {
|
||||
return keyGeneratorMac(res, HmacSHA1, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用DES加密算法进行加密(可逆)
|
||||
*
|
||||
* @param res 需要加密的原文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public static String DESencode(String res, String key) {
|
||||
return keyGeneratorES(res, DES, key, keysizeDES, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对使用DES加密算法的密文进行解密(可逆)
|
||||
*
|
||||
* @param res 需要解密的密文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String DESdecode(String res, String key) {
|
||||
return keyGeneratorES(res, DES, key, keysizeDES, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 使用异或进行加密
|
||||
*
|
||||
* @param res 需要加密的密文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String XORencode(String res, String key) {
|
||||
byte[] bs = res.getBytes();
|
||||
for (int i = 0; i < bs.length; i++) {
|
||||
bs[i] = (byte) ((bs[i]) ^ key.hashCode());
|
||||
}
|
||||
return parseByte2HexStr(bs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用异或进行解密
|
||||
*
|
||||
* @param res 需要解密的密文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String XORdecode(String res, String key) {
|
||||
byte[] bs = parseHexStr2Byte(res);
|
||||
for (int i = 0; i < bs.length; i++) {
|
||||
bs[i] = (byte) ((bs[i]) ^ key.hashCode());
|
||||
}
|
||||
return new String(bs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接使用异或(第一调用加密,第二次调用解密)
|
||||
*
|
||||
* @param res 密文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public int XOR(int res, String key) {
|
||||
return res ^ key.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用Base64进行加密
|
||||
*
|
||||
* @param res 密文
|
||||
* @return
|
||||
*/
|
||||
public String Base64Encode(String res) {
|
||||
return Base64.encode(res.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用Base64进行解密
|
||||
*
|
||||
* @param res
|
||||
* @return
|
||||
*/
|
||||
public String Base64Decode(String res) {
|
||||
return new String(Base64.decode(res));
|
||||
}
|
||||
|
||||
|
||||
private static final int length = 128;
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*
|
||||
* @param content 需要加密的内容
|
||||
* @param password 加密密码
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws NoSuchPaddingException
|
||||
* @throws UnsupportedEncodingException
|
||||
* @throws InvalidKeyException
|
||||
* @throws BadPaddingException
|
||||
* @throws IllegalBlockSizeException
|
||||
*/
|
||||
private static byte[] encrypt(String content, String password)
|
||||
throws Exception {
|
||||
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("AES");
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
secureRandom.setSeed(password.getBytes());
|
||||
kgen.init(length, secureRandom);
|
||||
SecretKey secretKey = kgen.generateKey();
|
||||
byte[] enCodeFormat = secretKey.getEncoded();
|
||||
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
|
||||
byte[] byteContent = content.getBytes("utf-8");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
|
||||
byte[] result = cipher.doFinal(byteContent);
|
||||
return result; // 加密
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
*
|
||||
* @param content 待解密内容
|
||||
* @param password 解密密钥
|
||||
* @return
|
||||
*/
|
||||
private static byte[] decrypt(byte[] content, String password)
|
||||
throws Exception {
|
||||
KeyGenerator kgen = KeyGenerator.getInstance("AES");
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
secureRandom.setSeed(password.getBytes());
|
||||
kgen.init(length, secureRandom);
|
||||
SecretKey secretKey = kgen.generateKey();
|
||||
byte[] enCodeFormat = secretKey.getEncoded();
|
||||
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
|
||||
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
|
||||
byte[] result = cipher.doFinal(content);
|
||||
return result; // 加密
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*
|
||||
* @param content 需要加密的内容
|
||||
* @param password 加密密码
|
||||
* @return
|
||||
*/
|
||||
public static byte[] encrypt2(String content, String password) {
|
||||
try {
|
||||
SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
|
||||
byte[] byteContent = content.getBytes("utf-8");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
|
||||
byte[] result = cipher.doFinal(byteContent);
|
||||
return result; // 加密
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | UnsupportedEncodingException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String AESencode(String content, String password) {
|
||||
try {
|
||||
byte[] encryptResult = encrypt(content, password);
|
||||
return Base64.encode(encryptResult);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String AESdecode(String content, String password) {
|
||||
try {
|
||||
byte[] decryptResult = decrypt(Base64.decode(content), password);
|
||||
return new String(decryptResult, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBase64(String str) {
|
||||
String base64Pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
|
||||
return Pattern.matches(base64Pattern, str);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// String s = AESencode("430602200007025537", "wfwbkdyrdmr");
|
||||
// System.out.println(s);
|
||||
|
||||
// String s = AESencode("18058743226", "gsdfeygasfw");
|
||||
// String s1 = AESencode("张三", "gsdfeygasfw");
|
||||
// System.out.println(s);
|
||||
// System.out.println(s1);
|
||||
// System.out.println(Arrays.toString(Base64.decode("5vpdaf8bTigPCRakqzIZXA==")));
|
||||
// String s = AESdecode("Lsz+2WDokzxEuAaoZYf0cQ==", "gsdfeygasfw");
|
||||
//
|
||||
// String phone = AESdecode("j6rj21kehQqc4JJS4NxTug==", "fdsasdfsdds");
|
||||
// System.out.println("phone:" + phone);
|
||||
// String s = AESencode("18058743226", "gsdfeygasfw");
|
||||
// String s1 = AESdecode("CVr/+AgX/sHe00OQnXet9Q==", "wfwbkdyrdmr");许
|
||||
// System.out.println(s1);
|
||||
// String s = AESencode("13750869639", "gsdfeygasfw");
|
||||
// System.out.println(s);
|
||||
// System.out.println(AESdecode("O1ZWNkiAaIJLDGzwAaTfug==","gsdfeygasfw"));
|
||||
// String a = AESdecode("罗娜","wfwbkdyrdmr");
|
||||
// System.out.println(a);
|
||||
// System.out.println(MD5Utils.encrypt(a));
|
||||
|
||||
// System.out.println(AESencode("17707051035","gsdfeygasfw"));
|
||||
System.out.println(AESdecode("W+/dxhwi5yBWiDnqtLKY+w==", "gsdfeygasfw"));
|
||||
System.out.println(AESdecode("J88FbYTTmTeKXfIBBedw1A==", "gsdfeygasfw"));
|
||||
|
||||
}
|
||||
|
||||
/***
|
||||
* 利用Apache的工具类实现SHA-256加密
|
||||
* @param str 加密后的报文
|
||||
* @return
|
||||
*/
|
||||
public static String getSHA256Str(String str){
|
||||
MessageDigest messageDigest;
|
||||
String encdeStr = "";
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("SHA-256");
|
||||
byte[] hash = messageDigest.digest(str.getBytes(StandardCharsets.UTF_8));
|
||||
encdeStr = Hex.encodeHexString(hash);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return encdeStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用 AES 算法加密 inputStr。
|
||||
* 使用 secretStr 作为 key,ivStr作为 iv。
|
||||
* 并对加密后的字节数组调用 sun.misc.BASE64Encoder.encode 方法,
|
||||
* 转换成 base64 字符串返回。
|
||||
*
|
||||
* (仅作为测试用途,具体加密流程以接口文档为准)
|
||||
*
|
||||
* @param secretStr
|
||||
* @param inputStr
|
||||
* @return
|
||||
*/
|
||||
public static String base64StrDecode(String secretStr, String ivStr, String inputStr){
|
||||
byte[] inputBytes;
|
||||
inputBytes = org.apache.commons.codec.binary.Base64.decodeBase64(inputStr);
|
||||
String outputStr = new String(decode(secretStr, ivStr, inputBytes), CHARSET);
|
||||
System.out.println("base64Decode > base64 decrypt " + outputStr);
|
||||
return outputStr.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 用 AES 算法解密 inputStr。
|
||||
* 使用 secretStr 作为 key,ivStr作为 iv。
|
||||
*
|
||||
* @param secretStr
|
||||
* @param ivStr
|
||||
* @return
|
||||
*/
|
||||
public static byte[] decode(String secretStr, String ivStr, byte[] inputBytes){
|
||||
if (keyStrSize != secretStr.length() || ivStrSize != ivStr.length()) {
|
||||
return null;
|
||||
}
|
||||
byte[] secretKeyBytes = secretStr.getBytes(CHARSET);
|
||||
byte[] ivBytes = ivStr.getBytes(CHARSET);
|
||||
|
||||
byte[] outputBytes = decryptCBCNoPadding(secretKeyBytes, ivBytes, inputBytes);
|
||||
return outputBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* AES/CBC/NoPadding decrypt
|
||||
* 16 bytes secretKeyStr
|
||||
* 16 bytes intVector
|
||||
*
|
||||
* @param secretKeyBytes
|
||||
* @param intVectorBytes
|
||||
* @param input
|
||||
* @return
|
||||
*/
|
||||
public static byte[] decryptCBCNoPadding(byte[] secretKeyBytes, byte[] intVectorBytes, byte[] input) {
|
||||
try {
|
||||
IvParameterSpec iv = new IvParameterSpec(intVectorBytes);
|
||||
SecretKey secretKey = new SecretKeySpec(secretKeyBytes, AES);
|
||||
|
||||
Cipher cipher = Cipher.getInstance(AES_CBC_NOPADDING);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
|
||||
byte[] encryptBytes = cipher.doFinal(input);
|
||||
return encryptBytes;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* DES 加密加密模式 ECB,填充方式 Pkcs7,输出方式 Base64,字符集 utf8
|
||||
* @param data
|
||||
* @param password
|
||||
* @return
|
||||
*/
|
||||
public static String encryptECBPkcs7(String data, String password) {
|
||||
if (password== null || password.length() < 8) { throw new RuntimeException("加密失败,key不能小于8位"); }
|
||||
if(StringUtils.isBlank(data)){ return null; }
|
||||
|
||||
try {
|
||||
//下面这行在进行PKCS7Padding加密时必须加上,否则报错
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
|
||||
//根据传入的秘钥内容生成符合DES加密解密格式的秘钥内容
|
||||
DESKeySpec dks = new DESKeySpec(password.getBytes());
|
||||
//获取DES秘钥生成器对象
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
|
||||
// 生成秘钥:key的长度不能够小于8位字节
|
||||
Key secretKey = keyFactory.generateSecret(dks);
|
||||
//获取DES/ECB/PKCS7Padding该种级别的加解密对象
|
||||
Cipher cipher = Cipher.getInstance(DES_ECB_PKCS7PADDING);
|
||||
//初始化加解密对象【opmode:确定是加密还是解密模式;secretKey是加密解密所用秘钥】
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
byte[] bytes = cipher.doFinal(data.getBytes(CHARSET));
|
||||
return Base64.encode(bytes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String decryptECBPkcs7(String data, String password) {
|
||||
if (password== null || password.length() < 8) { throw new RuntimeException("解密失败,key不能小于8位"); }
|
||||
if(StringUtils.isBlank(data)){ return null; }
|
||||
|
||||
try {
|
||||
//下面这行在进行PKCS7Padding加密时必须加上,否则报错
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
|
||||
//根据传入的秘钥内容生成符合DES加密解密格式的秘钥内容
|
||||
DESKeySpec dks = new DESKeySpec(password.getBytes());
|
||||
//获取DES秘钥生成器对象
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
|
||||
// 生成秘钥:key的长度不能够小于8位字节
|
||||
Key secretKey = keyFactory.generateSecret(dks);
|
||||
//获取DES/ECB/PKCS7Padding该种级别的加解密对象
|
||||
Cipher cipher = Cipher.getInstance(DES_ECB_PKCS7PADDING);
|
||||
//初始化加解密对象【opmode:确定是加密还是解密模式;secretKey是加密解密所用秘钥】
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey);
|
||||
return new String(cipher.doFinal(Base64.decode(data.getBytes(charset))), charset);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* AES加密
|
||||
* @param content 内容
|
||||
* @param password 密钥
|
||||
* @return 加密后数据
|
||||
*/
|
||||
public static byte[] encryptECBPkcs5(byte[] content, byte[] password) {
|
||||
if (content == null || password == null)
|
||||
return null;
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(AES_ECB_PKCS5PADDING);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(password, AES));
|
||||
return cipher.doFinal(content);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AES解密
|
||||
* @param content 加密内容
|
||||
* @param password 密钥
|
||||
* @return 解密后数据
|
||||
*/
|
||||
public static byte[] decryptECBPkcs5(byte[] content, byte[] password) {
|
||||
if (content == null || password == null)
|
||||
return null;
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(AES_ECB_PKCS5PADDING);
|
||||
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(password, AES));
|
||||
return cipher.doFinal(content);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,483 @@
|
|||
package com.ruoyi.common.core.utils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @program: JieYiHua-Cloud
|
||||
* @description: 时间工具类
|
||||
* @author: LiYu
|
||||
* @create: 2021-08-04 15:45
|
||||
**/
|
||||
public class LocalDateTimeUtils {
|
||||
/**
|
||||
* 获取指定日期所属周的周一的日期
|
||||
*
|
||||
* @param localDate
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getMondayForThisWeek(LocalDate localDate) {
|
||||
LocalDateTime monday = LocalDateTime.of(localDate, LocalTime.MIN).with(DayOfWeek.MONDAY);
|
||||
return monday;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期所属周的周日的日期
|
||||
*
|
||||
* @param localDate
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getSundayForThisWeek(LocalDate localDate) {
|
||||
LocalDateTime sunday = LocalDateTime.of(localDate, LocalTime.MIN).with(DayOfWeek.SUNDAY);
|
||||
return sunday;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期所属周的下周一的日期
|
||||
*
|
||||
* @param localDate
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getMondayForNextWeek(LocalDate localDate) {
|
||||
LocalDateTime monday = LocalDateTime.of(localDate, LocalTime.MIN).plusWeeks(1).with(DayOfWeek.MONDAY);
|
||||
return monday;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期所属周的下周日的日期
|
||||
*
|
||||
* @param localDate
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getSundayForNextWeek(LocalDate localDate) {
|
||||
LocalDateTime sunday = LocalDateTime.of(localDate, LocalTime.MIN).plusWeeks(1).with(DayOfWeek.SUNDAY);
|
||||
return sunday;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定格式为"yyyy-MM-dd HH:mm:ss"的字符串时间转化为LocalDateTime类型
|
||||
*
|
||||
* @param dateStr
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getLocalDateTimeFromString(String dateStr) {
|
||||
LocalDateTime localDateTime = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
return localDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定格式为"yyyy-MM-ddTHH:mm:ss"的字符串时间转化为LocalDateTime类型
|
||||
*
|
||||
* @param dateStr
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getLocalDateTimeFromString2(String dateStr) {
|
||||
LocalDateTime localDateTime = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd w hh:mm:ss"));
|
||||
return localDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime类型转化为格式为"yyyy-MM-dd HH:mm:ss"的字符串时间类型
|
||||
*
|
||||
* @param localDateTime
|
||||
* @return
|
||||
*/
|
||||
public static String getStringFromLocalDateTime(LocalDateTime localDateTime) {
|
||||
String localDateTimeStr = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
return localDateTimeStr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LocalDateTime类型转化为格式为"yyyy-MM-dd"的字符串时间类型
|
||||
*
|
||||
* @param localDateTime 时间
|
||||
* @return 结果
|
||||
*/
|
||||
public static String getStringFromLocalDateTime2(LocalDateTime localDateTime) {
|
||||
if (localDateTime == null) { return null; }
|
||||
return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime类型转化为格式为"yyyy-MM-dd HH"的字符串时间类型
|
||||
*
|
||||
* @param localDateTime 时间
|
||||
* @return 结果
|
||||
*/
|
||||
public static String getStringFromLocalDateTime4(LocalDateTime localDateTime) {
|
||||
if (localDateTime == null) { return null; }
|
||||
return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH"));
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime类型转化为格式为"yyyy-MM"的字符串时间类型
|
||||
*/
|
||||
public static String getStringFromLocalDateTime3(LocalDateTime localDateTime) {
|
||||
if (localDateTime == null) {
|
||||
return null;
|
||||
}
|
||||
return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Date类型时间转化为LocalDateTime类型
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getLocalDateTimeFromDate(Date date) {
|
||||
LocalDateTime localDateTime = date.toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
|
||||
return localDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime类型转化为Date类型时间
|
||||
*
|
||||
* @param localDateTime
|
||||
* @return
|
||||
*/
|
||||
public static Date getDateFromLocalDateTime(LocalDateTime localDateTime) {
|
||||
Date date = Date.from(localDateTime.toInstant(ZoneOffset.of("+8")));
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定时间的00:00:00
|
||||
*
|
||||
* @param localDateTime
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getLocalDateTimeForBegin(LocalDateTime localDateTime) {
|
||||
LocalDateTime begin = LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MIN);
|
||||
return begin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定时间的23:59:59
|
||||
*
|
||||
* @param localDateTime
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getLocalDateTimeForEnd(LocalDateTime localDateTime) {
|
||||
LocalDateTime end = LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX);
|
||||
return end;
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间戳(毫秒)转化为LocalDateTime格式
|
||||
*
|
||||
* @param timestamp
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getLocalDateTimeFromTimestamp(Long timestamp) {
|
||||
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(timestamp / 1000, 0, ZoneOffset.ofHours(8));
|
||||
return localDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime格式转化为时间戳(毫秒)
|
||||
*
|
||||
* @param localDateTime
|
||||
* @return
|
||||
*/
|
||||
public static Long getTimestampFromLocalDateTime(LocalDateTime localDateTime) {
|
||||
Long timestamp = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间戳(毫秒)转 yyyy-MM-dd HH:mm:ss
|
||||
* @param timestamp
|
||||
* @return
|
||||
*/
|
||||
public static String getStringFromTimestamp(Long timestamp) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
return dateFormat.format(timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本月开始时间
|
||||
*
|
||||
* @return 开始时间
|
||||
*/
|
||||
public static LocalDateTime getFirstDayOfMonth() {
|
||||
return LocalDateTime.of(LocalDate.from(LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth())), LocalTime.MIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取月初
|
||||
*
|
||||
* @param localDateTime 时间
|
||||
* @return 数据
|
||||
*/
|
||||
public static LocalDateTime getTheBeginningOfTheMonth(LocalDateTime localDateTime) {
|
||||
return LocalDateTime.of(LocalDate.from(localDateTime.with(TemporalAdjusters.firstDayOfMonth())), LocalTime.MIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本月结束时间
|
||||
*
|
||||
* @return 结束时间
|
||||
*/
|
||||
public static LocalDateTime getLastDay() {
|
||||
return LocalDateTime.of(LocalDate.from(LocalDateTime.now().with(TemporalAdjusters.lastDayOfMonth())), LocalTime.MAX);
|
||||
}
|
||||
|
||||
public static LocalDateTime getTheEndOfTheMonth(LocalDateTime localDateTime) {
|
||||
return LocalDateTime.of(LocalDate.from(localDateTime.with(TemporalAdjusters.lastDayOfMonth())), LocalTime.MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间差 (秒)
|
||||
*
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 秒
|
||||
*/
|
||||
public static Long getTimeDifference(LocalDateTime startTime, LocalDateTime endTime) {
|
||||
Duration duration = Duration.between(startTime, endTime);
|
||||
return duration.toMinutes() * 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取两个时间差 (天数)
|
||||
*
|
||||
* @param localDateTime 时间
|
||||
* @return 天数
|
||||
*/
|
||||
public static Long timeDifferenceByDay(LocalDateTime localDateTime) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
Duration duration = Duration.between(localDateTime, now);
|
||||
return duration.toDays();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取两天时间间隔
|
||||
*
|
||||
* @param startingTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 结果
|
||||
*/
|
||||
public static Long twoDayInterval(LocalDateTime startingTime, LocalDateTime endTime) {
|
||||
Duration duration = Duration.between(startingTime, endTime);
|
||||
return duration.toDays();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转白话
|
||||
*
|
||||
* @param localDateTime 时间
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String toTheVernacular(LocalDateTime localDateTime) {
|
||||
return localDateTime.getYear() + "年" + localDateTime.getMonthValue() + "月" + localDateTime.getDayOfMonth() + "日";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取昨天
|
||||
*
|
||||
* @return 获取昨天
|
||||
*/
|
||||
public static LocalDateTime getYesterdaySDate() {
|
||||
return LocalDateTime.now().plusDays(1);
|
||||
}
|
||||
/**
|
||||
* 获取昨天
|
||||
*
|
||||
* @return 获取昨天
|
||||
*/
|
||||
public static LocalDateTime getMinusDays() {
|
||||
return LocalDateTime.now().minusDays(1);
|
||||
}
|
||||
/**
|
||||
* 获取明天
|
||||
*
|
||||
* @return 获取明天
|
||||
*/
|
||||
public static LocalDateTime getPlusDays() {
|
||||
return LocalDateTime.now().plusDays(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今年开始时间
|
||||
*
|
||||
* @return 开始时间
|
||||
*/
|
||||
public static LocalDateTime startThisYear() {
|
||||
return LocalDateTime.of(LocalDate.from(LocalDateTime.now().with(TemporalAdjusters.firstDayOfYear())), LocalTime.MIN);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据日期获取 星期 (2019-05-06 ——> 星期一)
|
||||
*
|
||||
* @param datetime
|
||||
* @return
|
||||
*/
|
||||
public static int dateToWeek(LocalDateTime datetime) {
|
||||
//获取当前时间
|
||||
LocalDateTime currentDate = LocalDateTime.now();
|
||||
//获取当前周
|
||||
int week = currentDate.getDayOfWeek().getValue();
|
||||
System.out.println("获取当前周:" + week);
|
||||
return week;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(twoDayInterval(LocalDateTime.now(),LocalDateTime.now()));
|
||||
System.out.println(getNowBeforeHourTime(-24L));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取今天开始时间
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public static LocalDateTime getTodayStartTime() {
|
||||
return getLocalDateTimeForBegin(LocalDateTime.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今天结束时间
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public static LocalDateTime getTodayEndTime() {
|
||||
return getLocalDateTimeForEnd(LocalDateTime.now());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 相隔所有时间
|
||||
*
|
||||
* @param startingTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 结果
|
||||
*/
|
||||
public static List<String> allTimeApart(String startingTime, String endTime) {
|
||||
Long size = LocalDateTimeUtils.twoDayInterval(LocalDateTimeUtils.getLocalDateTimeFromString(startingTime), LocalDateTimeUtils.getLocalDateTimeFromString(endTime));
|
||||
List<String> list = new ArrayList<>(Math.toIntExact(size));
|
||||
LocalDateTime time = getLocalDateTimeFromString(endTime);
|
||||
for (int i = 0; i <= size; i++) {
|
||||
LocalDateTime localDateTime = time.minusDays(i);
|
||||
list.add(getStringFromLocalDateTime2(localDateTime));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断当前用户登录时段是否在09:00-18:00
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public static boolean setFirstLogTime(){
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");//获取时,分
|
||||
//当前系统时间
|
||||
Date data = new Date();
|
||||
String dateString = formatter.format(data);
|
||||
String format = "HH:mm";
|
||||
try{
|
||||
Date nowTime = new SimpleDateFormat(format).parse(dateString);
|
||||
Date startTime = new SimpleDateFormat(format).parse("09:00");
|
||||
Date endTime = new SimpleDateFormat(format).parse("18:00");
|
||||
return isEffectiveDate(nowTime, startTime, endTime);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前时间是否在[startTime, endTime]区间,注意时间格式要一致
|
||||
*
|
||||
* @param nowTime 当前时间
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
|
||||
if (nowTime.getTime() == startTime.getTime() || nowTime.getTime() == endTime.getTime()) {
|
||||
return true;
|
||||
}
|
||||
Calendar date = Calendar.getInstance();
|
||||
date.setTime(nowTime);
|
||||
Calendar begin = Calendar.getInstance();
|
||||
begin.setTime(startTime);
|
||||
Calendar end = Calendar.getInstance();
|
||||
end.setTime(endTime);
|
||||
if (date.after(begin) && date.before(end)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前日期是否大于某个日期
|
||||
* @param date yyyy-MM-dd
|
||||
* @return
|
||||
*/
|
||||
public static boolean afterDate(LocalDateTime date){
|
||||
//针对好享管家图片相反
|
||||
String times = "2022-08-23";
|
||||
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
//把String转为LocalDate
|
||||
LocalDate localTime=LocalDate.parse(times,dtf);
|
||||
//判断当前日期是否大于指定日期
|
||||
return date.toLocalDate().isAfter(localTime);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前时间指定偏移多长小时前的时间
|
||||
* @param hour 负向前偏移 正向后偏移
|
||||
* @return
|
||||
*/
|
||||
public static LocalDateTime getNowBeforeHourTime(Long hour){
|
||||
LocalDateTime localDateTime = LocalDateTime.now(ZoneId.systemDefault());
|
||||
return localDateTime.plusHours(hour);
|
||||
}
|
||||
|
||||
public static Long timeDifferenceByLocalDate(LocalDateTime localDateTime) {
|
||||
LocalDate toLocalDate = localDateTime.toLocalDate();
|
||||
LocalDate now = LocalDate.now();
|
||||
long until = toLocalDate.until(now, ChronoUnit.DAYS);
|
||||
return toLocalDate.until(now, ChronoUnit.DAYS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断时间是否是今天
|
||||
* @param localDateTime 时间
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean isToday(LocalDateTime localDateTime) {
|
||||
return localDateTime.toLocalDate().equals(LocalDate.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断日期是否是指定天数内
|
||||
* @param localDateTime 时间
|
||||
* @param day 天数
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean isDay(LocalDateTime localDateTime,Long day) {
|
||||
return localDateTime.toLocalDate().equals(LocalDate.now().plusDays(day));
|
||||
}
|
||||
|
||||
public static long getTimeStamp(String dateTime){
|
||||
LocalDateTime time = LocalDateTimeUtils.getLocalDateTimeFromString(dateTime);
|
||||
return time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
package com.ruoyi.common.core.utils;
|
||||
|
||||
|
||||
import com.ruoyi.common.core.domain.GuestProbabilityReq;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 计算助贷计划概率
|
||||
* @Author: daisi
|
||||
* @Date: 2022/4/2 11:10
|
||||
*/
|
||||
@Slf4j
|
||||
public class ProbitUtil {
|
||||
public static GuestProbabilityReq calculatePlanTheProbability(List<GuestProbabilityReq> guestProbabilityReqs) {
|
||||
//按排序价格排序
|
||||
Collections.sort(guestProbabilityReqs, new Comparator<GuestProbabilityReq>() {
|
||||
@Override
|
||||
public int compare(GuestProbabilityReq o1, GuestProbabilityReq o2) {
|
||||
return o2.getOrderPrice().compareTo(o1.getOrderPrice());
|
||||
}
|
||||
});
|
||||
List<GuestProbabilityReq> list = new ArrayList<>(5);
|
||||
for (GuestProbabilityReq guestProbabilityReq : guestProbabilityReqs) {
|
||||
// if (guestProbabilityReq.getOrderPrice().compareTo(guestProbabilityReqs.get(0).getOrderPrice()) == 0) {
|
||||
// list.add(guestProbabilityReq);
|
||||
// }
|
||||
list.add(guestProbabilityReq);
|
||||
}
|
||||
log.info("排序后的数据:{}",list);
|
||||
//重置概率
|
||||
resetTranslate(list);
|
||||
int index = drawGift(list);
|
||||
return guestProbabilityReqs.get(index);
|
||||
}
|
||||
|
||||
private static List<GuestProbabilityReq> resetTranslate(List<GuestProbabilityReq> reqs) {
|
||||
if (reqs.size()!=1){
|
||||
//高值得一部分
|
||||
int count = 0;
|
||||
//获取计数
|
||||
BigDecimal orderPrice = reqs.get(0).getOrderPrice();
|
||||
for (int i = 0; i < reqs.size(); i++) {
|
||||
if (i+1<reqs.size()&&reqs.get(i).getOrderPrice().compareTo(reqs.get(i+1).getOrderPrice())==0&&orderPrice.compareTo(reqs.get(i).getOrderPrice())==0){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
///获取最高的概率
|
||||
BigDecimal bigDecimal = new BigDecimal(reqs.get(0).getGuestProbability().toString());
|
||||
if (count!=0){
|
||||
//用最高的概率除以计数 得到最高价的平均概率
|
||||
BigDecimal divide = bigDecimal.divide(new BigDecimal(count+1),3,BigDecimal.ROUND_DOWN);
|
||||
for (int i = 0; i <= count; i++) {
|
||||
//循环重设最高概率
|
||||
reqs.get(i).setGuestProbability(divide.doubleValue());
|
||||
}
|
||||
}
|
||||
//低值得一部分
|
||||
BigDecimal remTotal = new BigDecimal(1).subtract(bigDecimal);
|
||||
BigDecimal b = remTotal.divide(new BigDecimal((reqs.size()-count-1)==0?1:(reqs.size()-count-1)),3,BigDecimal.ROUND_HALF_UP);
|
||||
|
||||
for (int i = count+1; i < reqs.size(); i++) {
|
||||
reqs.get(i).setGuestProbability(b.doubleValue());
|
||||
}
|
||||
|
||||
}
|
||||
//log.info("重置概率后的概率,{}",reqs);
|
||||
return reqs;
|
||||
}
|
||||
|
||||
public static int drawGift(List<GuestProbabilityReq> guestProbabilityReqList) {
|
||||
if (null != guestProbabilityReqList && guestProbabilityReqList.size() > 0) {
|
||||
List<Double> orgProbList = new ArrayList<Double>(guestProbabilityReqList.size());
|
||||
for (GuestProbabilityReq guest : guestProbabilityReqList) {
|
||||
//按顺序将概率添加到集合中
|
||||
orgProbList.add(guest.getGuestProbability());
|
||||
}
|
||||
return draw(orgProbList);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public static int draw(List<Double> giftProbList) {
|
||||
List<Double> sortRateList = new ArrayList<Double>();
|
||||
// 计算概率总和
|
||||
Double sumRate = 0D;
|
||||
for (Double prob : giftProbList) {
|
||||
sumRate += prob;
|
||||
}
|
||||
if (sumRate != 0) {
|
||||
double rate = 0D; //概率所占比例
|
||||
for (Double prob : giftProbList) {
|
||||
rate += prob;
|
||||
// 构建一个比例区段组成的集合(避免概率和不为1)
|
||||
sortRateList.add(rate / sumRate);
|
||||
}
|
||||
// 随机生成一个随机数,并排序
|
||||
double random = Math.random();
|
||||
sortRateList.add(random);
|
||||
Collections.sort(sortRateList);
|
||||
// 返回该随机数在比例集合中的索引
|
||||
return sortRateList.indexOf(random);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
//// System.out.println(LocalDateTimeUtils.getStringFromLocalDateTime(LocalDateTimeUtil.beginOfDay(LocalDateTimeUtil.offset(LocalDateTime.now(), -7, ChronoUnit.DAYS))));
|
||||
//// System.out.println(LocalDateTimeUtils.getStringFromLocalDateTime(LocalDateTimeUtil.endOfDay(LocalDateTimeUtil.offset(LocalDateTime.now(), -1, ChronoUnit.DAYS))));
|
||||
// int a=0;
|
||||
// List<GuestProbabilityReq> guestProbabilityReqs = new ArrayList<>();
|
||||
// for (int i = 0; i < 20; i++) {
|
||||
// List<GuestProbabilityReq> list = new ArrayList<>();
|
||||
// GuestProbabilityReq req = new GuestProbabilityReq();
|
||||
// req.setPlanId(1L).setOrderPrice(new BigDecimal(104.00)).setGuestProbability(0.8D);
|
||||
//
|
||||
// GuestProbabilityReq req1 = new GuestProbabilityReq();
|
||||
// req1.setPlanId(2L).setOrderPrice(new BigDecimal(120)).setGuestProbability(0.8D);
|
||||
//
|
||||
// GuestProbabilityReq req2 = new GuestProbabilityReq();
|
||||
// req2.setPlanId(3L).setOrderPrice(new BigDecimal(90)).setGuestProbability(0.8D);
|
||||
//
|
||||
// GuestProbabilityReq req3 = new GuestProbabilityReq();
|
||||
// req3.setPlanId(4L).setOrderPrice(new BigDecimal(110)).setGuestProbability(0.4D);
|
||||
//
|
||||
// GuestProbabilityReq req4 = new GuestProbabilityReq();
|
||||
// req4.setPlanId(5L).setOrderPrice(new BigDecimal(110)).setGuestProbability(0.6D);
|
||||
////
|
||||
//// GuestProbabilityReq req5 = new GuestProbabilityReq();
|
||||
//// req5.setPlanId(6L).setOrderPrice(new BigDecimal(80)).setGuestProbability(0.6D);
|
||||
//
|
||||
// list.add(req);
|
||||
// list.add(req1);
|
||||
// list.add(req2);
|
||||
// list.add(req3);
|
||||
// list.add(req4);
|
||||
//// list.add(req5);
|
||||
//
|
||||
// guestProbabilityReqs.add(calculatePlanTheProbability(list));
|
||||
//
|
||||
// }
|
||||
// int b = 0;
|
||||
// int c = 0;
|
||||
// for (GuestProbabilityReq req:guestProbabilityReqs) {
|
||||
// if (req.getPlanId()==2){
|
||||
// b++;
|
||||
// }else {
|
||||
// c++;
|
||||
// }
|
||||
// }
|
||||
// System.out.println("几率:"+c+" "+b);
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,517 @@
|
|||
package com.ruoyi.common.core.utils;
|
||||
|
||||
|
||||
import com.ruoyi.common.core.constant.HttpStatus;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author LiYu
|
||||
* @ClassName SecureUtil.java
|
||||
* @Description 加解密工具类
|
||||
* @createTime 2024年05月20日 11:04:00
|
||||
*/
|
||||
@Slf4j
|
||||
public class SecureUtils {
|
||||
/**
|
||||
* md5加密
|
||||
*/
|
||||
public static class Md5Util {
|
||||
|
||||
/**
|
||||
* 判断是否为md5加密
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean isMd5(String str) {
|
||||
return str.matches("^[a-f0-9]{32}$");
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密并转大写
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return 结果
|
||||
*/
|
||||
public static String md5ToUpperCase(String str) {
|
||||
return StringUtils.hasText(str) ? isMd5(str) ? str : cn.hutool.crypto.SecureUtil.md5(str).toUpperCase() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密并转小写
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return 结果
|
||||
*/
|
||||
public static String md5ToLowerCase(String str) {
|
||||
return StringUtils.hasText(str) ? isMd5(str) ? str : cn.hutool.crypto.SecureUtil.md5(str).toLowerCase() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return 结果
|
||||
*/
|
||||
public static String md5(String str) {
|
||||
return StringUtils.hasText(str) ? isMd5(str) ? str : cn.hutool.crypto.SecureUtil.md5(str) : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* des加密
|
||||
*/
|
||||
public static class DesUtil {
|
||||
/**
|
||||
* 加密key
|
||||
*/
|
||||
public static final String KEY = "_@Ks`Y*9jLb.hvho}C;GwDpw";
|
||||
/**
|
||||
* 偏移量
|
||||
*/
|
||||
public static final String IV = "2%8iTpSi";
|
||||
|
||||
/**
|
||||
* 创建加密对象
|
||||
*
|
||||
* @param iv 偏移量
|
||||
* @param mode 模式
|
||||
* @return 结果
|
||||
*/
|
||||
private static Cipher createCipher(String iv, int mode) throws NoSuchAlgorithmException, NoSuchPaddingException,
|
||||
InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
byte[] key = KEY.getBytes();
|
||||
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
|
||||
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
|
||||
cipher.init(mode, new SecretKeySpec(key, "DESede"), ivParameterSpec);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*
|
||||
* @param data 数据
|
||||
* @param iv 偏移量
|
||||
* @return 结果
|
||||
*/
|
||||
public static String encrypt(String data, String iv) {
|
||||
try {
|
||||
Cipher cipher = createCipher(iv, Cipher.ENCRYPT_MODE);
|
||||
return URLEncoder.encode(Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes())), "UTF-8");
|
||||
} catch (Exception e) {
|
||||
log.error("加密失败", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*
|
||||
* @param data 数据
|
||||
* @return 结果
|
||||
*/
|
||||
public static String encrypt(String data) {
|
||||
return encrypt(data, IV);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
*
|
||||
* @param data 数据
|
||||
* @param iv 偏移量
|
||||
* @return 结果
|
||||
*/
|
||||
public static String decrypt(String data, String iv) {
|
||||
try {
|
||||
Cipher cipher = createCipher(iv, Cipher.DECRYPT_MODE);
|
||||
return new String(cipher.doFinal(Base64.getDecoder().decode(URLDecoder.decode(data, "UTF-8"))));
|
||||
} catch (Exception e) {
|
||||
log.error("解密失败", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
*
|
||||
* @param data 数据
|
||||
* @return 结果
|
||||
*/
|
||||
public static String decrypt(String data) {
|
||||
return decrypt(data, IV);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* AES加解密
|
||||
*/
|
||||
public static class AesUtil {
|
||||
/**
|
||||
* 加密模式之 ECB,算法/模式/补码方式
|
||||
*/
|
||||
public static final String AES_ECB = "AES/ECB/PKCS5Padding";
|
||||
|
||||
/**
|
||||
* 加密模式之 CBC,算法/模式/补码方式
|
||||
*/
|
||||
public static final String AES_CBC = "AES/CBC/PKCS5Padding";
|
||||
|
||||
/**
|
||||
* 加密模式之 CFB,算法/模式/补码方式
|
||||
*/
|
||||
public static final String AES_CFB = "AES/CFB/PKCS5Padding";
|
||||
|
||||
/**
|
||||
* AES 中的 IV 必须是 16 字节(128位)长
|
||||
*/
|
||||
public static final Integer IV_LENGTH = 16;
|
||||
|
||||
/***
|
||||
* 空校验
|
||||
* @param str 需要判断的值
|
||||
*/
|
||||
public static boolean isEmpty(Object str) {
|
||||
return null == str || "".equals(str);
|
||||
}
|
||||
|
||||
/***
|
||||
* String 转 byte
|
||||
* @param str 需要转换的字符串
|
||||
*/
|
||||
public static byte[] getBytes(String str) {
|
||||
if (isEmpty(str)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return str.getBytes(StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* 初始化向量(IV),它是一个随机生成的字节数组,用于增加加密和解密的安全性
|
||||
*/
|
||||
public static String getIv() {
|
||||
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
Random random = new Random();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < IV_LENGTH; i++) {
|
||||
int number = random.nextInt(str.length());
|
||||
sb.append(str.charAt(number));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 获取一个 AES 密钥规范
|
||||
*/
|
||||
public static SecretKeySpec getSecretKeySpec(String key) {
|
||||
return new SecretKeySpec(Objects.requireNonNull(getBytes(key)), "AES");
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密 - 模式 ECB
|
||||
*
|
||||
* @param text 需要加密的文本内容
|
||||
* @param key 加密的密钥 key
|
||||
*/
|
||||
public static String encrypt(String text, String key) {
|
||||
if (isEmpty(text) || isEmpty(key)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
// 创建AES加密器
|
||||
Cipher cipher = Cipher.getInstance(AES_ECB);
|
||||
SecretKeySpec secretKeySpec = getSecretKeySpec(key);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
|
||||
// 加密字节数组
|
||||
byte[] encryptedBytes = cipher.doFinal(Objects.requireNonNull(getBytes(text)));
|
||||
// 将密文转换为 Base64 编码字符串
|
||||
return Base64.getEncoder().encodeToString(encryptedBytes);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解密 - 模式 ECB
|
||||
*
|
||||
* @param text 需要解密的文本内容
|
||||
* @param key 解密的密钥 key
|
||||
*/
|
||||
public static String decrypt(String text, String key) {
|
||||
if (isEmpty(text) || isEmpty(key)) {
|
||||
return null;
|
||||
}
|
||||
// 将密文转换为16字节的字节数组
|
||||
byte[] textBytes = Base64.getDecoder().decode(text);
|
||||
try {
|
||||
// 创建AES加密器
|
||||
Cipher cipher = Cipher.getInstance(AES_ECB);
|
||||
SecretKeySpec secretKeySpec = getSecretKeySpec(key);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
|
||||
// 解密字节数组
|
||||
byte[] decryptedBytes = cipher.doFinal(textBytes);
|
||||
// 将明文转换为字符串
|
||||
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密 - 自定义加密模式
|
||||
*
|
||||
* @param text 需要加密的文本内容
|
||||
* @param key 加密的密钥 key
|
||||
* @param iv 初始化向量
|
||||
* @param mode 加密模式
|
||||
*/
|
||||
public static String encrypt(String text, String key, String iv, String mode) {
|
||||
if (isEmpty(text) || isEmpty(key) || isEmpty(iv)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
// 创建AES加密器
|
||||
Cipher cipher = Cipher.getInstance(mode);
|
||||
SecretKeySpec secretKeySpec = getSecretKeySpec(key);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(Objects.requireNonNull(getBytes(iv))));
|
||||
// 加密字节数组
|
||||
byte[] encryptedBytes = cipher.doFinal(Objects.requireNonNull(getBytes(text)));
|
||||
// 将密文转换为 Base64 编码字符串
|
||||
return Base64.getEncoder().encodeToString(encryptedBytes);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*
|
||||
* @param content 待加密内容
|
||||
* @param password 加密密钥
|
||||
* @return 加密后的内容
|
||||
*/
|
||||
public static String AesEncode(String content, String password) {
|
||||
try {
|
||||
byte[] encryptResult = encryptByte(content, password);
|
||||
return Base64Util.encode(encryptResult);
|
||||
} catch (Exception e) {
|
||||
log.error("加密出现问题!", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
String s = "{\"accumulationFund\":1,\"age\":18,\"car\":1,\"career\":1,\"city\":\"重庆\",\"cityCode\":1000,\"creditCard\":1,\"education\":1,\"guarantee\":1,\"hourse\":1,\"idCardMd5\":\"331d17d1ca8a091410e3238fab16a863\",\"monthlyIncome\":5000,\"nameMd5\":\"331d17d1ca8a091410e3238fab16a863\",\"phoneMd5\":\"331d17d1ca8a091410e3238fab16a863\",\"sex\":0,\"socialSecurity\":1,\"zhiMa\":600}";
|
||||
String s1 = "{\"accumulationFund\":1,\"age\":18,\"car\":1,\"career\":1,\"city\":\"重庆\",\"cityCode\":1000,\"creditCard\":1,\"education\":1,\"guarantee\":1,\"hourse\":1,\"idCard\":\"341202199306023511\",\"idCardMd5\":\"331d17d1ca8a091410e3238fab16a863\",\"monthlyIncome\":5000,\"name\":\"朱三\",\"nameMd5\":\"331d17d1ca8a091410e3238fab16a863\",\"phone\":\"15205600635\",\"phoneMd5\":\"331d17d1ca8a091410e3238fab16a863\",\"sex\":0,\"socialSecurity\":1,\"zhiMa\":600}";
|
||||
String s3 = "{\n" +
|
||||
" \"orderNo\":\"111111\",\n" +
|
||||
" \"md5\":\"aaaaaa\",\n" +
|
||||
" \"price\":100.00,\n" +
|
||||
" \"orderStatus\":\"2\"\n" +
|
||||
"}";
|
||||
|
||||
System.out.println(AesEncode(s1,"g5N8XTYaOEwEmBgg"));
|
||||
}
|
||||
/**
|
||||
* 解密
|
||||
*
|
||||
* @param content 待解密内容
|
||||
* @param password 解密密钥
|
||||
* @return 解密后的内容
|
||||
*/
|
||||
public static String AesDecode(String content, String password) {
|
||||
try {
|
||||
byte[] decryptResult = decryptByte(Base64Util.decodeToByteArray(content), password);
|
||||
return new String(decryptResult, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
log.error("解密出现问题!", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密 - 模式 CBC
|
||||
*
|
||||
* @param text 需要加密的文本内容
|
||||
* @param key 加密的密钥 key
|
||||
* @param iv 初始化向量
|
||||
* @return 加密后的内容
|
||||
*/
|
||||
public static String encryptCbc(String text, String key, String iv) {
|
||||
return encrypt(text, key, iv, AES_CBC);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密 - 自定义加密模式
|
||||
*
|
||||
* @param text 需要解密的文本内容
|
||||
* @param key 解密的密钥 key
|
||||
* @param iv 初始化向量
|
||||
* @param mode 加密模式
|
||||
*/
|
||||
public static String decrypt(String text, String key, String iv, String mode) {
|
||||
if (isEmpty(text) || isEmpty(key) || isEmpty(iv)) {
|
||||
return null;
|
||||
}
|
||||
// 将密文转换为16字节的字节数组
|
||||
byte[] textBytes = Base64.getDecoder().decode(text);
|
||||
try {
|
||||
// 创建AES加密器
|
||||
Cipher cipher = Cipher.getInstance(mode);
|
||||
SecretKeySpec secretKeySpec = getSecretKeySpec(key);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(Objects.requireNonNull(getBytes(iv))));
|
||||
// 解密字节数组
|
||||
byte[] decryptedBytes = cipher.doFinal(textBytes);
|
||||
// 将明文转换为字符串
|
||||
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
*
|
||||
* @param content 待解密内容
|
||||
* @param password 解密密钥
|
||||
* @return 解密后的内容
|
||||
*/
|
||||
private static byte[] decryptByte(byte[] content, String password)
|
||||
throws Exception {
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
secureRandom.setSeed(password.getBytes());
|
||||
keyGenerator.init(128, secureRandom);
|
||||
SecretKey secretKey = keyGenerator.generateKey();
|
||||
byte[] enCodeFormat = secretKey.getEncoded();
|
||||
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES");
|
||||
cipher.init(Cipher.DECRYPT_MODE, key);
|
||||
return cipher.doFinal(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*
|
||||
* @param content 需要加密的内容
|
||||
* @param password 加密密码
|
||||
* @return 加密后的字节数组
|
||||
*/
|
||||
private static byte[] encryptByte(String content, String password)
|
||||
throws Exception {
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
||||
secureRandom.setSeed(password.getBytes());
|
||||
keyGenerator.init(128, secureRandom);
|
||||
SecretKey secretKey = keyGenerator.generateKey();
|
||||
byte[] enCodeFormat = secretKey.getEncoded();
|
||||
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
|
||||
byte[] byteContent = content.getBytes(StandardCharsets.UTF_8);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
return cipher.doFinal(byteContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密 - 模式 CBC
|
||||
*
|
||||
* @param text 需要加密的文本内容
|
||||
* @param key 加密的密钥 key
|
||||
* @param iv 初始化向量
|
||||
* @return 加密后的内容
|
||||
*/
|
||||
public static String decryptCbc(String text, String key, String iv) {
|
||||
return decrypt(text, key, iv, AES_CBC);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base64加解密
|
||||
*/
|
||||
public static class Base64Util {
|
||||
/**
|
||||
* 编码字符串为Base64
|
||||
*
|
||||
* @param input 需要编码的字符串
|
||||
* @return 编码后的Base64字符串
|
||||
*/
|
||||
public static String encode(String input) {
|
||||
return Base64.getEncoder().encodeToString(input.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Base64编码解码为字符串
|
||||
*
|
||||
* @param input Base64编码的字符串
|
||||
* @return 解码后的字符串
|
||||
*/
|
||||
public static String decode(String input) {
|
||||
byte[] decodedBytes = Base64.getDecoder().decode(input);
|
||||
return new String(decodedBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码字节数组为Base64字符串
|
||||
*
|
||||
* @param input 需要编码的字节数组
|
||||
* @return 编码后的Base64字符串
|
||||
*/
|
||||
public static String encode(byte[] input) {
|
||||
return Base64.getEncoder().encodeToString(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码Base64字符串为字节数组
|
||||
*
|
||||
* @param input Base64编码的字符串
|
||||
* @return 解码后的字节数组
|
||||
*/
|
||||
public static byte[] decodeToByteArray(String input) {
|
||||
return Base64.getDecoder().decode(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为Base64编码
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean isBase64(String str) {
|
||||
String base64Pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
|
||||
return Pattern.matches(base64Pattern, str);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,456 @@
|
|||
package com.ruoyi.common.core.utils.match;
|
||||
|
||||
import com.ruoyi.common.core.domain.http.Customer;
|
||||
import com.ruoyi.common.core.domain.http.Merchant;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
public class MatchQualification {
|
||||
|
||||
/**
|
||||
* 是否可以匹配上产品
|
||||
* @param customer 用户信息
|
||||
* @param merchant 产品前筛
|
||||
* openInfoFilter 开启资质筛选 0:不筛选, 1:满足1, 2:满足全部
|
||||
*
|
||||
* @return 结构
|
||||
*/
|
||||
public static Boolean doesItMatchProduct(Customer customer, Merchant merchant) {
|
||||
// if (Objects.isNull(merchant)){
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// if (Objects.isNull(merchant.getCustomerInfoFilterType()) || merchant.getCustomerInfoFilterType() == 0){
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// //满足1个
|
||||
// boolean openOne = merchant.getCustomerInfoFilterType() == 1;
|
||||
// //满足所有
|
||||
// boolean openAll = merchant.getCustomerInfoFilterType() == 2;
|
||||
// //结果
|
||||
// boolean result = false;
|
||||
//
|
||||
// String userInfo = customer.getId() + "-" + customer.getChannelId() + "-" + merchant.getId();
|
||||
//
|
||||
// //社保
|
||||
// if (merchant.getSocialSecurityHigh() || merchant.getSocialSecurityNo() ||merchant.getSocialSecurityLow()) {
|
||||
// if (openAll && Objects.isNull(customer.getSocialSecurity())){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-社保为空, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// Integer infoByCode = customer.getSocialSecurity();
|
||||
// if (Objects.nonNull(customer.getSocialSecurity())) {
|
||||
// if (merchant.getSocialSecurityNo()) {
|
||||
// if (customer.getSocialSecurity()==merchant.getSocialSecurityNo())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (merchant.getSocialSecurityLow()) {
|
||||
// if (customer.getSocialSecurity().equals(CustomerSocialSecurityType.GREAT_SOCIAL_SECURITY.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足一个即可, 恰巧现在就有满足的, 则返回true(通过)
|
||||
// if (openOne && result) {
|
||||
//// log.info("资质匹配筛选, 配置[满足其一]-社保:{}, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getSocialSecurity() + "-" + infoByCode, userInfo);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足全部, 恰巧现在这个不满足, 则返回false(不通过)
|
||||
// if (openAll && !result) {
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-社保:{}, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getSocialSecurity() + "-" + infoByCode, userInfo);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //公积金
|
||||
// if (productLimit.getSmallProvidentFund() || productLimit.getGreatProvidentFund()) {
|
||||
// if (openAll && Objects.isNull(userDetailsDTO.getProvidentFund())){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-公积金为空, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// //判断结果置默认
|
||||
// result = false;
|
||||
// String infoByCode = CustomerProvidentFundType.getInfoByCode(userDetailsDTO.getProvidentFund());
|
||||
// if (Objects.nonNull(userDetailsDTO.getProvidentFund())) {
|
||||
// if (productLimit.getSmallProvidentFund()) {
|
||||
// if (userDetailsDTO.getProvidentFund().equals(CustomerProvidentFundType.SMALL_PROVIDENT_FUND.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getGreatProvidentFund()) {
|
||||
// if (userDetailsDTO.getProvidentFund().equals(CustomerProvidentFundType.GREAT_PROVIDENT_FUND.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足一个即可, 恰巧现在就有满足的, 则返回true(通过)
|
||||
// if (openOne && result) {
|
||||
//// log.info("资质匹配筛选, 配置[满足其一]-公积金:{}, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getProvidentFund() + "-" + infoByCode, userInfo);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足全部, 恰巧现在这个不满足, 则返回false(不通过)
|
||||
// if (openAll && !result) {
|
||||
//// log.info("资质匹配筛选, 配置[满足所有]-公积金:{}, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getProvidentFund() + "-" + infoByCode, userInfo);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //车产
|
||||
// if (productLimit.getHavaCar()) {
|
||||
// if (openAll && Objects.isNull(userDetailsDTO.getCarProduction())){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-车产为空, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// //判断结果置默认
|
||||
// result = false;
|
||||
// String infoByCode = CustomerCarProductionType.getInfoByCode(userDetailsDTO.getCarProduction());
|
||||
// if (Objects.nonNull(userDetailsDTO.getCarProduction())) {
|
||||
// if (userDetailsDTO.getCarProduction().equals(CustomerCarProductionType.HAVE_CAR.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// //条件为 满足一个即可, 恰巧现在就有满足的, 则返回true(通过)
|
||||
// if (openOne && result) {
|
||||
// log.info("资质匹配筛选, 配置[满足其一]-车产:{}, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getCarProduction() + "-" + infoByCode, userInfo);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足全部, 恰巧现在这个不满足, 则返回false(不通过)
|
||||
// if (openAll && !result) {
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-车产:{}, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getCarProduction() + "-" + infoByCode, userInfo);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //房产
|
||||
// if (productLimit.getHaveMortgageRoom() || productLimit.getHaveFullRoom()) {
|
||||
// if (openAll && Objects.isNull(userDetailsDTO.getEstate())){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-房产为空, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// //判断结果置默认
|
||||
// result = false;
|
||||
// String infoByCode = CustomerEstateType.getInfoByCode(userDetailsDTO.getEstate());
|
||||
// if (Objects.nonNull(userDetailsDTO.getEstate())) {
|
||||
// if (productLimit.getHaveMortgageRoom()){
|
||||
// if (userDetailsDTO.getEstate().equals(CustomerEstateType.HAVE_PROPERTY.getCode())){
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getHaveFullRoom()){
|
||||
// if (userDetailsDTO.getEstate().equals(CustomerEstateType.FULL_PAYMENT_FOR_HOUSING.getCode())){
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足一个即可, 恰巧现在就有满足的, 则返回true(通过)
|
||||
// if (openOne && result) {
|
||||
//// log.info("资质匹配筛选, 配置[满足其一]-房产:{}, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getEstate() + "-" + infoByCode, userInfo);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足全部, 恰巧现在这个不满足, 则返回false(不通过)
|
||||
// if (openAll && !result) {
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-房产:{}, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getEstate() + "-" + infoByCode, userInfo);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //保单
|
||||
// if (productLimit.getPolicyLessThanOneYear() || productLimit.getPolicyPaymentForOneYear() || productLimit.getPolicyPaymentForTwoYear()) {
|
||||
// if (openAll && Objects.isNull(userDetailsDTO.getPersonalInsurance())){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-保单为空, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// //判断结果置默认
|
||||
// result = false;
|
||||
// String infoByCode = CustomerInsurancePolicyType.getInfoByCode(userDetailsDTO.getPersonalInsurance());
|
||||
// if (Objects.nonNull(userDetailsDTO.getPersonalInsurance())) {
|
||||
// if (productLimit.getPolicyLessThanOneYear()) {
|
||||
// if (userDetailsDTO.getPersonalInsurance().equals(CustomerInsurancePolicyType.POLICY_LESS_THAN_ONE_YEAR.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getPolicyPaymentForOneYear()) {
|
||||
// if (userDetailsDTO.getPersonalInsurance().equals(CustomerInsurancePolicyType.POLICY_PAYMENT_FOR_ONE_YEAR.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getPolicyPaymentForTwoYear()) {
|
||||
// if (userDetailsDTO.getPersonalInsurance().equals(CustomerInsurancePolicyType.POLICY_PAYMENT_FOR_TWO_YEAR.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足一个即可, 恰巧现在就有满足的, 则返回true(通过)
|
||||
// if (openOne && result) {
|
||||
// log.info("资质匹配筛选, 配置[满足其一]-保单:{}, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getPersonalInsurance() + "-" + infoByCode, userInfo);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足全部, 恰巧现在这个不满足, 则返回false(不通过)
|
||||
// if (openAll && !result) {
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-保单:{}, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getPersonalInsurance() + "-" + infoByCode, userInfo);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //芝麻分
|
||||
// if (Objects.nonNull(productLimit.getSesame())){
|
||||
// if (openAll && Objects.isNull(userDetailsDTO.getSesame())){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-芝麻分为空, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// //判断结果置默认
|
||||
// result = false;
|
||||
// if (Objects.nonNull(userDetailsDTO.getSesame())) {
|
||||
// if (userDetailsDTO.getSesame() >= productLimit.getSesame()){
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// //条件为 满足一个即可, 恰巧现在就有满足的, 则返回true(通过)
|
||||
// if (openOne && result) {
|
||||
// log.info("资质匹配筛选, 配置[满足其一]-芝麻分:{}, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getSesame(), userInfo);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足全部, 恰巧现在这个不满足, 则返回false(不通过)
|
||||
// if (openAll && !result) {
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-芝麻分:{}, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getSesame(), userInfo);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //职业
|
||||
// if (productLimit.getOfficeWorker() ||
|
||||
// productLimit.getCivilServant() ||
|
||||
// productLimit.getPrivateOwners() ||
|
||||
// productLimit.getSmallPrivateBusiness() ||
|
||||
// productLimit.getOtherOccupations()) {
|
||||
//
|
||||
// if (openAll && Objects.isNull(userDetailsDTO.getProfessionalIdentity())){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-职业为空, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// //判断结果置默认
|
||||
// result = false;
|
||||
// String infoByCode = CustomerProfessionalIdentityType.getInfoByCode(userDetailsDTO.getProfessionalIdentity());
|
||||
// if (Objects.nonNull(userDetailsDTO.getProfessionalIdentity())) {
|
||||
// if (productLimit.getOfficeWorker()){
|
||||
// if (userDetailsDTO.getProfessionalIdentity().equals(CustomerProfessionalIdentityType.OFFICE_WORKER.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getCivilServant()){
|
||||
// if (userDetailsDTO.getProfessionalIdentity().equals(CustomerProfessionalIdentityType.CIVIL_SERVANT.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getPrivateOwners()){
|
||||
// if (userDetailsDTO.getProfessionalIdentity().equals(CustomerProfessionalIdentityType.PRIVATE_OWNERS.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getSmallPrivateBusiness()){
|
||||
// if (userDetailsDTO.getProfessionalIdentity().equals(CustomerProfessionalIdentityType.SMALL_PRIVATE_BUSINESS.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getOtherOccupations()){
|
||||
// if (userDetailsDTO.getProfessionalIdentity().equals(CustomerProfessionalIdentityType.OTHER_OCCUPATIONS.getCode())) {
|
||||
// result = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足一个即可, 恰巧现在就有满足的, 则返回true(通过)
|
||||
// if (openOne && result) {
|
||||
// log.info("资质匹配筛选, 配置[满足其一]-职业:{}, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getProfessionalIdentity() + "-" + infoByCode, userInfo);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足全部, 恰巧现在这个不满足, 则返回false(不通过)
|
||||
// if (openAll && !result) {
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-职业:{}, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getProfessionalIdentity() + "-" + infoByCode, userInfo);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //学历 字典映射 1: "初中及以下,2: "高中",3: "中专",4: "大专",5: "本科",6: "研究生及以上"
|
||||
// if (productLimit.getJuniorMiddleSchool() ||
|
||||
// productLimit.getSeniorMiddleSchool() ||
|
||||
// productLimit.getMiddleSchool() ||
|
||||
// productLimit.getCollege() ||
|
||||
// productLimit.getUndergraduate() ||
|
||||
// productLimit.getPostgraduate()) {
|
||||
//
|
||||
// if (openAll && Objects.isNull(userDetailsDTO.getEducation())){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-学历为空, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// //判断结果置默认
|
||||
// result = false;
|
||||
// String infoByCode = getEducationByCode(userDetailsDTO.getEducation());
|
||||
// if (Objects.nonNull(userDetailsDTO.getEducation())) {
|
||||
// if (productLimit.getJuniorMiddleSchool() && userDetailsDTO.getEducation() == 1) { //初中
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getSeniorMiddleSchool() && userDetailsDTO.getEducation() == 2) { //高中
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getMiddleSchool() && userDetailsDTO.getEducation() == 3) { //中专
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getCollege() && userDetailsDTO.getEducation() == 4) { //大专
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getUndergraduate() && userDetailsDTO.getEducation() == 5) { //本科
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getPostgraduate() && userDetailsDTO.getEducation() == 6) { //研究生
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// //条件为 满足一个即可, 恰巧现在就有满足的, 则返回true(通过)
|
||||
// if (openOne && result) {
|
||||
// log.info("资质匹配筛选, 配置[满足其一]-学历:{}, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getEducation() + "-" + infoByCode, userInfo);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足全部, 恰巧现在这个不满足, 则返回false(不通过)
|
||||
// if (openAll && !result) {
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-学历:{}, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getEducation() + "-" + infoByCode, userInfo);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //白条可用额度 字典映射 1: 无额度,2: 2000以下,3: 2000-10000,4: 大于10000
|
||||
// if (productLimit.getBaiTiaoLevelOne() ||
|
||||
// productLimit.getBaiTiaoLevelTwo() ||
|
||||
// productLimit.getBaiTiaoLevelThree()) {
|
||||
//
|
||||
// if (openAll && Objects.isNull(userDetailsDTO.getBaiTiaoQuota())){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-白条为空, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// //判断结果置默认
|
||||
// result = false;
|
||||
// String infoByCode = getBaiTiaoByCode(userDetailsDTO.getBaiTiaoQuota());
|
||||
// if (Objects.nonNull(userDetailsDTO.getBaiTiaoQuota())) {
|
||||
// if (productLimit.getBaiTiaoLevelOne() && userDetailsDTO.getBaiTiaoQuota() == 2) { //2000以下
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getBaiTiaoLevelTwo() && userDetailsDTO.getBaiTiaoQuota() == 3) { //2000-10000
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getBaiTiaoLevelThree() && userDetailsDTO.getBaiTiaoQuota() == 4) { //大于10000
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// //条件为 满足一个即可, 恰巧现在就有满足的, 则返回true(通过)
|
||||
// if (openOne && result) {
|
||||
// log.info("资质匹配筛选, 配置[满足其一]-白条:{}, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getBaiTiaoQuota() + "-" + infoByCode, userInfo);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足全部, 恰巧现在这个不满足, 则返回false(不通过)
|
||||
// if (openAll && !result) {
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-白条:{}, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getBaiTiaoQuota() + "-" + infoByCode, userInfo);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //花呗可用额度 字典映射 1: 无额度,2: 2000以下,3: 2000-10000,4: 大于10000
|
||||
// if (productLimit.getHuaBeiLevelOne() ||
|
||||
// productLimit.getHuaBeiLevelTwo() ||
|
||||
// productLimit.getHuaBeiLevelThree()) {
|
||||
//
|
||||
// if (openAll && Objects.isNull(userDetailsDTO.getHuaBeiQuota())){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-花呗为空, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// //判断结果置默认
|
||||
// result = false;
|
||||
// String infoByCode = getBaiTiaoByCode(userDetailsDTO.getHuaBeiQuota());
|
||||
// if (Objects.nonNull(userDetailsDTO.getHuaBeiQuota())) {
|
||||
// if (productLimit.getHuaBeiLevelOne() && userDetailsDTO.getHuaBeiQuota() == 2) { //2000以下
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getHuaBeiLevelTwo() && userDetailsDTO.getHuaBeiQuota() == 3) { //2000-10000
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// if (productLimit.getHuaBeiLevelThree() && userDetailsDTO.getHuaBeiQuota() == 4) { //大于10000
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// //条件为 满足一个即可, 恰巧现在就有满足的, 则返回true(通过)
|
||||
// if (openOne && result) {
|
||||
// log.info("资质匹配筛选, 配置[满足其一]-花呗:{}, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getHuaBeiQuota() + "-" + infoByCode, userInfo);
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //条件为 满足全部, 恰巧现在这个不满足, 则返回false(不通过)
|
||||
// if (openAll && !result) {
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-花呗:{}, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userDetailsDTO.getHuaBeiQuota() + "-" + infoByCode, userInfo);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //满足其一, 但结果为false, 则不通过
|
||||
// if (openOne && !result){
|
||||
//// log.info("资质匹配筛选, 配置[满足其一]-未匹配成功, 匹配不通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// if (openAll && result){
|
||||
// log.info("资质匹配筛选, 配置[满足所有]-匹配成功, 匹配通过, 结束匹配, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// log.info("资质匹配筛选, 此行日志我觉得不会输出, 用户id-渠道id-渠道名称-产品id:{}", userInfo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -129,6 +129,17 @@ public class BaseController
|
|||
return rows > 0 ? AjaxResult.success() : AjaxResult.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应返回结果
|
||||
*
|
||||
* @param rows 影响行数
|
||||
* @return 操作结果
|
||||
*/
|
||||
protected AjaxResult toAjax(Long rows)
|
||||
{
|
||||
return rows > 0 ? AjaxResult.success() : AjaxResult.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应返回结果
|
||||
*
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import java.io.Serializable;
|
|||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
|
@ -19,9 +21,11 @@ public class BaseEntity implements Serializable
|
|||
|
||||
/** 搜索值 */
|
||||
@JsonIgnore
|
||||
@TableField(exist = false)
|
||||
private String searchValue;
|
||||
|
||||
/** 创建者 */
|
||||
@TableField(exist = false)
|
||||
private String createBy;
|
||||
|
||||
/** 创建时间 */
|
||||
|
|
@ -29,6 +33,7 @@ public class BaseEntity implements Serializable
|
|||
private Date createTime;
|
||||
|
||||
/** 更新者 */
|
||||
@TableField(exist = false)
|
||||
private String updateBy;
|
||||
|
||||
/** 更新时间 */
|
||||
|
|
@ -40,6 +45,7 @@ public class BaseEntity implements Serializable
|
|||
|
||||
/** 请求参数 */
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
@TableField(exist = false)
|
||||
private Map<String, Object> params;
|
||||
|
||||
public String getSearchValue()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,391 @@
|
|||
package com.ruoyi.common.redis.service;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ruoyi.common.core.constant.RedisConstant;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
*
|
||||
* @Author:
|
||||
* @Date: 18点29分
|
||||
* @Description: 用户token管理
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CustomerTokenService {
|
||||
|
||||
private final RedisService redisService;
|
||||
/**
|
||||
* token过期时间
|
||||
*/
|
||||
private static final Long EXPIRE_TIME = 30 * 24 * 60 * 60L;
|
||||
|
||||
/**
|
||||
* 随机生成128位的token,包含数字、大小写字母
|
||||
*
|
||||
* @param customerId 用户id
|
||||
* @param phone 手机号
|
||||
* @param deviceType 设备类型
|
||||
* @param channelId 渠道id
|
||||
* @return token
|
||||
*/
|
||||
public String generateToken(Long customerId, String phone, String deviceType, Long channelId) {
|
||||
//获取到老的token
|
||||
String oldToken = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
|
||||
if (StringUtils.hasText(oldToken)) {
|
||||
//删除老的token
|
||||
this.refreshToken(oldToken);
|
||||
}
|
||||
String newToken = null;
|
||||
boolean exit = true;
|
||||
while (exit) {
|
||||
newToken = RandomUtil.randomString(128);
|
||||
if (!redisService.hasKey(RedisConstant.APP_CUSTOMER_USERNAME_KEY + newToken)) {
|
||||
exit = false;
|
||||
}
|
||||
}
|
||||
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_USERNAME_KEY + newToken, phone, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId, newToken, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + newToken, channelId, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + newToken, customerId, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.setCacheObject(RedisConstant.APP_DEVICE_IDENTIFICATION + newToken, deviceType.toString(), EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
return newToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断token是否过期
|
||||
*
|
||||
* @param token token
|
||||
* @return true:过期,false:未过期
|
||||
*/
|
||||
public boolean isExpire(String token) {
|
||||
String customerId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token) + StrUtil.EMPTY;
|
||||
String originalToken = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
|
||||
String username = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_USERNAME_KEY + token) + StrUtil.EMPTY;
|
||||
return StringUtils.isEmpty(customerId) || StringUtils.isEmpty(originalToken) || !originalToken.equals(token) || !StringUtils.hasText(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新token有效期
|
||||
*
|
||||
* @param token token
|
||||
* @param booleans 是否需要退出登录
|
||||
*/
|
||||
public void refreshToken(String token, Boolean... booleans) {
|
||||
boolean logOut = isLogOut(booleans);
|
||||
Long customerId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token);
|
||||
if (Objects.isNull(customerId) && logOut) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
redisService.expire(RedisConstant.APP_CUSTOMER_USERNAME_KEY + token, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.expire(RedisConstant.APP_CUSTOMER_KEY + customerId, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.expire(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.expire(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.expire(RedisConstant.APP_DEVICE_IDENTIFICATION + token, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id刷新token有效期
|
||||
*
|
||||
* @param customerId 用户id
|
||||
* @param booleans 是否需要退出登录
|
||||
* @return token
|
||||
*/
|
||||
public String refreshToken(Long customerId, Boolean... booleans) {
|
||||
boolean logOut = isLogOut(booleans);
|
||||
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
|
||||
if (StringUtils.isEmpty(token) && logOut) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
this.refreshToken(token);
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新token有效期
|
||||
*
|
||||
* @param request 请求
|
||||
*/
|
||||
public void refreshToken(HttpServletRequest request) {
|
||||
String token = getToken(request);
|
||||
this.refreshToken(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除token
|
||||
*
|
||||
* @param token token
|
||||
* @param booleans 是否需要退出登录
|
||||
*/
|
||||
public void removeToken(String token, Boolean... booleans) {
|
||||
boolean logOut = isLogOut(booleans);
|
||||
Long customerId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token);
|
||||
if (Objects.isNull(customerId) && logOut) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
redisService.deleteObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
|
||||
redisService.deleteObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token);
|
||||
redisService.deleteObject(RedisConstant.APP_CUSTOMER_USERNAME_KEY + token);
|
||||
redisService.deleteObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token);
|
||||
redisService.deleteObject(RedisConstant.APP_DEVICE_IDENTIFICATION + token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id移除token
|
||||
*
|
||||
* @param customerId 用户id
|
||||
*/
|
||||
public void removeToken(Long customerId) {
|
||||
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
|
||||
this.removeToken(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据HttpServletRequest获取token
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @param booleans 是否需要退出登录
|
||||
* @return token
|
||||
*/
|
||||
public String getToken(HttpServletRequest request, Boolean... booleans) {
|
||||
boolean logOut = isLogOut(booleans);
|
||||
String token = request.getHeader("Authorization");
|
||||
if (StringUtils.isEmpty(token) && logOut) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.info("登录过期重新登录, requestURI:{}, logOut:{}, token:{}", requestURI, logOut, token);
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id获取到token
|
||||
*
|
||||
* @param customerId 用户id
|
||||
* @return token
|
||||
*/
|
||||
public String getToken(Long customerId) {
|
||||
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
|
||||
if (StringUtils.isEmpty(token)) {
|
||||
return null;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过token获取到用户的ID
|
||||
*
|
||||
* @param token token
|
||||
* @param logOut 是否需要退出登录
|
||||
* @return 用户ID
|
||||
*/
|
||||
public Long getCustomerId(String token, Boolean logOut) {
|
||||
Long customerId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token);
|
||||
if (Objects.isNull(customerId) && logOut) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
return customerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据HttpServletRequest获取到用户的ID
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @param booleans 是否需要退出登录
|
||||
* @return 用户ID
|
||||
*/
|
||||
public Long getCustomerId(HttpServletRequest request, Boolean... booleans) {
|
||||
boolean logOut = isLogOut(booleans);
|
||||
String token = getToken(request, logOut);
|
||||
if (StringUtils.isEmpty(token)) {
|
||||
return null;
|
||||
}
|
||||
return getCustomerId(token, logOut);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据token获取到用户的手机号 未解密
|
||||
*
|
||||
* @param token token
|
||||
* @param booleans 是否需要退出登录
|
||||
* @return 手机号
|
||||
*/
|
||||
public String getPhone(String token, Boolean... booleans) {
|
||||
boolean logOut = isLogOut(booleans);
|
||||
String phone = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_USERNAME_KEY + token);
|
||||
if (Objects.isNull(phone) && logOut) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
return phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID获取手机号码
|
||||
*
|
||||
* @param customerId 用户ID
|
||||
* @param booleans 是否需要退出登录
|
||||
* @return 手机号
|
||||
*/
|
||||
public String getPhone(Long customerId, Boolean... booleans) {
|
||||
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
|
||||
if (Objects.isNull(token) && isLogOut(booleans)) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
String phone = getPhone(token);
|
||||
// try {
|
||||
// phone = EncryptUtil.AESdecode(phone, redisService.getAppEncrypted());
|
||||
// }catch (Exception e) {
|
||||
// return phone;
|
||||
// }
|
||||
|
||||
return phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据HttpServletRequest获取到用户的手机号
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @return 手机号
|
||||
*/
|
||||
public String getPhone(HttpServletRequest request) {
|
||||
String token = getToken(request);
|
||||
return getPhone(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据token获取到用户的渠道ID
|
||||
*
|
||||
* @param token token
|
||||
* @param booleans 是否需要退出登录
|
||||
* @return 渠道ID
|
||||
*/
|
||||
public Long getChannelId(String token, Boolean... booleans) {
|
||||
Long channelId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token);
|
||||
if (Objects.isNull(channelId) && isLogOut(booleans)) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
return channelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据HttpServletRequest获取到用户的渠道ID
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @return 渠道ID
|
||||
*/
|
||||
public Long getChannelId(HttpServletRequest request, Boolean... booleans) {
|
||||
String token = getToken(request,booleans);
|
||||
return getChannelId(token,booleans);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID获取渠道ID
|
||||
*
|
||||
* @param customerId 用户ID
|
||||
* @param booleans 是否需要退出登录
|
||||
* @return 渠道ID
|
||||
*/
|
||||
public Long getChannelId(Long customerId, Boolean... booleans) {
|
||||
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
|
||||
if (Objects.isNull(token) && isLogOut(booleans)) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
Long channelId = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token);
|
||||
if (Objects.isNull(channelId) && isLogOut(booleans)) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
return channelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新渠道
|
||||
* @param customerId 用户ID
|
||||
* @param channelId 渠道ID
|
||||
*/
|
||||
public void setChannelId(Long customerId,Long channelId) {
|
||||
String token = getToken(customerId);
|
||||
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token, channelId, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据token获取设备类型
|
||||
*
|
||||
* @param token token
|
||||
* @param booleans 是否需要退出登录
|
||||
* @return 设备类型
|
||||
*/
|
||||
public String getDeviceType(String token, Boolean... booleans) {
|
||||
String deviceType = redisService.getCacheObject(RedisConstant.APP_DEVICE_IDENTIFICATION + token);
|
||||
if (Objects.isNull(deviceType) && isLogOut(booleans)) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据HttpServletRequest获取设备类型
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @return 设备类型
|
||||
*/
|
||||
public String getDeviceType(HttpServletRequest request,Boolean... booleans) {
|
||||
String token = getToken(request,booleans);
|
||||
return getDeviceType(token,booleans);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据HttpServletRequest获取设备类型
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @return 设备类型
|
||||
*/
|
||||
public String getDeviceTypeStr(HttpServletRequest request) {
|
||||
String token = getToken(request);
|
||||
return getDeviceType(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID获取设备类型
|
||||
*
|
||||
* @param customerId 用户ID
|
||||
* @param booleans 是否需要退出登录
|
||||
* @return 设备类型
|
||||
*/
|
||||
public String getDeviceType(Long customerId, Boolean... booleans) {
|
||||
String token = redisService.getCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId);
|
||||
if (Objects.isNull(token) && isLogOut(booleans)) {
|
||||
new Exception("登录已过期,请重新登录");
|
||||
}
|
||||
String deviceType = redisService.getCacheObject(RedisConstant.APP_DEVICE_IDENTIFICATION + token);
|
||||
if (!StringUtils.hasText(deviceType)) {
|
||||
deviceType = "ANDROID";
|
||||
}
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要退出登录
|
||||
*
|
||||
* @param booleans 参数值
|
||||
* @return 是否需要退出登录
|
||||
*/
|
||||
public Boolean isLogOut(Boolean... booleans) {
|
||||
if (booleans == null || booleans.length == 0) {
|
||||
return true;
|
||||
}
|
||||
return booleans[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,2 +1,3 @@
|
|||
com.ruoyi.common.redis.configure.RedisConfig
|
||||
com.ruoyi.common.redis.service.RedisService
|
||||
com.ruoyi.common.redis.service.CustomerTokenService
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.ruoyi.common.core.constant.RedisConstant;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -42,6 +44,11 @@ public class TokenService
|
|||
|
||||
private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
|
||||
|
||||
/**
|
||||
* token过期时间
|
||||
*/
|
||||
private static final Long EXPIRE_TIME = 30 * 24 * 60 * 60L;
|
||||
|
||||
/**
|
||||
* 创建令牌
|
||||
*/
|
||||
|
|
@ -69,6 +76,40 @@ public class TokenService
|
|||
return rspMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建令牌
|
||||
*/
|
||||
public String createTokenApp(Long customerId,Long channelId)
|
||||
{
|
||||
String token = IdUtils.fastUUID();
|
||||
// Long userId = loginUser.getSysUser().getUserId();
|
||||
// String userName = loginUser.getSysUser().getUserName();
|
||||
// loginUser.setToken(token);
|
||||
// loginUser.setUserid(userId);
|
||||
// loginUser.setUsername(userName);
|
||||
// loginUser.setIpaddr(IpUtils.getIpAddr());
|
||||
// refreshToken(loginUser);
|
||||
|
||||
// Jwt存储信息
|
||||
Map<String, Object> claimsMap = new HashMap<String, Object>();
|
||||
claimsMap.put(SecurityConstants.USER_KEY, token);
|
||||
claimsMap.put(SecurityConstants.DETAILS_USER_ID, customerId);
|
||||
claimsMap.put(SecurityConstants.DETAILS_USERNAME, "userName");
|
||||
|
||||
// 接口返回信息
|
||||
Map<String, Object> rspMap = new HashMap<String, Object>();
|
||||
String token1 = JwtUtils.createToken(claimsMap);
|
||||
rspMap.put("access_token", token1);
|
||||
rspMap.put("expires_in", expireTime);
|
||||
|
||||
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_USERNAME_KEY + token1, customerId, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_KEY + customerId, token1, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_CHANNEL_KEY + token1, channelId, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.setCacheObject(RedisConstant.APP_CUSTOMER_TOKEN_KEY + token1, customerId, EXPIRE_TIME, TimeUnit.SECONDS);
|
||||
redisService.setCacheObject( CacheConstants.LOGIN_TOKEN_KEY+token,customerId,EXPIRE_TIME,TimeUnit.SECONDS);
|
||||
return token1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户身份信息
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>3.6.4</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ruoyi-common-sms</artifactId>
|
||||
|
||||
<description>
|
||||
ruoyi-common-sms 短信模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.7.0</version> <!-- 或其他兼容版本 -->
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.7.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos Config -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.ruoyi.common.sms;
|
||||
|
||||
import com.ruoyi.common.sms.component.SmsComponent;
|
||||
import com.ruoyi.common.sms.properties.XunDaYunXinProperties;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(XunDaYunXinProperties.class)
|
||||
public class XunDaYunXinAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public SmsComponent smsComponent() {
|
||||
return new SmsComponent();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
package com.ruoyi.common.sms.component;
|
||||
|
||||
import com.ruoyi.common.sms.entity.response.SmsEntity;
|
||||
import com.ruoyi.common.sms.entity.response.SmsResponse;
|
||||
import com.ruoyi.common.sms.properties.XunDaYunXinProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
public class SmsComponent {
|
||||
@Autowired
|
||||
private XunDaYunXinProperties properties;
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
/**
|
||||
* 点对点
|
||||
*
|
||||
* @param mobileContentKvp 号码内容键值对 示例 {"15100000000":"【测试】test1","15100000001":"【测试】test2"}
|
||||
* @return SmsResponse<SmsEntity>
|
||||
*/
|
||||
public SmsResponse sendP2PMsg(Map<String, String> mobileContentKvp) {
|
||||
Map<String, Object> extraParams = new HashMap<>();
|
||||
|
||||
for (Map.Entry<String, String> entry : mobileContentKvp.entrySet()) {
|
||||
String oldValue = entry.getValue();
|
||||
String newValue = replaceCode(properties.getTemplate(), oldValue);
|
||||
entry.setValue(newValue);
|
||||
}
|
||||
extraParams.put("mobileContentKvp", mobileContentKvp);
|
||||
return sendSmsRequest("p2p", extraParams, new ParameterizedTypeReference<SmsResponse>() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送群发信息
|
||||
*
|
||||
* @param mobile 电话号码按照,分割 示例 "15100000000,15100000001"
|
||||
* @param content 内容 一般为验证码
|
||||
* @return SmsResponse<SmsEntity>
|
||||
*/
|
||||
public SmsResponse<SmsEntity> sendGroupMsg(String mobile, String content) {
|
||||
Map<String, Object> extraParams = new HashMap<>();
|
||||
extraParams.put("mobile", removeDuplicates(mobile));
|
||||
extraParams.put("content", replaceCode(properties.getTemplate(), content));
|
||||
return sendSmsRequest("send", extraParams, new ParameterizedTypeReference<SmsResponse<SmsEntity>>() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public SmsResponse<?> checkBalance() {
|
||||
String url = properties.getBaseUrl() + "/smsv2";
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("action", "balance");
|
||||
params.put("account", properties.getAccount());
|
||||
params.put("password", properties.getPassword());
|
||||
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(params);
|
||||
ResponseEntity<SmsResponse<?>> responseEntity = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.POST,
|
||||
requestEntity,
|
||||
new ParameterizedTypeReference<SmsResponse<?>>() {
|
||||
}
|
||||
);
|
||||
return responseEntity.getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信请求的通用方法,适用于不同的短信操作。
|
||||
*
|
||||
* @param action 短信操作的类型,例如 "p2p"、"send" "balance"。
|
||||
* @param extraParams 附加的请求参数,具体取决于短信操作的需求。可以为 null。
|
||||
* @param responseType 返回值的泛型类型,用于指定响应的具体类型。
|
||||
* @param <T> 响应体中泛型的类型参数。
|
||||
* @return 包含响应结果的 SmsResponse 对象,响应体中可能包含不同类型的数据。
|
||||
*/
|
||||
private <T> T sendSmsRequest(String action, Map<String, Object> extraParams, ParameterizedTypeReference<T> responseType) {
|
||||
// 拼接请求的 URL 地址
|
||||
String url = properties.getBaseUrl() + "/smsv2";
|
||||
|
||||
// 创建请求参数 Map,并填充必需的账户信息和操作类型
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("action", action); // 设置请求的操作类型,如发送短信或查询余额
|
||||
params.put("account", properties.getAccount()); // 设置账户名
|
||||
params.put("password", properties.getPassword()); // 设置密码
|
||||
params.put("extno", properties.getExtno()); // 虚拟接入码
|
||||
|
||||
// 如果有额外的参数,则将它们添加到请求参数中
|
||||
if (extraParams != null) {
|
||||
params.putAll(extraParams);
|
||||
}
|
||||
// 构建 HttpEntity 实体,包含请求参数
|
||||
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(params);
|
||||
|
||||
// 使用 RestTemplate 的 exchange 方法发送 POST 请求,并指定返回的泛型类型
|
||||
ResponseEntity<T> responseEntity = restTemplate.exchange(
|
||||
url, // 请求 URL
|
||||
HttpMethod.POST, // HTTP 方法类型为 POST
|
||||
requestEntity, // 请求体包含请求参数
|
||||
responseType // 指定返回类型的泛型引用,用于保留泛型信息
|
||||
);
|
||||
|
||||
// 返回响应体(根据调用方法传入的类型)
|
||||
return responseEntity.getBody();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 相同号码去重
|
||||
*
|
||||
* @param input 字符串电话号码 逗号分隔符分割
|
||||
* @return String 去重之后的手机电话号码
|
||||
*/
|
||||
private String removeDuplicates(String input) {
|
||||
// 使用 LinkedHashSet 保持插入顺序并去重
|
||||
Set<String> uniqueSet = new LinkedHashSet<>(Arrays.asList(input.split(",")));
|
||||
if (uniqueSet.size() >= 1000) {
|
||||
throw new IllegalArgumentException("群发不建议超过1000个电话号码");
|
||||
}
|
||||
// 将去重后的集合转换回字符串
|
||||
return String.join(",", uniqueSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板替换占位符
|
||||
*
|
||||
* @param template 模板
|
||||
* @param code 实际值
|
||||
* @return 替换之后的模板
|
||||
*/
|
||||
public String replaceCode(String template, String code) {
|
||||
return template.replace("{code}", code);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
package com.ruoyi.common.sms.entity;
|
||||
|
|
@ -0,0 +1 @@
|
|||
package com.ruoyi.common.sms.entity.request;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.ruoyi.common.sms.entity.response;
|
||||
|
||||
public class SmsEntity {
|
||||
private String mid;
|
||||
private String mobile;
|
||||
private int result;
|
||||
|
||||
// Getters and Setters
|
||||
public String getMid() {
|
||||
return mid;
|
||||
}
|
||||
|
||||
public void setMid(String mid) {
|
||||
this.mid = mid;
|
||||
}
|
||||
|
||||
public String getMobile() {
|
||||
return mobile;
|
||||
}
|
||||
|
||||
public void setMobile(String mobile) {
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
public int getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(int result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.ruoyi.common.sms.entity.response;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class SmsResponse<T> {
|
||||
private Integer status;
|
||||
private Integer balance;
|
||||
private List<T> list;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.ruoyi.common.sms.properties;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* 迅达云信短信 配置类
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "xundayunxin")
|
||||
public class XunDaYunXinProperties {
|
||||
/**
|
||||
* 请求地址
|
||||
*/
|
||||
private String baseUrl = "http://47.96.236.136:7862/";
|
||||
/**
|
||||
* 账号
|
||||
*/
|
||||
private String account = "932425";
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password = "alDE77Gmo";
|
||||
|
||||
/**
|
||||
* 虚拟接入码
|
||||
*/
|
||||
private String extno = "10690367";
|
||||
|
||||
/**
|
||||
* 是否启用手机号加密
|
||||
*/
|
||||
private boolean encryptionEnabled;
|
||||
|
||||
/**
|
||||
* 短信模板
|
||||
*/
|
||||
private String template = "【信用秒租】验证码为:{code},您正在登录信用秒租,请在3分钟内完成验证,如非本人操作,请忽略本短信。";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
com.ruoyi.common.sms.XunDaYunXinAutoConfiguration
|
||||
com.ruoyi.common.sms.component.SmsComponent
|
||||
|
|
@ -15,15 +15,6 @@ public class RuoYiGatewayApplication
|
|||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(RuoYiGatewayApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ 若依网关启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||
" .-------. ____ __ \n" +
|
||||
" | _ _ \\ \\ \\ / / \n" +
|
||||
" | ( ' ) | \\ _. / ' \n" +
|
||||
" |(_ o _) / _( )_ .' \n" +
|
||||
" | (_,_).' __ ___(_ o _)' \n" +
|
||||
" | |\\ \\ | || |(_,_)' \n" +
|
||||
" | | \\ `' /| `-' / \n" +
|
||||
" | | \\ / \\ / \n" +
|
||||
" ''-' `'-' `-..-' ");
|
||||
System.out.println("(♥◠‿◠)ノ゙ 租研舍网关启动成功 ლ(´ڡ`ლ)゙ \n");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@ spring:
|
|||
nacos:
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 127.0.0.1:8848
|
||||
server-addr: 47.109.135.151:8848
|
||||
namespace: b8ad3fd2-18ea-4cdf-a82c-4ce483392b1a
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 127.0.0.1:8848
|
||||
server-addr: 47.109.135.151:8848
|
||||
namespace: b8ad3fd2-18ea-4cdf-a82c-4ce483392b1a
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
|
|
@ -28,12 +30,12 @@ spring:
|
|||
eager: true
|
||||
transport:
|
||||
# 控制台地址
|
||||
dashboard: 127.0.0.1:8718
|
||||
dashboard: 47.109.135.151:8718
|
||||
# nacos配置持久化
|
||||
datasource:
|
||||
ds1:
|
||||
nacos:
|
||||
server-addr: 127.0.0.1:8848
|
||||
server-addr: 47.109.135.151:8848
|
||||
dataId: sentinel-ruoyi-gateway
|
||||
groupId: DEFAULT_GROUP
|
||||
data-type: json
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
<module>ruoyi-gen</module>
|
||||
<module>ruoyi-job</module>
|
||||
<module>ruoyi-file</module>
|
||||
<module>ruoyi-btc</module>
|
||||
</modules>
|
||||
|
||||
<artifactId>ruoyi-modules</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-modules</artifactId>
|
||||
<version>3.6.4</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ruoyi-modules-btc</artifactId>
|
||||
|
||||
<description>
|
||||
ruoyi-modules-btc三方业务服务
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos Config -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Sentinel -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringBoot Actuator -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringBoot Web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- RuoYi Api System -->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-api-system</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.ruoyi.btc;
|
||||
|
||||
import com.ruoyi.common.security.annotation.EnableRyFeignClients;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
|
||||
/**
|
||||
* 三方调用服务
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@EnableRyFeignClients
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
|
||||
public class RuoYiBtcApplication
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(RuoYiBtcApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ 三方业务服务模块启动成功 ლ(´ڡ`ლ)゙ \n");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.ruoyi.btc.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "system")
|
||||
@Data
|
||||
public class Config {
|
||||
|
||||
/**
|
||||
* 加密密钥
|
||||
*/
|
||||
private String AESkey;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.ruoyi.btc.controller;
|
||||
|
||||
import com.ruoyi.btc.domain.ComPublicHalfDto;
|
||||
import com.ruoyi.btc.service.ISysPublicAllService;
|
||||
import com.ruoyi.btc.service.ISysPublicHalfService;
|
||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 半流程API接口写这里
|
||||
*
|
||||
* @author z
|
||||
*/
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequestMapping("/all/api")
|
||||
@RequiredArgsConstructor
|
||||
public class PublicAllController {
|
||||
private final ISysPublicAllService sysPublicAllService;
|
||||
|
||||
/**
|
||||
* 通用半流程撞库
|
||||
*/
|
||||
@PostMapping("check")
|
||||
public AjaxResult upload(@RequestBody ComPublicHalfDto comPublicHalfDto)
|
||||
{
|
||||
sysPublicAllService.check(comPublicHalfDto);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用半流程撞库
|
||||
*/
|
||||
@PostMapping("input")
|
||||
public AjaxResult input(@RequestBody ComPublicHalfDto comPublicHalfDto)
|
||||
{
|
||||
sysPublicAllService.input(comPublicHalfDto);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.ruoyi.btc.controller;
|
||||
|
||||
import com.ruoyi.btc.domain.ComPublicHalfDto;
|
||||
import com.ruoyi.btc.service.ISysPublicHalfService;
|
||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 半流程API接口写这里
|
||||
*
|
||||
* @author z
|
||||
*/
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequestMapping("/half/api")
|
||||
@RequiredArgsConstructor
|
||||
public class PublicHalfController{
|
||||
private final ISysPublicHalfService sysPublicHalfService;
|
||||
|
||||
/**
|
||||
* 通用半流程撞库
|
||||
*/
|
||||
@PostMapping("/check")
|
||||
public AjaxResult upload(@RequestBody ComPublicHalfDto comPublicHalfDto)
|
||||
{
|
||||
return sysPublicHalfService.check(comPublicHalfDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用半流程撞库
|
||||
*/
|
||||
@PostMapping("/input")
|
||||
public AjaxResult input(@RequestBody ComPublicHalfDto comPublicHalfDto)
|
||||
{
|
||||
return sysPublicHalfService.input(comPublicHalfDto);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通用半流程撞库
|
||||
*/
|
||||
@GetMapping("/checkOrder")
|
||||
public AjaxResult checkOrder(String phoneMd5,String channelSign)
|
||||
{
|
||||
|
||||
return sysPublicHalfService.checkOrder(phoneMd5,channelSign);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.ruoyi.btc.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ComPublicHalfDto {
|
||||
|
||||
//参数实体类
|
||||
private String data;
|
||||
//渠道标识
|
||||
private String channelSignature;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.ruoyi.btc.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CustomerInfoDto {
|
||||
//手机号码(Md5)
|
||||
private String phoneMd5;
|
||||
//手机号
|
||||
private String phone;
|
||||
//性别 0 男 1 女
|
||||
private Integer sex;
|
||||
//手机号码(Md5)
|
||||
private String nameMd5;
|
||||
//姓名
|
||||
private String name;
|
||||
//年龄
|
||||
private Integer age;
|
||||
//手身份证md5
|
||||
private String idCardMd5;
|
||||
//身份证好
|
||||
private String idCard;
|
||||
//所在城市
|
||||
private String city;
|
||||
//所在城市代码
|
||||
private Integer cityCode;
|
||||
//本地社保
|
||||
private Integer socialSecurity;
|
||||
//本地公积金
|
||||
private Integer accumulationFund;
|
||||
//名下车产
|
||||
private Integer car;
|
||||
//名下房产
|
||||
private Integer hourse;
|
||||
//个人保险
|
||||
private Integer guarantee;
|
||||
//芝麻分
|
||||
private Integer zhiMa;
|
||||
//职业身份
|
||||
private Integer career;
|
||||
//信用卡(1无 2有
|
||||
private Integer creditCard;
|
||||
//学历
|
||||
private Integer education;
|
||||
//月收入
|
||||
private Integer monthlyIncome;
|
||||
//ip地址
|
||||
private String ip;
|
||||
//渠道标识
|
||||
private String channelSignature;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.ruoyi.btc.service;
|
||||
|
||||
import com.ruoyi.btc.domain.ComPublicHalfDto;
|
||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||
|
||||
/**
|
||||
* 文件上传接口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ISysPublicAllService
|
||||
{
|
||||
|
||||
/**
|
||||
* 半流程通用撞库接口
|
||||
* @param comPublicHalfDto
|
||||
*/
|
||||
AjaxResult check(ComPublicHalfDto comPublicHalfDto);
|
||||
|
||||
/**
|
||||
* 半流程通用进件
|
||||
* @param comPublicHalfDto
|
||||
*/
|
||||
AjaxResult input(ComPublicHalfDto comPublicHalfDto);
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.ruoyi.btc.service;
|
||||
|
||||
import com.ruoyi.btc.domain.ComPublicHalfDto;
|
||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* 文件上传接口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ISysPublicHalfService
|
||||
{
|
||||
|
||||
/**
|
||||
* 半流程通用撞库接口
|
||||
* @param comPublicHalfDto
|
||||
*/
|
||||
AjaxResult check(ComPublicHalfDto comPublicHalfDto);
|
||||
|
||||
/**
|
||||
* 半流程通用进件
|
||||
* @param comPublicHalfDto
|
||||
*/
|
||||
AjaxResult input(ComPublicHalfDto comPublicHalfDto);
|
||||
|
||||
/**
|
||||
* 渠道查询订单是否成功
|
||||
* @param
|
||||
*/
|
||||
AjaxResult checkOrder(String phoneMd5, String channelSign);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
package com.ruoyi.btc.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ruoyi.btc.domain.ComPublicHalfDto;
|
||||
import com.ruoyi.btc.domain.CustomerInfoDto;
|
||||
import com.ruoyi.btc.service.ISysPublicAllService;
|
||||
import com.ruoyi.common.core.constant.CacheConstants;
|
||||
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||
import com.ruoyi.common.core.domain.GetSumDto;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.domain.http.Channel;
|
||||
import com.ruoyi.common.core.domain.http.Customer;
|
||||
import com.ruoyi.common.core.domain.http.CustomerApplyLog;
|
||||
import com.ruoyi.common.core.domain.http.Merchant;
|
||||
import com.ruoyi.common.core.utils.SecureUtils;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||
import com.ruoyi.common.redis.service.RedisService;
|
||||
import com.ruoyi.system.api.RemoteCustomerApplyLogService;
|
||||
import com.ruoyi.system.api.RemoteCustomerService;
|
||||
import com.ruoyi.system.api.RemoteMerchantService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 本地文件存储
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysPublicAllServiceImpl implements ISysPublicAllService
|
||||
{
|
||||
private final RemoteCustomerService remoteCustomerService;
|
||||
private final RemoteMerchantService remoteMerchantService;
|
||||
private final RemoteCustomerApplyLogService remoteCustomerApplyLogService;
|
||||
private final RedisService redisService;
|
||||
|
||||
/**
|
||||
* 半流程通用撞库
|
||||
* @param comPublicHalfDto
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult check(ComPublicHalfDto comPublicHalfDto) {
|
||||
//校验 IP地址是否正常 渠道标识是否存在 数据是否为空
|
||||
|
||||
if (StringUtils.isEmpty(comPublicHalfDto.getChannelSignature())){
|
||||
return AjaxResult.error("渠道标识不能未空");
|
||||
}
|
||||
Channel channel = redisService.getCacheObject(CacheConstants.CHANNEL_SIGN + comPublicHalfDto.getChannelSignature());
|
||||
if (channel==null||channel.getId()==null){
|
||||
return AjaxResult.error("渠道不存在");
|
||||
}
|
||||
if (StringUtils.isEmpty(comPublicHalfDto.getData())){
|
||||
return AjaxResult.error("加密数据不能为空");
|
||||
}
|
||||
//解密为customerInfoDto
|
||||
String s = SecureUtils.AesUtil.AesDecode(comPublicHalfDto.getData(), comPublicHalfDto.getChannelSignature());
|
||||
if (s==null){
|
||||
return AjaxResult.error("解密异常");
|
||||
}
|
||||
CustomerInfoDto customerInfoDto = JSONObject.parseObject(s, CustomerInfoDto.class);
|
||||
//校验数据必传参数是否未传
|
||||
String checkData = checkData(customerInfoDto);
|
||||
if (checkData!=null){
|
||||
return AjaxResult.error(checkData);
|
||||
}
|
||||
//转化字段未数据库中资质字段 并保存 用户未实名状态 一并保存用户申请记录 未申请状态
|
||||
Customer customer = new Customer();
|
||||
BeanUtil.copyProperties(customerInfoDto,customer);
|
||||
customer.setChannelId(channel.getId());
|
||||
customer.setActurlName(customerInfoDto.getNameMd5());
|
||||
customer.setFirstLoginTime(new Date());
|
||||
customer.setLastLoginTime(new Date());
|
||||
customer.setIsAuth(false);
|
||||
customer.setStatus(2);
|
||||
R<Customer> customerInfoByPhoneMd5 = remoteCustomerService.getCustomerInfoByPhoneMd5(customerInfoDto.getPhoneMd5(), SecurityConstants.INNER);
|
||||
if (customerInfoByPhoneMd5.getCode()==200){
|
||||
remoteCustomerService.updateByPhoneMd5(customer,SecurityConstants.INNER);
|
||||
}else {
|
||||
remoteCustomerService.add(customer,SecurityConstants.INNER);
|
||||
}
|
||||
//TODO 暂时不做 目前下游暂时不需要 匹配资质 造轮子 返回多个符合的商户
|
||||
List<Merchant> merchants = matchMerchant(customer);
|
||||
//结束返回上游结果
|
||||
Map<String,Boolean> re = new HashMap<>();
|
||||
if (merchants.size()>0){
|
||||
re.put("data",true);
|
||||
return AjaxResult.success(re);
|
||||
}
|
||||
re.put("data",false);
|
||||
return AjaxResult.success(re);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取前筛符合的商户
|
||||
* @param customer
|
||||
*/
|
||||
private List<Merchant> matchMerchant(Customer customer) {
|
||||
R<List<Merchant>> listR = remoteMerchantService.merchantList(SecurityConstants.INNER);
|
||||
if (listR.getCode()!=200){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<Merchant> merchants = new ArrayList<>();
|
||||
for (Merchant merchant:listR.getData()) {
|
||||
//限量判定
|
||||
GetSumDto dto = new GetSumDto();
|
||||
dto.setMerchantId(merchant.getId());
|
||||
R<Integer> sum = remoteCustomerApplyLogService.sum(dto, SecurityConstants.INNER);
|
||||
if (merchant.getLimitType()==1&&merchant.getLimitNum()<=sum.getData()){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (customer.getAge()<merchant.getAgeLimitStart()||customer.getAge()>merchant.getAgeLimitEnd()){
|
||||
continue;
|
||||
}
|
||||
if (merchant.getChannelLimitType()==1||merchant.getChannelLimitType()==2){
|
||||
|
||||
List<Long> list = Arrays.asList(merchant.getChannelLimit().split(",")).stream().map(val->Long.parseLong(val)).collect(Collectors.toList());
|
||||
if (merchant.getChannelLimitType()==1&& !list.contains(customer.getChannelId())){
|
||||
continue;
|
||||
}
|
||||
if (merchant.getChannelLimitType()==2&& list.contains(customer.getChannelId())){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
merchants.add(merchant);
|
||||
}
|
||||
return merchants;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验参数
|
||||
* @param customerInfoDto
|
||||
*/
|
||||
private String checkData(CustomerInfoDto customerInfoDto) {
|
||||
if (customerInfoDto.getAge()==null){
|
||||
return "年龄不能为空";
|
||||
}
|
||||
if (StringUtils.isEmpty(customerInfoDto.getPhoneMd5())){
|
||||
return "手机号MD5不能为空";
|
||||
}
|
||||
if (StringUtils.isEmpty(customerInfoDto.getCity())){
|
||||
return "城市不能为空";
|
||||
}
|
||||
if (customerInfoDto.getCityCode()==null){
|
||||
return "城市编码不能为空";
|
||||
}
|
||||
if (customerInfoDto.getSocialSecurity()==null){
|
||||
return "本地社保不能为空";
|
||||
}
|
||||
if (customerInfoDto.getAccumulationFund()==null){
|
||||
return "本地公积金不能为空";
|
||||
}
|
||||
if (customerInfoDto.getCar()==null){
|
||||
return "车产不能为空";
|
||||
}
|
||||
if (customerInfoDto.getHourse()==null){
|
||||
return "房产不能为空";
|
||||
}
|
||||
if (customerInfoDto.getGuarantee()==null){
|
||||
return "房产不能为空";
|
||||
}
|
||||
if (customerInfoDto.getZhiMa()==null){
|
||||
return "芝麻分不能为空";
|
||||
}
|
||||
if (customerInfoDto.getCareer()==null){
|
||||
return "职业不能为空";
|
||||
}
|
||||
if (customerInfoDto.getCreditCard()==null){
|
||||
return "信用卡不能为空";
|
||||
}
|
||||
if (customerInfoDto.getEducation()==null){
|
||||
return "学历不能为空";
|
||||
}
|
||||
if (customerInfoDto.getMonthlyIncome()==null){
|
||||
return "月收入不能为空";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 半流程通用进件
|
||||
* @param comPublicHalfDto
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult input(ComPublicHalfDto comPublicHalfDto) {
|
||||
//校验 IP地址是否正常 渠道标识是否存在 数据是否为空
|
||||
if (StringUtils.isEmpty(comPublicHalfDto.getChannelSignature())){
|
||||
return AjaxResult.error("渠道标识不能未空");
|
||||
}
|
||||
Channel channel = redisService.getCacheObject(CacheConstants.CHANNEL_SIGN + comPublicHalfDto.getChannelSignature());
|
||||
if (channel==null||channel.getId()==null){
|
||||
return AjaxResult.error("渠道不存在");
|
||||
}
|
||||
if (StringUtils.isEmpty(comPublicHalfDto.getData())){
|
||||
return AjaxResult.error("加密数据不能为空");
|
||||
}
|
||||
//解密为customerInfoDto
|
||||
String s = SecureUtils.AesUtil.AesDecode(comPublicHalfDto.getData(), comPublicHalfDto.getChannelSignature());
|
||||
if (s==null){
|
||||
return AjaxResult.error("解密异常");
|
||||
}
|
||||
CustomerInfoDto customerInfoDto = JSONObject.parseObject(s, CustomerInfoDto.class);
|
||||
//校验数据必传参数是否未传
|
||||
String checkData = checkData(customerInfoDto);
|
||||
//转化字段未数据库中资质字段 更新 用户实名状态 一并保存用户申请记录 已申请
|
||||
if (checkData!=null){
|
||||
return AjaxResult.error(checkData);
|
||||
}
|
||||
//转化字段未数据库中资质字段 并保存 用户未实名状态 一并保存用户申请记录 未申请状态
|
||||
Customer customer = new Customer();
|
||||
BeanUtil.copyProperties(customerInfoDto,customer);
|
||||
customer.setChannelId(channel.getId());
|
||||
customer.setActurlName(customerInfoDto.getName());
|
||||
customer.setFirstLoginTime(new Date());
|
||||
customer.setLastLoginTime(new Date());
|
||||
customer.setIsAuth(true);
|
||||
customer.setStatus(1);
|
||||
R<Customer> customerInfoByPhoneMd5 = remoteCustomerService.getCustomerInfoByPhoneMd5(customerInfoDto.getPhoneMd5(), SecurityConstants.INNER);
|
||||
if (customerInfoByPhoneMd5.getCode()==200){
|
||||
remoteCustomerService.updateByPhoneMd5(customer,SecurityConstants.INNER);
|
||||
}else {
|
||||
return AjaxResult.error("今日未撞库");
|
||||
}
|
||||
//匹配资质 造轮子 返回多个符合的商户
|
||||
List<Merchant> merchants = matchMerchant(customer);
|
||||
//TODO 取排序第一的
|
||||
|
||||
//返回渠道绑定的注册页拼接token
|
||||
Map<String,Object> result = new HashMap<>();
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
|
||||
//TODO 下游是H5承接不了上游全流程 暂时不做
|
||||
CustomerApplyLog customerApplyLog = new CustomerApplyLog();
|
||||
customerApplyLog.setCustomerId(customerInfoByPhoneMd5.getData().getId());
|
||||
customerApplyLog.setChannelId(channel.getId());
|
||||
customerApplyLog.setMerchantId(merchants.get(0).getId());
|
||||
customerApplyLog.setOrderStatus(0l);
|
||||
remoteCustomerApplyLogService.add(customerApplyLog);
|
||||
//返回上游信息
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,328 @@
|
|||
package com.ruoyi.btc.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ruoyi.btc.config.Config;
|
||||
import com.ruoyi.btc.domain.ComPublicHalfDto;
|
||||
import com.ruoyi.btc.domain.CustomerInfoDto;
|
||||
import com.ruoyi.btc.service.ISysPublicHalfService;
|
||||
import com.ruoyi.common.core.constant.CacheConstants;
|
||||
import com.ruoyi.common.core.constant.RedisConstant;
|
||||
import com.ruoyi.common.core.constant.SecurityConstants;
|
||||
import com.ruoyi.common.core.domain.GetSumDto;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.domain.http.Channel;
|
||||
import com.ruoyi.common.core.domain.http.Customer;
|
||||
import com.ruoyi.common.core.domain.http.Merchant;
|
||||
import com.ruoyi.common.core.utils.EncryptUtil;
|
||||
import com.ruoyi.common.core.utils.ProbitUtil;
|
||||
import com.ruoyi.common.core.utils.SecureUtils;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||
import com.ruoyi.common.redis.service.RedisService;
|
||||
import com.ruoyi.system.api.RemoteCustomerApplyLogService;
|
||||
import com.ruoyi.system.api.RemoteCustomerService;
|
||||
import com.ruoyi.system.api.RemoteMerchantService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 本地文件存储
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class SysPublicHalfServiceImpl implements ISysPublicHalfService
|
||||
{
|
||||
private final RemoteCustomerService remoteCustomerService;
|
||||
private final RemoteMerchantService remoteMerchantService;
|
||||
private final RemoteCustomerApplyLogService remoteCustomerApplyLogService;
|
||||
private final RedisService redisService;
|
||||
private final Config config;
|
||||
|
||||
/**
|
||||
* 半流程通用撞库
|
||||
* @param comPublicHalfDto
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult check(ComPublicHalfDto comPublicHalfDto) {
|
||||
//校验 IP地址是否正常 渠道标识是否存在 数据是否为空
|
||||
if (StringUtils.isEmpty(comPublicHalfDto.getChannelSignature())){
|
||||
return AjaxResult.error("渠道标识不能未空");
|
||||
}
|
||||
Channel channel = redisService.getCacheObject(CacheConstants.CHANNEL_SIGN + comPublicHalfDto.getChannelSignature());
|
||||
if (channel==null||channel.getId()==null){
|
||||
return AjaxResult.error("渠道不存在");
|
||||
}
|
||||
if (StringUtils.isEmpty(comPublicHalfDto.getData())){
|
||||
return AjaxResult.error("加密数据不能为空");
|
||||
}
|
||||
|
||||
//解密为customerInfoDto
|
||||
String s = SecureUtils.AesUtil.AesDecode(comPublicHalfDto.getData(), comPublicHalfDto.getChannelSignature());
|
||||
if (s==null){
|
||||
return AjaxResult.error("解密异常");
|
||||
}
|
||||
CustomerInfoDto customerInfoDto = JSONObject.parseObject(s, CustomerInfoDto.class);
|
||||
//撞库幂等性校验 暂时不加
|
||||
// Boolean aBoolean = redisService.hasKey(RedisConstant.HIT_CHECK_CACHE+customerInfoDto.getPhoneMd5()+":"+comPublicHalfDto.getChannelSignature());
|
||||
// if (aBoolean){
|
||||
// return AjaxResult.error("手机号:"+customerInfoDto.getPhoneMd5()+"请勿重复撞库");
|
||||
// }
|
||||
// redisService.setCacheObject(RedisConstant.HIT_CHECK_CACHE+customerInfoDto.getPhoneMd5(),1,60*3l, TimeUnit.SECONDS);
|
||||
log.info("渠道:{},撞库手机号:{}",channel.getChannelName(),customerInfoDto.getPhoneMd5());
|
||||
//校验数据必传参数是否未传
|
||||
String checkData = checkData(customerInfoDto);
|
||||
if (checkData!=null){
|
||||
return AjaxResult.error(checkData);
|
||||
}
|
||||
//转化字段未数据库中资质字段 并保存 用户未实名状态 一并保存用户申请记录 未申请状态
|
||||
Customer customer = new Customer();
|
||||
BeanUtil.copyProperties(customerInfoDto,customer);
|
||||
customer.setChannelId(channel.getId());
|
||||
customer.setActurlName(customerInfoDto.getNameMd5());
|
||||
customer.setFirstLoginTime(new Date());
|
||||
customer.setLastLoginTime(new Date());
|
||||
customer.setIsAuth(false);
|
||||
customer.setStatus(2);
|
||||
customer.setPhoneMd5(customerInfoDto.getPhoneMd5());
|
||||
R<Customer> customerInfoByPhoneMd5 = remoteCustomerService.getCustomerInfoByPhoneMd5(customerInfoDto.getPhoneMd5(), SecurityConstants.INNER);
|
||||
log.info("渠道:{},是否查询到用户:{}",channel.getChannelName(),customerInfoByPhoneMd5.getCode());
|
||||
if (customerInfoByPhoneMd5.getCode()==200){
|
||||
remoteCustomerService.updateByPhoneMd5(customer,SecurityConstants.INNER);
|
||||
}else {
|
||||
remoteCustomerService.add(customer,SecurityConstants.INNER);
|
||||
}
|
||||
//TODO 暂时不做 目前下游暂时不需要 匹配资质 造轮子 返回多个符合的商户
|
||||
List<Merchant> merchants = matchMerchant(customer);
|
||||
//结束返回上游结果
|
||||
Map<String,Boolean> re = new HashMap<>();
|
||||
if (merchants.size()>0){
|
||||
re.put("data",true);
|
||||
return AjaxResult.success(re);
|
||||
}
|
||||
re.put("data",false);
|
||||
return AjaxResult.success(re);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取前筛符合的商户
|
||||
* @param customer
|
||||
*/
|
||||
private List<Merchant> matchMerchant(Customer customer) {
|
||||
R<List<Merchant>> listR = remoteMerchantService.merchantList(SecurityConstants.INNER);
|
||||
if (listR.getCode()!=200){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<Merchant> merchants = new ArrayList<>();
|
||||
for (Merchant merchant:listR.getData()) {
|
||||
//限量判定
|
||||
GetSumDto dto = new GetSumDto();
|
||||
dto.setMerchantId(merchant.getId());
|
||||
R<Integer> sum = remoteCustomerApplyLogService.sum(dto, SecurityConstants.INNER);
|
||||
if (merchant.getLimitType()==1&&merchant.getLimitNum()<=sum.getData()){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (customer.getAge()<merchant.getAgeLimitStart()||customer.getAge()>merchant.getAgeLimitEnd()){
|
||||
continue;
|
||||
}
|
||||
if (merchant.getChannelLimitType()==1||merchant.getChannelLimitType()==2){
|
||||
|
||||
List<Long> list = Arrays.asList(merchant.getChannelLimit().split(",")).stream().map(val->Long.parseLong(val)).collect(Collectors.toList());
|
||||
if (merchant.getChannelLimitType()==1&& !list.contains(customer.getChannelId())){
|
||||
continue;
|
||||
}
|
||||
if (merchant.getChannelLimitType()==2&& list.contains(customer.getChannelId())){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
merchants.add(merchant);
|
||||
}
|
||||
return merchants;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验参数
|
||||
* @param customerInfoDto
|
||||
*/
|
||||
private String checkData(CustomerInfoDto customerInfoDto) {
|
||||
if (customerInfoDto.getAge()==null){
|
||||
return "年龄不能为空";
|
||||
}
|
||||
if (StringUtils.isEmpty(customerInfoDto.getPhoneMd5())){
|
||||
return "手机号MD5不能为空";
|
||||
}
|
||||
if (StringUtils.isEmpty(customerInfoDto.getCity())){
|
||||
return "城市不能为空";
|
||||
}
|
||||
if (customerInfoDto.getCityCode()==null){
|
||||
return "城市编码不能为空";
|
||||
}
|
||||
if (customerInfoDto.getSocialSecurity()==null){
|
||||
return "本地社保不能为空";
|
||||
}
|
||||
if (customerInfoDto.getAccumulationFund()==null){
|
||||
return "本地公积金不能为空";
|
||||
}
|
||||
if (customerInfoDto.getCar()==null){
|
||||
return "车产不能为空";
|
||||
}
|
||||
if (customerInfoDto.getHourse()==null){
|
||||
return "房产不能为空";
|
||||
}
|
||||
if (customerInfoDto.getGuarantee()==null){
|
||||
return "房产不能为空";
|
||||
}
|
||||
if (customerInfoDto.getZhiMa()==null){
|
||||
return "芝麻分不能为空";
|
||||
}
|
||||
if (customerInfoDto.getCareer()==null){
|
||||
return "职业不能为空";
|
||||
}
|
||||
if (customerInfoDto.getCreditCard()==null){
|
||||
return "信用卡不能为空";
|
||||
}
|
||||
if (customerInfoDto.getEducation()==null){
|
||||
return "学历不能为空";
|
||||
}
|
||||
if (customerInfoDto.getMonthlyIncome()==null){
|
||||
return "月收入不能为空";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 半流程通用进件
|
||||
* @param comPublicHalfDto
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult input(ComPublicHalfDto comPublicHalfDto) {
|
||||
//校验 IP地址是否正常 渠道标识是否存在 数据是否为空
|
||||
if (StringUtils.isEmpty(comPublicHalfDto.getChannelSignature())){
|
||||
return AjaxResult.error("渠道标识不能未空");
|
||||
}
|
||||
Channel channel = redisService.getCacheObject(CacheConstants.CHANNEL_SIGN + comPublicHalfDto.getChannelSignature());
|
||||
if (channel==null||channel.getId()==null){
|
||||
return AjaxResult.error("渠道不存在");
|
||||
}
|
||||
if (StringUtils.isEmpty(comPublicHalfDto.getData())){
|
||||
return AjaxResult.error("加密数据不能为空");
|
||||
}
|
||||
//解密为customerInfoDto
|
||||
String s = SecureUtils.AesUtil.AesDecode(comPublicHalfDto.getData(), comPublicHalfDto.getChannelSignature());
|
||||
if (s==null){
|
||||
return AjaxResult.error("解密异常");
|
||||
}
|
||||
CustomerInfoDto customerInfoDto = JSONObject.parseObject(s, CustomerInfoDto.class);
|
||||
log.info("渠道:{},进件手机号:{}",channel.getChannelName(),customerInfoDto.getPhone());
|
||||
//校验数据必传参数是否未传
|
||||
String checkData = checkData(customerInfoDto);
|
||||
//转化字段未数据库中资质字段 更新 用户实名状态 一并保存用户申请记录 已申请
|
||||
if (checkData!=null){
|
||||
return AjaxResult.error(checkData);
|
||||
}
|
||||
//转化字段未数据库中资质字段 并保存 用户未实名状态 一并保存用户申请记录 未申请状态
|
||||
Customer customer = new Customer();
|
||||
BeanUtil.copyProperties(customerInfoDto,customer);
|
||||
customer.setChannelId(channel.getId());
|
||||
customer.setActurlName(customerInfoDto.getName());
|
||||
customer.setFirstLoginTime(new Date());
|
||||
customer.setLastLoginTime(new Date());
|
||||
customer.setIsAuth(true);
|
||||
customer.setStatus(1);
|
||||
R<Customer> customerInfoByPhoneMd5 = remoteCustomerService.getCustomerInfoByPhoneMd5(customerInfoDto.getPhoneMd5(), SecurityConstants.INNER);
|
||||
if (customerInfoByPhoneMd5.getCode()==200){
|
||||
customer.setPhone(EncryptUtil.AESencode(customer.getPhone(), config.getAESkey()));
|
||||
customer.setIdCard(EncryptUtil.AESencode(customer.getIdCard(),config.getAESkey()));
|
||||
customer.setActurlName(EncryptUtil.AESencode(customer.getActurlName(),config.getAESkey()));
|
||||
remoteCustomerService.updateByPhoneMd5(customer,SecurityConstants.INNER);
|
||||
}else {
|
||||
remoteCustomerService.add(customer,SecurityConstants.INNER);
|
||||
}
|
||||
//匹配资质 造轮子 返回多个符合的商户
|
||||
List<Merchant> merchants = matchMerchant(customer);
|
||||
//TODO 取排序第一的
|
||||
//返回渠道绑定的注册页拼接token
|
||||
Map<String,Object> result = new HashMap<>();
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
if (CollectionUtil.isEmpty(merchants)){
|
||||
map.put("url","");
|
||||
map.put("regist",false);
|
||||
result.put("data",map);
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
String url = channel.getHtmlLocation()+"?sign="+channel.getChannelSign() + "&token="+remoteCustomerService.getCustomerToken(customer.getPhone(),channel.getId() );
|
||||
map.put("url",url);
|
||||
map.put("regist",true);
|
||||
result.put("data",map);
|
||||
//CustomerApplyLog customerApplyLog = new CustomerApplyLog();
|
||||
// customerApplyLog.setCustomerId(customerInfoByPhoneMd5.getData().getId());
|
||||
// customerApplyLog.setChannelId(channel.getId());
|
||||
// customerApplyLog.setOrderStatus(0l);
|
||||
//+"&orderNo="+ LocalDateTimeUtils.getStringFromLocalDateTime()
|
||||
//remoteCustomerApplyLogService.add(customerApplyLog);
|
||||
//返回上游信息
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 渠道查询订单是否成功
|
||||
* @param comPublicHalfDto
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult checkOrder(String phoneMd5, String channelSign) {
|
||||
//根据手机号MD5渠道标识 查询是否成功
|
||||
R<Customer> customerInfoByPhoneMd5 = remoteCustomerService.getCustomerInfoByPhoneMd5(phoneMd5, SecurityConstants.INNER);
|
||||
Channel channel = redisService.getCacheObject(CacheConstants.CHANNEL_ID + customerInfoByPhoneMd5.getData().getChannelId());
|
||||
R<Boolean> booleanR = remoteCustomerApplyLogService.customerApply(customerInfoByPhoneMd5.getData().getId(), SecurityConstants.INNER);
|
||||
//失败直接失败
|
||||
if (!booleanR.getData()){
|
||||
return AjaxResult.success("用户未申请","false");
|
||||
}
|
||||
//成功抽奖 按扣量比抽
|
||||
//成功数
|
||||
double succ = channel.getScore()*0.01;
|
||||
//扣量数
|
||||
double socre = 1-(channel.getScore()*0.01);
|
||||
List<Double> drow = new ArrayList<>();
|
||||
drow.add(succ);
|
||||
drow.add(socre);
|
||||
int draw = ProbitUtil.draw(drow);
|
||||
//返回是否成功
|
||||
return draw==0?AjaxResult.success("用户已申请",true):AjaxResult.success("用户未申请","false");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
CustomerInfoDto customerInfoDto = new CustomerInfoDto();
|
||||
customerInfoDto.setPhoneMd5("331d17d1ca8a091410e3238fab16a863");
|
||||
customerInfoDto.setPhone("15205600635");
|
||||
customerInfoDto.setSex(0);
|
||||
customerInfoDto.setNameMd5("331d17d1ca8a091410e3238fab16a863");
|
||||
customerInfoDto.setName("朱三");
|
||||
customerInfoDto.setAge(18);
|
||||
customerInfoDto.setIdCardMd5("331d17d1ca8a091410e3238fab16a863");
|
||||
customerInfoDto.setIdCard("341202199306023511");
|
||||
customerInfoDto.setCity("重庆");
|
||||
customerInfoDto.setCityCode(1000);
|
||||
customerInfoDto.setSocialSecurity(1);
|
||||
customerInfoDto.setAccumulationFund(1);
|
||||
customerInfoDto.setCar(1);
|
||||
customerInfoDto.setHourse(1);
|
||||
customerInfoDto.setGuarantee(1);
|
||||
customerInfoDto.setZhiMa(600);
|
||||
customerInfoDto.setCareer(1);
|
||||
customerInfoDto.setCreditCard(1);
|
||||
customerInfoDto.setEducation(1);
|
||||
customerInfoDto.setMonthlyIncome(5000);
|
||||
System.out.println(JSONObject.toJSONString(customerInfoDto));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
Spring Boot Version: ${spring-boot.version}
|
||||
Spring Application Name: ${spring.application.name}
|
||||
_ __ _ _
|
||||
(_) / _|(_)| |
|
||||
_ __ _ _ ___ _ _ _ ______ | |_ _ | | ___
|
||||
| '__|| | | | / _ \ | | | || ||______|| _|| || | / _ \
|
||||
| | | |_| || (_) || |_| || | | | | || || __/
|
||||
|_| \__,_| \___/ \__, ||_| |_| |_||_| \___|
|
||||
__/ |
|
||||
|___/
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# Tomcat
|
||||
server:
|
||||
port: 9301
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: ruoyi-btc
|
||||
profiles:
|
||||
# 环境配置
|
||||
active: dev
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 47.109.135.151:8848
|
||||
namespace: b8ad3fd2-18ea-4cdf-a82c-4ce483392b1a
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 47.109.135.151:8848
|
||||
namespace: b8ad3fd2-18ea-4cdf-a82c-4ce483392b1a
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
shared-configs:
|
||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="logs/ruoyi-file" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统日志输出 -->
|
||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/info.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>INFO</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/error.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>ERROR</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 系统模块日志级别控制 -->
|
||||
<logger name="com.ruoyi" level="info" />
|
||||
<!-- Spring日志级别控制 -->
|
||||
<logger name="org.springframework" level="warn" />
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="file_info" />
|
||||
<appender-ref ref="file_error" />
|
||||
</root>
|
||||
</configuration>
|
||||
|
|
@ -15,15 +15,6 @@ public class RuoYiFileApplication
|
|||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(RuoYiFileApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ 文件服务模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||
" .-------. ____ __ \n" +
|
||||
" | _ _ \\ \\ \\ / / \n" +
|
||||
" | ( ' ) | \\ _. / ' \n" +
|
||||
" |(_ o _) / _( )_ .' \n" +
|
||||
" | (_,_).' __ ___(_ o _)' \n" +
|
||||
" | |\\ \\ | || |(_,_)' \n" +
|
||||
" | | \\ `' /| `-' / \n" +
|
||||
" | | \\ / \\ / \n" +
|
||||
" ''-' `'-' `-..-' ");
|
||||
System.out.println("(♥◠‿◠)ノ゙ 文件服务模块启动成功 ლ(´ڡ`ლ)゙ \n");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,82 +1,82 @@
|
|||
package com.ruoyi.file.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import io.minio.MinioClient;
|
||||
|
||||
/**
|
||||
* Minio 配置信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "minio")
|
||||
public class MinioConfig
|
||||
{
|
||||
/**
|
||||
* 服务地址
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* 存储桶名称
|
||||
*/
|
||||
private String bucketName;
|
||||
|
||||
public String getUrl()
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url)
|
||||
{
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getAccessKey()
|
||||
{
|
||||
return accessKey;
|
||||
}
|
||||
|
||||
public void setAccessKey(String accessKey)
|
||||
{
|
||||
this.accessKey = accessKey;
|
||||
}
|
||||
|
||||
public String getSecretKey()
|
||||
{
|
||||
return secretKey;
|
||||
}
|
||||
|
||||
public void setSecretKey(String secretKey)
|
||||
{
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
|
||||
public String getBucketName()
|
||||
{
|
||||
return bucketName;
|
||||
}
|
||||
|
||||
public void setBucketName(String bucketName)
|
||||
{
|
||||
this.bucketName = bucketName;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MinioClient getMinioClient()
|
||||
{
|
||||
return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
|
||||
}
|
||||
}
|
||||
package com.ruoyi.file.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import io.minio.MinioClient;
|
||||
|
||||
/**
|
||||
* Minio 配置信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "minio")
|
||||
public class MinioConfig
|
||||
{
|
||||
/**
|
||||
* 服务地址
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* 存储桶名称
|
||||
*/
|
||||
private String bucketName;
|
||||
|
||||
public String getUrl()
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url)
|
||||
{
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getAccessKey()
|
||||
{
|
||||
return accessKey;
|
||||
}
|
||||
|
||||
public void setAccessKey(String accessKey)
|
||||
{
|
||||
this.accessKey = accessKey;
|
||||
}
|
||||
|
||||
public String getSecretKey()
|
||||
{
|
||||
return secretKey;
|
||||
}
|
||||
|
||||
public void setSecretKey(String secretKey)
|
||||
{
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
|
||||
public String getBucketName()
|
||||
{
|
||||
return bucketName;
|
||||
}
|
||||
|
||||
public void setBucketName(String bucketName)
|
||||
{
|
||||
this.bucketName = bucketName;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MinioClient getMinioClient()
|
||||
{
|
||||
return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,50 +1,50 @@
|
|||
package com.ruoyi.file.config;
|
||||
|
||||
import java.io.File;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* 通用映射配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class ResourcesConfig implements WebMvcConfigurer
|
||||
{
|
||||
/**
|
||||
* 上传文件存储在本地的根路径
|
||||
*/
|
||||
@Value("${file.path}")
|
||||
private String localFilePath;
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
@Value("${file.prefix}")
|
||||
public String localFilePrefix;
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry)
|
||||
{
|
||||
/** 本地文件上传路径 */
|
||||
registry.addResourceHandler(localFilePrefix + "/**")
|
||||
.addResourceLocations("file:" + localFilePath + File.separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启跨域
|
||||
*/
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
// 设置允许跨域的路由
|
||||
registry.addMapping(localFilePrefix + "/**")
|
||||
// 设置允许跨域请求的域名
|
||||
.allowedOrigins("*")
|
||||
// 设置允许的方法
|
||||
.allowedMethods("GET");
|
||||
}
|
||||
package com.ruoyi.file.config;
|
||||
|
||||
import java.io.File;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* 通用映射配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class ResourcesConfig implements WebMvcConfigurer
|
||||
{
|
||||
/**
|
||||
* 上传文件存储在本地的根路径
|
||||
*/
|
||||
@Value("${file.path}")
|
||||
private String localFilePath;
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
@Value("${file.prefix}")
|
||||
public String localFilePrefix;
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry)
|
||||
{
|
||||
/** 本地文件上传路径 */
|
||||
registry.addResourceHandler(localFilePrefix + "/**")
|
||||
.addResourceLocations("file:" + localFilePath + File.separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启跨域
|
||||
*/
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
// 设置允许跨域的路由
|
||||
registry.addMapping(localFilePrefix + "/**")
|
||||
// 设置允许跨域请求的域名
|
||||
.allowedOrigins("*")
|
||||
// 设置允许的方法
|
||||
.allowedMethods("GET");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +1,48 @@
|
|||
package com.ruoyi.file.controller;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.utils.file.FileUtils;
|
||||
import com.ruoyi.file.service.ISysFileService;
|
||||
import com.ruoyi.system.api.domain.SysFile;
|
||||
|
||||
/**
|
||||
* 文件请求处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@RestController
|
||||
public class SysFileController
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
|
||||
|
||||
@Autowired
|
||||
private ISysFileService sysFileService;
|
||||
|
||||
/**
|
||||
* 文件上传请求
|
||||
*/
|
||||
@PostMapping("upload")
|
||||
public R<SysFile> upload(MultipartFile file)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 上传并返回访问地址
|
||||
String url = sysFileService.uploadFile(file);
|
||||
SysFile sysFile = new SysFile();
|
||||
sysFile.setName(FileUtils.getName(url));
|
||||
sysFile.setUrl(url);
|
||||
return R.ok(sysFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("上传文件失败", e);
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
package com.ruoyi.file.controller;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.utils.file.FileUtils;
|
||||
import com.ruoyi.file.service.ISysFileService;
|
||||
import com.ruoyi.system.api.domain.SysFile;
|
||||
|
||||
/**
|
||||
* 文件请求处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@RestController
|
||||
public class SysFileController
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
|
||||
|
||||
@Autowired
|
||||
private ISysFileService sysFileService;
|
||||
|
||||
/**
|
||||
* 文件上传请求
|
||||
*/
|
||||
@PostMapping("upload")
|
||||
public R<SysFile> upload(MultipartFile file)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 上传并返回访问地址
|
||||
String url = sysFileService.uploadFile(file);
|
||||
SysFile sysFile = new SysFile();
|
||||
sysFile.setName(FileUtils.getName(url));
|
||||
sysFile.setUrl(url);
|
||||
return R.ok(sysFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("上传文件失败", e);
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +1,46 @@
|
|||
package com.ruoyi.file.service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
|
||||
import com.github.tobato.fastdfs.service.FastFileStorageClient;
|
||||
import com.ruoyi.common.core.utils.file.FileTypeUtils;
|
||||
|
||||
/**
|
||||
* FastDFS 文件存储
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class FastDfsSysFileServiceImpl implements ISysFileService
|
||||
{
|
||||
/**
|
||||
* 域名或本机访问地址
|
||||
*/
|
||||
@Value("${fdfs.domain}")
|
||||
public String domain;
|
||||
|
||||
@Autowired
|
||||
private FastFileStorageClient storageClient;
|
||||
|
||||
/**
|
||||
* FastDfs文件上传接口
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 访问地址
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public String uploadFile(MultipartFile file) throws Exception
|
||||
{
|
||||
InputStream inputStream = file.getInputStream();
|
||||
StorePath storePath = storageClient.uploadFile(inputStream, file.getSize(),
|
||||
FileTypeUtils.getExtension(file), null);
|
||||
IoUtils.closeQuietly(inputStream);
|
||||
return domain + "/" + storePath.getFullPath();
|
||||
}
|
||||
}
|
||||
package com.ruoyi.file.service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
|
||||
import com.github.tobato.fastdfs.service.FastFileStorageClient;
|
||||
import com.ruoyi.common.core.utils.file.FileTypeUtils;
|
||||
|
||||
/**
|
||||
* FastDFS 文件存储
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class FastDfsSysFileServiceImpl implements ISysFileService
|
||||
{
|
||||
/**
|
||||
* 域名或本机访问地址
|
||||
*/
|
||||
@Value("${fdfs.domain}")
|
||||
public String domain;
|
||||
|
||||
@Autowired
|
||||
private FastFileStorageClient storageClient;
|
||||
|
||||
/**
|
||||
* FastDfs文件上传接口
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 访问地址
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public String uploadFile(MultipartFile file) throws Exception
|
||||
{
|
||||
InputStream inputStream = file.getInputStream();
|
||||
StorePath storePath = storageClient.uploadFile(inputStream, file.getSize(),
|
||||
FileTypeUtils.getExtension(file), null);
|
||||
IoUtils.closeQuietly(inputStream);
|
||||
return domain + "/" + storePath.getFullPath();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
package com.ruoyi.file.service;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 文件上传接口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ISysFileService
|
||||
{
|
||||
/**
|
||||
* 文件上传接口
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 访问地址
|
||||
* @throws Exception
|
||||
*/
|
||||
public String uploadFile(MultipartFile file) throws Exception;
|
||||
}
|
||||
package com.ruoyi.file.service;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 文件上传接口
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ISysFileService
|
||||
{
|
||||
/**
|
||||
* 文件上传接口
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 访问地址
|
||||
* @throws Exception
|
||||
*/
|
||||
public String uploadFile(MultipartFile file) throws Exception;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,50 +1,53 @@
|
|||
package com.ruoyi.file.service;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.file.utils.FileUploadUtils;
|
||||
|
||||
/**
|
||||
* 本地文件存储
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Primary
|
||||
@Service
|
||||
public class LocalSysFileServiceImpl implements ISysFileService
|
||||
{
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
@Value("${file.prefix}")
|
||||
public String localFilePrefix;
|
||||
|
||||
/**
|
||||
* 域名或本机访问地址
|
||||
*/
|
||||
@Value("${file.domain}")
|
||||
public String domain;
|
||||
|
||||
/**
|
||||
* 上传文件存储在本地的根路径
|
||||
*/
|
||||
@Value("${file.path}")
|
||||
private String localFilePath;
|
||||
|
||||
/**
|
||||
* 本地文件上传接口
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 访问地址
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public String uploadFile(MultipartFile file) throws Exception
|
||||
{
|
||||
String name = FileUploadUtils.upload(localFilePath, file);
|
||||
String url = domain + localFilePrefix + name;
|
||||
return url;
|
||||
}
|
||||
}
|
||||
package com.ruoyi.file.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.file.utils.FileUploadUtils;
|
||||
|
||||
/**
|
||||
* 本地文件存储
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Primary
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LocalSysFileServiceImpl implements ISysFileService
|
||||
{
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
@Value("${file.prefix}")
|
||||
public String localFilePrefix;
|
||||
|
||||
/**
|
||||
* 域名或本机访问地址
|
||||
*/
|
||||
@Value("${file.domain}")
|
||||
public String domain;
|
||||
|
||||
/**
|
||||
* 上传文件存储在本地的根路径
|
||||
*/
|
||||
@Value("${file.path}")
|
||||
private String localFilePath;
|
||||
|
||||
/**
|
||||
* 本地文件上传接口
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 访问地址
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public String uploadFile(MultipartFile file) throws Exception
|
||||
{
|
||||
String name = FileUploadUtils.upload(localFilePath, file);
|
||||
String url = domain + localFilePrefix + name;
|
||||
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,49 @@
|
|||
package com.ruoyi.file.service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.ruoyi.file.config.MinioConfig;
|
||||
import com.ruoyi.file.utils.FileUploadUtils;
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.PutObjectArgs;
|
||||
|
||||
/**
|
||||
* Minio 文件存储
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class MinioSysFileServiceImpl implements ISysFileService
|
||||
{
|
||||
@Autowired
|
||||
private MinioConfig minioConfig;
|
||||
|
||||
@Autowired
|
||||
private MinioClient client;
|
||||
|
||||
/**
|
||||
* Minio文件上传接口
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 访问地址
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public String uploadFile(MultipartFile file) throws Exception
|
||||
{
|
||||
String fileName = FileUploadUtils.extractFilename(file);
|
||||
InputStream inputStream = file.getInputStream();
|
||||
PutObjectArgs args = PutObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.object(fileName)
|
||||
.stream(inputStream, file.getSize(), -1)
|
||||
.contentType(file.getContentType())
|
||||
.build();
|
||||
client.putObject(args);
|
||||
IoUtils.closeQuietly(inputStream);
|
||||
return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
|
||||
}
|
||||
}
|
||||
package com.ruoyi.file.service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.ruoyi.file.config.MinioConfig;
|
||||
import com.ruoyi.file.utils.FileUploadUtils;
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.PutObjectArgs;
|
||||
|
||||
/**
|
||||
* Minio 文件存储
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class MinioSysFileServiceImpl implements ISysFileService
|
||||
{
|
||||
@Autowired
|
||||
private MinioConfig minioConfig;
|
||||
|
||||
@Autowired
|
||||
private MinioClient client;
|
||||
|
||||
/**
|
||||
* Minio文件上传接口
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 访问地址
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public String uploadFile(MultipartFile file) throws Exception
|
||||
{
|
||||
String fileName = FileUploadUtils.extractFilename(file);
|
||||
InputStream inputStream = file.getInputStream();
|
||||
PutObjectArgs args = PutObjectArgs.builder()
|
||||
.bucket(minioConfig.getBucketName())
|
||||
.object(fileName)
|
||||
.stream(inputStream, file.getSize(), -1)
|
||||
.contentType(file.getContentType())
|
||||
.build();
|
||||
client.putObject(args);
|
||||
IoUtils.closeQuietly(inputStream);
|
||||
return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,185 +1,185 @@
|
|||
package com.ruoyi.file.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.core.exception.file.FileException;
|
||||
import com.ruoyi.common.core.exception.file.FileNameLengthLimitExceededException;
|
||||
import com.ruoyi.common.core.exception.file.FileSizeLimitExceededException;
|
||||
import com.ruoyi.common.core.exception.file.InvalidExtensionException;
|
||||
import com.ruoyi.common.core.utils.DateUtils;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.core.utils.file.FileTypeUtils;
|
||||
import com.ruoyi.common.core.utils.file.MimeTypeUtils;
|
||||
import com.ruoyi.common.core.utils.uuid.Seq;
|
||||
|
||||
/**
|
||||
* 文件上传工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class FileUploadUtils
|
||||
{
|
||||
/**
|
||||
* 默认大小 50M
|
||||
*/
|
||||
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024L;
|
||||
|
||||
/**
|
||||
* 默认的文件名最大长度 100
|
||||
*/
|
||||
public static final int DEFAULT_FILE_NAME_LENGTH = 100;
|
||||
|
||||
/**
|
||||
* 根据文件路径上传
|
||||
*
|
||||
* @param baseDir 相对应用的基目录
|
||||
* @param file 上传的文件
|
||||
* @return 文件名称
|
||||
* @throws IOException
|
||||
*/
|
||||
public static final String upload(String baseDir, MultipartFile file) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
||||
}
|
||||
catch (FileException fe)
|
||||
{
|
||||
throw new IOException(fe.getDefaultMessage(), fe);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param baseDir 相对应用的基目录
|
||||
* @param file 上传的文件
|
||||
* @param allowedExtension 上传文件类型
|
||||
* @return 返回上传成功的文件名
|
||||
* @throws FileSizeLimitExceededException 如果超出最大大小
|
||||
* @throws FileNameLengthLimitExceededException 文件名太长
|
||||
* @throws IOException 比如读写文件出错时
|
||||
* @throws InvalidExtensionException 文件校验异常
|
||||
*/
|
||||
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
|
||||
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
|
||||
InvalidExtensionException
|
||||
{
|
||||
int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
|
||||
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
|
||||
{
|
||||
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
|
||||
}
|
||||
|
||||
assertAllowed(file, allowedExtension);
|
||||
|
||||
String fileName = extractFilename(file);
|
||||
|
||||
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
|
||||
file.transferTo(Paths.get(absPath));
|
||||
return getPathFileName(fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码文件名
|
||||
*/
|
||||
public static final String extractFilename(MultipartFile file)
|
||||
{
|
||||
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
|
||||
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), FileTypeUtils.getExtension(file));
|
||||
}
|
||||
|
||||
private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
|
||||
{
|
||||
File desc = new File(uploadDir + File.separator + fileName);
|
||||
|
||||
if (!desc.exists())
|
||||
{
|
||||
if (!desc.getParentFile().exists())
|
||||
{
|
||||
desc.getParentFile().mkdirs();
|
||||
}
|
||||
}
|
||||
return desc.isAbsolute() ? desc : desc.getAbsoluteFile();
|
||||
}
|
||||
|
||||
private static final String getPathFileName(String fileName) throws IOException
|
||||
{
|
||||
String pathFileName = "/" + fileName;
|
||||
return pathFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件大小校验
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @throws FileSizeLimitExceededException 如果超出最大大小
|
||||
* @throws InvalidExtensionException 文件校验异常
|
||||
*/
|
||||
public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
|
||||
throws FileSizeLimitExceededException, InvalidExtensionException
|
||||
{
|
||||
long size = file.getSize();
|
||||
if (size > DEFAULT_MAX_SIZE)
|
||||
{
|
||||
throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
|
||||
}
|
||||
|
||||
String fileName = file.getOriginalFilename();
|
||||
String extension = FileTypeUtils.getExtension(file);
|
||||
if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
|
||||
{
|
||||
if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidExtensionException(allowedExtension, extension, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断MIME类型是否是允许的MIME类型
|
||||
*
|
||||
* @param extension 上传文件类型
|
||||
* @param allowedExtension 允许上传文件类型
|
||||
* @return true/false
|
||||
*/
|
||||
public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
|
||||
{
|
||||
for (String str : allowedExtension)
|
||||
{
|
||||
if (str.equalsIgnoreCase(extension))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
package com.ruoyi.file.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.core.exception.file.FileException;
|
||||
import com.ruoyi.common.core.exception.file.FileNameLengthLimitExceededException;
|
||||
import com.ruoyi.common.core.exception.file.FileSizeLimitExceededException;
|
||||
import com.ruoyi.common.core.exception.file.InvalidExtensionException;
|
||||
import com.ruoyi.common.core.utils.DateUtils;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.core.utils.file.FileTypeUtils;
|
||||
import com.ruoyi.common.core.utils.file.MimeTypeUtils;
|
||||
import com.ruoyi.common.core.utils.uuid.Seq;
|
||||
|
||||
/**
|
||||
* 文件上传工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class FileUploadUtils
|
||||
{
|
||||
/**
|
||||
* 默认大小 50M
|
||||
*/
|
||||
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024L;
|
||||
|
||||
/**
|
||||
* 默认的文件名最大长度 100
|
||||
*/
|
||||
public static final int DEFAULT_FILE_NAME_LENGTH = 100;
|
||||
|
||||
/**
|
||||
* 根据文件路径上传
|
||||
*
|
||||
* @param baseDir 相对应用的基目录
|
||||
* @param file 上传的文件
|
||||
* @return 文件名称
|
||||
* @throws IOException
|
||||
*/
|
||||
public static final String upload(String baseDir, MultipartFile file) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
||||
}
|
||||
catch (FileException fe)
|
||||
{
|
||||
throw new IOException(fe.getDefaultMessage(), fe);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param baseDir 相对应用的基目录
|
||||
* @param file 上传的文件
|
||||
* @param allowedExtension 上传文件类型
|
||||
* @return 返回上传成功的文件名
|
||||
* @throws FileSizeLimitExceededException 如果超出最大大小
|
||||
* @throws FileNameLengthLimitExceededException 文件名太长
|
||||
* @throws IOException 比如读写文件出错时
|
||||
* @throws InvalidExtensionException 文件校验异常
|
||||
*/
|
||||
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
|
||||
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
|
||||
InvalidExtensionException
|
||||
{
|
||||
int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
|
||||
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
|
||||
{
|
||||
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
|
||||
}
|
||||
|
||||
assertAllowed(file, allowedExtension);
|
||||
|
||||
String fileName = extractFilename(file);
|
||||
|
||||
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
|
||||
file.transferTo(Paths.get(absPath));
|
||||
return getPathFileName(fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码文件名
|
||||
*/
|
||||
public static final String extractFilename(MultipartFile file)
|
||||
{
|
||||
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
|
||||
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), FileTypeUtils.getExtension(file));
|
||||
}
|
||||
|
||||
private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
|
||||
{
|
||||
File desc = new File(uploadDir + File.separator + fileName);
|
||||
|
||||
if (!desc.exists())
|
||||
{
|
||||
if (!desc.getParentFile().exists())
|
||||
{
|
||||
desc.getParentFile().mkdirs();
|
||||
}
|
||||
}
|
||||
return desc.isAbsolute() ? desc : desc.getAbsoluteFile();
|
||||
}
|
||||
|
||||
private static final String getPathFileName(String fileName) throws IOException
|
||||
{
|
||||
String pathFileName = "/" + fileName;
|
||||
return pathFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件大小校验
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @throws FileSizeLimitExceededException 如果超出最大大小
|
||||
* @throws InvalidExtensionException 文件校验异常
|
||||
*/
|
||||
public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
|
||||
throws FileSizeLimitExceededException, InvalidExtensionException
|
||||
{
|
||||
long size = file.getSize();
|
||||
if (size > DEFAULT_MAX_SIZE)
|
||||
{
|
||||
throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
|
||||
}
|
||||
|
||||
String fileName = file.getOriginalFilename();
|
||||
String extension = FileTypeUtils.getExtension(file);
|
||||
if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
|
||||
{
|
||||
if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidExtensionException(allowedExtension, extension, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断MIME类型是否是允许的MIME类型
|
||||
*
|
||||
* @param extension 上传文件类型
|
||||
* @param allowedExtension 允许上传文件类型
|
||||
* @return true/false
|
||||
*/
|
||||
public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
|
||||
{
|
||||
for (String str : allowedExtension)
|
||||
{
|
||||
if (str.equalsIgnoreCase(extension))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,10 +14,12 @@ spring:
|
|||
nacos:
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 127.0.0.1:8848
|
||||
server-addr: 47.109.135.151:8848
|
||||
namespace: b8ad3fd2-18ea-4cdf-a82c-4ce483392b1a
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 127.0.0.1:8848
|
||||
server-addr: 47.109.135.151:8848
|
||||
namespace: b8ad3fd2-18ea-4cdf-a82c-4ce483392b1a
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
|
|
|
|||
|
|
@ -18,15 +18,6 @@ public class RuoYiGenApplication
|
|||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(RuoYiGenApplication.class, args);
|
||||
System.out.println("(♥◠‿◠)ノ゙ 代码生成模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||
" .-------. ____ __ \n" +
|
||||
" | _ _ \\ \\ \\ / / \n" +
|
||||
" | ( ' ) | \\ _. / ' \n" +
|
||||
" |(_ o _) / _( )_ .' \n" +
|
||||
" | (_,_).' __ ___(_ o _)' \n" +
|
||||
" | |\\ \\ | || |(_,_)' \n" +
|
||||
" | | \\ `' /| `-' / \n" +
|
||||
" | | \\ / \\ / \n" +
|
||||
" ''-' `'-' `-..-' ");
|
||||
System.out.println("(♥◠‿◠)ノ゙ 代码生成模块启动成功 ლ(´ڡ`ლ)゙ \n");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ public class GenUtils
|
|||
*/
|
||||
public static String replaceText(String text)
|
||||
{
|
||||
return RegExUtils.replaceAll(text, "(?:表|若依)", "");
|
||||
return RegExUtils.replaceAll(text, "(?:表|租研舍)", "");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue