diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f91184ff05898206c69d15e877c0e1105d54e586 --- /dev/null +++ b/README.md @@ -0,0 +1,462 @@ +# 项目环境 + +首先说明一下项目环境: + +| 环境 | 版本号 | +| :------: | :------: | +| Node.js | v14.16.1 | +| MySQL | 5.7.34 | +| JDK | 1.8 | +| Maven | 3.6.3 | +| Nacos | 1.4.0 | +| Redis | 6.2.3 | +| RabbitMQ | 3.8.1 | + +# 环境搭建 + +我们的首要目的是先让项目跑起来,所以接下来将介绍项目中用到的各种环境的搭建方法。 + +## Redis + +如果自己会搭建Redis环境的可以跳过这一节,如果不会的,我建议你使用Docker进行环境搭建,所以我们首先需要在CentOS7下安装Docker。 + +首先卸载旧版本的Docker: + +```shell +sudo yum remove docker \ + docker-client \ + docker-client-latest \ + docker-common \ + docker-latest \ + docker-latest-logrotate \ + docker-logrotate \ + docker-engine +``` + +然后安装Docker依赖: + +```shell +sudo yum install -y yum-utils +``` + +接着配置地址: + +```shell +sudo yum-config-manager \ + --add-repo \ + https://download.docker.com/linux/centos/docker-ce.repo +``` + +此时即可安装Docker: + +```shell +sudo yum install docker-ce docker-ce-cli containerd.io +``` + +安装完成后启动Docker服务: + +```shell +sudo systemctl start docker +``` + +最后让Docker开启自启动: + +```shell +sudo systemctl enable docker +``` + +--- + +然后安装Redis,首先下载Redis的镜像: + +```shell +docker pull redis +``` + +创建目录结构: + +```shell +mkdir -p /mydata/redis/conf +touch /mydata/redis/conf/redis.conf +``` + +创建Redis的实例并启动: + +```shell +docker run -p 6379:6379 --name redis\ + -v /mydata/redis/data:/data\ + -v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf\ + -d redis redis-server /etc/redis/redis.conf +``` + +使用该命令即可操作Redis客户端: + +```shell +docker exec -it redis redis-cli +``` + +现在的Redis是不支持数据持久化的,所以来到/mydata/redis/conf目录下,修改redis.conf文件: + +```shell +appendonly yes +``` + +然后重启Redis: + +```shell +docker restart redis +``` + +配置一下使Redis随着Docker的启动而启动: + +```shell +docker update redis --restart=always +``` + +--- + +现在我们将CentOS7的防火墙关闭,以免产生一些不必要的麻烦: + +```shell +systemctl stop firewalld +``` + +## RabbitMQ + +仍然使用Docker下载RabbitMQ: + +```shell +docker pull rabbitmq:3.8.1-management +``` + +创建目录结构: + +```shell +cd /mydata +mkdir -p /rabbitmq/data +``` + +然后启动RabbitMQ: + +```shell +docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -v /mydata/rabbitmq/data:/var/lib/rabbitmq --hostname myRabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin rabbitmq:3.8.1-management +``` + +让RabbitMQ随着Docker的启动而启动: + +```shell +docker update rabbitmq --restart=always +``` + +访问[http://192.168.56.10:15672/#/users](http://192.168.56.10:15672/#/users): + +![img](https://img-blog.csdnimg.cn/20210514124725232.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +用户名和密码均为`admin` ,进入到后台管理页面后,添加一个用户: + +![img](https://img-blog.csdnimg.cn/20210514124927616.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +如果你没有学习过RabbitMQ的相关知识,请保持和我的配置一致,点击左下角的`Add user` 即可完成添加。 + +然后添加一下虚拟机: + +![img](https://img-blog.csdnimg.cn/20210514125239528.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +需要注意`/srb-host` 前面的`/` 是一定要有的,填写完成后点击`Add virtual host` ,接着点击创建好的用户进行权限设置: + +![img](https://img-blog.csdnimg.cn/202105141254048.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +此处选择`my_vhost`: + +![img](https://img-blog.csdnimg.cn/20210514125438664.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +最后点击`Set permission`即可,以同样的方式将`/srb-host`虚拟机权限也添加进去: + +![img](https://img-blog.csdnimg.cn/20210514125959473.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +## Nacos + +本项目使用了Nacos作为服务的注册中心,所以我们需要下载Nacos,下载地址:[https://github.com/alibaba/nacos/releases/tag/1.4.0](https://github.com/alibaba/nacos/releases/tag/1.4.0),网页拉到底部: + +![img](https://img-blog.csdnimg.cn/20210512205355786.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +下载以tar.gz为后缀的压缩包,若是想将其部署在Windows上,就下载zip压缩包,部署方式是一样的。 + +下载完成后将其上传至CentOS7,并启动(在Nacos的bin目录下启动): + +```shell +cd nacos +cd bin +./startup.sh -m standalone +``` + +Nacos的启动需要JDK的支持,所以你的CentOS7中必须有JDK的环境,至于JDK的环境在这里就不赘述了。 + +## 阿里云短信服务 + +本项目对接了阿里云的短信服务,所以我们需要在阿里云开通一下短信服务,来到官网:[https://www.aliyun.com/](https://www.aliyun.com/),在首页搜索短信服务,进入短信服务控制台: + +![img](https://img-blog.csdnimg.cn/20210512210105108.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +然后进行短信申请: + +![img](https://img-blog.csdnimg.cn/20210512210159976.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +不过阿里云平台对短信的申请审核力度非常大,很有可能你是申请不到短信服务的,至于怎么解决这一问题我们一会说。 + +## 阿里云OSS对象存储服务 + +本项目对接了阿里云的OSS对象存储服务用于实现图片的存取,开通方式也非常简单,首页搜索对象存储,点击对象存储OSS控制台: + +![img](https://img-blog.csdnimg.cn/20210512210521922.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +按照提示进行开通即可,至于接入细节后面再说。 + +# 启动项目 + +一切准备就绪后,我们就可以启动项目了,本系统共分为四个项目: + +1. 后台接口:[https://gitee.com/blizzawang/srb](https://gitee.com/blizzawang/srb) +2. 后台管理页面:[https://gitee.com/blizzawang/srb-admin](https://gitee.com/blizzawang/srb-admin) +3. 用户前端页面:[https://gitee.com/blizzawang/srb-site](https://gitee.com/blizzawang/srb-site) +4. 支付系统: + +其中后台接口和支付系统都是使用SpringBoot开发的项目,后台管理页面和用户前端页面是使用Vue + ElementUI进行开发的,我们先来启动一下前端项目,将前端项目克隆到本地后,执行指令: + +```shell +npm install +npm run dev +``` + +这就是后台管理页面: + +![img](https://img-blog.csdnimg.cn/20210512211426335.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +它将管理本系统中的所有数据,然后以同样的方式启动用户前端项目: + +![img](https://img-blog.csdnimg.cn/20210512211601978.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +接下来就该启动后台接口项目了,在启动之前,我们需要修改一些配置,首先修改`service-core` 服务下的`application.yml` 文件: + +![img](https://img-blog.csdnimg.cn/20210514134130985.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +然后修改`service-gateway`服务的配置文件: + +![img](https://img-blog.csdnimg.cn/20210512212501588.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +接着是`service-oss`服务的配置文件: + +![img](https://img-blog.csdnimg.cn/2021051221243530.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +这里需要配置阿里云对象存储服务的相关内容,所以我们打开阿里云的对象存储服务控制台,点击左侧的Bucket列表: + +![img](https://img-blog.csdnimg.cn/20210512212552995.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +选择创建一个bucket: + +![img](https://img-blog.csdnimg.cn/20210512212647253.png) + +Bucket名称可以随意填写,读写权限选择公共读: + +![img](https://img-blog.csdnimg.cn/20210512212814805.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +创建完成后会得到一个Bucket,点击创建好的Bucket: + +![img](https://img-blog.csdnimg.cn/20210512212956256.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +点击左侧的概览: + +![img](https://img-blog.csdnimg.cn/20210512213027211.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +此处便会有endpoint的属性值: + +![img](https://img-blog.csdnimg.cn/20210512213122469.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +而keyId和keySecret是你在创建对象存储服务时需要创建一个子账户,这就是子账户的keyId和keySecret,bucketName就是刚刚创建Bucket时填写的Bucket名称。 + +最后我们来修改`service-sms` 服务的配置文件: + +![img](https://img-blog.csdnimg.cn/20210514134324786.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +将申请好的短信模板编号和名称填入即可,若是无法申请到短信,则我们可以在Redis中直接查看验证码,因为验证码会被存储到Redis中。 + +最后启动支付项目,它为整个系统提供了支付功能,该项目同样需要修改配置文件: + +![img](https://img-blog.csdnimg.cn/20210512213748639.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +全部修改完成后,我们需要将数据库表导入一下,在这两个项目的根路径下分别有一个`.sql`文件,将它们分别导入一下,最后就可以启动这两个项目了,启动的服务如下: + +* ServiceCoreApplication +* ServiceGatewayApplication +* ServiceOssApplication +* ServiceSmsApplication +* ManageApplication + +# 项目介绍 + +![img](https://img-blog.csdnimg.cn/20210514080421360.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +本项目是一个借贷系统,系统中共有三个角色,借款人、投资人和管理员,其中借款人通过该系统发起借款,管理员需要层层审核借款人的相关信息才能允与借款,投资人选择合适的项目进行投资赚取利息。 + +具体操作流程如下,首先在首页右上角点击`免费注册` : + +![img](https://img-blog.csdnimg.cn/2021051413040080.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +注册之前需要获取验证码,验证码会同步存储到Redis中,所以我们在Redis中直接查看即可: + +![img](https://img-blog.csdnimg.cn/20210514130444389.png) + +这样我们就注册好了一个投资人,接着登录到系统: + +![img](https://img-blog.csdnimg.cn/20210514130532345.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +此时系统会提示我们去开通第三方账户: + +![img](https://img-blog.csdnimg.cn/20210514130620699.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +点击立即开通会跳转至开户页面: + +![img](https://img-blog.csdnimg.cn/20210514130655510.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +填写好信息后,点击开户,此时页面会跳转至第三方平台汇付宝: + +![img](https://img-blog.csdnimg.cn/20210514130817844.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +这里校验手机的功能并没有实现,有兴趣的同学可以尝试做一下,重要的是下面的支付密码,它将贯穿我们后面的流程,所以设置完后一定要记住它。 + +绑定成功后会回到用户中心,此时系统会显示我们的账户详情: + +![img](https://img-blog.csdnimg.cn/20210514131004809.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +点击充值会跳转至充值页面: + +![img](https://img-blog.csdnimg.cn/20210514131040811.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +输入充值金额,点击充值,此时会前往汇付宝进行付款: + +![img](https://img-blog.csdnimg.cn/2021051413112798.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +输入我们在绑定第三方账户时设置的支付密码即可完成充值,现在我们的投资人账户中就有了20万的余额: + +![img](https://img-blog.csdnimg.cn/20210514131221720.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +--- + +接下来我们创建借款人账户,点击右上角退出登录,然后重新进行注册: + +![img](https://img-blog.csdnimg.cn/20210514131332480.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +记得选中`我要借钱`,注册完成后登录到系统,以同样的方式进行开户: + +![img](https://img-blog.csdnimg.cn/20210514131437149.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +开户完成后,我们可以在用户中心选择借钱: + +![img](https://img-blog.csdnimg.cn/20210514131501111.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +点击`立即借款`后会跳转至借款页面: + +![img](https://img-blog.csdnimg.cn/20210514131702236.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +我们需要填写并上传相关信息,提交过后会进入审核状态: + +![img](https://img-blog.csdnimg.cn/20210514131753500.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +此时我们需要进入后台管理系统对借款申请进行审核,访问[http://localhost:9528/](http://localhost:9528/),输入用户名和密码进入系统(用户名密码均为`admin`): + +![img](https://img-blog.csdnimg.cn/2021051413192228.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +点击左侧菜单栏的借款人列表: + +![img](https://img-blog.csdnimg.cn/20210514132008679.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +即可对刚才的借款申请进行审批: + +![img](https://img-blog.csdnimg.cn/20210514132105280.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +此处会看到刚才的借款人提交的信息,根据信息的有效性对其进行一个积分的评判,点击确定后审批就完成了。 + +此时借款人就可以进行借款了: + +![img](https://img-blog.csdnimg.cn/20210514132157427.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +点击`我要借款`跳转至借款页面: + +![img](https://img-blog.csdnimg.cn/20210514132250112.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +输入相关信息,点击提交,此时又会进入审核状态: + +![img](https://img-blog.csdnimg.cn/20210514132307856.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +我们需要在后台系统中对其进行审核: + +![img](https://img-blog.csdnimg.cn/20210514132355190.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +点击左侧菜单栏的借款列表,对刚刚的借款申请进行审批: + +![img](https://img-blog.csdnimg.cn/20210514132438808.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +为这次借款标的起一个名字,然后设置起息日、服务费率等,点击确定后审批就通过了,此时借款人的借款就成功开始了: + +![img](https://img-blog.csdnimg.cn/20210514132533735.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +我们重新登录上投资人的账户,然后点击右上角的`我要投资`: + +![img](https://img-blog.csdnimg.cn/2021051413262577.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +在底部即可看到刚刚借款人申请的医疗贷: + +![img](https://img-blog.csdnimg.cn/20210514132707221.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +点击进入后,我们可以选择对其进行投资: + +![img](https://img-blog.csdnimg.cn/20210514132812843.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +此处会计算出本次投资可以得到多少收益,点击`立即投资`会跳转至汇付宝进行转账业务。 + +该页面也会展示当前的投资进度,我们再投一笔,将其投满: + +![img](https://img-blog.csdnimg.cn/20210514132915596.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +此时观察投资人的账户详情: + +![img](https://img-blog.csdnimg.cn/20210514133001803.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +会发现被冻结了10万元,这是因为投资项目完成后还需要等待平台放款才会真正地将钱款交给借款人,所以来到后台管理系统: + +![img](https://img-blog.csdnimg.cn/20210514133134107.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +点击左侧菜单栏的标的列表,即可在此处进行放款,点击查看还可以看到本次标的的详细信息。 + +放款完成后,查看投资人的账户: + +![img](https://img-blog.csdnimg.cn/202105141332479.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +标的也进入还款流程: + +![img](https://img-blog.csdnimg.cn/20210514133301370.png) + +投资人还能够看到还款的详情: + +![img](https://img-blog.csdnimg.cn/20210514133351801.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +此时我们再将用户切换至借款人: + +![img](https://img-blog.csdnimg.cn/20210514133436615.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +借款人收到了98750元,这是因为平台收取了服务费,借款人之后可以在标的详情中进行还款: + +![img](https://img-blog.csdnimg.cn/20210514133545614.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +点击还款按钮进行还款: + +![img](https://img-blog.csdnimg.cn/20210514133647297.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +还款两期后,查看借款人和投资人的账户详情: + +![img](https://img-blog.csdnimg.cn/20210514133729901.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +![img](https://img-blog.csdnimg.cn/20210514133804101.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNDUzMTE3,size_16,color_FFFFFF,t_70) + +以上便是系统使用的整个流程。 + diff --git a/pom.xml b/pom.xml index 6dab757092211728047f97568072b63a64e6ca72..0b3291b87515dbd434f1727be510b27b5c608a05 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,7 @@ service-oss service-sms service-gateway + rabbit-mq org.springframework.boot diff --git a/rabbit-mq/pom.xml b/rabbit-mq/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..39b9c31a20e478b6d158cd8e7a2f184fbd694af0 --- /dev/null +++ b/rabbit-mq/pom.xml @@ -0,0 +1,33 @@ + + + + srb + com.wwj + 0.0.1-SNAPSHOT + + 4.0.0 + + rabbit-mq + + + 8 + 8 + + + + + org.springframework.boot + spring-boot-starter-amqp + + + com.alibaba + fastjson + + + org.projectlombok + lombok + + + \ No newline at end of file diff --git a/rabbit-mq/src/main/java/com/wwj/srb/rabbitutil/config/MQConfig.java b/rabbit-mq/src/main/java/com/wwj/srb/rabbitutil/config/MQConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..85eaa444b23d3c0069862fae4bc839e7f3293ec8 --- /dev/null +++ b/rabbit-mq/src/main/java/com/wwj/srb/rabbitutil/config/MQConfig.java @@ -0,0 +1,16 @@ +package com.wwj.srb.rabbitutil.config; + +import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MQConfig { + + @Bean + public MessageConverter messageConverter() { + // json字符串转换器 + return new Jackson2JsonMessageConverter(); + } +} diff --git a/rabbit-mq/src/main/java/com/wwj/srb/rabbitutil/constant/MQConst.java b/rabbit-mq/src/main/java/com/wwj/srb/rabbitutil/constant/MQConst.java new file mode 100644 index 0000000000000000000000000000000000000000..9ac3774aa0c7f720ca0ba31900b8223b6826e01d --- /dev/null +++ b/rabbit-mq/src/main/java/com/wwj/srb/rabbitutil/constant/MQConst.java @@ -0,0 +1,8 @@ +package com.wwj.srb.rabbitutil.constant; + +public class MQConst { + + public static final String EXCHANGE_TOPIC_SMS = "exchange.topic.sms";//交换机 + public static final String ROUTING_SMS_ITEM = "routing.sms.item";//路由 + public static final String QUEUE_SMS_ITEM = "queue.sms.item";//消息队列 +} diff --git a/rabbit-mq/src/main/java/com/wwj/srb/rabbitutil/service/MQService.java b/rabbit-mq/src/main/java/com/wwj/srb/rabbitutil/service/MQService.java new file mode 100644 index 0000000000000000000000000000000000000000..41d9c1049f70674f450238d55846b742592032d1 --- /dev/null +++ b/rabbit-mq/src/main/java/com/wwj/srb/rabbitutil/service/MQService.java @@ -0,0 +1,27 @@ +package com.wwj.srb.rabbitutil.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.core.AmqpTemplate; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Service +@Slf4j +public class MQService { + + @Resource + private AmqpTemplate amqpTemplate; + + /** + * 发送消息 + * @param exchange 交换机 + * @param routingKey 路由 + * @param message 消息 + */ + public boolean sendMessage(String exchange, String routingKey, Object message) { + log.info("发送消息..........."); + amqpTemplate.convertAndSend(exchange, routingKey, message); + return true; + } +} diff --git a/service-base/src/main/java/com/wwj/srb/base/dto/SmsDTO.java b/service-base/src/main/java/com/wwj/srb/base/dto/SmsDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..e9855b31683903cceb9f935a9a1fb05896c5a783 --- /dev/null +++ b/service-base/src/main/java/com/wwj/srb/base/dto/SmsDTO.java @@ -0,0 +1,16 @@ +package com.wwj.srb.base.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(description = "短信") +public class SmsDTO { + + @ApiModelProperty(value = "手机号") + private String mobile; + + @ApiModelProperty(value = "消息内容") + private String message; +} \ No newline at end of file diff --git a/service-core/pom.xml b/service-core/pom.xml index 4d58d3344f23645208e7edf5886de348468fe429..e5560d4c89707b08860a09fb21c5276f96976308 100644 --- a/service-core/pom.xml +++ b/service-core/pom.xml @@ -51,6 +51,12 @@ org.apache.xmlbeans xmlbeans + + + com.wwj + rabbit-mq + 0.0.1-SNAPSHOT + diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/LendItemController.java b/service-core/src/main/java/com/wwj/srb/core/controller/LendItemController.java deleted file mode 100644 index 30c016dac15e211708627923f2618fd9e7ba66eb..0000000000000000000000000000000000000000 --- a/service-core/src/main/java/com/wwj/srb/core/controller/LendItemController.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.wwj.srb.core.controller; - - -import org.springframework.web.bind.annotation.RequestMapping; - -import org.springframework.web.bind.annotation.RestController; - -/** - *

- * 标的出借记录表 前端控制器 - *

- * - * @author wangweijun - * @since 2021-04-27 - */ -@RestController -@RequestMapping("/lendItem") -public class LendItemController { - -} - diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/LendItemReturnController.java b/service-core/src/main/java/com/wwj/srb/core/controller/LendItemReturnController.java deleted file mode 100644 index f9b8037f63f9826e4ec12123640c908c71302bc3..0000000000000000000000000000000000000000 --- a/service-core/src/main/java/com/wwj/srb/core/controller/LendItemReturnController.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.wwj.srb.core.controller; - - -import org.springframework.web.bind.annotation.RequestMapping; - -import org.springframework.web.bind.annotation.RestController; - -/** - *

- * 标的出借回款记录表 前端控制器 - *

- * - * @author wangweijun - * @since 2021-04-27 - */ -@RestController -@RequestMapping("/lendItemReturn") -public class LendItemReturnController { - -} - diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/LendReturnController.java b/service-core/src/main/java/com/wwj/srb/core/controller/LendReturnController.java deleted file mode 100644 index ef2b1cc3603fda9c1de9e1e01ae6b8f6919fc2bb..0000000000000000000000000000000000000000 --- a/service-core/src/main/java/com/wwj/srb/core/controller/LendReturnController.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.wwj.srb.core.controller; - - -import org.springframework.web.bind.annotation.RequestMapping; - -import org.springframework.web.bind.annotation.RestController; - -/** - *

- * 还款记录表 前端控制器 - *

- * - * @author wangweijun - * @since 2021-04-27 - */ -@RestController -@RequestMapping("/lendReturn") -public class LendReturnController { - -} - diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/TransFlowController.java b/service-core/src/main/java/com/wwj/srb/core/controller/TransFlowController.java deleted file mode 100644 index bec1794389f6c042fec8e0a7efd25c373611d984..0000000000000000000000000000000000000000 --- a/service-core/src/main/java/com/wwj/srb/core/controller/TransFlowController.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.wwj.srb.core.controller; - - -import org.springframework.web.bind.annotation.RequestMapping; - -import org.springframework.web.bind.annotation.RestController; - -/** - *

- * 交易流水表 前端控制器 - *

- * - * @author wangweijun - * @since 2021-04-27 - */ -@RestController -@RequestMapping("/transFlow") -public class TransFlowController { - -} - diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/admin/AdminLendController.java b/service-core/src/main/java/com/wwj/srb/core/controller/admin/AdminLendController.java index 5c207036733ce8d9cacb770f64203ef94c665151..aaa34f49664e699f0536c2a7de93fe973bcb9ebe 100644 --- a/service-core/src/main/java/com/wwj/srb/core/controller/admin/AdminLendController.java +++ b/service-core/src/main/java/com/wwj/srb/core/controller/admin/AdminLendController.java @@ -49,5 +49,14 @@ public class AdminLendController { Map result = lendService.getLendDetail(id); return R.ok().data("lendDetail", result); } + + @ApiOperation("放款") + @GetMapping("/makeLoan/{id}") + public R makeLoan( + @ApiParam(value = "标的id", required = true) + @PathVariable("id") Long id) { + lendService.makeLoan(id); + return R.ok().message("放款成功"); + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/admin/AdminLendItemController.java b/service-core/src/main/java/com/wwj/srb/core/controller/admin/AdminLendItemController.java new file mode 100644 index 0000000000000000000000000000000000000000..d77b316b9a4cf90ad45c1377fc67043fee565504 --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/controller/admin/AdminLendItemController.java @@ -0,0 +1,35 @@ +package com.wwj.srb.core.controller.admin; + +import com.wwj.common.result.R; +import com.wwj.srb.core.pojo.entity.LendItem; +import com.wwj.srb.core.service.LendItemService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +@Api(tags = "标的的投资") +@RestController +@RequestMapping("/admin/core/lendItem") +@Slf4j +public class AdminLendItemController { + + @Resource + private LendItemService lendItemService; + + @ApiOperation("获取列表") + @GetMapping("/list/{lendId}") + public R list( + @ApiParam(value = "标的id", required = true) + @PathVariable Long lendId) { + List list = lendItemService.selectByLendId(lendId); + return R.ok().data("list", list); + } +} diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/admin/AdminLendReturnController.java b/service-core/src/main/java/com/wwj/srb/core/controller/admin/AdminLendReturnController.java new file mode 100644 index 0000000000000000000000000000000000000000..fc7f26fce4368b259c67bc1f78ce9679c92942fa --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/controller/admin/AdminLendReturnController.java @@ -0,0 +1,35 @@ +package com.wwj.srb.core.controller.admin; + +import com.wwj.common.result.R; +import com.wwj.srb.core.pojo.entity.LendReturn; +import com.wwj.srb.core.service.LendReturnService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +@Api(tags = "还款记录") +@RestController +@RequestMapping("/admin/core/lendReturn") +@Slf4j +public class AdminLendReturnController { + + @Resource + private LendReturnService lendReturnService; + + @ApiOperation("获取列表") + @GetMapping("/list/{lendId}") + public R list( + @ApiParam(value = "标的id", required = true) + @PathVariable Long lendId) { + List list = lendReturnService.selectByLendId(lendId); + return R.ok().data("list", list); + } +} diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/api/LendController.java b/service-core/src/main/java/com/wwj/srb/core/controller/api/LendController.java index 7c9a703163b1aa580d7c3f16e230c5780f13007c..45c52ee1eb71a5dae757287a17c4f81efdf583c9 100644 --- a/service-core/src/main/java/com/wwj/srb/core/controller/api/LendController.java +++ b/service-core/src/main/java/com/wwj/srb/core/controller/api/LendController.java @@ -6,13 +6,17 @@ import com.wwj.srb.core.pojo.entity.Lend; import com.wwj.srb.core.service.LendService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.List; +import java.util.Map; /** *

@@ -37,5 +41,33 @@ public class LendController { List lendList = lendService.selectList(); return R.ok().data("lendList", lendList); } + + @ApiOperation("获取标的信息") + @GetMapping("/show/{id}") + public R show( + @ApiParam(value = "标的id", required = true) + @PathVariable Long id) { + Map lendDetail = lendService.getLendDetail(id); + return R.ok().data("lendDetail", lendDetail); + } + + @ApiOperation("计算投资收益") + @GetMapping("/getInterestCount/{invest}/{yearRate}/{totalmonth}/{returnMethod}") + public R getInterestCount( + @ApiParam(value = "投资金额", required = true) + @PathVariable("invest") BigDecimal invest, + + @ApiParam(value = "年化收益", required = true) + @PathVariable("yearRate")BigDecimal yearRate, + + @ApiParam(value = "期数", required = true) + @PathVariable("totalmonth")Integer totalmonth, + + @ApiParam(value = "还款方式", required = true) + @PathVariable("returnMethod")Integer returnMethod) { + + BigDecimal interestCount = lendService.getInterestCount(invest, yearRate, totalmonth, returnMethod); + return R.ok().data("interestCount", interestCount); + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/api/LendItemController.java b/service-core/src/main/java/com/wwj/srb/core/controller/api/LendItemController.java new file mode 100644 index 0000000000000000000000000000000000000000..387970329fba4dd58a16aa9b083ce6ddc1559937 --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/controller/api/LendItemController.java @@ -0,0 +1,84 @@ +package com.wwj.srb.core.controller.api; + + +import com.alibaba.fastjson.JSON; +import com.wwj.common.result.R; +import com.wwj.srb.base.util.JwtUtils; +import com.wwj.srb.core.hfb.RequestHelper; +import com.wwj.srb.core.pojo.entity.LendItem; +import com.wwj.srb.core.pojo.vo.InvestVO; +import com.wwj.srb.core.service.LendItemService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Map; + +/** + *

+ * 标的出借记录表 前端控制器 + *

+ * + * @author wangweijun + * @since 2021-04-27 + */ +@Api(tags = "标的投资") +@RestController +@RequestMapping("/api/core/lendItem") +@Slf4j +public class LendItemController { + + @Resource + LendItemService lendItemService; + + @ApiOperation("会员投资提交数据") + @PostMapping("/auth/commitInvest") + public R commitInvest(@RequestBody InvestVO investVO, HttpServletRequest request) { + + String token = request.getHeader("token"); + Long userId = JwtUtils.getUserId(token); + String userName = JwtUtils.getUserName(token); + investVO.setInvestUserId(userId); + investVO.setInvestName(userName); + + //构建充值自动提交表单 + String formStr = lendItemService.commitInvest(investVO); + return R.ok().data("formStr", formStr); + } + + @ApiOperation("会员投资异步回调") + @PostMapping("/notify") + public String notify(HttpServletRequest request) { + + Map paramMap = RequestHelper.switchMap(request.getParameterMap()); + log.info("用户投资异步回调:" + JSON.toJSONString(paramMap)); + + //校验签名 P2pInvestNotifyVo + if(RequestHelper.isSignEquals(paramMap)) { + if("0001".equals(paramMap.get("resultCode"))) { + lendItemService.notify(paramMap); + } else { + log.info("用户投资异步回调失败:" + JSON.toJSONString(paramMap)); + return "fail"; + } + } else { + log.info("用户投资异步回调签名错误:" + JSON.toJSONString(paramMap)); + return "fail"; + } + return "success"; + } + + @ApiOperation("获取列表") + @GetMapping("/list/{lendId}") + public R list( + @ApiParam(value = "标的id", required = true) + @PathVariable Long lendId) { + List list = lendItemService.selectByLendId(lendId); + return R.ok().data("list", list); + } +} \ No newline at end of file diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/api/LendItemReturnController.java b/service-core/src/main/java/com/wwj/srb/core/controller/api/LendItemReturnController.java new file mode 100644 index 0000000000000000000000000000000000000000..efa76a971f25b8e85c7a10bb82fefef36f4bab5a --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/controller/api/LendItemReturnController.java @@ -0,0 +1,50 @@ +package com.wwj.srb.core.controller.api; + + +import com.wwj.common.result.R; +import com.wwj.srb.base.util.JwtUtils; +import com.wwj.srb.core.pojo.entity.LendItemReturn; +import com.wwj.srb.core.service.LendItemReturnService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + *

+ * 标的出借回款记录表 前端控制器 + *

+ * + * @author wangweijun + * @since 2021-04-27 + */ +@Api(tags = "回款计划") +@RestController +@RequestMapping("/api/core/lendItemReturn") +@Slf4j +public class LendItemReturnController { + + @Resource + private LendItemReturnService lendItemReturnService; + + @ApiOperation("获取列表") + @GetMapping("/auth/list/{lendId}") + public R list( + @ApiParam(value = "标的id", required = true) + @PathVariable Long lendId, HttpServletRequest request) { + + String token = request.getHeader("token"); + Long userId = JwtUtils.getUserId(token); + List list = lendItemReturnService.selectByLendId(lendId, userId); + return R.ok().data("list", list); + } +} + diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/api/LendReturnController.java b/service-core/src/main/java/com/wwj/srb/core/controller/api/LendReturnController.java new file mode 100644 index 0000000000000000000000000000000000000000..a333aa8f5ecbdb323fc5cf82a3e77e4537700a1f --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/controller/api/LendReturnController.java @@ -0,0 +1,81 @@ +package com.wwj.srb.core.controller.api; + + +import com.alibaba.fastjson.JSON; +import com.wwj.common.result.R; +import com.wwj.srb.base.util.JwtUtils; +import com.wwj.srb.core.hfb.RequestHelper; +import com.wwj.srb.core.pojo.entity.LendReturn; +import com.wwj.srb.core.service.LendReturnService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Map; + +/** + *

+ * 还款记录表 前端控制器 + *

+ * + * @author wangweijun + * @since 2021-04-27 + */ +@Api(tags = "还款计划") +@RestController +@RequestMapping("/api/core/lendReturn") +@Slf4j +public class LendReturnController { + + @Resource + private LendReturnService lendReturnService; + + @ApiOperation("获取列表") + @GetMapping("/list/{lendId}") + public R list( + @ApiParam(value = "标的id", required = true) + @PathVariable Long lendId) { + List list = lendReturnService.selectByLendId(lendId); + return R.ok().data("list", list); + } + + @ApiOperation("用户还款") + @PostMapping("/auth/commitReturn/{lendReturnId}") + public R commitReturn( + @ApiParam(value = "还款计划id", required = true) + @PathVariable Long lendReturnId, HttpServletRequest request) { + + String token = request.getHeader("token"); + Long userId = JwtUtils.getUserId(token); + String formStr = lendReturnService.commitReturn(lendReturnId, userId); + return R.ok().data("formStr", formStr); + } + + @ApiOperation("还款异步回调") + @PostMapping("/notifyUrl") + public String notifyUrl(HttpServletRequest request) { + + Map paramMap = RequestHelper.switchMap(request.getParameterMap()); + log.info("还款异步回调:" + JSON.toJSONString(paramMap)); + + //校验签名 + if(RequestHelper.isSignEquals(paramMap)) { + if("0001".equals(paramMap.get("resultCode"))) { + lendReturnService.notify(paramMap); + } else { + log.info("还款异步回调失败:" + JSON.toJSONString(paramMap)); + return "fail"; + } + } else { + log.info("还款异步回调签名错误:" + JSON.toJSONString(paramMap)); + return "fail"; + } + return "success"; + } +} + diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/api/TransFlowController.java b/service-core/src/main/java/com/wwj/srb/core/controller/api/TransFlowController.java new file mode 100644 index 0000000000000000000000000000000000000000..ad6cc42f72e31d2d559154f87535d562fa4528ca --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/controller/api/TransFlowController.java @@ -0,0 +1,45 @@ +package com.wwj.srb.core.controller.api; + + +import com.wwj.common.result.R; +import com.wwj.srb.base.util.JwtUtils; +import com.wwj.srb.core.pojo.entity.TransFlow; +import com.wwj.srb.core.service.TransFlowService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + *

+ * 交易流水表 前端控制器 + *

+ * + * @author wangweijun + * @since 2021-04-27 + */ +@Api(tags = "资金记录") +@RestController +@RequestMapping("/api/core/transFlow") +@Slf4j +public class TransFlowController { + + @Resource + private TransFlowService transFlowService; + + @ApiOperation("获取列表") + @GetMapping("/list") + public R list(HttpServletRequest request) { + String token = request.getHeader("token"); + Long userId = JwtUtils.getUserId(token); + List list = transFlowService.selectByUserId(userId); + return R.ok().data("list", list); + } +} + diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/api/UserAccountController.java b/service-core/src/main/java/com/wwj/srb/core/controller/api/UserAccountController.java index b613c09ed7ed5755889ce77944f2b6f31acdbd0f..ffd3edc1dd038ba48c87194eb12d22c591c5046c 100644 --- a/service-core/src/main/java/com/wwj/srb/core/controller/api/UserAccountController.java +++ b/service-core/src/main/java/com/wwj/srb/core/controller/api/UserAccountController.java @@ -10,10 +10,7 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -69,4 +66,47 @@ public class UserAccountController { return "fail"; } } + + @ApiOperation("查询账户余额") + @GetMapping("/auth/getAccount") + public R getAccount(HttpServletRequest request) { + String token = request.getHeader("token"); + Long userId = JwtUtils.getUserId(token); + BigDecimal account = userAccountService.getAccount(userId); + return R.ok().data("account", account); + } + + @ApiOperation("用户提现") + @PostMapping("/auth/commitWithdraw/{fetchAmt}") + public R commitWithdraw( + @ApiParam(value = "金额", required = true) + @PathVariable BigDecimal fetchAmt, HttpServletRequest request) { + + String token = request.getHeader("token"); + Long userId = JwtUtils.getUserId(token); + String formStr = userAccountService.commitWithdraw(fetchAmt, userId); + return R.ok().data("formStr", formStr); + } + + @ApiOperation("用户提现异步回调") + @PostMapping("/notifyWithdraw") + public String notifyWithdraw(HttpServletRequest request) { + Map paramMap = RequestHelper.switchMap(request.getParameterMap()); + log.info("提现异步回调:" + JSON.toJSONString(paramMap)); + + //校验签名 + if(RequestHelper.isSignEquals(paramMap)) { + //提现成功交易 + if("0001".equals(paramMap.get("resultCode"))) { + userAccountService.notifyWithdraw(paramMap); + } else { + log.info("提现异步回调充值失败:" + JSON.toJSONString(paramMap)); + return "fail"; + } + } else { + log.info("提现异步回调签名错误:" + JSON.toJSONString(paramMap)); + return "fail"; + } + return "success"; + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/controller/api/UserInfoController.java b/service-core/src/main/java/com/wwj/srb/core/controller/api/UserInfoController.java index b8c966dd6689886a03acedd1a44b735b0605542a..b5764e904dcbe8dd14f789fb2baf81c2bbaa7775 100644 --- a/service-core/src/main/java/com/wwj/srb/core/controller/api/UserInfoController.java +++ b/service-core/src/main/java/com/wwj/srb/core/controller/api/UserInfoController.java @@ -7,6 +7,7 @@ import com.wwj.common.util.RegexValidateUtils; import com.wwj.srb.base.util.JwtUtils; import com.wwj.srb.core.pojo.vo.LoginVO; import com.wwj.srb.core.pojo.vo.RegisterVO; +import com.wwj.srb.core.pojo.vo.UserIndexVO; import com.wwj.srb.core.pojo.vo.UserInfoVO; import com.wwj.srb.core.service.UserInfoService; import io.swagger.annotations.Api; @@ -87,4 +88,13 @@ public class UserInfoController { public boolean checkMobile(@PathVariable String mobile) { return userInfoService.checkMobile(mobile); } + + @ApiOperation("获取个人空间用户信息") + @GetMapping("/auth/getIndexUserInfo") + public R getIndexUserInfo(HttpServletRequest request) { + String token = request.getHeader("token"); + Long userId = JwtUtils.getUserId(token); + UserIndexVO userIndexVO = userInfoService.getIndexUserInfo(userId); + return R.ok().data("userIndexVO", userIndexVO); + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/pojo/vo/InvestVO.java b/service-core/src/main/java/com/wwj/srb/core/pojo/vo/InvestVO.java new file mode 100644 index 0000000000000000000000000000000000000000..1ba05aa3b4c49602b660a898eb641052100705ac --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/pojo/vo/InvestVO.java @@ -0,0 +1,27 @@ +package com.wwj.srb.core.pojo.vo; + +import io.swagger.annotations.ApiModel; +import lombok.Data; + +@Data +@ApiModel(description = "投标信息") +public class InvestVO { + + private Long lendId; + + /** + * 投标金额 + */ + private String investAmount; + + + /** + * 用户id + */ + private Long investUserId; + + /** + * 用户姓名 + */ + private String investName; +} diff --git a/service-core/src/main/java/com/wwj/srb/core/pojo/vo/UserIndexVO.java b/service-core/src/main/java/com/wwj/srb/core/pojo/vo/UserIndexVO.java new file mode 100644 index 0000000000000000000000000000000000000000..cd83100cc7cb994310309c016db5372e96880eb7 --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/pojo/vo/UserIndexVO.java @@ -0,0 +1,41 @@ +package com.wwj.srb.core.pojo.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +@ApiModel(description = "首页用户信息") +public class UserIndexVO { + + @ApiModelProperty(value = "用户id") + private Long userId; + + @ApiModelProperty(value = "用户姓名") + private String name; + + @ApiModelProperty(value = "用户昵称") + private String nickName; + + @ApiModelProperty(value = "1:出借人 2:借款人") + private Integer userType; + + @ApiModelProperty(value = "用户头像") + private String headImg; + + @ApiModelProperty(value = "绑定状态(0:未绑定,1:绑定成功 -1:绑定失败)") + private Integer bindStatus; + + @ApiModelProperty(value = "帐户可用余额") + private BigDecimal amount; + + @ApiModelProperty(value = "冻结金额") + private BigDecimal freezeAmount; + + @ApiModelProperty(value = "上次登录时间") + private LocalDateTime lastLoginTime; + +} \ No newline at end of file diff --git a/service-core/src/main/java/com/wwj/srb/core/service/LendItemReturnService.java b/service-core/src/main/java/com/wwj/srb/core/service/LendItemReturnService.java index 6f434c4b324a406396bd2a54921ac84773d9c84b..1ccf487f7ab175ed171ad722db3192005e55bf25 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/LendItemReturnService.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/LendItemReturnService.java @@ -3,6 +3,9 @@ package com.wwj.srb.core.service; import com.wwj.srb.core.pojo.entity.LendItemReturn; import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; +import java.util.Map; + /** *

* 标的出借回款记录表 服务类 @@ -13,4 +16,15 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface LendItemReturnService extends IService { + List selectByLendId(Long lendId, Long userId); + + List> addReturnDetail(Long lendReturnId); + + /** + * 根据还款记录的id查询对应的回款记录 + * + * @param lendReturnId + * @return + */ + List selectLendItemReturnList(Long lendReturnId); } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/LendItemService.java b/service-core/src/main/java/com/wwj/srb/core/service/LendItemService.java index 0a0537ecb679a35937ebeb67cce9e589400b5133..d1c1003388b9944c0f42ef65d0c64b65d9f25e55 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/LendItemService.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/LendItemService.java @@ -2,6 +2,10 @@ package com.wwj.srb.core.service; import com.wwj.srb.core.pojo.entity.LendItem; import com.baomidou.mybatisplus.extension.service.IService; +import com.wwj.srb.core.pojo.vo.InvestVO; + +import java.util.List; +import java.util.Map; /** *

@@ -13,4 +17,11 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface LendItemService extends IService { + String commitInvest(InvestVO investVO); + + void notify(Map paramMap); + + List selectByLendId(Long lendId, Integer status); + + List selectByLendId(Long lendId); } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/LendReturnService.java b/service-core/src/main/java/com/wwj/srb/core/service/LendReturnService.java index 8dee8d1ad16d1ae56ede597df07df84a22a1198e..40f1f0225a4208c808d4e2dd524faf4eb5c7656c 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/LendReturnService.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/LendReturnService.java @@ -3,6 +3,9 @@ package com.wwj.srb.core.service; import com.wwj.srb.core.pojo.entity.LendReturn; import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; +import java.util.Map; + /** *

* 还款记录表 服务类 @@ -13,4 +16,9 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface LendReturnService extends IService { + List selectByLendId(Long lendId); + + String commitReturn(Long lendReturnId, Long userId); + + void notify(Map paramMap); } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/LendService.java b/service-core/src/main/java/com/wwj/srb/core/service/LendService.java index b0b39eee0b41e79e27dc9dd39fa2453e8671eea6..35291ecfb830fa8828a293f6e49301b923840efd 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/LendService.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/LendService.java @@ -5,6 +5,7 @@ import com.wwj.srb.core.pojo.entity.Lend; import com.baomidou.mybatisplus.extension.service.IService; import com.wwj.srb.core.pojo.vo.BorrowInfoApprovalVO; +import java.math.BigDecimal; import java.util.List; import java.util.Map; @@ -23,4 +24,10 @@ public interface LendService extends IService { List selectList(); Map getLendDetail(Long id); + + BigDecimal getInterestCount(BigDecimal invest, BigDecimal yearRate, Integer totalmonth, Integer returnMethod); + + void makeLoan(Long id); + + } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/TransFlowService.java b/service-core/src/main/java/com/wwj/srb/core/service/TransFlowService.java index d74403309185a1a76caf9467e99f4d2d52b3e9cc..4e24b7953317788d52e5dc72466d8599fab9dd04 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/TransFlowService.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/TransFlowService.java @@ -4,6 +4,8 @@ import com.wwj.srb.core.pojo.bo.TransFlowBO; import com.wwj.srb.core.pojo.entity.TransFlow; import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + /** *

* 交易流水表 服务类 @@ -16,4 +18,6 @@ public interface TransFlowService extends IService { void saveTransFlow(TransFlowBO transFlowBO); boolean isSaveTransFlow(String agentBillNo); + + List selectByUserId(Long userId); } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/UserAccountService.java b/service-core/src/main/java/com/wwj/srb/core/service/UserAccountService.java index 6f0e7d7ffaa70d7f3667db1139d332a9f5298dc8..86a521fd559e2cd4861e838cf6412763572a5cf3 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/UserAccountService.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/UserAccountService.java @@ -19,4 +19,10 @@ public interface UserAccountService extends IService { String commitCharge(BigDecimal chargeAmt, Long userId); String notify(Map paramMap); + + BigDecimal getAccount(Long userId); + + String commitWithdraw(BigDecimal fetchAmt, Long userId); + + void notifyWithdraw(Map paramMap); } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/UserBindService.java b/service-core/src/main/java/com/wwj/srb/core/service/UserBindService.java index 055e669dd23a81083bcf4561d4a0a4c154594d30..332adb40f3df37b43437e2b602d861038b380acf 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/UserBindService.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/UserBindService.java @@ -26,4 +26,6 @@ public interface UserBindService extends IService { String commitBindUser(UserBindVO userBindVO, Long userId); void notify(Map paramMap); + + String getBindCodeByUserId(Long userId); } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/UserInfoService.java b/service-core/src/main/java/com/wwj/srb/core/service/UserInfoService.java index c75f839cb63d51427d62b6d64c53abf3ba712c31..345c341e3327539b79fcd2d37d2e311f5bcf734d 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/UserInfoService.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/UserInfoService.java @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.wwj.srb.core.pojo.query.UserInfoQuery; import com.wwj.srb.core.pojo.vo.LoginVO; import com.wwj.srb.core.pojo.vo.RegisterVO; +import com.wwj.srb.core.pojo.vo.UserIndexVO; import com.wwj.srb.core.pojo.vo.UserInfoVO; /** @@ -53,4 +54,8 @@ public interface UserInfoService extends IService { * @return 返回是否被注册,true:已经被注册;false:未被注册 */ boolean checkMobile(String mobile); + + UserIndexVO getIndexUserInfo(Long userId); + + String getMobileByBindCode(String bindCode); } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/impl/LendItemReturnServiceImpl.java b/service-core/src/main/java/com/wwj/srb/core/service/impl/LendItemReturnServiceImpl.java index 87a1f1db76040b86699125051a570d41fafae056..9642f715db9dcf3b9dcc519c93c0cff644c3fc74 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/impl/LendItemReturnServiceImpl.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/impl/LendItemReturnServiceImpl.java @@ -1,11 +1,26 @@ package com.wwj.srb.core.service.impl; -import com.wwj.srb.core.pojo.entity.LendItemReturn; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wwj.srb.core.mapper.LendItemMapper; import com.wwj.srb.core.mapper.LendItemReturnMapper; +import com.wwj.srb.core.mapper.LendMapper; +import com.wwj.srb.core.mapper.LendReturnMapper; +import com.wwj.srb.core.pojo.entity.Lend; +import com.wwj.srb.core.pojo.entity.LendItem; +import com.wwj.srb.core.pojo.entity.LendItemReturn; +import com.wwj.srb.core.pojo.entity.LendReturn; import com.wwj.srb.core.service.LendItemReturnService; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wwj.srb.core.service.UserBindService; import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** *

* 标的出借回款记录表 服务实现类 @@ -17,4 +32,68 @@ import org.springframework.stereotype.Service; @Service public class LendItemReturnServiceImpl extends ServiceImpl implements LendItemReturnService { + @Resource + private UserBindService userBindService; + @Resource + private LendItemMapper lendItemMapper; + @Resource + private LendMapper lendMapper; + @Resource + private LendReturnMapper lendReturnMapper; + + @Override + public List selectByLendId(Long lendId, Long userId) { + return baseMapper.selectList( + new LambdaQueryWrapper() + .eq(LendItemReturn::getLendId, lendId) + .eq(LendItemReturn::getInvestUserId, userId) + .orderByAsc(LendItemReturn::getCurrentPeriod)); + } + + /** + * 添加还款明细 + * @param lendReturnId + */ + @Override + public List> addReturnDetail(Long lendReturnId) { + + //获取还款记录 + LendReturn lendReturn = lendReturnMapper.selectById(lendReturnId); + //获取标的信息 + Lend lend = lendMapper.selectById(lendReturn.getLendId()); + + //根据还款id获取回款列表 + List lendItemReturnList = this.selectLendItemReturnList(lendReturnId); + List> lendItemReturnDetailList = new ArrayList<>(); + for(LendItemReturn lendItemReturn : lendItemReturnList) { + LendItem lendItem = lendItemMapper.selectById(lendItemReturn.getLendItemId()); + String bindCode = userBindService.getBindCodeByUserId(lendItem.getInvestUserId()); + + Map map = new HashMap<>(); + //项目编号 + map.put("agentProjectCode", lend.getLendNo()); + //出借编号 + map.put("voteBillNo", lendItem.getLendItemNo()); + //收款人(出借人) + map.put("toBindCode", bindCode); + //还款金额 + map.put("transitAmt", lendItemReturn.getTotal()); + //还款本金 + map.put("baseAmt", lendItemReturn.getPrincipal()); + //还款利息 + map.put("benifitAmt", lendItemReturn.getInterest()); + //商户手续费 + map.put("feeAmt", new BigDecimal("0")); + + lendItemReturnDetailList.add(map); + } + return lendItemReturnDetailList; + } + + @Override + public List selectLendItemReturnList(Long lendReturnId) { + return baseMapper.selectList( + new LambdaQueryWrapper() + .eq(LendItemReturn::getLendReturnId,lendReturnId)); + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/impl/LendItemServiceImpl.java b/service-core/src/main/java/com/wwj/srb/core/service/impl/LendItemServiceImpl.java index 4d3367d7aa13a5cb16f545ef787a800c3fc36979..28c300a3194186a4fd7a35b8071668635e70f2f3 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/impl/LendItemServiceImpl.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/impl/LendItemServiceImpl.java @@ -1,10 +1,33 @@ package com.wwj.srb.core.service.impl; -import com.wwj.srb.core.pojo.entity.LendItem; -import com.wwj.srb.core.mapper.LendItemMapper; -import com.wwj.srb.core.service.LendItemService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wwj.common.result.ResponseEnum; +import com.wwj.common.result.exception.Assert; +import com.wwj.srb.core.enums.LendStatusEnum; +import com.wwj.srb.core.enums.TransTypeEnum; +import com.wwj.srb.core.hfb.FormHelper; +import com.wwj.srb.core.hfb.HfbConst; +import com.wwj.srb.core.hfb.RequestHelper; +import com.wwj.srb.core.mapper.LendItemMapper; +import com.wwj.srb.core.mapper.LendMapper; +import com.wwj.srb.core.mapper.UserAccountMapper; +import com.wwj.srb.core.pojo.bo.TransFlowBO; +import com.wwj.srb.core.pojo.entity.Lend; +import com.wwj.srb.core.pojo.entity.LendItem; +import com.wwj.srb.core.pojo.vo.InvestVO; +import com.wwj.srb.core.service.*; +import com.wwj.srb.core.util.LendNoUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** *

@@ -17,4 +40,165 @@ import org.springframework.stereotype.Service; @Service public class LendItemServiceImpl extends ServiceImpl implements LendItemService { + @Resource + private LendMapper lendMapper; + @Autowired + private UserAccountService userAccountService; + @Autowired + private UserBindService userBindService; + @Autowired + private LendService lendService; + @Autowired + private TransFlowService transFlowService; + @Resource + private UserAccountMapper userAccountMapper; + + @Override + public String commitInvest(InvestVO investVO) { + + //输入校验========================================== + Long lendId = investVO.getLendId(); + //获取标的信息 + Lend lend = lendMapper.selectById(lendId); + + //标的状态必须为募资中 + Assert.isTrue(lend.getStatus().intValue() == LendStatusEnum.INVEST_RUN.getStatus().intValue(), ResponseEnum.LEND_INVEST_ERROR); + + //标的不能超卖:(已投金额 + 本次投资金额 )>=标的金额(超卖) + BigDecimal sum = lend.getInvestAmount().add(new BigDecimal(investVO.getInvestAmount())); + Assert.isTrue(sum.doubleValue() <= lend.getAmount().doubleValue(), ResponseEnum.LEND_FULL_SCALE_ERROR); + + //账户可用余额充足:当前用户的余额 >= 当前用户的投资金额(可以投资) + Long investUserId = investVO.getInvestUserId(); + BigDecimal amount = userAccountService.getAccount(investUserId);//获取当前用户的账户余额 + Assert.isTrue(amount.doubleValue() >= Double.parseDouble(investVO.getInvestAmount()), ResponseEnum.NOT_SUFFICIENT_FUNDS_ERROR); + + //在商户平台中生成投资信息========================================== + //标的下的投资信息 + LendItem lendItem = new LendItem(); + lendItem.setInvestUserId(investUserId);//投资人id + lendItem.setInvestName(investVO.getInvestName());//投资人名字 + String lendItemNo = LendNoUtils.getLendItemNo(); + lendItem.setLendItemNo(lendItemNo); //投资条目编号(一个Lend对应一个或多个LendItem) + lendItem.setLendId(investVO.getLendId());//对应的标的id + lendItem.setInvestAmount(new BigDecimal(investVO.getInvestAmount())); //此笔投资金额 + lendItem.setLendYearRate(lend.getLendYearRate());//年化 + lendItem.setInvestTime(LocalDateTime.now()); //投资时间 + lendItem.setLendStartDate(lend.getLendStartDate()); //开始时间 + lendItem.setLendEndDate(lend.getLendEndDate()); //结束时间 + + //预期收益 + BigDecimal expectAmount = lendService.getInterestCount( + lendItem.getInvestAmount(), + lendItem.getLendYearRate(), + lend.getPeriod(), + lend.getReturnMethod()); + lendItem.setExpectAmount(expectAmount); + + //实际收益 + lendItem.setRealAmount(new BigDecimal(0)); + + lendItem.setStatus(0);//默认状态:刚刚创建 + baseMapper.insert(lendItem); + + + //组装投资相关的参数,提交到汇付宝资金托管平台========================================== + //在托管平台同步用户的投资信息,修改用户的账户资金信息========================================== + //获取投资人的绑定协议号 + String bindCode = userBindService.getBindCodeByUserId(investUserId); + //获取借款人的绑定协议号 + String benefitBindCode = userBindService.getBindCodeByUserId(lend.getUserId()); + + //封装提交至汇付宝的参数 + Map paramMap = new HashMap<>(); + paramMap.put("agentId", HfbConst.AGENT_ID); + paramMap.put("voteBindCode", bindCode); + paramMap.put("benefitBindCode", benefitBindCode); + paramMap.put("agentProjectCode", lend.getLendNo());//项目标号 + paramMap.put("agentProjectName", lend.getTitle()); + + //在资金托管平台上的投资订单的唯一编号,要和lendItemNo保持一致。 + paramMap.put("agentBillNo", lendItemNo);//订单编号 + paramMap.put("voteAmt", investVO.getInvestAmount()); + paramMap.put("votePrizeAmt", "0"); + paramMap.put("voteFeeAmt", "0"); + paramMap.put("projectAmt", lend.getAmount()); //标的总金额 + paramMap.put("note", ""); + paramMap.put("notifyUrl", HfbConst.INVEST_NOTIFY_URL); //检查常量是否正确 + paramMap.put("returnUrl", HfbConst.INVEST_RETURN_URL); + paramMap.put("timestamp", RequestHelper.getTimestamp()); + String sign = RequestHelper.getSign(paramMap); + paramMap.put("sign", sign); + + //构建充值自动提交表单 + return FormHelper.buildForm(HfbConst.INVEST_URL, paramMap); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void notify(Map paramMap) { + // 幂等性返回 + String agentBillNo = (String) paramMap.get("agentBillNo"); + boolean result = transFlowService.isSaveTransFlow(agentBillNo); + if (result) { + log.warn("幂等性返回"); + return; + } + + // 修改账户金额,从余额中减去投资金额,在冻结金额中加上投资金额 + String voteBindCode = (String) paramMap.get("voteBindCode"); + String voteAmt = (String) paramMap.get("voteAmt"); + userAccountMapper.updateAccount( + voteBindCode, + new BigDecimal("-" + voteAmt), + new BigDecimal(voteAmt)); + + // 修改投资记录的状态 + LendItem lendItem = this.getByLendItemNo(agentBillNo); + lendItem.setStatus(1); + baseMapper.updateById(lendItem); + + // 修改标的记录(投资人数、已投金额) + Long lendId = lendItem.getLendId(); + Lend lend = lendMapper.selectById(lendId); + lend.setInvestNum(lend.getInvestNum() + 1); + lend.setInvestAmount(lend.getInvestAmount().add(lendItem.getInvestAmount())); + lendMapper.updateById(lend); + + // 新增交易流水 + TransFlowBO transFlowBO = new TransFlowBO( + agentBillNo, + voteBindCode, + new BigDecimal(voteAmt), + TransTypeEnum.INVEST_LOCK, + "项目编号:" + lend.getLendNo() + ",项目名称:" + lend.getTitle()); + transFlowService.saveTransFlow(transFlowBO); + } + + @Override + public List selectByLendId(Long lendId, Integer status) { + return baseMapper.selectList( + new LambdaQueryWrapper() + .eq(LendItem::getLendId, lendId) + .eq(LendItem::getStatus, status)); + } + + @Override + public List selectByLendId(Long lendId) { + return baseMapper.selectList( + new LambdaQueryWrapper() + .eq(LendItem::getLendId, lendId)); + } + + /** + * 根据流水号获取投资记录 + * + * @param lendItemNo + * @return + */ + private LendItem getByLendItemNo(String lendItemNo) { + return baseMapper.selectOne( + new LambdaQueryWrapper() + .eq(LendItem::getLendItemNo, lendItemNo)); + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/impl/LendReturnServiceImpl.java b/service-core/src/main/java/com/wwj/srb/core/service/impl/LendReturnServiceImpl.java index cee2fd0f2d3f6d352fd6edf29440f825245274e2..9627a138a60870475f0ff6c0e8d13e61e81654c4 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/impl/LendReturnServiceImpl.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/impl/LendReturnServiceImpl.java @@ -1,10 +1,33 @@ package com.wwj.srb.core.service.impl; -import com.wwj.srb.core.pojo.entity.LendReturn; -import com.wwj.srb.core.mapper.LendReturnMapper; -import com.wwj.srb.core.service.LendReturnService; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wwj.common.result.ResponseEnum; +import com.wwj.common.result.exception.Assert; +import com.wwj.srb.core.enums.LendStatusEnum; +import com.wwj.srb.core.enums.TransTypeEnum; +import com.wwj.srb.core.hfb.FormHelper; +import com.wwj.srb.core.hfb.HfbConst; +import com.wwj.srb.core.hfb.RequestHelper; +import com.wwj.srb.core.mapper.*; +import com.wwj.srb.core.pojo.bo.TransFlowBO; +import com.wwj.srb.core.pojo.entity.Lend; +import com.wwj.srb.core.pojo.entity.LendItem; +import com.wwj.srb.core.pojo.entity.LendItemReturn; +import com.wwj.srb.core.pojo.entity.LendReturn; +import com.wwj.srb.core.service.*; +import com.wwj.srb.core.util.LendNoUtils; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** *

@@ -15,6 +38,148 @@ import org.springframework.stereotype.Service; * @since 2021-04-27 */ @Service +@Slf4j public class LendReturnServiceImpl extends ServiceImpl implements LendReturnService { + @Resource + private UserAccountService userAccountService; + @Resource + private LendMapper lendMapper; + @Resource + private UserBindService userBindService; + @Resource + private LendItemReturnService lendItemReturnService; + @Resource + private TransFlowService transFlowService; + @Resource + private UserAccountMapper userAccountMapper; + @Resource + private LendItemReturnMapper lendItemReturnMapper; + @Resource + private LendItemMapper lendItemMapper; + + @Override + public List selectByLendId(Long lendId) { + return baseMapper.selectList( + new LambdaQueryWrapper() + .eq(LendReturn::getLendId, lendId)); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public String commitReturn(Long lendReturnId, Long userId) { + //获取还款记录 + LendReturn lendReturn = baseMapper.selectById(lendReturnId); + + //判断账号余额是否充足 + BigDecimal amount = userAccountService.getAccount(userId); + Assert.isTrue(amount.doubleValue() >= lendReturn.getTotal().doubleValue(), + ResponseEnum.NOT_SUFFICIENT_FUNDS_ERROR); + + //获取借款人code + String bindCode = userBindService.getBindCodeByUserId(userId); + //获取lend + Long lendId = lendReturn.getLendId(); + Lend lend = lendMapper.selectById(lendId); + + Map paramMap = new HashMap<>(); + paramMap.put("agentId", HfbConst.AGENT_ID); + //商户商品名称 + paramMap.put("agentGoodsName", lend.getTitle()); + //批次号 + paramMap.put("agentBatchNo", lendReturn.getReturnNo()); + //还款人绑定协议号 + paramMap.put("fromBindCode", bindCode); + //还款总额 + paramMap.put("totalAmt", lendReturn.getTotal()); + paramMap.put("note", ""); + //还款明细 + List> lendItemReturnDetailList = lendItemReturnService.addReturnDetail(lendReturnId); + paramMap.put("data", JSONObject.toJSONString(lendItemReturnDetailList)); + paramMap.put("voteFeeAmt", new BigDecimal(0)); + paramMap.put("notifyUrl", HfbConst.BORROW_RETURN_NOTIFY_URL); + paramMap.put("returnUrl", HfbConst.BORROW_RETURN_RETURN_URL); + paramMap.put("timestamp", RequestHelper.getTimestamp()); + String sign = RequestHelper.getSign(paramMap); + paramMap.put("sign", sign); + + //构建自动提交表单 + return FormHelper.buildForm(HfbConst.BORROW_RETURN_URL, paramMap); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void notify(Map paramMap) { + log.info("还款成功"); + + //还款编号 + String agentBatchNo = (String) paramMap.get("agentBatchNo"); + + boolean result = transFlowService.isSaveTransFlow(agentBatchNo); + if (result) { + log.warn("幂等性返回"); + return; + } + + //获取还款数据 + String voteFeeAmt = (String) paramMap.get("voteFeeAmt"); + LendReturn lendReturn = baseMapper.selectOne( + new LambdaQueryWrapper() + .eq(LendReturn::getReturnNo, agentBatchNo)); + + //更新还款状态 + lendReturn.setStatus(1); + lendReturn.setFee(new BigDecimal(voteFeeAmt)); + lendReturn.setRealReturnTime(LocalDateTime.now()); + baseMapper.updateById(lendReturn); + + //更新标的信息 + Lend lend = lendMapper.selectById(lendReturn.getLendId()); + //最后一次还款更新标的状态 + if (lendReturn.getLast()) { + lend.setStatus(LendStatusEnum.PAY_OK.getStatus()); + lendMapper.updateById(lend); + } + + //借款账号转出金额 + BigDecimal totalAmt = new BigDecimal((String) paramMap.get("totalAmt"));//还款金额 + String bindCode = userBindService.getBindCodeByUserId(lend.getUserId()); + userAccountMapper.updateAccount(bindCode, totalAmt.negate(), new BigDecimal(0)); + + //借款人交易流水 + TransFlowBO transFlowBO = new TransFlowBO( + agentBatchNo, + bindCode, + totalAmt, + TransTypeEnum.RETURN_DOWN, + "借款人还款扣减,项目编号:" + lend.getLendNo() + ",项目名称:" + lend.getTitle()); + transFlowService.saveTransFlow(transFlowBO); + + //获取回款明细 + List lendItemReturnList = lendItemReturnService.selectLendItemReturnList(lendReturn.getId()); + lendItemReturnList.forEach(item -> { + //更新回款状态 + item.setStatus(1); + item.setRealReturnTime(LocalDateTime.now()); + lendItemReturnMapper.updateById(item); + + //更新出借信息 + LendItem lendItem = lendItemMapper.selectById(item.getLendItemId()); + lendItem.setRealAmount(item.getInterest()); + lendItemMapper.updateById(lendItem); + + //投资账号转入金额 + String investBindCode = userBindService.getBindCodeByUserId(item.getInvestUserId()); + userAccountMapper.updateAccount(investBindCode, item.getTotal(), new BigDecimal(0)); + + //投资账号交易流水 + TransFlowBO investTransFlowBO = new TransFlowBO( + LendNoUtils.getReturnItemNo(), + investBindCode, + item.getTotal(), + TransTypeEnum.INVEST_BACK, + "还款到账,项目编号:" + lend.getLendNo() + ",项目名称:" + lend.getTitle()); + transFlowService.saveTransFlow(investTransFlowBO); + }); + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/impl/LendServiceImpl.java b/service-core/src/main/java/com/wwj/srb/core/service/impl/LendServiceImpl.java index 7f260c4ac9d20481b99647fb1180efcfd8cc7446..715e78493eb0a1e7e76822cb855a63a13f631e2a 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/impl/LendServiceImpl.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/impl/LendServiceImpl.java @@ -1,19 +1,25 @@ package com.wwj.srb.core.service.impl; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wwj.common.result.exception.BusinessException; import com.wwj.srb.core.enums.LendStatusEnum; +import com.wwj.srb.core.enums.ReturnMethodEnum; +import com.wwj.srb.core.enums.TransTypeEnum; +import com.wwj.srb.core.hfb.HfbConst; +import com.wwj.srb.core.hfb.RequestHelper; import com.wwj.srb.core.mapper.BorrowerMapper; import com.wwj.srb.core.mapper.LendMapper; -import com.wwj.srb.core.pojo.entity.BorrowInfo; -import com.wwj.srb.core.pojo.entity.Borrower; -import com.wwj.srb.core.pojo.entity.Lend; +import com.wwj.srb.core.mapper.UserAccountMapper; +import com.wwj.srb.core.mapper.UserInfoMapper; +import com.wwj.srb.core.pojo.bo.TransFlowBO; +import com.wwj.srb.core.pojo.entity.*; import com.wwj.srb.core.pojo.vo.BorrowInfoApprovalVO; import com.wwj.srb.core.pojo.vo.BorrowerDetailVO; -import com.wwj.srb.core.service.BorrowerService; -import com.wwj.srb.core.service.DictService; -import com.wwj.srb.core.service.LendService; -import com.wwj.srb.core.util.LendNoUtils; +import com.wwj.srb.core.service.*; +import com.wwj.srb.core.util.*; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -22,9 +28,11 @@ import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** *

@@ -35,6 +43,7 @@ import java.util.Map; * @since 2021-04-27 */ @Service +@Slf4j public class LendServiceImpl extends ServiceImpl implements LendService { @Autowired @@ -43,6 +52,18 @@ public class LendServiceImpl extends ServiceImpl implements Le private BorrowerMapper borrowerMapper; @Autowired private BorrowerService borrowerService; + @Resource + private UserInfoMapper userInfoMapper; + @Resource + private UserAccountMapper userAccountMapper; + @Resource + private LendItemService lendItemService; + @Resource + private TransFlowService transFlowService; + @Resource + private LendReturnService lendReturnService; + @Resource + private LendItemReturnService lendItemReturnService; @Override public void createLend(BorrowInfoApprovalVO borrowInfoApprovalVO, BorrowInfo borrowInfo) { @@ -119,4 +140,277 @@ public class LendServiceImpl extends ServiceImpl implements Le result.put("borrower", borrowerDetailVO); return result; } + + @Override + public BigDecimal getInterestCount(BigDecimal invest, BigDecimal yearRate, Integer totalmonth, Integer returnMethod) { + if (invest == null) { + return new BigDecimal(0); + } + BigDecimal interestCount = null; + // 判断还款方式 + if (returnMethod.intValue() == ReturnMethodEnum.ONE.getMethod()) { + interestCount = Amount1Helper.getInterestCount(invest, yearRate, totalmonth); + } else if (returnMethod.intValue() == ReturnMethodEnum.TWO.getMethod()) { + interestCount = Amount2Helper.getInterestCount(invest, yearRate, totalmonth); + } else if (returnMethod.intValue() == ReturnMethodEnum.THREE.getMethod()) { + interestCount = Amount3Helper.getInterestCount(invest, yearRate, totalmonth); + } else if (returnMethod.intValue() == ReturnMethodEnum.FOUR.getMethod()) { + interestCount = Amount4Helper.getInterestCount(invest, yearRate, totalmonth); + } + return interestCount; + } + + @Override + public void makeLoan(Long id) { + // 获取标的信息 + Lend lend = baseMapper.selectById(id); + // 调用汇付宝放款接口 + Map map = new HashMap<>(); + map.put("agentId", HfbConst.AGENT_ID); + map.put("agentProjectCode", lend.getLendNo()); + map.put("agentBillNo", LendNoUtils.getLoanNo()); + // 计算月化率 + BigDecimal monthRate = lend.getServiceRate().divide(new BigDecimal(12), 8, BigDecimal.ROUND_DOWN); + // 平台服务费(已投金额 * 月化率 * 投资时长) + BigDecimal realAmount = lend.getInvestAmount().multiply(monthRate).multiply(new BigDecimal(lend.getPeriod())); + map.put("mchFee", realAmount); + map.put("timestamp", RequestHelper.getTimestamp()); + map.put("sign", RequestHelper.getSign(map)); + + // 提交远程请求 + JSONObject result = RequestHelper.sendRequest(map, HfbConst.MAKE_LOAD_URL); + log.info("放款结果:" + result.toJSONString()); + // 若是放款失败,则抛出异常 + if (!"0000".equals(result.getString("resultCode"))) { + throw new BusinessException(result.getString("resultMsg")); + } + + // 标的状态和标的平台收益 + lend.setRealAmount(realAmount); // 平台收益 + lend.setStatus(LendStatusEnum.PAY_RUN.getStatus()); // 标的状态 + lend.setPaymentTime(LocalDateTime.now()); + baseMapper.updateById(lend); + + // 给借款账号转入金额 + // 获取借款人的bindCode + Long userId = lend.getUserId(); + UserInfo userInfo = userInfoMapper.selectById(userId); + String bindCode = userInfo.getBindCode(); + BigDecimal voteAmt = new BigDecimal(result.getString("voteAmt")); + userAccountMapper.updateAccount(bindCode, voteAmt, new BigDecimal(0)); + + // 增加借款交易流水 + TransFlowBO transFlowBO = new TransFlowBO( + result.getString("agentBillNo"), + bindCode, + voteAmt, + TransTypeEnum.BORROW_BACK, + "开始放款,项目编号:" + lend.getLendNo() + ",项目名称:" + lend.getTitle()); + + transFlowService.saveTransFlow(transFlowBO); + + // 解冻并扣除投资人资金 + // 获取标的下的投资列表 + List lendItemList = lendItemService.selectByLendId(id, 1); + lendItemList.stream().forEach(item -> { + Long investUserId = item.getInvestUserId(); + // 投资人 + UserInfo investUserInfo = userInfoMapper.selectById(investUserId); + String investBindCode = investUserInfo.getBindCode(); + BigDecimal investAmount = item.getInvestAmount(); + userAccountMapper.updateAccount(investBindCode, new BigDecimal(0), investAmount.negate()); + // 增加投资人交易流水 + TransFlowBO investTransFlowBO = new TransFlowBO( + LendNoUtils.getTransNo(), + investBindCode, + investAmount, + TransTypeEnum.INVEST_UNLOCK, + "项目放款,冻结资金转出,项目编号:" + lend.getLendNo() + ",项目名称:" + lend.getTitle()); + + }); + // 生成借款人还款计划和出借人回款计划 + this.repaymentPlan(lend); + } + + /** + * 还款计划 + * + * @param lend + */ + private void repaymentPlan(Lend lend) { + + //还款计划列表 + List lendReturnList = new ArrayList<>(); + + //按还款时间生成还款计划 + int len = lend.getPeriod(); + for (int i = 1; i <= len; i++) { + + //创建还款计划对象 + LendReturn lendReturn = new LendReturn(); + lendReturn.setReturnNo(LendNoUtils.getReturnNo()); + lendReturn.setLendId(lend.getId()); + lendReturn.setBorrowInfoId(lend.getBorrowInfoId()); + lendReturn.setUserId(lend.getUserId()); + lendReturn.setAmount(lend.getAmount()); + lendReturn.setBaseAmount(lend.getInvestAmount()); + lendReturn.setLendYearRate(lend.getLendYearRate()); + lendReturn.setCurrentPeriod(i);//当前期数 + lendReturn.setReturnMethod(lend.getReturnMethod()); + + //说明:还款计划中的这三项 = 回款计划中对应的这三项和:因此需要先生成对应的回款计划 + // lendReturn.setPrincipal(); + // lendReturn.setInterest(); + // lendReturn.setTotal(); + + lendReturn.setFee(new BigDecimal(0)); + lendReturn.setReturnDate(lend.getLendStartDate().plusMonths(i)); //第二个月开始还款 + lendReturn.setOverdue(false); + if (i == len) { //最后一个月 + //标识为最后一次还款 + lendReturn.setLast(true); + } else { + lendReturn.setLast(false); + } + lendReturn.setStatus(0); + lendReturnList.add(lendReturn); + } + //批量保存 + lendReturnService.saveBatch(lendReturnList); + + //获取lendReturnList中还款期数与还款计划id对应map + Map lendReturnMap = lendReturnList.stream().collect( + Collectors.toMap(LendReturn::getCurrentPeriod, LendReturn::getId) + ); + + //====================================================== + //=============获取所有投资者,生成回款计划=================== + //====================================================== + //回款计划列表 + List lendItemReturnAllList = new ArrayList<>(); + //获取投资成功的投资记录 + List lendItemList = lendItemService.selectByLendId(lend.getId(), 1); + for (LendItem lendItem : lendItemList) { + //创建回款计划列表 + List lendItemReturnList = this.returnInvest(lendItem.getId(), lendReturnMap, lend); + lendItemReturnAllList.addAll(lendItemReturnList); + } + + //更新还款计划中的相关金额数据 + for (LendReturn lendReturn : lendReturnList) { + BigDecimal sumPrincipal = lendItemReturnAllList.stream() + //过滤条件:当回款计划中的还款计划id == 当前还款计划id的时候 + .filter(item -> item.getLendReturnId().longValue() == lendReturn.getId().longValue()) + //将所有回款计划中计算的每月应收本金相加 + .map(LendItemReturn::getPrincipal) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + BigDecimal sumInterest = lendItemReturnAllList.stream() + .filter(item -> item.getLendReturnId().longValue() == lendReturn.getId().longValue()) + .map(LendItemReturn::getInterest) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + BigDecimal sumTotal = lendItemReturnAllList.stream() + .filter(item -> item.getLendReturnId().longValue() == lendReturn.getId().longValue()) + .map(LendItemReturn::getTotal) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + lendReturn.setPrincipal(sumPrincipal); //每期还款本金 + lendReturn.setInterest(sumInterest); //每期还款利息 + lendReturn.setTotal(sumTotal); //每期还款本息 + } + lendReturnService.updateBatchById(lendReturnList); + } + + /** + * 回款计划 + * + * @param lendItemId + * @param lendReturnMap + * @param lend + * @return + */ + public List returnInvest(Long lendItemId, Map lendReturnMap, Lend lend) { + + //投标信息 + LendItem lendItem = lendItemService.getById(lendItemId); + + //投资金额 + BigDecimal amount = lendItem.getInvestAmount(); + //年化利率 + BigDecimal yearRate = lendItem.getLendYearRate(); + //投资期数 + int totalMonth = lend.getPeriod(); + + Map mapInterest = null; //还款期数 -> 利息 + Map mapPrincipal = null; //还款期数 -> 本金 + + //根据还款方式计算本金和利息 + if (lend.getReturnMethod().intValue() == ReturnMethodEnum.ONE.getMethod()) { + //利息 + mapInterest = Amount1Helper.getPerMonthInterest(amount, yearRate, totalMonth); + //本金 + mapPrincipal = Amount1Helper.getPerMonthPrincipal(amount, yearRate, totalMonth); + } else if (lend.getReturnMethod().intValue() == ReturnMethodEnum.TWO.getMethod()) { + mapInterest = Amount2Helper.getPerMonthInterest(amount, yearRate, totalMonth); + mapPrincipal = Amount2Helper.getPerMonthPrincipal(amount, yearRate, totalMonth); + } else if (lend.getReturnMethod().intValue() == ReturnMethodEnum.THREE.getMethod()) { + mapInterest = Amount3Helper.getPerMonthInterest(amount, yearRate, totalMonth); + mapPrincipal = Amount3Helper.getPerMonthPrincipal(amount, yearRate, totalMonth); + } else { + mapInterest = Amount4Helper.getPerMonthInterest(amount, yearRate, totalMonth); + mapPrincipal = Amount4Helper.getPerMonthPrincipal(amount, yearRate, totalMonth); + } + + //创建回款计划列表 + List lendItemReturnList = new ArrayList<>(); + for (Map.Entry entry : mapInterest.entrySet()) { + Integer currentPeriod = entry.getKey(); + //根据还款期数获取还款计划的id + Long lendReturnId = lendReturnMap.get(currentPeriod); + + LendItemReturn lendItemReturn = new LendItemReturn(); + lendItemReturn.setLendReturnId(lendReturnId); + lendItemReturn.setLendItemId(lendItemId); + lendItemReturn.setInvestUserId(lendItem.getInvestUserId()); + lendItemReturn.setLendId(lendItem.getLendId()); + lendItemReturn.setInvestAmount(lendItem.getInvestAmount()); + lendItemReturn.setLendYearRate(lend.getLendYearRate()); + lendItemReturn.setCurrentPeriod(currentPeriod); + lendItemReturn.setReturnMethod(lend.getReturnMethod()); + //最后一次本金计算 + if (lendItemReturnList.size() > 0 && currentPeriod.intValue() == lend.getPeriod().intValue()) { + //最后一期本金 = 本金 - 前几次之和 + BigDecimal sumPrincipal = lendItemReturnList.stream() + .map(LendItemReturn::getPrincipal) + .reduce(BigDecimal.ZERO, BigDecimal::add); + //最后一期应还本金 = 用当前投资人的总投资金额 - 除了最后一期前面期数计算出来的所有的应还本金 + BigDecimal lastPrincipal = lendItem.getInvestAmount().subtract(sumPrincipal); + lendItemReturn.setPrincipal(lastPrincipal); + + // 利息 + BigDecimal sumInterest = lendItemReturnList.stream() + .map(LendItemReturn::getInterest) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal lastInterest = lendItem.getExpectAmount().subtract(sumInterest); + lendItemReturn.setInterest(lastInterest); + } else { + lendItemReturn.setPrincipal(mapPrincipal.get(currentPeriod)); + lendItemReturn.setInterest(mapInterest.get(currentPeriod)); + } + + // 回款总金额 + lendItemReturn.setTotal(lendItemReturn.getPrincipal().add(lendItemReturn.getInterest())); + lendItemReturn.setFee(new BigDecimal("0")); + lendItemReturn.setReturnDate(lend.getLendStartDate().plusMonths(currentPeriod)); + //是否逾期,默认未逾期 + lendItemReturn.setOverdue(false); + lendItemReturn.setStatus(0); + + lendItemReturnList.add(lendItemReturn); + } + lendItemReturnService.saveBatch(lendItemReturnList); + + return lendItemReturnList; + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/impl/TransFlowServiceImpl.java b/service-core/src/main/java/com/wwj/srb/core/service/impl/TransFlowServiceImpl.java index f169c5627af7ae39e35c853495aca129eb65570c..41a1039b19cf223e22b9670e7952acb20d5619a4 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/impl/TransFlowServiceImpl.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/impl/TransFlowServiceImpl.java @@ -1,16 +1,17 @@ package com.wwj.srb.core.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wwj.srb.core.mapper.TransFlowMapper; import com.wwj.srb.core.mapper.UserInfoMapper; import com.wwj.srb.core.pojo.bo.TransFlowBO; import com.wwj.srb.core.pojo.entity.TransFlow; -import com.wwj.srb.core.mapper.TransFlowMapper; import com.wwj.srb.core.pojo.entity.UserInfo; import com.wwj.srb.core.service.TransFlowService; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.util.List; /** *

@@ -53,4 +54,12 @@ public class TransFlowServiceImpl extends ServiceImpl 0; } + + @Override + public List selectByUserId(Long userId) { + return baseMapper.selectList( + new LambdaQueryWrapper() + .eq(TransFlow::getUserId, userId) + .orderByDesc(TransFlow::getId)); + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/impl/UserAccountServiceImpl.java b/service-core/src/main/java/com/wwj/srb/core/service/impl/UserAccountServiceImpl.java index 728c670be94898d44f193740cb83821a93ee0a27..62e91b756bf08588d685153fbfb67fdc6e1fa6a0 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/impl/UserAccountServiceImpl.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/impl/UserAccountServiceImpl.java @@ -1,6 +1,10 @@ package com.wwj.srb.core.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wwj.common.result.ResponseEnum; +import com.wwj.common.result.exception.Assert; +import com.wwj.srb.base.dto.SmsDTO; import com.wwj.srb.core.enums.TransTypeEnum; import com.wwj.srb.core.hfb.FormHelper; import com.wwj.srb.core.hfb.HfbConst; @@ -12,7 +16,12 @@ import com.wwj.srb.core.pojo.entity.UserAccount; import com.wwj.srb.core.pojo.entity.UserInfo; import com.wwj.srb.core.service.TransFlowService; import com.wwj.srb.core.service.UserAccountService; +import com.wwj.srb.core.service.UserBindService; +import com.wwj.srb.core.service.UserInfoService; import com.wwj.srb.core.util.LendNoUtils; +import com.wwj.srb.rabbitutil.constant.MQConst; +import com.wwj.srb.rabbitutil.service.MQService; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -31,12 +40,21 @@ import java.util.Map; * @since 2021-04-27 */ @Service +@Slf4j public class UserAccountServiceImpl extends ServiceImpl implements UserAccountService { @Resource private UserInfoMapper userInfoMapper; @Autowired private TransFlowService transFlowService; + @Resource + private UserBindService userBindService; + @Resource + private UserAccountService userAccountService; + @Resource + private UserInfoService userInfoService; + @Resource + private MQService mqService; @Override public String commitCharge(BigDecimal chargeAmt, Long userId) { @@ -81,6 +99,76 @@ public class UserAccountServiceImpl extends ServiceImpl() + .eq(UserAccount::getUserId, userId)); + return userAccount.getAmount(); + } + + @Override + public String commitWithdraw(BigDecimal fetchAmt, Long userId) { + //账户可用余额充足:当前用户的余额 >= 当前用户的提现金额 + BigDecimal amount = userAccountService.getAccount(userId);//获取当前用户的账户余额 + Assert.isTrue(amount.doubleValue() >= fetchAmt.doubleValue(), + ResponseEnum.NOT_SUFFICIENT_FUNDS_ERROR); + + String bindCode = userBindService.getBindCodeByUserId(userId); + + Map paramMap = new HashMap<>(); + paramMap.put("agentId", HfbConst.AGENT_ID); + paramMap.put("agentBillNo", LendNoUtils.getWithdrawNo()); + paramMap.put("bindCode", bindCode); + paramMap.put("fetchAmt", fetchAmt); + paramMap.put("feeAmt", new BigDecimal(0)); + paramMap.put("notifyUrl", HfbConst.WITHDRAW_NOTIFY_URL); + paramMap.put("returnUrl", HfbConst.WITHDRAW_RETURN_URL); + paramMap.put("timestamp", RequestHelper.getTimestamp()); + String sign = RequestHelper.getSign(paramMap); + paramMap.put("sign", sign); + + //构建自动提交表单 + return FormHelper.buildForm(HfbConst.WITHDRAW_URL, paramMap); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void notifyWithdraw(Map paramMap) { + log.info("提现成功"); + String agentBillNo = (String) paramMap.get("agentBillNo"); + boolean result = transFlowService.isSaveTransFlow(agentBillNo); + if (result) { + log.warn("幂等性返回"); + return; + } + + String bindCode = (String) paramMap.get("bindCode"); + String fetchAmt = (String) paramMap.get("fetchAmt"); + + //根据用户账户修改账户金额 + baseMapper.updateAccount(bindCode, new BigDecimal("-" + fetchAmt), new BigDecimal(0)); + + //增加交易流水 + TransFlowBO transFlowBO = new TransFlowBO( + agentBillNo, + bindCode, + new BigDecimal(fetchAmt), + TransTypeEnum.WITHDRAW, + "提现"); + transFlowService.saveTransFlow(transFlowBO); + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/impl/UserBindServiceImpl.java b/service-core/src/main/java/com/wwj/srb/core/service/impl/UserBindServiceImpl.java index db3ce5a5c7177ff06e55222ef3fc15b74cd21b68..c7c43512fe4901697c83077efb0d392585e25b39 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/impl/UserBindServiceImpl.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/impl/UserBindServiceImpl.java @@ -110,4 +110,12 @@ public class UserBindServiceImpl extends ServiceImpl i userInfo.setBindStatus(UserBindEnum.BIND_OK.getStatus()); userInfoMapper.updateById(userInfo); } + + @Override + public String getBindCodeByUserId(Long userId) { + UserBind userBind = baseMapper.selectOne( + new LambdaQueryWrapper() + .eq(UserBind::getUserId, userId)); + return userBind.getBindCode(); + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/service/impl/UserInfoServiceImpl.java b/service-core/src/main/java/com/wwj/srb/core/service/impl/UserInfoServiceImpl.java index a3d55e0d75a15255ba5edfaa68af9e668b7eee73..3c4b0638bad8b854d84a4c30278bf9d645ab207e 100644 --- a/service-core/src/main/java/com/wwj/srb/core/service/impl/UserInfoServiceImpl.java +++ b/service-core/src/main/java/com/wwj/srb/core/service/impl/UserInfoServiceImpl.java @@ -18,6 +18,7 @@ import com.wwj.srb.core.pojo.entity.UserLoginRecord; import com.wwj.srb.core.pojo.query.UserInfoQuery; import com.wwj.srb.core.pojo.vo.LoginVO; import com.wwj.srb.core.pojo.vo.RegisterVO; +import com.wwj.srb.core.pojo.vo.UserIndexVO; import com.wwj.srb.core.pojo.vo.UserInfoVO; import com.wwj.srb.core.service.UserInfoService; import org.springframework.stereotype.Service; @@ -153,4 +154,43 @@ public class UserInfoServiceImpl extends ServiceImpl i ); return count > 0; } + + @Override + public UserIndexVO getIndexUserInfo(Long userId) { + //用户信息 + UserInfo userInfo = baseMapper.selectById(userId); + + //账户信息 + UserAccount userAccount = userAccountMapper.selectOne( + new LambdaQueryWrapper() + .eq(UserAccount::getUserId, userId)); + //登录信息 + UserLoginRecord userLoginRecord = userLoginRecordMapper.selectOne( + new LambdaQueryWrapper() + .eq(UserLoginRecord::getUserId, userId) + .orderByDesc(UserLoginRecord::getId) + .last("limit 1")); + + //组装结果数据 + UserIndexVO userIndexVO = new UserIndexVO(); + userIndexVO.setUserId(userInfo.getId()); + userIndexVO.setUserType(userInfo.getUserType()); + userIndexVO.setName(userInfo.getName()); + userIndexVO.setNickName(userInfo.getNickName()); + userIndexVO.setHeadImg(userInfo.getHeadImg()); + userIndexVO.setBindStatus(userInfo.getBindStatus()); + userIndexVO.setAmount(userAccount.getAmount()); + userIndexVO.setFreezeAmount(userAccount.getFreezeAmount()); + userIndexVO.setLastLoginTime(userLoginRecord.getCreateTime()); + + return userIndexVO; + } + + @Override + public String getMobileByBindCode(String bindCode) { + UserInfo userInfo = baseMapper.selectOne( + new LambdaQueryWrapper() + .eq(UserInfo::getBindCode, bindCode)); + return userInfo.getMobile(); + } } diff --git a/service-core/src/main/java/com/wwj/srb/core/util/Amount1Helper.java b/service-core/src/main/java/com/wwj/srb/core/util/Amount1Helper.java new file mode 100644 index 0000000000000000000000000000000000000000..46612d9945193260bc8a06d899f14a5bfb5c6060 --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/util/Amount1Helper.java @@ -0,0 +1,87 @@ +package com.wwj.srb.core.util; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +/** + * 等额本息工具类 + * 校验网址:http://www.xjumc.com/ + * 等额本息是指一种贷款的还款方式,是在还款期内,每月偿还同等数额的贷款(包括本金和利息),和等额本金是不一样的概念,虽然刚开始还款时每月还款额可能会低于等额本金还款方式,但是最终所还利息会高于等额本金还款方式,该方式经常被银行使用。 + * + * 每月还款数额计算公式如下: + * 每月还款额=贷款本金×[月利率×(1+月利率) ^ 还款月数]÷{[(1+月利率) ^ 还款月数]-1} + */ +public class Amount1Helper { + + /** + * 每月还款利息 + * @param invest 总借款额(贷款本金) + * @param yearRate 年利率 + * @param totalMonth 还款总月数 + * @return 每月偿还利息 + */ + public static Map getPerMonthInterest(BigDecimal invest, BigDecimal yearRate, int totalMonth) { + Map map = new HashMap(); + //月利息 + double monthRate = yearRate.divide(new BigDecimal("12"), 8, BigDecimal.ROUND_DOWN).doubleValue(); + BigDecimal monthInterest; + for (int i = 1; i < totalMonth + 1; i++) { + BigDecimal multiply = invest.multiply(new BigDecimal(monthRate)); + BigDecimal sub = new BigDecimal(Math.pow(1 + monthRate, totalMonth)).subtract(new BigDecimal(Math.pow(1 + monthRate, i-1))); + monthInterest = multiply.multiply(sub).divide(new BigDecimal(Math.pow(1 + monthRate, totalMonth) - 1), 8, BigDecimal.ROUND_DOWN); + monthInterest = monthInterest.setScale(2, BigDecimal.ROUND_DOWN); + map.put(i, monthInterest); + } + return map; + } + + /** + * 每月还款本金 + * @param invest 总借款额(贷款本金) + * @param yearRate 年利率 + * @param totalMonth 还款总月数 + * @return 每月偿还本金 + */ + public static Map getPerMonthPrincipal(BigDecimal invest, BigDecimal yearRate, int totalMonth) { + double monthRate = yearRate.divide(new BigDecimal("12"), 8, BigDecimal.ROUND_DOWN).doubleValue(); + BigDecimal monthIncome = invest.multiply(new BigDecimal(monthRate * Math.pow(1 + monthRate, totalMonth))) + .divide(new BigDecimal(Math.pow(1 + monthRate, totalMonth) - 1), 8, BigDecimal.ROUND_DOWN); + Map mapInterest = getPerMonthInterest(invest, yearRate, totalMonth); + Map mapPrincipal = new HashMap(); + + for (Map.Entry entry : mapInterest.entrySet()) { + mapPrincipal.put(entry.getKey(), monthIncome.subtract(entry.getValue())); + } + return mapPrincipal; + } + + /** + * 总利息 + * @param invest 总借款额(贷款本金) + * @param yearRate 年利率 + * @param totalMonth 还款总月数 + * @return 总利息 + */ + public static BigDecimal getInterestCount(BigDecimal invest, BigDecimal yearRate, int totalMonth) { + BigDecimal count = new BigDecimal(0); + Map mapInterest = getPerMonthInterest(invest, yearRate, totalMonth); + + for (Map.Entry entry : mapInterest.entrySet()) { + count = count.add(entry.getValue()); + } + return count; + } + + public static void main(String[] args) { + BigDecimal invest = new BigDecimal("500"); // 本金 + int month = 12; + BigDecimal yearRate = new BigDecimal("0.20"); // 年利率 + Map mapInterest = getPerMonthInterest(invest, yearRate, month); + System.out.println("等额本息---每月还款利息:" + mapInterest); + Map mapPrincipal = getPerMonthPrincipal(invest, yearRate, month); + System.out.println("等额本息---每月还款本金:" + mapPrincipal); + BigDecimal count = getInterestCount(invest, yearRate, month); + System.out.println("等额本息---总利息:" + count); + } +} diff --git a/service-core/src/main/java/com/wwj/srb/core/util/Amount2Helper.java b/service-core/src/main/java/com/wwj/srb/core/util/Amount2Helper.java new file mode 100644 index 0000000000000000000000000000000000000000..1ad7988de3df184fcc6af26dc8cd1afef534a139 --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/util/Amount2Helper.java @@ -0,0 +1,105 @@ +package com.wwj.srb.core.util; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + + +/** + * 等额本金工具类 + * 校验网址:http://www.xjumc.com/ + * 等额本金是指一种贷款的还款方式,是在还款期内把贷款数总额等分,每月偿还同等数额的本金和剩余贷款在该月所产生的利息,这样由于每月的还款本金额固定, + * * 而利息越来越少,借款人起初还款压力较大,但是随时间的推移每月还款数也越来越少。 + */ +public class Amount2Helper { + + /** + * 每月本息 + * @param invest 总借款额(贷款本金) + * @param yearRate 年利率 + * @param totalMonth 还款总月数 + * @return 每月偿还利息 + */ + public static Map getPerMonthPrincipalInterest(BigDecimal invest, BigDecimal yearRate, int totalMonth) { + Map map = new HashMap(); + // 每月本金 + BigDecimal monthPri = invest.divide(new BigDecimal(totalMonth), 8, BigDecimal.ROUND_DOWN); + // 获取月利率 + double monthRate = yearRate.divide(new BigDecimal(12), 8, BigDecimal.ROUND_DOWN).doubleValue(); + monthRate = new BigDecimal(monthRate).setScale(8, BigDecimal.ROUND_DOWN).doubleValue(); + for (int i = 1; i <= totalMonth; i++) { + double monthRes = monthPri.doubleValue() + (invest.doubleValue() - monthPri.doubleValue() * (i - 1)) * monthRate; + monthRes = new BigDecimal(monthRes).setScale(2, BigDecimal.ROUND_DOWN).doubleValue(); + map.put(i, new BigDecimal(monthRes)); + } + return map; + } + + /** + * 每月还款利息 + * @param invest 总借款额(贷款本金) + * @param yearRate 年利率 + * @param totalMonth 还款总月数 + * @return 每月偿还本金 + * @return + */ + public static Map getPerMonthInterest(BigDecimal invest, BigDecimal yearRate, int totalMonth) { + Map inMap = new HashMap(); + BigDecimal principal = invest.divide(new BigDecimal(totalMonth), 8, BigDecimal.ROUND_DOWN); + Map map = getPerMonthPrincipalInterest(invest, yearRate, totalMonth); + for (Map.Entry entry : map.entrySet()) { + BigDecimal principalBigDecimal = principal; + BigDecimal principalInterestBigDecimal = new BigDecimal(entry.getValue().toString()); + BigDecimal interestBigDecimal = principalInterestBigDecimal.subtract(principalBigDecimal); + interestBigDecimal = interestBigDecimal.setScale(2, BigDecimal.ROUND_DOWN); + inMap.put(entry.getKey(), interestBigDecimal); + } + return inMap; + } + + /** + * 每月还款本金 + * @param invest 总借款额(贷款本金) + * @param yearRate 年利率 + * @param totalMonth 还款总月数 + * @return 总利息 + */ + public static Map getPerMonthPrincipal(BigDecimal invest, BigDecimal yearRate, int totalMonth) { + Map map = new HashMap<>(); + BigDecimal monthIncome = invest.divide(new BigDecimal(totalMonth), 8, BigDecimal.ROUND_DOWN); + for(int i=1; i<=totalMonth; i++) { + map.put(i, monthIncome); + } + return map; + } + + /** + * 总利息 + * @param invest + * @param yearRate + * @param totalMonth + * @return + */ + public static BigDecimal getInterestCount(BigDecimal invest, BigDecimal yearRate, int totalMonth) { + BigDecimal count = new BigDecimal(0); + Map mapInterest = getPerMonthInterest(invest, yearRate, totalMonth); + + for (Map.Entry entry : mapInterest.entrySet()) { + count = count.add(entry.getValue()); + } + return count; + } + + public static void main(String[] args) { + BigDecimal invest = new BigDecimal("12000"); // 本金 + int month = 12; + BigDecimal yearRate = new BigDecimal("0.12"); // 年利率 + + Map benjin = getPerMonthPrincipal(invest, yearRate, month); + System.out.println("等额本金---每月本金:" + benjin); + Map mapInterest = getPerMonthInterest(invest, yearRate, month); + System.out.println("等额本金---每月利息:" + mapInterest); + BigDecimal count = getInterestCount(invest, yearRate, month); + System.out.println("等额本金---总利息:" + count); + } +} \ No newline at end of file diff --git a/service-core/src/main/java/com/wwj/srb/core/util/Amount3Helper.java b/service-core/src/main/java/com/wwj/srb/core/util/Amount3Helper.java new file mode 100644 index 0000000000000000000000000000000000000000..7e8bbad2ba6d006c3c0ff2b3ccbb9b8e203813bd --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/util/Amount3Helper.java @@ -0,0 +1,78 @@ +package com.wwj.srb.core.util; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +/** + * 按月付息到期还本工具类 + */ +public class Amount3Helper { + + /** + * 每月还款利息 + * 按月付息,到期还本-计算获取还款方式为按月付息,到期还本的每月偿还利息 + * 公式:每月应还利息=总借款额*年利率÷还款月数 + * + * @param invest 总借款额(贷款本金) + * @param yearRate 年利率 + * @param totalMonth 还款总月数 + * @return 每月偿还利息 + */ + public static Map getPerMonthInterest(BigDecimal invest, BigDecimal yearRate, int totalMonth) { + Map map = new HashMap<>(); + //每月偿还利息 + BigDecimal monthIncome = invest.multiply(yearRate).divide(new BigDecimal(12), 8, BigDecimal.ROUND_DOWN); + for(int i=1; i<=totalMonth; i++) { + map.put(i, monthIncome); + } + return map; + } + + /** + * 每月偿还本金 + * @param invest 总借款额(贷款本金) + * @param yearRate 年利率 + * @param totalMonth 还款总月数 + * @return 每月偿还本金 + */ + public static Map getPerMonthPrincipal(BigDecimal invest, BigDecimal yearRate, int totalMonth) { + Map map = new HashMap(); + // 每月利息 + for (int i = 1; i <= totalMonth; i++) { + if(i == totalMonth){ + map.put(i, invest); + } else { + map.put(i, new BigDecimal("0")); + } + } + return map; + } + + /** + * 总利息 + * @param invest 总借款额(贷款本金) + * @param yearRate 年利率 + * @param totalMonth 还款总月数 + * @return 总利息 + */ + public static BigDecimal getInterestCount(BigDecimal invest, BigDecimal yearRate, int totalMonth) { + //每月偿还利息 + BigDecimal count = invest.multiply(yearRate).divide(new BigDecimal(12), 2, BigDecimal.ROUND_DOWN); + + return count.multiply(new BigDecimal(totalMonth)); + } + + public static void main(String[] args) { + BigDecimal invest = new BigDecimal("10000"); // 本金 + int month = 12; + BigDecimal yearRate = new BigDecimal("0.12"); // 年利率 + + Map getPerMonthPrincipalInterest = getPerMonthPrincipal(invest, yearRate, month); + System.out.println("按月付息到期还本---每月偿还本金:" + getPerMonthPrincipalInterest); + Map mapInterest = getPerMonthInterest(invest, yearRate, month); + System.out.println("按月付息到期还本---每月偿还利息:" + mapInterest); + BigDecimal count = getInterestCount(invest, yearRate, month); + System.out.println("按月付息到期还本---总利息:" + count); + } +} \ No newline at end of file diff --git a/service-core/src/main/java/com/wwj/srb/core/util/Amount4Helper.java b/service-core/src/main/java/com/wwj/srb/core/util/Amount4Helper.java new file mode 100644 index 0000000000000000000000000000000000000000..17c373318f86713bce0bcf7cb3e54e0308411512 --- /dev/null +++ b/service-core/src/main/java/com/wwj/srb/core/util/Amount4Helper.java @@ -0,0 +1,66 @@ +package com.wwj.srb.core.util; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +/** + * 一次还本还息工具类 + */ +public class Amount4Helper { + + /** + * 还款金额 = 本金 + 本金*月利率*期限 + * @param amount + * @param yearRate + * @param totalmonth + * @return + */ + public static Map getPerMonthInterest(BigDecimal amount, BigDecimal yearRate, int totalmonth) { + Map map = new HashMap<>(); + BigDecimal monthInterest = yearRate.divide(new BigDecimal("12"), 8, BigDecimal.ROUND_HALF_UP); + BigDecimal multiply = amount.multiply(monthInterest).multiply(new BigDecimal(totalmonth)); + map.put(1, multiply); + return map; + } + + /** + * 还款本金 + * @param amount + * @param yearRate + * @param totalmonth + * @return + */ + public static Map getPerMonthPrincipal(BigDecimal amount, BigDecimal yearRate, int totalmonth) { + Map map = new HashMap<>(); + map.put(1, amount); + return map; + } + + /** + * 总利息 + * @param amount + * @param yearRate + * @param totalmonth + * @return + */ + public static BigDecimal getInterestCount(BigDecimal amount, BigDecimal yearRate, int totalmonth) { + BigDecimal monthInterest = yearRate.divide(new BigDecimal("12"), 8, BigDecimal.ROUND_HALF_UP); + BigDecimal multiply =amount.multiply(monthInterest).multiply(new BigDecimal(totalmonth)).divide(new BigDecimal("1"), 8, BigDecimal.ROUND_HALF_UP); + return multiply; + } + + + public static void main(String[] args) { + BigDecimal invest = new BigDecimal("10000"); // 本金 + int month = 12; + BigDecimal yearRate = new BigDecimal("0.12"); // 年利率 + + Map getPerMonthPrincipalInterest = getPerMonthPrincipal(invest, yearRate, month); + System.out.println("一次还本还息---偿还本金:" + getPerMonthPrincipalInterest); + Map mapInterest = getPerMonthInterest(invest, yearRate, month); + System.out.println("一次还本还息---总利息:" + mapInterest); + BigDecimal count = getInterestCount(invest, yearRate, month); + System.out.println("一次还本还息---总利息:" + count); + } +} \ No newline at end of file diff --git a/service-core/src/main/resources/application.yml b/service-core/src/main/resources/application.yml index 4b700b09d8708c26dbe3c861dbad4250f2736904..75ba3bc91fc8490c08b85e3dd5c1c672055acfb5 100644 --- a/service-core/src/main/resources/application.yml +++ b/service-core/src/main/resources/application.yml @@ -28,6 +28,12 @@ spring: nacos: discovery: server-addr: 192.168.56.10:8848 # 配置nacos注册中心地址 + rabbitmq: + host: 192.168.56.10 + port: 5672 + virtual-host: /srb-host + username: srb-user + password: 1234 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl diff --git a/service-core/src/main/resources/logback-spring.xml b/service-core/src/main/resources/logback-spring.xml deleted file mode 100644 index ff896d4974436ca5a8fb0ed0496a0d1f203d5ad7..0000000000000000000000000000000000000000 --- a/service-core/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - wwjSrb - - - - - - - - - - - - - - - - - - - - - ${CONSOLE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/log.log - true - - ${FILE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/log-rolling.log - - ${FILE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log - - 15 - - - 10MB - - - - - - - - - - - - - - - - - - - - - - - diff --git a/service-gateway/src/main/resources/logback-spring.xml b/service-gateway/src/main/resources/logback-spring.xml deleted file mode 100644 index 2726e3d30813977171efe158f5c288b1ff8f18fd..0000000000000000000000000000000000000000 --- a/service-gateway/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - wwjSrb - - - - - - - - - - - - - - - - - - - - - ${CONSOLE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/log.log - true - - ${FILE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/log-rolling.log - - ${FILE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log - - 15 - - - 10MB - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/service-oss/src/main/resources/application.yml b/service-oss/src/main/resources/application.yml index 4cdca4ade61d159569e37e5f6325f1e104dfaf98..27f2b3bc71fd876dc0877f59fcd33b534d6404ca 100644 --- a/service-oss/src/main/resources/application.yml +++ b/service-oss/src/main/resources/application.yml @@ -10,6 +10,14 @@ spring: discovery: server-addr: 192.168.56.10:8848 # 配置nacos注册中心地址 +# 阿里云对象存储服务配置 +#aliyun: +# oss: +# endpoint: xxxxxx +# keyId: xxxxxx +# keySecret: xxxxxx +# bucketName: xxxxxx + # 阿里云对象存储服务配置 aliyun: oss: diff --git a/service-oss/src/main/resources/logback-spring.xml b/service-oss/src/main/resources/logback-spring.xml deleted file mode 100644 index 443d1eee8fe18494d0b1db2ee32c9561fba45ce6..0000000000000000000000000000000000000000 --- a/service-oss/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - wwjSrb - - - - - - - - - - - - - - - - - - - - - ${CONSOLE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/log.log - true - - ${FILE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/log-rolling.log - - ${FILE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log - - 15 - - - 10MB - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/service-sms/pom.xml b/service-sms/pom.xml index 8a87132a67f6f452fbfd44d1ea8ce1792e8afdd5..2785c9e6ff87301aa0c553c4cc06b0b06bc74036 100644 --- a/service-sms/pom.xml +++ b/service-sms/pom.xml @@ -41,5 +41,11 @@ spring-boot-configuration-processor true + + + com.wwj + rabbit-mq + 0.0.1-SNAPSHOT + \ No newline at end of file diff --git a/service-sms/src/main/java/com/wwj/srb/sms/controller/api/ApiSmsController.java b/service-sms/src/main/java/com/wwj/srb/sms/controller/api/ApiSmsController.java index d4d9064f51a4463c75d9ebda218069df17f07bca..a93cda593ff7b86d41579bf0aa4342ce67fdd3d0 100644 --- a/service-sms/src/main/java/com/wwj/srb/sms/controller/api/ApiSmsController.java +++ b/service-sms/src/main/java/com/wwj/srb/sms/controller/api/ApiSmsController.java @@ -7,14 +7,16 @@ import com.wwj.common.util.RandomUtils; import com.wwj.common.util.RegexValidateUtils; import com.wwj.srb.sms.client.CoreUserInfoClient; import com.wwj.srb.sms.service.SmsService; -import com.wwj.srb.sms.util.SmsProperties; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.HashMap; @@ -53,7 +55,7 @@ public class ApiSmsController { Map map = new HashMap<>(); String code = RandomUtils.getFourBitRandom(); map.put("code", code); - smsService.send(mobile, SmsProperties.TEMPLATE_CODE, map); +// smsService.send(mobile, SmsProperties.TEMPLATE_CODE, map); // 调用阿里云短信服务发送短信 // 将验证码存入Redis,过期时间为5分钟 redisTemplate.opsForValue().set("srb:sms:code:" + mobile, code, 5, TimeUnit.MINUTES); diff --git a/service-sms/src/main/java/com/wwj/srb/sms/receiver/SmsReceiver.java b/service-sms/src/main/java/com/wwj/srb/sms/receiver/SmsReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..5b18f1638353f76f78aef037dcb5da9dc716cc6d --- /dev/null +++ b/service-sms/src/main/java/com/wwj/srb/sms/receiver/SmsReceiver.java @@ -0,0 +1,36 @@ +package com.wwj.srb.sms.receiver; + +import com.wwj.srb.base.dto.SmsDTO; +import com.wwj.srb.rabbitutil.constant.MQConst; +import com.wwj.srb.sms.service.SmsService; +import com.wwj.srb.sms.util.SmsProperties; +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.annotation.Exchange; +import org.springframework.amqp.rabbit.annotation.Queue; +import org.springframework.amqp.rabbit.annotation.QueueBinding; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +@Component +@Slf4j +public class SmsReceiver { + + @Resource + private SmsService smsService; + + @RabbitListener(bindings = @QueueBinding( + value = @Queue(value = MQConst.QUEUE_SMS_ITEM, durable = "true"), + exchange = @Exchange(value = MQConst.EXCHANGE_TOPIC_SMS), + key = {MQConst.ROUTING_SMS_ITEM})) + public void send(SmsDTO smsDTO) throws IOException { + log.info("SmsReceiver 消息监听"); + Map param = new HashMap<>(); + param.put("code", smsDTO.getMessage()); + smsService.send(smsDTO.getMobile(), SmsProperties.TEMPLATE_CODE, param); + } +} diff --git a/service-sms/src/main/resources/application.yml b/service-sms/src/main/resources/application.yml index 2dbf99f1fa11f030279c37cfae3617edc6ff3c77..204c6ae227a49d5e56f9d5a546cb4181f9f27420 100644 --- a/service-sms/src/main/resources/application.yml +++ b/service-sms/src/main/resources/application.yml @@ -21,6 +21,12 @@ spring: nacos: discovery: server-addr: 192.168.56.10:8848 # 配置nacos注册中心地址 + rabbitmq: + host: 192.168.56.10 + port: 5672 + virtual-host: /srb-host + username: srb-user + password: 1234 # openfeign默认的超时时间为1秒,为了防止远程调用出现超时的情况,这里将超时时间设置得更长一些 feign: @@ -46,4 +52,4 @@ aliyun: sign-name: 谷粒 logging: level: - com.wwj.srb.sms.client.CoreUserInfoClient: DEBUG # 以debug级别监控远程服务接口 + com.wwj.srb.sms.client.CoreUserInfoClient: DEBUG # 以debug级别监控远程服务接口 \ No newline at end of file diff --git a/service-sms/src/main/resources/logback-spring.xml b/service-sms/src/main/resources/logback-spring.xml deleted file mode 100644 index eff67429ff8f55b493bcb9957e9728e53cbeff10..0000000000000000000000000000000000000000 --- a/service-sms/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - wwjSrb - - - - - - - - - - - - - - - - - - - - - ${CONSOLE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/log.log - true - - ${FILE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/log-rolling.log - - ${FILE_LOG_PATTERN} - ${ENCODING} - - - - - - ${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log - - 15 - - - 10MB - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/srb_core.sql b/srb_core.sql new file mode 100644 index 0000000000000000000000000000000000000000..62b3fb618176676ac15a21171fb054abd0d22e1d --- /dev/null +++ b/srb_core.sql @@ -0,0 +1,485 @@ +/* + Navicat Premium Data Transfer + + Source Server : localhost + Source Server Type : MySQL + Source Server Version : 50721 + Source Host : localhost:3306 + Source Schema : srb_core + + Target Server Type : MySQL + Target Server Version : 50721 + File Encoding : 65001 + + Date: 21/03/2021 22:39:29 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for borrow_info +-- ---------------------------- +DROP TABLE IF EXISTS `borrow_info`; +CREATE TABLE `borrow_info` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '借款用户id', + `amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '借款金额', + `period` int(11) NULL DEFAULT NULL COMMENT '借款期限', + `borrow_year_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '年化利率', + `return_method` tinyint(3) NULL DEFAULT NULL COMMENT '还款方式 1-等额本息 2-等额本金 3-每月还息一次还本 4-一次还本', + `money_use` tinyint(3) NULL DEFAULT NULL COMMENT '资金用途', + `status` tinyint(3) NOT NULL DEFAULT 0 COMMENT '状态(0:未提交,1:审核中, 2:审核通过, -1:审核不通过)', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '借款信息表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of borrow_info +-- ---------------------------- + +-- ---------------------------- +-- Table structure for borrower +-- ---------------------------- +DROP TABLE IF EXISTS `borrower`; +CREATE TABLE `borrower` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '用户id', + `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名', + `id_card` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '身份证号', + `mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手机', + `sex` tinyint(3) NULL DEFAULT NULL COMMENT '性别(1:男 0:女)', + `age` tinyint(3) NULL DEFAULT NULL COMMENT '年龄', + `education` tinyint(3) NULL DEFAULT NULL COMMENT '学历', + `is_marry` tinyint(1) NULL DEFAULT NULL COMMENT '是否结婚(1:是 0:否)', + `industry` tinyint(3) NULL DEFAULT NULL COMMENT '行业', + `income` tinyint(3) NULL DEFAULT NULL COMMENT '月收入', + `return_source` tinyint(3) NULL DEFAULT NULL COMMENT '还款来源', + `contacts_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人名称', + `contacts_mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系人手机', + `contacts_relation` tinyint(3) NULL DEFAULT NULL COMMENT '联系人关系', + `status` tinyint(3) NOT NULL DEFAULT 0 COMMENT '状态(0:未认证,1:认证中, 2:认证通过, -1:认证失败)', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_user_id`(`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '借款人' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of borrower +-- ---------------------------- + +-- ---------------------------- +-- Table structure for borrower_attach +-- ---------------------------- +DROP TABLE IF EXISTS `borrower_attach`; +CREATE TABLE `borrower_attach` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `borrower_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '借款人id', + `image_type` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片类型(idCard1:身份证正面,idCard2:身份证反面,house:房产证,car:车)', + `image_url` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片路径', + `image_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片名称', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_borrower_id`(`borrower_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '借款人上传资源表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of borrower_attach +-- ---------------------------- + +-- ---------------------------- +-- Table structure for dict +-- ---------------------------- +DROP TABLE IF EXISTS `dict`; +CREATE TABLE `dict` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `parent_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '上级id', + `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '名称', + `value` int(11) NULL DEFAULT NULL COMMENT '值', + `dict_code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '编码', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '删除标记(0:不可用 1:可用)', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_parent_id_value`(`parent_id`, `value`) USING BTREE, + INDEX `idx_parent_id`(`parent_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 82008 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '数据字典' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of dict +-- ---------------------------- +INSERT INTO `dict` VALUES (1, 0, '全部分类', NULL, 'ROOT', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (20000, 1, '行业', NULL, 'industry', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (20001, 20000, 'IT', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (20002, 20000, '医生', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (20003, 20000, '教师', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (20004, 20000, '导游', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (20005, 20000, '律师', 5, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (20006, 20000, '其他', 6, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (30000, 1, '学历', NULL, 'education', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (30001, 30000, '高中', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (30002, 30000, '大专', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (30003, 30000, '本科', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (30004, 30000, '研究生', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (30005, 30000, '其他', 5, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (40000, 1, '收入', NULL, 'income', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (40001, 40000, '0-3000', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (40002, 40000, '3000-5000', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (40003, 40000, '5000-10000', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (40004, 40000, '10000以上', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (50000, 1, '收入来源', NULL, 'returnSource', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (50001, 50000, '工资', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (50002, 50000, '股票', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (50003, 50000, '兼职', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (60000, 1, '关系', NULL, 'relation', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (60001, 60000, '夫妻', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (60002, 60000, '兄妹', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (60003, 60000, '父母', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (60004, 60000, '其他', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (70000, 1, '还款方式', NULL, 'returnMethod', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (70001, 70000, '等额本息', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (70002, 70000, '等额本金', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (70003, 70000, '每月还息一次还本', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (70004, 70000, '一次还本还息', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (80000, 1, '资金用途', NULL, 'moneyUse', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (80001, 80000, '旅游', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (80002, 80000, '买房', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (80003, 80000, '装修', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (80004, 80000, '医疗', 4, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (80005, 80000, '美容', 5, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (80006, 80000, '其他', 6, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (81000, 1, '借款状态', NULL, 'borrowStatus', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (81001, 81000, '待审核', 0, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (81002, 81000, '审批通过', 1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (81003, 81000, '还款中', 2, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (81004, 81000, '结束', 3, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (81005, 81000, '审批不通过', -1, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (82000, 1, '学校性质', NULL, 'SchoolStatus', '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (82001, 82000, '211/985', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (82002, 82000, '一本', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (82003, 82000, '二本', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (82004, 82000, '三本', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (82005, 82000, '高职高专', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (82006, 82000, '中职中专', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); +INSERT INTO `dict` VALUES (82007, 82000, '高中及以下', NULL, NULL, '2021-02-20 00:26:22', '2021-02-20 00:26:22', 0); + +-- ---------------------------- +-- Table structure for integral_grade +-- ---------------------------- +DROP TABLE IF EXISTS `integral_grade`; +CREATE TABLE `integral_grade` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `integral_start` int(11) NULL DEFAULT NULL COMMENT '积分区间开始', + `integral_end` int(11) NULL DEFAULT NULL COMMENT '积分区间结束', + `borrow_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '借款额度', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '积分等级表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of integral_grade +-- ---------------------------- +INSERT INTO `integral_grade` VALUES (1, 10, 50, 10000.00, '2020-12-08 17:02:29', '2021-02-19 17:58:10', 0); +INSERT INTO `integral_grade` VALUES (2, 51, 100, 30000.00, '2020-12-08 17:02:42', '2021-02-19 18:00:25', 0); +INSERT INTO `integral_grade` VALUES (3, 101, 2000, 100000.00, '2020-12-08 17:02:57', '2021-02-23 21:03:03', 0); + +-- ---------------------------- +-- Table structure for lend +-- ---------------------------- +DROP TABLE IF EXISTS `lend`; +CREATE TABLE `lend` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `user_id` bigint(20) NULL DEFAULT NULL COMMENT '借款用户id', + `borrow_info_id` bigint(20) NULL DEFAULT NULL COMMENT '借款信息id', + `lend_no` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标的编号', + `title` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标题', + `amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '标的金额', + `period` int(11) NULL DEFAULT NULL COMMENT '投资期数', + `lend_year_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '年化利率', + `service_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '平台服务费率', + `return_method` tinyint(3) NULL DEFAULT NULL COMMENT '还款方式', + `lowest_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '最低投资金额', + `invest_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '已投金额', + `invest_num` int(11) NULL DEFAULT NULL COMMENT '投资人数', + `publish_date` datetime(0) NULL DEFAULT NULL COMMENT '发布日期', + `lend_start_date` date NULL DEFAULT NULL COMMENT '开始日期', + `lend_end_date` date NULL DEFAULT NULL COMMENT '结束日期', + `lend_info` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '说明', + `expect_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '平台预期收益', + `real_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '实际收益', + `status` tinyint(3) NOT NULL DEFAULT 0 COMMENT '状态', + `check_time` datetime(0) NULL DEFAULT NULL COMMENT '审核时间', + `check_admin_id` bigint(1) NULL DEFAULT NULL COMMENT '审核用户id', + `payment_time` datetime(0) NULL DEFAULT NULL COMMENT '放款时间', + `payment_admin_id` datetime(0) NULL DEFAULT NULL COMMENT '放款人id', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_lend_no`(`lend_no`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE, + INDEX `idx_borrow_info_id`(`borrow_info_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '标的准备表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of lend +-- ---------------------------- + +-- ---------------------------- +-- Table structure for lend_item +-- ---------------------------- +DROP TABLE IF EXISTS `lend_item`; +CREATE TABLE `lend_item` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `lend_item_no` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '投资编号', + `lend_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '标的id', + `invest_user_id` bigint(20) NULL DEFAULT NULL COMMENT '投资用户id', + `invest_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '投资人名称', + `invest_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '投资金额', + `lend_year_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '年化利率', + `invest_time` datetime(0) NULL DEFAULT NULL COMMENT '投资时间', + `lend_start_date` date NULL DEFAULT NULL COMMENT '开始日期', + `lend_end_date` date NULL DEFAULT NULL COMMENT '结束日期', + `expect_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '预期收益', + `real_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '实际收益', + `status` tinyint(3) NULL DEFAULT NULL COMMENT '状态(0:默认 1:已支付 2:已还款)', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_lend_item_no`(`lend_item_no`) USING BTREE, + INDEX `idx_lend_id`(`lend_id`) USING BTREE, + INDEX `idx_invest_user_id`(`invest_user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '标的出借记录表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of lend_item +-- ---------------------------- + +-- ---------------------------- +-- Table structure for lend_item_return +-- ---------------------------- +DROP TABLE IF EXISTS `lend_item_return`; +CREATE TABLE `lend_item_return` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `lend_return_id` bigint(20) NULL DEFAULT NULL COMMENT '标的还款id', + `lend_item_id` bigint(20) NULL DEFAULT NULL COMMENT '标的项id', + `lend_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '标的id', + `invest_user_id` bigint(1) NULL DEFAULT NULL COMMENT '出借用户id', + `invest_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '出借金额', + `current_period` int(11) NULL DEFAULT NULL COMMENT '当前的期数', + `lend_year_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '年化利率', + `return_method` tinyint(3) NULL DEFAULT NULL COMMENT '还款方式 1-等额本息 2-等额本金 3-每月还息一次还本 4-一次还本', + `principal` decimal(10, 2) NULL DEFAULT NULL COMMENT '本金', + `interest` decimal(10, 2) NULL DEFAULT NULL COMMENT '利息', + `total` decimal(10, 2) NULL DEFAULT NULL COMMENT '本息', + `fee` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '手续费', + `return_date` date NULL DEFAULT NULL COMMENT '还款时指定的还款日期', + `real_return_time` datetime(0) NULL DEFAULT NULL COMMENT '实际发生的还款时间', + `is_overdue` tinyint(1) NULL DEFAULT NULL COMMENT '是否逾期', + `overdue_total` decimal(10, 2) NULL DEFAULT NULL COMMENT '逾期金额', + `status` tinyint(3) NULL DEFAULT NULL COMMENT '状态(0-未归还 1-已归还)', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_lend_return_id`(`lend_return_id`) USING BTREE, + INDEX `idx_lend_item_id`(`lend_item_id`) USING BTREE, + INDEX `idx_lend_id`(`lend_id`) USING BTREE, + INDEX `idx_invest_user_id`(`invest_user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '标的出借回款记录表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of lend_item_return +-- ---------------------------- + +-- ---------------------------- +-- Table structure for lend_return +-- ---------------------------- +DROP TABLE IF EXISTS `lend_return`; +CREATE TABLE `lend_return` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `lend_id` bigint(20) NULL DEFAULT NULL COMMENT '标的id', + `borrow_info_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '借款信息id', + `return_no` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '还款批次号', + `user_id` bigint(20) NULL DEFAULT NULL COMMENT '借款人用户id', + `amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '借款金额', + `base_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '计息本金额', + `current_period` int(11) NULL DEFAULT NULL COMMENT '当前的期数', + `lend_year_rate` decimal(10, 2) NULL DEFAULT NULL COMMENT '年化利率', + `return_method` tinyint(3) NULL DEFAULT NULL COMMENT '还款方式 1-等额本息 2-等额本金 3-每月还息一次还本 4-一次还本', + `principal` decimal(10, 2) NULL DEFAULT NULL COMMENT '本金', + `interest` decimal(10, 2) NULL DEFAULT NULL COMMENT '利息', + `total` decimal(10, 2) NULL DEFAULT NULL COMMENT '本息', + `fee` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '手续费', + `return_date` date NULL DEFAULT NULL COMMENT '还款时指定的还款日期', + `real_return_time` datetime(0) NULL DEFAULT NULL COMMENT '实际发生的还款时间', + `is_overdue` tinyint(1) NULL DEFAULT NULL COMMENT '是否逾期', + `overdue_total` decimal(10, 2) NULL DEFAULT NULL COMMENT '逾期金额', + `is_last` tinyint(1) NULL DEFAULT NULL COMMENT '是否最后一次还款', + `status` tinyint(3) NULL DEFAULT NULL COMMENT '状态(0-未归还 1-已归还)', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_return_no`(`return_no`) USING BTREE, + INDEX `idx_lend_id`(`lend_id`) USING BTREE, + INDEX `idx_borrow_info_id`(`borrow_info_id`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '还款记录表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of lend_return +-- ---------------------------- + +-- ---------------------------- +-- Table structure for trans_flow +-- ---------------------------- +DROP TABLE IF EXISTS `trans_flow`; +CREATE TABLE `trans_flow` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '用户id', + `user_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名称', + `trans_no` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '交易单号', + `trans_type` tinyint(3) NOT NULL DEFAULT 0 COMMENT '交易类型(1:充值 2:提现 3:投标 4:投资回款 ...)', + `trans_type_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '交易类型名称', + `trans_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '交易金额', + `memo` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_trans_no`(`trans_no`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 57 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '交易流水表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of trans_flow +-- ---------------------------- + +-- ---------------------------- +-- Table structure for user_account +-- ---------------------------- +DROP TABLE IF EXISTS `user_account`; +CREATE TABLE `user_account` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '用户id', + `amount` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '帐户可用余额', + `freeze_amount` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '冻结金额', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + `version` int(11) NOT NULL DEFAULT 0 COMMENT '版本号', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_user_id`(`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户账户' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of user_account +-- ---------------------------- + +-- ---------------------------- +-- Table structure for user_bind +-- ---------------------------- +DROP TABLE IF EXISTS `user_bind`; +CREATE TABLE `user_bind` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '用户id', + `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户姓名', + `id_card` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '身份证号', + `bank_no` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '银行卡号', + `bank_type` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '银行类型', + `mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '手机号', + `bind_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '绑定账户协议号', + `status` tinyint(3) NULL DEFAULT NULL COMMENT '状态', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_user_id`(`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户绑定表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of user_bind +-- ---------------------------- + +-- ---------------------------- +-- Table structure for user_info +-- ---------------------------- +DROP TABLE IF EXISTS `user_info`; +CREATE TABLE `user_info` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `user_type` tinyint(3) NOT NULL DEFAULT 0 COMMENT '1:出借人 2:借款人', + `mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '手机号', + `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '用户密码', + `nick_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户昵称', + `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户姓名', + `id_card` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '身份证号', + `email` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱', + `openid` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '微信用户标识openid', + `head_img` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '头像', + `bind_status` tinyint(3) NOT NULL DEFAULT 0 COMMENT '绑定状态(0:未绑定,1:绑定成功 -1:绑定失败)', + `borrow_auth_status` tinyint(3) NOT NULL DEFAULT 0 COMMENT '借款人认证状态(0:未认证 1:认证中 2:认证通过 -1:认证失败)', + `bind_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '绑定账户协议号', + `integral` int(11) NOT NULL DEFAULT 0 COMMENT '用户积分', + `status` tinyint(3) NOT NULL DEFAULT 1 COMMENT '状态(0:锁定 1:正常)', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + INDEX `uk_mobile`(`mobile`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户基本信息' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of user_info +-- ---------------------------- + +-- ---------------------------- +-- Table structure for user_integral +-- ---------------------------- +DROP TABLE IF EXISTS `user_integral`; +CREATE TABLE `user_integral` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户id', + `integral` int(11) NULL DEFAULT NULL COMMENT '积分', + `content` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '获取积分说明', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户积分记录表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of user_integral +-- ---------------------------- + +-- ---------------------------- +-- Table structure for user_login_record +-- ---------------------------- +DROP TABLE IF EXISTS `user_login_record`; +CREATE TABLE `user_login_record` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户id', + `ip` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'ip', + `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', + `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除,0:未删除)', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 29 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户登录记录表' ROW_FORMAT = DYNAMIC; + +-- ---------------------------- +-- Records of user_login_record +-- ---------------------------- + +SET FOREIGN_KEY_CHECKS = 1;