Pre Merge pull request !380 from 鲸落/master_zhp
commit
47b9563ddf
@ -1 +0,0 @@
|
||||
custom: http://doc.ruoyi.vip/ruoyi-cloud/other/donate.html
|
@ -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.
|
@ -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,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 @@
|
||||
# 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,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,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,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,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,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,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"]
|
@ -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
|
@ -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,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);
|
||||
// }
|
||||
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
com.ruoyi.common.redis.configure.RedisConfig
|
||||
com.ruoyi.common.redis.service.RedisService
|
||||
com.ruoyi.common.redis.service.CustomerTokenService
|
||||
|
@ -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 @@
|
||||
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,2 @@
|
||||
com.ruoyi.common.sms.XunDaYunXinAutoConfiguration
|
||||
com.ruoyi.common.sms.component.SmsComponent
|
@ -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,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>
|
@ -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;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue