diff --git a/LICENSE b/LICENSE
index 02258e34..3462706c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,165 @@
-MIT License
-
-Copyright (c) 2017 https://github.com/jmdhappy/xxpay-master
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/README.md b/README.md
index e660ece8..0809a71f 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,120 @@
-### 郑重声明
+
+
+
+
+ 适合互联网企业使用的开源支付系统
+
+
+ 👉 https://www.jeepay.vip 👈
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+-------------------------------------------------------------------------------
+
+## 📚 项目介绍
+
+Jeepay是一套适合互联网企业使用的开源支付系统,支持多渠道服务商和普通商户模式。已对接`微信支付`,`支付宝`,`云闪付`官方接口,支持聚合码支付。
+
+Jeepay使用`Spring Boot`和`Ant Design Vue`开发,集成`Spring Security`实现权限管理功能,是一套非常实用的web开发框架。
+
+### 🎁 名称的由来
+
+Jeepay = Jee + pay,是由原XxPay支付系统作者带领团队开发,“Jee”是公司计全科技名称的表示,pay表示支付。中文名称为计全支付,释为:计出万全、支付安全,让支付更加方便安全。
+
+
+### 🍟 项目体验
+
+- Jeepay支付流程体验:[https://www.jeequan.com/demo/jeepay_cashier.html](https://www.jeequan.com/demo/jeepay_cashier.html "Jeepay支付体验")
+- Jeepay运营平台和商户系统演体验:[https://www.jeequan.com/doc/detail_84.html](https://www.jeequan.com/doc/detail_84.html "Jeepay支付系统体验")
+- Jeepay项目文档:[https://www.jeepay.vip](https://www.jeepay.vip "Jeepay项目文档")
+
+### 🍎 项目特点
+
+* 支持多渠道对接,支付网关自动路由
+* 已对接`微信`服务商和普通商户接口,支持`V2`和`V3`接口
+* 已对接`支付宝`服务商和普通商户接口,支持RSA和RSA2签名
+* 已对接`云闪付`服务商接口,可选择多家支付机构
+* 提供http形式接口,提供各语言的`sdk`实现,方便对接
+* 接口请求和响应数据采用签名机制,保证交易安全可靠
+* 系统安全,支持`分布式`部署,`高并发`
+* 管理端包括`运营平台`和`商户系统`
+* 管理平台操作界面简洁、易用
+* 支付平台到商户系统的订单通知使用MQ实现,保证了高可用,消息可达
+* 支付渠道的接口参数配置界面自动化生成
+* 使用`spring security`实现权限管理
+* 前后端分离架构,方便二次开发
+* 由原`XxPay`团队开发,有着多年支付系统开发经验
+
+## 🥞 系统架构
+
+> Jeepay计全支付系统架构图

-> 原`XxPay聚合支付`项目已更名为Jeepay,由原XxPay团队开发维护。目前`Jeepay`开发已经进入收尾阶段,最晚6月初会发布源码到Github和码云上。
-
-> 新版Jeepay支付系统,使用SpringBoot + Ant Vue开发,适合互联网企业搭建内部支付系统。支持普通商户和服务商模式,已对接微信、支付宝、云闪付官方通道。统一的下单接口,实现主扫/被扫(聚合)。
-
-> 请关注官方网站[www.jeequan.com](https://www.jeequan.com "计全科技官网")或官方公众号(微信搜索:计全科技),获取Jeepay最新发布消息,如果您喜欢该项目,不妨随手Star下。
-
-> 待发布源码时,会更公布官方qq或微信技术交流群,同时会发布使用文档及演示地址。
-
-### 功能列表
+> 核心技术栈
+
+| 软件名称 | 描述 | 版本
+|---|---|---
+|Jdk | Java环境 | 1.8
+|Spring Boot | 开发框架 | 2.4.5
+|Redis | 分布式缓存 | 3.2.8 或 高版本
+|MySQL | 数据库 | 5.7.X
+|ActiveMQ | 消息中间件 | 5.15.8 或 高版本
+|[Ant Design Vue](https://www.antdv.com/docs/vue/introduce-cn/) | Ant Design的Vue实现,前端开发使用 | 2.1.2
+|[MyBatis-Plus](https://mp.baomidou.com/) | MyBatis增强工具 | 3.4.2
+|[WxJava](https://gitee.com/binary/weixin-java-tools) | 微新开发Java SDK | 4.0.0
+|[Hutool](https://www.hutool.cn/) | Java工具类库 | 5.6.6
+
+> 项目结构
+
+```lua
+jeepay-ui -- https://gitee.com/jeequan/jeepay-ui
+
+jeepay
+├── conf -- 存放系统部署使用的.yml文件
+└── docs -- 存放项目相关文档说明
+ ├── script -- 项目启动shell脚本
+ └── sql -- 初始化sql文件
+├── jeepay-core -- 核心依赖包
+├── jeepay-manager -- 运营平台服务端[9217]
+├── jeepay-merchant -- 商户系统服务端[9218]
+├── jeepay-payment -- 支付网关[9216]
+├── jeepay-service -- 业务层代码
+└── jeepay-z-codegen -- mybatis代码生成
+```
+
+> 开发部署
+
+- 系统开发:[https://www.jeepay.vip/#/develop/dev_serv](https://www.jeepay.vip/#/develop/dev_serv)
+- 通道对接:[https://www.jeepay.vip/#/develop/dev_channel](https://www.jeepay.vip/#/develop/dev_channel)
+- 线上部署:[https://www.jeepay.vip/#/develop/deploy](https://www.jeepay.vip/#/develop/deploy)
+- 接口文档:[https://www.jeepay.vip/#/interface/payment_api](https://www.jeepay.vip/#/interface/payment_api)
+
+## 🍿 功能模块
> Jeepay运营平台功能
@@ -20,7 +124,7 @@

-### 功能预览
+## 🍯 系统截图
`以下截图是从实际已完成功能界面截取,截图时间为:2021-05-29 02:05`
@@ -28,18 +132,10 @@

-
-
-
-


-
-
-
-


@@ -54,21 +150,9 @@

-
-
-
-
-
-
-
-
-
-
-
-

-### 关于我们
+## 🥪 关于我们
***
微信扫描下面二维码,关注官方公众号:计全科技,获取更多精彩内容。
diff --git a/conf/manager/application.yml b/conf/manager/application.yml
new file mode 100644
index 00000000..b97ff675
--- /dev/null
+++ b/conf/manager/application.yml
@@ -0,0 +1,45 @@
+#################################
+# spring boot支持外部application.yml 读取优先级为:
+# 1、file:./config/(当前目录下的config文件夹)
+# 2、file:./(当前目录)
+# 3、classpath:/config/(classpath下的config目录)
+# 4、classpath:/(classpath根目录)
+# 建议: 如果是jar则放置到与jar相同的目录下, 如果解压文件放置到classpath: config目录下。 (需要将文件重命名为 application.yml )
+#
+# 该yml文件只配置与环境相关的参数, 其他配置读取项目下的配置项
+#
+#################################
+
+server:
+ port: 9217 #设置端口为 9217
+spring:
+ datasource:
+ # yml填写url连接串, 无需将&符号进行转义
+ url: jdbc:mysql://127.0.0.1:3306/jeepaydb?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false
+ username: jeepay
+ password: 123456
+ redis:
+ host: 127.0.0.1
+ port: 6379
+ password:
+ #activeMQ配置
+ activemq:
+ broker-url: tcp://localhost:61616 #连接地址
+
+ #日志配置参数。
+ # 当存在logback-spring.xml文件时: 该配置将引进到logback配置, springboot配置不生效。
+ # 不存在logback-spring.xml 文件时, 使用springboot的配置, 同样可用。
+logging:
+ level:
+ root: info #主日志级别
+ com.jeequan.jeepay: debug #该项目日志级别,当需要打印sql时请开启为debug
+ path: ./logs #日志存放地址
+
+#系统业务参数
+isys:
+ allow-cors: false #是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时,应开启此配置或在nginx统一配置允许跨域]
+ jwt-secret: t7w3P8X6472qWc3u #生成jwt的秘钥。 要求每个系统有单独的秘钥管理机制。
+
+ # 文件系统配置项(系统内oss, 并非云oss)
+ oss-file:
+ root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
diff --git a/conf/merchant/application.yml b/conf/merchant/application.yml
new file mode 100644
index 00000000..029965f5
--- /dev/null
+++ b/conf/merchant/application.yml
@@ -0,0 +1,45 @@
+#################################
+# spring boot支持外部application.yml 读取优先级为:
+# 1、file:./config/(当前目录下的config文件夹)
+# 2、file:./(当前目录)
+# 3、classpath:/config/(classpath下的config目录)
+# 4、classpath:/(classpath根目录)
+# 建议: 如果是jar则放置到与jar相同的目录下, 如果解压文件放置到classpath: config目录下。 (需要将文件重命名为 application.yml )
+#
+# 该yml文件只配置与环境相关的参数, 其他配置读取项目下的配置项
+#
+#################################
+
+server:
+ port: 9218 # 设置端口为 9218
+spring:
+ datasource:
+ # yml填写url连接串, 无需将&符号进行转义
+ url: jdbc:mysql://127.0.0.1:3306/jeepaydb?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false
+ username: jeepay
+ password: 123456
+ redis:
+ host: 127.0.0.1
+ port: 6379
+ password:
+ #activeMQ配置
+ activemq:
+ broker-url: tcp://localhost:61616 #连接地址
+
+ #日志配置参数。
+ # 当存在logback-spring.xml文件时: 该配置将引进到logback配置, springboot配置不生效。
+ # 不存在logback-spring.xml 文件时, 使用springboot的配置, 同样可用。
+logging:
+ level:
+ root: info #主日志级别
+ com.jeequan.jeepay: debug #该项目日志级别,当需要打印sql时请开启为debug
+ path: ./logs #日志存放地址
+
+#系统业务参数
+isys:
+ allow-cors: false #是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时,应开启此配置或在nginx统一配置允许跨域]
+ jwt-secret: ARNXp4MzjOOQqxtv #生成jwt的秘钥。 要求每个系统有单独的秘钥管理机制。
+
+ # 文件系统配置项(系统内oss, 并非云oss)
+ oss-file:
+ root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
\ No newline at end of file
diff --git a/conf/payment/application.yml b/conf/payment/application.yml
new file mode 100644
index 00000000..177bcfea
--- /dev/null
+++ b/conf/payment/application.yml
@@ -0,0 +1,44 @@
+#################################
+# spring boot支持外部application.yml 读取优先级为:
+# 1、file:./config/(当前目录下的config文件夹)
+# 2、file:./(当前目录)
+# 3、classpath:/config/(classpath下的config目录)
+# 4、classpath:/(classpath根目录)
+# 建议: 如果是jar则放置到与jar相同的目录下, 如果解压文件放置到classpath: config目录下。 (需要将文件重命名为 application.yml )
+#
+# 该yml文件只配置与环境相关的参数, 其他配置读取项目下的配置项
+#
+#################################
+
+server:
+ port: 9216 #设置端口为 9216
+spring:
+ datasource:
+ # yml填写url连接串, 无需将&符号进行转义
+ url: jdbc:mysql://127.0.0.1:3306/jeepaydb?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false
+ username: jeepay
+ password: 123456
+ redis:
+ host: 127.0.0.1
+ port: 6379
+ password:
+ #activeMQ配置
+ activemq:
+ broker-url: tcp://localhost:61616 #连接地址
+
+ #日志配置参数。
+ # 当存在logback-spring.xml文件时: 该配置将引进到logback配置, springboot配置不生效。
+ # 不存在logback-spring.xml 文件时, 使用springboot的配置, 同样可用。
+logging:
+ level:
+ root: info #主日志级别
+ com.jeequan.jeepay: debug #该项目日志级别,当需要打印sql时请开启为debug
+ path: ./logs #日志存放地址
+
+#系统业务参数
+isys:
+ allow-cors: false #是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时,应开启此配置或在nginx统一配置允许跨域]
+
+ # 文件系统配置项(系统内oss, 并非云oss)
+ oss-file:
+ root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
\ No newline at end of file
diff --git a/docs/script/app.sh b/docs/script/app.sh
new file mode 100644
index 00000000..5514ef05
--- /dev/null
+++ b/docs/script/app.sh
@@ -0,0 +1,135 @@
+#!/bin/sh
+#功能简介:启动 xxx.jar 文件
+#请先cd到项目下执行
+#注意:在sh文件中=赋值,左右两侧不能有空格
+# .Power by terrfly
+
+#当前所在目录
+PROJECT_PATH=$(cd `dirname $0`; pwd)
+
+#当前所在文件夹名
+PROJECT_NAME="${PROJECT_PATH##*/}"
+
+#jar名称
+APP_NAME='jeepay-'$PROJECT_NAME'.jar'
+
+#=======================================================================
+
+#当前应用进行的变量标识
+APP_PID=''
+
+
+# 重新获取APPID
+function refAppPID(){
+
+ APP_PID=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'`
+}
+
+
+# 获取运行程序的pid 进程号
+function getAppPID(){
+
+ if [ ! $APP_PID ]; then #未获取过
+ refAppPID
+ fi
+}
+
+
+# 启动
+function start(){
+
+ refAppPID #获取进程PID, 需重新获取, 避免restart时无法正确启动。
+
+ if [ $APP_PID ]; then
+ echo " [$APP_NAME] App is running. this start fail. "
+ return 0
+ fi
+
+ nohup java -jar $APP_NAME >/dev/null 2>start.log &
+ # tail -200f start.log
+
+ echo " [$APP_NAME] App starting ... "
+}
+
+# 停止
+function stop(){
+
+ getAppPID #获取进程PID
+
+
+ if [ ! $APP_PID ]; then
+ echo " [$APP_NAME] App is NOT running. "
+ return 0
+ fi
+
+ echo " [$APP_NAME] [pid=$APP_PID] [kill -15] stop process... "
+ kill -15 $APP_PID # kill-15 :正常退出程序
+
+ sleep 5 #等待5s
+
+ # 重新获取PID
+ refAppPID
+
+ #仍然存在 需要kill -9
+ if [ $APP_PID ]; then
+ forcekill
+ fi
+
+ echo " [$APP_NAME] Stop Success! "
+
+}
+
+# 检查
+function check(){
+
+ getAppPID #获取进程PID
+
+ if [ $APP_PID ]; then
+ echo " [$APP_NAME] App is running. PID:[$APP_PID] "
+ else
+ echo " [$APP_NAME] App is NOT running. "
+ fi
+
+}
+
+# 强制kill进程
+function forcekill(){
+
+ getAppPID #获取进程PID
+
+ if [ $APP_PID ]; then
+ echo " [$APP_NAME] [pid=$APP_PID] [kill -9] Kill ing ... "
+ kill -9 $APP_PID
+ echo " [$APP_NAME] [pid=$APP_PID] [kill -9] Kill Success! "
+ else
+ echo " [$APP_NAME] App is NOT running. "
+ fi
+
+}
+
+echo ''
+
+command=$1
+
+if [ "${command}" == "start" ]; then
+ start
+
+elif [ "${command}" == "stop" ]; then
+ stop
+
+elif [ "${command}" == "restart" ]; then
+ stop
+ start
+
+elif [ "${command}" == "check" ]; then
+ check
+
+elif [ "${command}" == "kill" ]; then
+ forcekill
+
+else
+ echo "Usage: $0 {start|stop|restart|check|kill|}"
+fi
+
+echo ''
+
diff --git a/docs/sql/init.sql b/docs/sql/init.sql
new file mode 100644
index 00000000..e058d444
--- /dev/null
+++ b/docs/sql/init.sql
@@ -0,0 +1,567 @@
+#
+# * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+# *
+# * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+# * you may not use this file except in compliance with the License.
+# * You may obtain a copy of the License at
+# *
+# * http://www.gnu.org/licenses/lgpl.html
+# *
+# * Unless required by applicable law or agreed to in writing, software
+# * distributed under the License is distributed on an "AS IS" BASIS,
+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# * See the License for the specific language governing permissions and
+# * limitations under the License.
+#
+##### ↓↓↓↓↓↓↓↓↓↓ 表结构DDL ↓↓↓↓↓↓↓↓↓↓ #####
+
+-- RBAC设计思路: [用户] 1<->N [角色] 1<->N [权限]
+
+-- 权限表
+DROP TABLE IF EXISTS `t_sys_entitlement`;
+CREATE TABLE `t_sys_entitlement` (
+ `ent_id` VARCHAR(32) NOT NULL COMMENT '权限ID[ENT_功能模块_子模块_操作], eg: ENT_ROLE_LIST_ADD',
+ `ent_name` VARCHAR(32) NOT NULL COMMENT '权限名称',
+ `menu_icon` VARCHAR(32) COMMENT '菜单图标',
+ `menu_uri` VARCHAR(128) COMMENT '菜单uri/路由地址',
+ `component_name` VARCHAR(32) COMMENT '组件Name(前后端分离使用)',
+ `ent_type` CHAR(2) NOT NULL COMMENT '权限类型 ML-左侧显示菜单, MO-其他菜单, PB-页面/按钮',
+ `quick_jump` TINYINT(6) NOT NULL DEFAULT 0 COMMENT '快速开始菜单 0-否, 1-是',
+ `state` TINYINT(6) NOT NULL DEFAULT 1 COMMENT '状态 0-停用, 1-启用',
+ `pid` VARCHAR(32) NOT NULL COMMENT '父ID',
+ `ent_sort` INT(11) NOT NULL DEFAULT 0 COMMENT '排序字段, 规则:正序',
+ `system` VARCHAR(8) NOT NULL COMMENT '所属系统: MGR-运营平台, MCH-商户中心',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`ent_id`, `system`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统权限表';
+
+-- 角色表
+DROP TABLE IF EXISTS `t_sys_role`;
+CREATE TABLE `t_sys_role` (
+ `role_id` VARCHAR(32) NOT NULL COMMENT '角色ID, ROLE_开头',
+ `role_name` VARCHAR(32) NOT NULL COMMENT '角色名称',
+ `system` VARCHAR(8) NOT NULL COMMENT '所属系统: MGR-运营平台, MCH-商户中心',
+ `belong_info_id` VARCHAR(64) NOT NULL DEFAULT '0' COMMENT '所属商户ID / 0(平台)',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`role_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统角色表';
+
+-- 角色<->权限 关联表
+DROP TABLE IF EXISTS `t_sys_role_ent_rela`;
+CREATE TABLE `t_sys_role_ent_rela` (
+ `role_id` VARCHAR(32) NOT NULL COMMENT '角色ID',
+ `ent_id` VARCHAR(32) NOT NULL COMMENT '权限ID' ,
+ PRIMARY KEY (`role_id`, `ent_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统角色权限关联表';
+
+-- 系统用户表
+DROP TABLE IF EXISTS `t_sys_user`;
+CREATE TABLE `t_sys_user` (
+ `sys_user_id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '系统用户ID',
+ `login_username` VARCHAR(32) NOT NULL COMMENT '登录用户名',
+ `realname` VARCHAR(32) NOT NULL COMMENT '真实姓名',
+ `telphone` VARCHAR(32) NOT NULL COMMENT '手机号',
+ `sex` TINYINT(6) NOT NULL DEFAULT 0 COMMENT '性别 0-未知, 1-男, 2-女',
+ `avatar_url` VARCHAR(128) COMMENT '头像地址',
+ `user_no` VARCHAR(32) COMMENT '员工编号',
+ `is_admin` TINYINT(6) NOT NULL DEFAULT 0 COMMENT '是否超管(超管拥有全部权限) 0-否 1-是',
+ `state` TINYINT(6) NOT NULL DEFAULT 0 COMMENT '状态 0-停用 1-启用',
+ `system` VARCHAR(8) NOT NULL COMMENT '所属系统: MGR-运营平台, MCH-商户中心',
+ `belong_info_id` VARCHAR(64) NOT NULL DEFAULT '0' COMMENT '所属商户ID / 0(平台)',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`sys_user_id`),
+ UNIQUE KEY(`system`,`login_username`),
+ UNIQUE KEY(`system`,`telphone`),
+ UNIQUE KEY(`system`, `user_no`)
+) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表';
+
+-- 系统用户认证表
+DROP TABLE IF EXISTS `t_sys_user_auth`;
+CREATE TABLE `t_sys_user_auth` (
+ `auth_id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+ `user_id` BIGINT(20) NOT NULL COMMENT 'user_id',
+ `identity_type` TINYINT(6) NOT NULL DEFAULT '0' COMMENT '登录类型 1-登录账号 2-手机号 3-邮箱 10-微信 11-QQ 12-支付宝 13-微博',
+ `identifier` VARCHAR(128) NOT NULL COMMENT '认证标识 ( 用户名 | open_id )',
+ `credential` VARCHAR(128) NOT NULL COMMENT '密码凭证',
+ `salt` VARCHAR(128) NOT NULL COMMENT 'salt',
+ `system` VARCHAR(8) NOT NULL COMMENT '所属系统: MGR-运营平台, MCH-商户中心',
+ PRIMARY KEY (`auth_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 COMMENT='系统用户认证表';
+
+-- 操作员<->角色 关联表
+DROP TABLE IF EXISTS `t_sys_user_role_rela`;
+CREATE TABLE `t_sys_user_role_rela` (
+ `user_id` BIGINT(20) NOT NULL COMMENT '用户ID',
+ `role_id`VARCHAR(32) NOT NULL COMMENT '角色ID',
+ PRIMARY KEY (`user_id`, `role_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作员<->角色 关联表';
+
+
+-- 系统配置表
+DROP TABLE IF EXISTS `t_sys_config`;
+CREATE TABLE `t_sys_config` (
+ `config_key` VARCHAR(50) NOT NULL COMMENT '配置KEY',
+ `config_name` VARCHAR(50) NOT NULL COMMENT '配置名称',
+ `config_desc` VARCHAR(200) NOT NULL COMMENT '描述信息',
+ `group_key` VARCHAR(50) NOT NULL COMMENT '分组key',
+ `group_name` VARCHAR(50) NOT NULL COMMENT '分组名称',
+ `config_val` TEXT NOT NULL COMMENT '配置内容项',
+ `type` VARCHAR(20) NOT NULL DEFAULT 'text' COMMENT '类型: text-输入框, textarea-多行文本, uploadImg-上传图片, switch-开关',
+ `sort_num` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '显示顺序',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`config_key`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统配置表';
+
+-- 系统操作日志表
+DROP TABLE IF EXISTS `t_sys_log`;
+CREATE TABLE `t_sys_log` (
+ `sys_log_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `user_id` bigint(20) DEFAULT NULL COMMENT '系统用户ID',
+ `user_name` varchar(32) DEFAULT NULL COMMENT '用户姓名',
+ `user_ip` varchar(128) NOT NULL DEFAULT '' COMMENT '用户IP',
+ `system` varchar(8) NOT NULL COMMENT '所属系统: MGR-运营平台, MCH-商户中心',
+ `method_name` varchar(128) NOT NULL DEFAULT '' COMMENT '方法名',
+ `method_remark` varchar(128) NOT NULL DEFAULT '' COMMENT '方法描述',
+ `req_url` varchar(256) NOT NULL DEFAULT '' COMMENT '请求地址',
+ `opt_req_param` varchar(2048) NOT NULL DEFAULT '' COMMENT '操作请求参数',
+ `opt_res_info` varchar(2048) NOT NULL DEFAULT '' COMMENT '操作响应结果',
+ `created_at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ PRIMARY KEY (`sys_log_id`)
+) ENGINE = INNODB DEFAULT CHARSET = utf8mb4 COMMENT = '系统操作日志表';
+
+-- 1.商户信息表
+DROP TABLE IF EXISTS t_mch_info;
+CREATE TABLE `t_mch_info` (
+ `mch_no` VARCHAR(64) NOT NULL COMMENT '商户号',
+ `mch_name` VARCHAR(64) NOT NULL COMMENT '商户名称',
+ `mch_short_name` VARCHAR(32) NOT NULL COMMENT '商户简称',
+ `type` TINYINT(6) NOT NULL DEFAULT 1 COMMENT '类型: 1-普通商户, 2-特约商户(服务商模式)',
+ `isv_no` VARCHAR(64) COMMENT '服务商号',
+ `contact_name` VARCHAR(32) COMMENT '联系人姓名',
+ `contact_tel` VARCHAR(32) COMMENT '联系人手机号',
+ `contact_email` VARCHAR(32) COMMENT '联系人邮箱',
+ `private_key` VARCHAR(128) COMMENT '私钥',
+ `state` TINYINT(6) NOT NULL DEFAULT 1 COMMENT '商户状态: 0-停用, 1-正常',
+ `remark` VARCHAR(128) COMMENT '商户备注',
+ `init_user_id` BIGINT(20) DEFAULT NULL COMMENT '初始用户ID(创建商户时,允许商户登录的用户)',
+ `created_uid` BIGINT(20) COMMENT '创建者用户ID',
+ `created_by` VARCHAR(64) COMMENT '创建者姓名',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`mch_no`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商户信息表';
+
+-- 2.服务商信息表
+DROP TABLE IF EXISTS t_isv_info;
+CREATE TABLE `t_isv_info` (
+ `isv_no` VARCHAR(64) NOT NULL COMMENT '服务商号',
+ `isv_name` VARCHAR(64) NOT NULL COMMENT '服务商名称',
+ `isv_short_name` VARCHAR(32) NOT NULL COMMENT '服务商简称',
+ `contact_name` VARCHAR(32) COMMENT '联系人姓名',
+ `contact_tel` VARCHAR(32) COMMENT '联系人手机号',
+ `contact_email` VARCHAR(32) COMMENT '联系人邮箱',
+ `state` TINYINT(6) NOT NULL DEFAULT 1 COMMENT '状态: 0-停用, 1-正常',
+ `remark` VARCHAR(128) DEFAULT NULL COMMENT '备注',
+ `created_uid` BIGINT(20) COMMENT '创建者用户ID',
+ `created_by` VARCHAR(64) COMMENT '创建者姓名',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`isv_no`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='服务商信息表';
+
+-- 3.支付方式表 pay_way
+DROP TABLE IF EXISTS t_pay_way;
+CREATE TABLE `t_pay_way` (
+ `way_code` VARCHAR(20) NOT NULL COMMENT '支付方式代码 例如: wxpay_jsapi',
+ `way_name` VARCHAR(20) NOT NULL COMMENT '支付方式名称',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`way_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付方式表';
+
+-- 4.支付接口定义表
+DROP TABLE IF EXISTS t_pay_interface_define;
+CREATE TABLE `t_pay_interface_define` (
+ `if_code` VARCHAR(20) NOT NULL COMMENT '接口代码 全小写 wxpay alipay ',
+ `if_name` VARCHAR(20) NOT NULL COMMENT '接口名称',
+ `is_mch_mode` TINYINT(6) NOT NULL DEFAULT 1 COMMENT '是否支持普通商户模式: 0-不支持, 1-支持',
+ `is_isv_mode` TINYINT(6) NOT NULL DEFAULT 1 COMMENT '是否支持服务商子商户模式: 0-不支持, 1-支持',
+ `isv_params` VARCHAR(4096) DEFAULT NULL COMMENT 'ISV接口配置定义描述,json字符串',
+ `isvsub_mch_params` VARCHAR(4096) DEFAULT NULL COMMENT '特约商户接口配置定义描述,json字符串',
+ `normal_mch_params` VARCHAR(4096) DEFAULT NULL COMMENT '普通商户接口配置定义描述,json字符串',
+ `way_codes` JSON NOT NULL COMMENT '支持的支付方式 ["wxpay_jsapi", "wxpay_bar"]',
+ `icon` VARCHAR(256) DEFAULT NULL COMMENT '页面展示:卡片-图标',
+ `bg_color` VARCHAR(20) DEFAULT NULL COMMENT '页面展示:卡片-背景色',
+ `state` TINYINT(6) NOT NULL DEFAULT 1 COMMENT '状态: 0-停用, 1-启用',
+ `remark` VARCHAR(128) DEFAULT NULL COMMENT '备注',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`if_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付接口定义表';
+
+-- 5.支付接口配置参数表
+DROP TABLE IF EXISTS t_pay_interface_config;
+CREATE TABLE `t_pay_interface_config` (
+ `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+ `info_type` TINYINT(6) NOT NULL COMMENT '账号类型:1-服务商 2-商户',
+ `info_id` VARCHAR(64) NOT NULL COMMENT '服务商或商户No',
+ `if_code` VARCHAR(20) NOT NULL COMMENT '支付接口代码',
+ `if_params` VARCHAR(4096) NOT NULL COMMENT '接口配置参数,json字符串',
+ `if_rate` DECIMAL(20,6) DEFAULT NULL COMMENT '支付接口费率',
+ `state` TINYINT(6) NOT NULL default 1 COMMENT '状态: 0-停用, 1-启用',
+ `remark` VARCHAR(128) DEFAULT NULL COMMENT '备注',
+ `created_uid` BIGINT(20) COMMENT '创建者用户ID',
+ `created_by` VARCHAR(64) COMMENT '创建者姓名',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_uid` BIGINT(20) COMMENT '更新者用户ID',
+ `updated_by` VARCHAR(64) COMMENT '更新者姓名',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `Uni_InfoType_InfoId_IfCode` (`info_type`, `info_id`, `if_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付接口配置参数表';
+
+
+-- 6.商户支付通道表 (允许商户 支付方式 对应多个支付接口的配置)
+DROP TABLE IF EXISTS t_mch_pay_passage;
+CREATE TABLE `t_mch_pay_passage` (
+ `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+ `mch_no` VARCHAR(64) NOT NULL COMMENT '商户号',
+ `if_code` VARCHAR(20) NOT NULL COMMENT '支付接口',
+ `way_code` VARCHAR(20) NOT NULL COMMENT '支付方式',
+ `rate` DECIMAL(20,6) NOT NULL COMMENT '支付方式费率',
+ `risk_config` JSON DEFAULT NULL COMMENT '风控数据',
+ `state` TINYINT(6) NOT NULL COMMENT '状态: 0-停用, 1-启用',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `Uni_MchNo_WayCode` (`mch_no`,`if_code`, `way_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商户支付通道表';
+
+
+-- 轮询表
+-- mch_no, way_code, 轮询策略。
+
+
+-- 7.支付订单表
+DROP TABLE IF EXISTS t_pay_order;
+CREATE TABLE `t_pay_order` (
+ `pay_order_id` VARCHAR(30) NOT NULL COMMENT '支付订单号',
+ `mch_no` VARCHAR(64) NOT NULL COMMENT '商户号',
+ `isv_no` VARCHAR(64) DEFAULT NULL COMMENT '服务商号',
+ `mch_name` VARCHAR(30) NOT NULL COMMENT '商户名称',
+ `mch_type` TINYINT(6) NOT NULL COMMENT '类型: 1-普通商户, 2-特约商户(服务商模式)',
+ `mch_order_no` VARCHAR(64) NOT NULL COMMENT '商户订单号',
+ `if_code` VARCHAR(20) COMMENT '支付接口代码',
+ `way_code` VARCHAR(20) NOT NULL COMMENT '支付方式代码',
+ `amount` BIGINT(20) NOT NULL COMMENT '支付金额,单位分',
+ `currency` VARCHAR(3) NOT NULL DEFAULT 'cny' COMMENT '三位货币代码,人民币:cny',
+ `state` TINYINT(6) NOT NULL DEFAULT '0' COMMENT '支付状态: 0-订单生成, 1-支付中, 2-支付成功, 3-支付失败, 4-已撤销, 5-已退款, 6-订单关闭',
+ `notify_state` TINYINT(6) NOT NULL DEFAULT '0' COMMENT '向下游回调状态, 0-未发送, 1-已发送',
+ `client_ip` VARCHAR(32) DEFAULT NULL COMMENT '客户端IP',
+ `subject` VARCHAR(64) NOT NULL COMMENT '商品标题',
+ `body` VARCHAR(256) NOT NULL COMMENT '商品描述信息',
+ `channel_extra` VARCHAR(512) DEFAULT NULL COMMENT '特定渠道发起额外参数',
+ `channel_user` VARCHAR(64) DEFAULT NULL COMMENT '渠道用户标识,如微信openId,支付宝账号',
+ `channel_order_no` VARCHAR(64) DEFAULT NULL COMMENT '渠道订单号',
+ `refund_times` INT NOT NULL DEFAULT 0 COMMENT '退款次数',
+ `refund_amount` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '退款总金额,单位分',
+ `division_flag` TINYINT(6) DEFAULT 0 COMMENT '订单分账标志:0-否 1-是',
+ `division_time` DATETIME COMMENT '预计分账发起时间',
+ `err_code` VARCHAR(64) DEFAULT NULL COMMENT '渠道支付错误码',
+ `err_msg` VARCHAR(128) DEFAULT NULL COMMENT '渠道支付错误描述',
+ `ext_param` VARCHAR(128) DEFAULT NULL COMMENT '商户扩展参数',
+ `notify_url` VARCHAR(128) NOT NULL default '' COMMENT '异步通知地址',
+ `return_url` VARCHAR(128) DEFAULT '' COMMENT '页面跳转地址',
+ `expired_time` DATETIME DEFAULT NULL COMMENT '订单失效时间',
+ `success_time` DATETIME DEFAULT NULL COMMENT '订单支付成功时间',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`pay_order_id`),
+ UNIQUE KEY `Uni_MchNo_MchOrderNo` (`mch_no`, `mch_order_no`),
+ INDEX(`created_at`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付订单表';
+
+
+-- 8.商户通知记录表
+DROP TABLE IF EXISTS t_mch_notify_record;
+CREATE TABLE `t_mch_notify_record` (
+ `notify_id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '商户通知记录ID',
+ `order_id` VARCHAR(64) NOT NULL COMMENT '订单ID',
+ `order_type` TINYINT(6) NOT NULL COMMENT '订单类型:1-支付,2-退款',
+ `mch_order_no` VARCHAR(64) NOT NULL COMMENT '商户订单号',
+ `mch_no` VARCHAR(64) NOT NULL COMMENT '商户号',
+ `isv_no` VARCHAR(64) COMMENT '服务商号',
+ `notify_url` TEXT NOT NULL COMMENT '通知地址',
+ `res_result` TEXT DEFAULT NULL COMMENT '通知响应结果',
+ `notify_count` INT(11) NOT NULL DEFAULT '0' COMMENT '通知次数',
+ `state` TINYINT(6) NOT NULL DEFAULT '1' COMMENT '通知状态,1-通知中,2-通知成功,3-通知失败',
+ `last_notify_time` DATETIME DEFAULT NULL COMMENT '最后一次通知时间',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`notify_id`),
+ UNIQUE KEY `Uni_OrderId_Type` (`order_id`, `order_type`)
+) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 COMMENT='商户通知记录表';
+
+
+-- 9.订单接口数据快照(加密存储)
+DROP TABLE IF EXISTS `t_order_snapshot`;
+CREATE TABLE `t_order_snapshot` (
+ `order_id` VARCHAR(64) NOT NULL COMMENT '订单ID',
+ `order_type` TINYINT(6) NOT NULL COMMENT '订单类型: 1-支付, 2-退款',
+ `mch_req_data` TEXT DEFAULT NULL COMMENT '下游请求数据',
+ `mch_req_time` DATETIME DEFAULT NULL COMMENT '下游请求时间',
+ `mch_resp_data` TEXT DEFAULT NULL COMMENT '向下游响应数据',
+ `mch_resp_time` DATETIME DEFAULT NULL COMMENT '向下游响应时间',
+ `channel_req_data` TEXT DEFAULT NULL COMMENT '向上游请求数据',
+ `channel_req_time` DATETIME DEFAULT NULL COMMENT '向上游请求时间',
+ `channel_resp_data` TEXT DEFAULT NULL COMMENT '上游响应数据',
+ `channel_resp_time` DATETIME DEFAULT NULL COMMENT '上游响应时间',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`order_id`, `order_type`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单接口数据快照';
+
+
+-- 10.退款订单表
+DROP TABLE IF EXISTS t_refund_order;
+CREATE TABLE `t_refund_order` (
+ `refund_order_id` VARCHAR(30) NOT NULL COMMENT '退款订单号',
+ `pay_order_id` VARCHAR(30) NOT NULL COMMENT '支付订单号',
+ `channel_pay_order_no` VARCHAR(64) DEFAULT NULL COMMENT '渠道支付单号',
+ `mch_no` VARCHAR(64) NOT NULL COMMENT '商户号',
+ `mch_type` TINYINT(6) NOT NULL COMMENT '类型: 1-普通商户, 2-特约商户(服务商模式)',
+ `mch_refund_no` VARCHAR(64) NOT NULL COMMENT '商户退款单号',
+ `isv_no` VARCHAR(64) DEFAULT NULL COMMENT '服务商号',
+ `way_code` VARCHAR(20) NOT NULL COMMENT '支付方式代码',
+ `if_code` VARCHAR(20) NOT NULL COMMENT '支付接口代码',
+ `pay_amount` BIGINT(20) NOT NULL COMMENT '支付金额,单位分',
+ `refund_amount` BIGINT(20) NOT NULL COMMENT '退款金额,单位分',
+ `currency` VARCHAR(3) NOT NULL DEFAULT 'cny' COMMENT '三位货币代码,人民币:cny',
+ `state` TINYINT(6) NOT NULL DEFAULT '0' COMMENT '退款状态:0-订单生成,1-退款中,2-退款成功,3-退款失败',
+ `result` TINYINT(6) NOT NULL DEFAULT '0' COMMENT '退款结果:0-不确认结果,1-等待手动处理,2-确认成功,3-确认失败',
+ `client_ip` VARCHAR(32) DEFAULT NULL COMMENT '客户端IP',
+ `remark` VARCHAR(256) DEFAULT NULL COMMENT '备注',
+ `channel_order_no` VARCHAR(32) DEFAULT NULL COMMENT '渠道订单号',
+ `channel_err_code` VARCHAR(128) DEFAULT NULL COMMENT '渠道错误码',
+ `channel_err_msg` VARCHAR(128) DEFAULT NULL COMMENT '渠道错误描述',
+ `channel_extra` VARCHAR(512) DEFAULT NULL COMMENT '特定渠道发起时额外参数',
+ `notify_url` VARCHAR(128) DEFAULT NULL COMMENT '通知地址',
+ `ext_param` VARCHAR(64) DEFAULT NULL COMMENT '扩展参数',
+ `success_time` DATETIME DEFAULT NULL COMMENT '订单退款成功时间',
+ `created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间',
+ PRIMARY KEY (`refund_order_id`),
+ UNIQUE KEY `Uni_MchNo_MchRefundNo` (`mch_no`, `mch_refund_no`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='退款订单表';
+
+
+##### ↑↑↑↑↑↑↑↑↑↑ 表结构DDL ↑↑↑↑↑↑↑↑↑↑ #####
+
+##### ↓↓↓↓↓↓↓↓↓↓ 初始化DML ↓↓↓↓↓↓↓↓↓↓ #####
+
+-- 权限表数据 ( 不包含根目录 )
+insert into t_sys_entitlement values('ENT_COMMONS', '系统通用菜单', 'no-icon', '', 'RouteView', 'MO', 0, 1, 'ROOT', '-1', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_C_USERINFO', '个人中心', 'no-icon', '/current/userinfo', 'CurrentUserInfo', 'MO', 0, 1, 'ENT_COMMONS', '-1', 'MGR', now(), now());
+
+insert into t_sys_entitlement values('ENT_C_MAIN', '主页', 'home', '/main', 'MainPage', 'ML', 0, 1, 'ROOT', '1', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_C_MAIN_PAY_AMOUNT_WEEK', '主页周支付统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_C_MAIN_NUMBER_COUNT', '主页数量总统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_C_MAIN_PAY_COUNT', '主页交易统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_C_MAIN_PAY_TYPE_COUNT', '主页交易方式统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'MGR', now(), now());
+
+-- 商户管理
+insert into t_sys_entitlement values('ENT_MCH_INFO', '商户管理', 'shop', '', 'RouteView', 'ML', 0, 1, 'ROOT', '30', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_INFO_LIST', '商户列表', 'profile', '/mch', 'MchListPage', 'ML', 0, 1, 'ENT_MCH_INFO', '10', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_INFO_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_INFO_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_INFO_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_INFO_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_CONFIG_LIST', '商户支付参数配置列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_CONFIG_ADD', '商户支付参数配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_PAY_CONFIG_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_CONFIG_VIEW', '商户支付参数配置详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_PAY_CONFIG_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_PASSAGE_LIST', '商户支付通道配置列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_PASSAGE_CONFIG', '商户支付通道配置入口', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_PAY_PASSAGE_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_PASSAGE_ADD', '商户支付通道配置保存', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_PAY_PASSAGE_LIST', '0', 'MGR', now(), now());
+
+-- 服务商管理
+insert into t_sys_entitlement values('ENT_ISV_INFO', '服务商管理', 'block', '', 'RouteView', 'ML', 0, 1, 'ROOT', '40', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_ISV_INFO_LIST', '服务商列表', 'profile', '/isv', 'IsvListPage', 'ML', 0, 1, 'ENT_ISV_INFO', '10', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_ISV_INFO_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_ISV_INFO_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_ISV_INFO_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_ISV_INFO_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_ISV_PAY_CONFIG_LIST', '服务商支付参数配置列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_ISV_PAY_CONFIG_ADD', '服务商支付参数配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_PAY_CONFIG_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_ISV_PAY_CONFIG_VIEW', '服务商支付参数配置详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_PAY_CONFIG_LIST', '0', 'MGR', now(), now());
+
+-- 订单管理
+insert into t_sys_entitlement values('ENT_ORDER', '订单管理', 'transaction', '', 'RouteView', 'ML', 0, 1, 'ROOT', '50', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PAY_ORDER_LIST', '支付订单', 'account-book', '/pay', 'PayOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '10', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PAY_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_REFUND_ORDER_LIST', '退款订单', 'exception', '/refund', 'RefundOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '20', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_REFUND_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_NOTIFY_LIST', '商户通知', 'notification', '/notify', 'MchNotifyListPage', 'ML', 0, 1, 'ENT_ORDER', '30', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_NOTIFY_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTIFY_LIST', '0', 'MGR', now(), now());
+
+-- 支付配置菜单
+insert into t_sys_entitlement values('ENT_PC', '支付配置', 'file-done', '', 'RouteView', 'ML', 0, 1, 'ROOT', '60', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_IF_DEFINE', '支付接口', 'interaction', '/ifdefines', 'IfDefinePage', 'ML', 0, 1, 'ENT_PC', '10', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_LIST', '页面:支付接口定义列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_SEARCH', '页面:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_WAY', '支付方式', 'appstore', '/payways', 'PayWayPage', 'ML', 0, 1, 'ENT_PC', '20', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_WAY_LIST', '页面:支付方式列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_WAY_SEARCH', '页面:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_WAY_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_WAY_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_WAY_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_PC_WAY_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'MGR', now(), now());
+
+-- 系统管理
+insert into t_sys_entitlement values('ENT_SYS_CONFIG', '系统管理', 'setting', '', 'RouteView', 'ML', 0, 1, 'ROOT', '200', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR', '用户角色管理', 'team', '', 'RouteView', 'ML', 0, 1, 'ENT_SYS_CONFIG', '10', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER', '操作员管理', 'contacts', '/users', 'SysUserPage', 'ML', 0, 1, 'ENT_UR', '10', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_LIST', '页面:操作员列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_SEARCH', '按钮:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_ADD', '按钮:添加操作员', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_VIEW', '按钮: 详情', '', 'no-icon', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_EDIT', '按钮: 修改基本信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_UPD_ROLE', '按钮: 角色分配', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MGR', now(), now());
+
+ insert into t_sys_entitlement values('ENT_UR_ROLE', '角色管理', 'user', '/roles', 'RolePage', 'ML', 0, 1, 'ENT_UR', '20', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_LIST', '页面:角色列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_SEARCH', '页面:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_ADD', '按钮:添加角色', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_DIST', '按钮: 分配权限', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_EDIT', '按钮: 修改基本信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_DEL', '按钮: 删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MGR', now(), now());
+
+ insert into t_sys_entitlement values('ENT_UR_ROLE_ENT', '权限管理', 'apartment', '/ents', 'EntPage', 'ML', 0, 1, 'ENT_UR', '30', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_ENT_LIST', '页面: 权限列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE_ENT', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_ENT_EDIT', '按钮: 权限变更', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE_ENT', '0', 'MGR', now(), now());
+
+ insert into t_sys_entitlement values('ENT_SYS_CONFIG_INFO', '系统配置', 'setting', '/config', 'SysConfigPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '15', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_SYS_CONFIG_EDIT', '按钮: 修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_CONFIG_INFO', '0', 'MGR', now(), now());
+
+ insert into t_sys_entitlement values('ENT_SYS_LOG_LIST', '系统日志', 'file-text', '/log', 'SysLogPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '20', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_SYS_LOG_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_LOG_LIST', '0', 'MGR', now(), now());
+ insert into t_sys_entitlement values('ENT_SYS_LOG_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_LOG_LIST', '0', 'MGR', now(), now());
+
+
+-- 【商户系统】 主页
+insert into t_sys_entitlement values('ENT_COMMONS', '系统通用菜单', 'no-icon', '', 'RouteView', 'MO', 0, 1, 'ROOT', '-1', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_C_USERINFO', '个人中心', 'no-icon', '/current/userinfo', 'CurrentUserInfo', 'MO', 0, 1, 'ENT_COMMONS', '-1', 'MCH', now(), now());
+
+insert into t_sys_entitlement values('ENT_MCH_MAIN', '主页', 'home', '/main', 'MainPage', 'ML', 0, 1, 'ROOT', '1', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_MAIN_PAY_AMOUNT_WEEK', '主页周支付统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_MAIN', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_MAIN_NUMBER_COUNT', '主页数量总统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_MAIN', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_MAIN_PAY_COUNT', '主页交易统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_MAIN', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_MAIN_PAY_TYPE_COUNT', '主页交易方式统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_MAIN', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_MAIN_USER_INFO', '主页用户信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_MAIN', '0', 'MCH', now(), now());
+
+-- 【商户系统】 商户中心
+-- insert into t_sys_entitlement values('ENT_MCH_CENTER', '商户中心', 'team', '', 'RouteView', 'ML', 0, 'ROOT', '10', 'MCH', now(), now());
+-- insert into t_sys_entitlement values('ENT_MCH_INFO', '商户信息', 'user', '/mch', 'MchInfoPage', 'ML', 0, 'ENT_MCH_CENTER', '10', 'MCH', now(), now());
+-- insert into t_sys_entitlement values('ENT_MCH_INFO_EDIT', '按钮:修改商户信息', 'no-icon', '', '', 'PB', 0, 'ENT_MCH_INFO', '0', 'MCH', now(), now());
+
+-- 【商户系统】 订单管理
+insert into t_sys_entitlement values('ENT_ORDER', '订单中心', 'transaction', '', 'RouteView', 'ML', 0, 1, 'ROOT', '20', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_PAY_ORDER_LIST', '订单管理', 'account-book', '/pay', 'PayOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '10', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_PAY_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER_LIST', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_REFUND_ORDER_LIST', '退款记录', 'exception', '/refund', 'RefundOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '20', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_REFUND_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER_LIST', '0', 'MCH', now(), now());
+
+-- 【商户系统】 支付配置
+insert into t_sys_entitlement values('ENT_MCH_PC', '支付配置', 'file-done', '', 'RouteView', 'ML', 0, 1, 'ROOT', '30', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_CONFIG_LIST', '支付参数', 'interaction', '/pay/config', 'PayConfigPage', 'ML', 0, 1, 'ENT_MCH_PC', '10', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_CONFIG_ADD', '商户支付参数配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_PAY_CONFIG_LIST', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_CONFIG_VIEW', '商户支付参数配置详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_PAY_CONFIG_LIST', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_PASSAGE_LIST', '支付通道', 'appstore', '/pay/passage', 'PayPassagePage', 'ML', 0, 1, 'ENT_MCH_PC', '20', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_PASSAGE_CONFIG', '商户支付通道配置入口', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_PAY_PASSAGE_LIST', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_MCH_PAY_PASSAGE_ADD', '商户支付通道配置保存', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_PAY_PASSAGE_LIST', '0', 'MCH', now(), now());
+
+
+-- 【商户系统】 系统管理
+insert into t_sys_entitlement values('ENT_SYS_CONFIG', '系统管理', 'setting', '', 'RouteView', 'ML', 0, 1, 'ROOT', '200', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR', '用户角色管理', 'team', '', 'RouteView', 'ML', 0, 1, 'ENT_SYS_CONFIG', '10', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER', '操作员管理', 'contacts', '/users', 'SysUserPage', 'ML', 0, 1, 'ENT_UR', '10', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_LIST', '页面:操作员列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_SEARCH', '按钮:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_ADD', '按钮:添加操作员', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_VIEW', '按钮: 详情', '', 'no-icon', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_EDIT', '按钮: 修改基本信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_USER_UPD_ROLE', '按钮: 角色分配', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', now(), now());
+
+ insert into t_sys_entitlement values('ENT_UR_ROLE', '角色管理', 'user', '/roles', 'RolePage', 'ML', 0, 1, 'ENT_UR', '20', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_LIST', '页面:角色列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_SEARCH', '页面:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_ADD', '按钮:添加角色', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_DIST', '按钮: 分配权限', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_EDIT', '按钮: 修改名称', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', now(), now());
+ insert into t_sys_entitlement values('ENT_UR_ROLE_DEL', '按钮: 删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', now(), now());
+
+-- 默认角色
+insert into t_sys_role values ('ROLE_ADMIN', '系统管理员', 'MGR', '0', '2021-05-01');
+insert into t_sys_role values ('ROLE_OP', '普通操作员', 'MGR', '0', '2021-05-01');
+-- 角色权限关联, [超管]用户 拥有所有权限
+-- insert into t_sys_role_ent_rela select '801', ent_id from t_sys_entitlement;
+
+-- 超管用户: jeepay / jeepay123
+insert into t_sys_user values (801, 'jeepay', '超管', '13000000001', '1', 'https://edu-system.oss-cn-beijing.aliyuncs.com/1/img/z/avatar_1.jpg', 'D0001', 1, 1, 'MGR', '0', '2020-06-13', '2020-06-13');
+insert into t_sys_user_auth values (801, '801', '1', 'jeepay', '$2a$10$WKuPJKE1XhX15ibqDM745eOCaZZVUiRitUjEyX6zVNd9k.cQXfzGa', 'testkey', 'MGR');
+
+-- insert into t_sys_user_role_rela values (801, 801);
+
+INSERT INTO `t_sys_config` VALUES ('mgrSiteUrl', '运营平台网址(不包含结尾/)', '运营平台网址(不包含结尾/)', 'applicationConfig', '系统应用配置', 'http://127.0.0.1:9217', 'text', 0, '2021-5-18 14:46:10');
+INSERT INTO `t_sys_config` VALUES ('mchSiteUrl', '商户平台网址(不包含结尾/)', '商户平台网址(不包含结尾/)', 'applicationConfig', '系统应用配置', 'http://127.0.0.1:9218', 'text', 0, '2021-5-18 14:46:10');
+INSERT INTO `t_sys_config` VALUES ('paySiteUrl', '支付网关地址(不包含结尾/)', '支付网关地址(不包含结尾/)', 'applicationConfig', '系统应用配置', 'http://127.0.0.1:9216', 'text', 0, '2021-5-18 14:46:10');
+INSERT INTO `t_sys_config` VALUES ('ossPublicSiteUrl', '公共oss访问地址(不包含结尾/)', '公共oss访问地址(不包含结尾/)', 'applicationConfig', '系统应用配置', 'http://127.0.0.1:9217/api/anon/localOssFiles', 'text', 0, '2021-5-18 14:46:10');
+
+
+-- 初始化支付方式
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_BAR', '支付宝条码');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_JSAPI', '支付宝生活号');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_APP', '支付宝APP');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_WAP', '支付宝WAP');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_PC', '支付宝PC网站');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_QR', '支付宝二维码');
+
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('WX_BAR', '微信条码');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('WX_JSAPI', '微信公众号');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('WX_APP', '微信APP');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('WX_H5', '微信H5');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('WX_NATIVE', '微信扫码');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('WX_LITE', '微信小程序');
+
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('YSF_BAR', '云闪付条码');
+INSERT INTO t_pay_way (way_code, way_name) VALUES ('YSF_JSAPI', '云闪付jsapi');
+
+-- 初始化支付接口定义
+INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
+VALUES ('alipay', '支付宝官方', 1, 1,
+ '[{"name":"sandbox","desc":"环境配置","type":"radio","verify":"","values":"1,0","titles":"沙箱环境,生产环境","verify":"required"},{"name":"pid","desc":"合作伙伴身份(PID)","type":"text","verify":"required"},{"name":"appId","desc":"应用App ID","type":"text","verify":"required"},{"name":"privateKey", "desc":"应用私钥", "type": "textarea","verify":"required"},{"name":"alipayPublicKey", "desc":"支付宝公钥(不使用证书时必填)", "type": "textarea"},{"name":"signType","desc":"接口签名方式(推荐使用RSA2)","type":"radio","verify":"","values":"RSA,RSA2","titles":"RSA,RSA2","verify":"required"},{"name":"useCert","desc":"公钥证书","type":"radio","verify":"","values":"1,0","titles":"使用证书(请使用RSA2私钥),不使用证书"},{"name":"appPublicCert","desc":"应用公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayPublicCert","desc":"支付宝公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayRootCert","desc":"支付宝根证书(.crt格式)","type":"file","verify":""}]',
+ '[{"name":"appAuthToken", "desc":"子商户app_auth_token", "type": "text","readonly":"readonly"},{"name":"refreshToken", "desc":"子商户刷新token", "type": "hidden","readonly":"readonly"},{"name":"expireTimestamp", "desc":"authToken有效期(13位时间戳)", "type": "hidden","readonly":"readonly"}]',
+ '[{"name":"sandbox","desc":"环境配置","type":"radio","verify":"","values":"1,0","titles":"沙箱环境,生产环境","verify":"required"},{"name":"appId","desc":"应用App ID","type":"text","verify":"required"},{"name":"privateKey", "desc":"应用私钥", "type": "textarea","verify":"required"},{"name":"alipayPublicKey", "desc":"支付宝公钥(不使用证书时必填)", "type": "textarea"},{"name":"signType","desc":"接口签名方式(推荐使用RSA2)","type":"radio","verify":"","values":"RSA,RSA2","titles":"RSA,RSA2","verify":"required"},{"name":"useCert","desc":"公钥证书","type":"radio","verify":"","values":"1,0","titles":"使用证书(请使用RSA2私钥),不使用证书"},{"name":"appPublicCert","desc":"应用公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayPublicCert","desc":"支付宝公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayRootCert","desc":"支付宝根证书(.crt格式)","type":"file","verify":""}]',
+ '[{"wayCode": "ALI_JSAPI"}, {"wayCode": "ALI_WAP"}, {"wayCode": "ALI_BAR"}, {"wayCode": "ALI_APP"}, {"wayCode": "ALI_PC"}, {"wayCode": "ALI_QR"}]',
+ 'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/alipay.png', '#1779FF', 1, '支付宝官方通道');
+
+INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
+VALUES ('wxpay', '微信支付官方', 1, 1,
+ '[{"name":"mchId", "desc":"微信支付商户号", "type": "text","verify":"required"},{"name":"appId","desc":"应用App ID","type":"text","verify":"required"},{"name":"appSecret","desc":"应用AppSecret","type":"text","verify":"required"},{"name":"oauth2Url", "desc":"oauth2地址(置空将使用官方)", "type": "text"},{"name":"key", "desc":"API密钥", "type": "textarea","verify":"required"},{"name":"apiVersion", "desc":"微信支付API版本", "type": "radio","values":"V2,V3","titles":"V2,V3","verify":"required"},{"name":"apiV3Key", "desc":"API V3秘钥(V3接口必填)", "type": "textarea","verify":""},{"name":"serialNo", "desc":"序列号(V3接口必填)", "type": "textarea","verify":""},{"name":"cert", "desc":"API证书(.p12格式)", "type": "file","verify":""},{"name":"apiClientKey", "desc":"私钥文件(.pem格式)", "type": "file","verify":""}]',
+ '[{"name":"subMchId","desc":"子商户ID","type":"text","verify":"required"},{"name":"subMchAppId","desc":"子账户appID(线上支付必填)","type":"text","verify":""}]',
+ '[{"name":"mchId", "desc":"微信支付商户号", "type": "text","verify":"required"},{"name":"appId","desc":"应用App ID","type":"text","verify":"required"},{"name":"appSecret","desc":"应用AppSecret","type":"text","verify":"required"},{"name":"oauth2Url", "desc":"oauth2地址(置空将使用官方)", "type": "text"},{"name":"key", "desc":"API密钥", "type": "textarea","verify":"required"},{"name":"apiVersion", "desc":"微信支付API版本", "type": "radio","values":"V2,V3","titles":"V2,V3","verify":"required"},{"name":"apiV3Key", "desc":"API V3秘钥(V3接口必填)", "type": "textarea","verify":""},{"name":"serialNo", "desc":"序列号(V3接口必填)", "type": "textarea","verify":""},{"name":"cert", "desc":"API证书(.p12格式)", "type": "file","verify":""},{"name":"apiClientKey", "desc":"私钥文件(.pem格式)", "type": "file","verify":""}]',
+ '[{"wayCode": "WX_APP"}, {"wayCode": "WX_H5"}, {"wayCode": "WX_NATIVE"}, {"wayCode": "WX_JSAPI"}, {"wayCode": "WX_BAR"}, {"wayCode": "WX_LITE"}]',
+ 'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/wxpay.png', '#04BE02', 1, '微信官方通道');
+
+INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
+VALUES ('ysfpay', '云闪付官方', 0, 1,
+ '[{"name":"sandbox","desc":"环境配置","type":"radio","verify":"","values":"1,0","titles":"沙箱环境,生产环境","verify":"required"},{"name":"serProvId","desc":"服务商开发ID[serProvId]","type":"text","verify":"required"},{"name":"isvPrivateCertFile","desc":"服务商私钥文件(.pfx格式)","type":"file","verify":"required"},{"name":"isvPrivateCertPwd","desc":"服务商私钥文件密码","type":"text","verify":"required"},{"name":"ysfpayPublicKey","desc":"云闪付开发公钥(证书管理页面可查询)","type":"textarea","verify":"required"},{"name":"acqOrgCode","desc":"可用支付机构编号","type":"text","verify":"required"}]',
+ '[{"name":"merId","desc":"商户编号","type":"text","verify":"required"}]',
+ NULL,
+ '[{"wayCode": "YSF_BAR"}, {"wayCode": "ALI_JSAPI"}, {"wayCode": "WX_JSAPI"}, {"wayCode": "ALI_BAR"}, {"wayCode": "WX_BAR"}]',
+ 'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/ysfpay.png', 'red', 1, '云闪付官方通道');
diff --git a/init_db.sql b/init_db.sql
deleted file mode 100644
index 13d25f9c..00000000
--- a/init_db.sql
+++ /dev/null
@@ -1,169 +0,0 @@
-
-/* 支付中心相关表结构 */
-
-CREATE TABLE `t_mch_info` (
- `MchId` varchar(30) NOT NULL COMMENT '商户ID',
- `Name` varchar(30) NOT NULL COMMENT '名称',
- `Type` varchar(24) NOT NULL COMMENT '类型',
- `ReqKey` varchar(128) NOT NULL COMMENT '请求私钥',
- `ResKey` varchar(128) NOT NULL COMMENT '响应私钥',
- `State` tinyint(6) NOT NULL DEFAULT '1' COMMENT '商户状态,0-停止使用,1-使用中',
- `CreateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `UpdateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- PRIMARY KEY (`MchId`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商户信息表';
-
-CREATE TABLE `t_pay_channel` (
- `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '渠道主键ID',
- `ChannelId` varchar(24) NOT NULL COMMENT '渠道ID',
- `ChannelName` varchar(30) NOT NULL COMMENT '渠道名称,如:alipay,wechat',
- `ChannelMchId` varchar(32) NOT NULL COMMENT '渠道商户ID',
- `MchId` varchar(30) NOT NULL COMMENT '商户ID',
- `State` tinyint(6) NOT NULL DEFAULT '1' COMMENT '渠道状态,0-停止使用,1-使用中',
- `Param` varchar(4096) NOT NULL COMMENT '配置参数,json字符串',
- `Remark` varchar(128) DEFAULT NULL COMMENT '备注',
- `CreateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `UpdateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- PRIMARY KEY (`ID`),
- UNIQUE KEY `IDX_MchId_MchOrderNo` (`ChannelId`, `MchId`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付渠道表';
-
-CREATE TABLE `t_pay_order` (
- `PayOrderId` varchar(30) NOT NULL COMMENT '支付订单号',
- `MchId` varchar(30) NOT NULL COMMENT '商户ID',
- `MchOrderNo` varchar(30) NOT NULL COMMENT '商户订单号',
- `ChannelId` varchar(24) NOT NULL COMMENT '渠道ID',
- `Amount` bigint(20) NOT NULL COMMENT '支付金额,单位分',
- `Currency` varchar(3) NOT NULL DEFAULT 'cny' COMMENT '三位货币代码,人民币:cny',
- `Status` tinyint(6) NOT NULL DEFAULT '0' COMMENT '支付状态,0-订单生成,1-支付中(目前未使用),2-支付成功,3-业务处理完成',
- `ClientIp` varchar(32) DEFAULT NULL COMMENT '客户端IP',
- `Device` varchar(64) DEFAULT NULL COMMENT '设备',
- `Subject` varchar(64) NOT NULL COMMENT '商品标题',
- `Body` varchar(256) NOT NULL COMMENT '商品描述信息',
- `Extra` varchar(512) DEFAULT NULL COMMENT '特定渠道发起时额外参数',
- `ChannelMchId` varchar(32) NOT NULL COMMENT '渠道商户ID',
- `ChannelOrderNo` varchar(64) DEFAULT NULL COMMENT '渠道订单号',
- `ErrCode` varchar(64) DEFAULT NULL COMMENT '渠道支付错误码',
- `ErrMsg` varchar(128) DEFAULT NULL COMMENT '渠道支付错误描述',
- `Param1` varchar(64) DEFAULT NULL COMMENT '扩展参数1',
- `Param2` varchar(64) DEFAULT NULL COMMENT '扩展参数2',
- `NotifyUrl` varchar(128) NOT NULL COMMENT '通知地址',
- `NotifyCount` tinyint(6) NOT NULL DEFAULT 0 COMMENT '通知次数',
- `LastNotifyTime` bigint(20) DEFAULT NULL COMMENT '最后一次通知时间',
- `ExpireTime` bigint(20) DEFAULT NULL COMMENT '订单失效时间',
- `PaySuccTime` bigint(20) DEFAULT NULL COMMENT '订单支付成功时间',
- `CreateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `UpdateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- PRIMARY KEY (`PayOrderId`),
- UNIQUE KEY `IDX_MchId_MchOrderNo` (`MchId`, MchOrderNo)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付订单表';
-
-CREATE TABLE `t_iap_receipt` (
- `PayOrderId` varchar(30) NOT NULL COMMENT '支付订单号',
- `MchId` varchar(30) NOT NULL COMMENT '商户ID',
- `TransactionId` varchar(24) NOT NULL COMMENT 'IAP业务号',
- `ReceiptData` TEXT NOT NULL COMMENT '渠道ID',
- `Status` tinyint(6) NOT NULL DEFAULT '0' COMMENT '处理状态:0-未处理,1-处理成功,-1-处理失败',
- `HandleCount` tinyint(6) NOT NULL DEFAULT 0 COMMENT '处理次数',
- `CreateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `UpdateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- PRIMARY KEY (`PayOrderId`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='苹果支付凭据表';
-
-CREATE TABLE `t_trans_order` (
- `TransOrderId` varchar(30) NOT NULL COMMENT '转账订单号',
- `MchId` varchar(30) NOT NULL COMMENT '商户ID',
- `MchTransNo` varchar(30) NOT NULL COMMENT '商户转账单号',
- `ChannelId` varchar(24) NOT NULL COMMENT '渠道ID',
- `Amount` bigint(20) NOT NULL COMMENT '转账金额,单位分',
- `Currency` varchar(3) NOT NULL DEFAULT 'cny' COMMENT '三位货币代码,人民币:cny',
- `Status` tinyint(6) NOT NULL DEFAULT '0' COMMENT '转账状态:0-订单生成,1-转账中,2-转账成功,3-转账失败,4-业务处理完成',
- `Result` tinyint(6) NOT NULL DEFAULT '0' COMMENT '转账结果:0-不确认结果,1-等待手动处理,2-确认成功,3-确认失败',
- `ClientIp` varchar(32) DEFAULT NULL COMMENT '客户端IP',
- `Device` varchar(64) DEFAULT NULL COMMENT '设备',
- `RemarkInfo` varchar(256) DEFAULT NULL COMMENT '备注',
- `ChannelUser` varchar(32) DEFAULT NULL COMMENT '渠道用户标识,如微信openId,支付宝账号',
- `UserName` varchar(24) DEFAULT NULL COMMENT '用户姓名',
- `ChannelMchId` varchar(32) NOT NULL COMMENT '渠道商户ID',
- `ChannelOrderNo` varchar(32) DEFAULT NULL COMMENT '渠道订单号',
- `ChannelErrCode` varchar(128) DEFAULT NULL COMMENT '渠道错误码',
- `ChannelErrMsg` varchar(128) DEFAULT NULL COMMENT '渠道错误描述',
- `Extra` varchar(512) DEFAULT NULL COMMENT '特定渠道发起时额外参数',
- `NotifyUrl` varchar(128) NOT NULL COMMENT '通知地址',
- `Param1` varchar(64) DEFAULT NULL COMMENT '扩展参数1',
- `Param2` varchar(64) DEFAULT NULL COMMENT '扩展参数2',
- `ExpireTime` datetime DEFAULT NULL COMMENT '订单失效时间',
- `TransSuccTime` datetime DEFAULT NULL COMMENT '订单转账成功时间',
- `CreateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `UpdateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- PRIMARY KEY (`TransOrderId`),
- UNIQUE KEY `IDX_MchId_MchOrderNo` (`MchId`, MchTransNo)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='转账订单表';
-
-CREATE TABLE `t_refund_order` (
- `RefundOrderId` varchar(30) NOT NULL COMMENT '退款订单号',
- `PayOrderId` varchar(30) NOT NULL COMMENT '支付订单号',
- `ChannelPayOrderNo` varchar(64) DEFAULT NULL COMMENT '渠道支付单号',
- `MchId` varchar(30) NOT NULL COMMENT '商户ID',
- `MchRefundNo` varchar(30) NOT NULL COMMENT '商户退款单号',
- `ChannelId` varchar(24) NOT NULL COMMENT '渠道ID',
- `PayAmount` bigint(20) NOT NULL COMMENT '支付金额,单位分',
- `RefundAmount` bigint(20) NOT NULL COMMENT '退款金额,单位分',
- `Currency` varchar(3) NOT NULL DEFAULT 'cny' COMMENT '三位货币代码,人民币:cny',
- `Status` tinyint(6) NOT NULL DEFAULT '0' COMMENT '退款状态:0-订单生成,1-退款中,2-退款成功,3-退款失败,4-业务处理完成',
- `Result` tinyint(6) NOT NULL DEFAULT '0' COMMENT '退款结果:0-不确认结果,1-等待手动处理,2-确认成功,3-确认失败',
- `ClientIp` varchar(32) DEFAULT NULL COMMENT '客户端IP',
- `Device` varchar(64) DEFAULT NULL COMMENT '设备',
- `RemarkInfo` varchar(256) DEFAULT NULL COMMENT '备注',
- `ChannelUser` varchar(32) DEFAULT NULL COMMENT '渠道用户标识,如微信openId,支付宝账号',
- `UserName` varchar(24) DEFAULT NULL COMMENT '用户姓名',
- `ChannelMchId` varchar(32) NOT NULL COMMENT '渠道商户ID',
- `ChannelOrderNo` varchar(32) DEFAULT NULL COMMENT '渠道订单号',
- `ChannelErrCode` varchar(128) DEFAULT NULL COMMENT '渠道错误码',
- `ChannelErrMsg` varchar(128) DEFAULT NULL COMMENT '渠道错误描述',
- `Extra` varchar(512) DEFAULT NULL COMMENT '特定渠道发起时额外参数',
- `NotifyUrl` varchar(128) NOT NULL COMMENT '通知地址',
- `Param1` varchar(64) DEFAULT NULL COMMENT '扩展参数1',
- `Param2` varchar(64) DEFAULT NULL COMMENT '扩展参数2',
- `ExpireTime` datetime DEFAULT NULL COMMENT '订单失效时间',
- `RefundSuccTime` datetime DEFAULT NULL COMMENT '订单退款成功时间',
- `CreateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `UpdateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- PRIMARY KEY (`RefundOrderId`),
- UNIQUE KEY `IDX_MchId_MchOrderNo` (`MchId`, MchRefundNo)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='退款订单表';
-
-CREATE TABLE `t_mch_notify` (
- `OrderId` varchar(24) NOT NULL COMMENT '订单ID',
- `MchId` varchar(30) NOT NULL COMMENT '商户ID',
- `MchOrderNo` varchar(30) NOT NULL COMMENT '商户订单号',
- `OrderType` varchar(8) NOT NULL COMMENT '订单类型:1-支付,2-转账,3-退款',
- `NotifyUrl` varchar(2048) NOT NULL COMMENT '通知地址',
- `NotifyCount` tinyint(6) NOT NULL DEFAULT 0 COMMENT '通知次数',
- `Result` varchar(2048) DEFAULT NULL COMMENT '通知响应结果',
- `Status` tinyint(6) NOT NULL DEFAULT '1' COMMENT '通知状态,1-通知中,2-通知成功,3-通知失败',
- `LastNotifyTime` datetime DEFAULT NULL COMMENT '最后一次通知时间',
- `CreateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `UpdateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- PRIMARY KEY (`OrderId`),
- UNIQUE KEY `IDX_MchId_OrderType_MchOrderNo` (`MchId`, `OrderType`, `MchOrderNo`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商户通知表';
-
-
-/* 支付演示商城相关表 */
-
-CREATE TABLE `t_goods_order` (
- `GoodsOrderId` varchar(30) NOT NULL COMMENT '商品订单ID',
- `GoodsId` varchar(30) NOT NULL COMMENT '商品ID',
- `GoodsName` varchar(64) NOT NULL DEFAULT '' COMMENT '商品名称',
- `Amount` bigint(20) NOT NULL COMMENT '金额,单位分',
- `UserId` varchar(30) NOT NULL COMMENT '用户ID',
- `Status` tinyint(6) NOT NULL DEFAULT '0' COMMENT '订单状态,订单生成(0),支付成功(1),处理完成(2),处理失败(-1)',
- `PayOrderId` varchar(30) DEFAULT NULL COMMENT '支付订单号',
- `ChannelId` varchar(24) DEFAULT NULL COMMENT '渠道ID',
- `ChannelUserId` varchar(64) DEFAULT NULL COMMENT '支付渠道用户ID(微信openID或支付宝账号等第三方支付账号)',
- `CreateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `UpdateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
- PRIMARY KEY (`GoodsOrderId`),
- UNIQUE KEY `IDX_PayOrderId` (PayOrderId)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品订单表';
\ No newline at end of file
diff --git a/jeepay-core/pom.xml b/jeepay-core/pom.xml
new file mode 100644
index 00000000..81f52965
--- /dev/null
+++ b/jeepay-core/pom.xml
@@ -0,0 +1,98 @@
+
+
+ 4.0.0
+
+ com.jeequan
+ jeepay-core
+ jar
+ ${isys.version}
+ Jeepay计全支付系统 [jeepay-core]
+ https://www.jeequan.com
+
+
+ com.jeequan
+ jeepay
+ 1.0.0
+
+
+
+
+
+
+
+ org.springframework
+ spring-context
+ provided
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+ provided
+
+
+
+
+ org.springframework
+ spring-webmvc
+ provided
+
+
+
+ javax.servlet
+ javax.servlet-api
+ provided
+
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ ${mybatis.plus.starter.version}
+ provided
+
+
+
+
+ io.jsonwebtoken
+ jjwt
+ provided
+
+
+
+
+ org.springframework.security
+ spring-security-core
+ provided
+
+
+
+
+ com.alibaba
+ fastjson
+
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
+
+
+
+ src/main/resources
+
+
+ src/main/java
+ **/*.xml
+
+
+
+
+
+
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/aop/MethodLog.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/aop/MethodLog.java
new file mode 100644
index 00000000..f14245f1
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/aop/MethodLog.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.aop;
+
+import java.lang.annotation.*;
+
+/*
+* 方法级日志切面注解
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 18:00
+*/
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface MethodLog {
+ String remark() default "";
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/beans/RequestKitBean.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/beans/RequestKitBean.java
new file mode 100644
index 00000000..5ec9e6d8
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/beans/RequestKitBean.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.beans;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.constants.ApiCodeEnum;
+import com.jeequan.jeepay.core.exception.BizException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Iterator;
+import java.util.Map;
+
+/*
+* 基于spring的 req 工具类
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/7 12:16
+*/
+@Slf4j
+@Component
+public class RequestKitBean {
+
+ @Autowired(required = false)
+ protected HttpServletRequest request; //自动注入request
+
+ /** reqContext对象中的key: 转换好的json对象 */
+ private static final String REQ_CONTEXT_KEY_PARAMJSON = "REQ_CONTEXT_KEY_PARAMJSON";
+
+
+ /**request.getParameter 获取参数 并转换为JSON格式 **/
+ public JSONObject reqParam2JSON() {
+
+ JSONObject returnObject = new JSONObject();
+
+ if(isConvertJSON()){
+
+ String body = "";
+ try {
+ String str;
+ while((str = request.getReader().readLine()) != null){
+ body += str;
+ }
+
+ if(StringUtils.isEmpty(body)) return returnObject;
+ return JSONObject.parseObject(body);
+
+ } catch (Exception e) {
+ log.error("请求参数转换异常! params=[{}]", body);
+ throw new BizException(ApiCodeEnum.PARAMS_ERROR, "转换异常");
+ }
+ }
+
+ // 参数Map
+ Map properties = request.getParameterMap();
+
+ // 返回值Map
+ Iterator entries = properties.entrySet().iterator();
+ Map.Entry entry;
+ String name;
+ String value = "";
+ while (entries.hasNext()) {
+ entry = (Map.Entry) entries.next();
+ name = (String) entry.getKey();
+ Object valueObj = entry.getValue();
+ if(null == valueObj){
+ value = "";
+ }else if(valueObj instanceof String[]){
+ String[] values = (String[])valueObj;
+ for(int i=0;i= 0
+ && !request.getMethod().equalsIgnoreCase("GET")
+ ){ //application/json 需要转换为json格式;
+ return true;
+ }
+
+ return false;
+ }
+
+ /** 获取客户端ip地址 **/
+ public String getClientIp() {
+ String ipAddress = null;
+ ipAddress = request.getHeader("x-forwarded-for");
+ if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+ ipAddress = request.getHeader("Proxy-Client-IP");
+ }
+ if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+ ipAddress = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+ ipAddress = request.getRemoteAddr();
+ }
+
+ // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
+ if (ipAddress != null && ipAddress.length() > 15) {
+ if (ipAddress.indexOf(",") > 0) {
+ ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
+ }
+ }
+ return ipAddress;
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/cache/ITokenService.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/cache/ITokenService.java
new file mode 100644
index 00000000..ccd14b1f
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/cache/ITokenService.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.cache;
+
+import com.jeequan.jeepay.core.constants.CS;
+import com.jeequan.jeepay.core.model.security.JeeUserDetails;
+
+/*
+* token service
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/5/24 09:06
+*/
+public class ITokenService {
+
+ /** 处理token信息
+ * 1. 如果不允许多用户则踢掉之前的所有用户信息
+ * 2. 更新token 缓存时间信息
+ * 3. 更新用户token列表
+ * **/
+ public static void processTokenCache(JeeUserDetails userDetail, String cacheKey){
+
+ userDetail.setCacheKey(cacheKey); //设置cacheKey
+
+ //当前用户的所有登录token 集合
+// if(!PropKit.isAllowMultiUser()){ //不允许多用户登录
+//
+// List allTokenList = new ArrayList<>();
+// for (String token : allTokenList) {
+// if(!cacheKey.equalsIgnoreCase(token)){
+// RedisUtil.del(token);
+// }
+// }
+// }
+
+ //保存token
+ RedisUtil.set(cacheKey, userDetail, CS.TOKEN_TIME); //缓存时间2小时, 保存具体信息而只是uid, 因为很多场景需要得到信息, 例如验证接口权限, 每次请求都需要获取。 将信息封装在一起减少磁盘请求次数, 如果放置多个key会增加非顺序读取。
+ }
+
+
+ /** 退出时,清除token信息 */
+ public static void removeIToken(String iToken, Long currentUID){
+
+ //1. 清除token的信息
+ RedisUtil.del(iToken);
+ }
+
+ /**
+ * 刷新数据
+ * **/
+ public static void refData(JeeUserDetails currentUserInfo){
+
+ //保存token 和 tokenList信息
+ RedisUtil.set(currentUserInfo.getCacheKey(), currentUserInfo, CS.TOKEN_TIME); //缓存时间2小时, 保存具体信息而只是uid, 因为很多场景需要得到信息, 例如验证接口权限, 每次请求都需要获取。 将信息封装在一起减少磁盘请求次数, 如果放置多个key会增加非顺序读取。
+
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/cache/RedisUtil.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/cache/RedisUtil.java
new file mode 100644
index 00000000..e5b3d0e0
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/cache/RedisUtil.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.cache;
+
+import com.alibaba.fastjson.JSON;
+import com.jeequan.jeepay.core.utils.SpringBeansUtil;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collection;
+import java.util.concurrent.TimeUnit;
+
+/*
+* Redis工具类
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/5/24 17:58
+*/
+public class RedisUtil {
+
+ private static StringRedisTemplate stringRedisTemplate = null;
+
+ /** 获取RedisTemplate对象, 默认使用 StringRedisTemplate, 客户端可查询 **/
+ private static final RedisTemplate getStringRedisTemplate(){
+
+ if(stringRedisTemplate == null){
+
+ if(SpringBeansUtil.getApplicationContext().containsBean("defaultStringRedisTemplate")){
+ stringRedisTemplate = SpringBeansUtil.getBean("defaultStringRedisTemplate", StringRedisTemplate.class);
+ }else{
+ stringRedisTemplate = SpringBeansUtil.getBean(StringRedisTemplate.class);
+ }
+ }
+ return stringRedisTemplate;
+ }
+
+ /** 获取缓存数据, String类型 */
+ public static String getString(String key) {
+ if(key == null) return null;
+ return (String)getStringRedisTemplate().opsForValue().get(key);
+ }
+
+ /** 获取缓存数据对象 */
+ public static T getObject(String key, Class cls) {
+
+ String val = getString(key);
+ return JSON.parseObject(val, cls);
+ }
+
+ /** 放置缓存对象 */
+ public static void setString(String key, String value) {
+ getStringRedisTemplate().opsForValue().set(key, value);
+ }
+
+ /** 普通缓存放入并设置时间, 默认单位:秒 */
+ public static void setString(String key, String value, long time) {
+ getStringRedisTemplate().opsForValue().set(key, value, time, TimeUnit.SECONDS);
+ }
+
+ /** 普通缓存放入并设置时间 */
+ public static void setString(String key, String value, long time, TimeUnit timeUnit) {
+ getStringRedisTemplate().opsForValue().set(key, value, time, timeUnit);
+ }
+
+ /** 放置缓存对象 */
+ public static void set(String key, Object value) {
+ setString(key, JSON.toJSONString(value));
+ }
+
+ /** 普通缓存放入并设置时间, 默认单位:秒 */
+ public static void set(String key, Object value, long time) {
+ setString(key, JSON.toJSONString(value), time);
+ }
+
+ /** 普通缓存放入并设置时间 */
+ public static void set(String key, Object value, long time, TimeUnit timeUnit) {
+ setString(key, JSON.toJSONString(value), time, timeUnit);
+ }
+
+ /** 指定缓存失效时间 */
+ public static void expire(String key, long time) {
+ getStringRedisTemplate().expire(key, time, TimeUnit.SECONDS);
+ }
+
+ /** 指定缓存失效时间 */
+ public static void expire(String key, long time, TimeUnit timeUnit) {
+ getStringRedisTemplate().expire(key, time, timeUnit);
+ }
+
+ /**
+ * 根据key 获取过期时间
+ * @param key 键 不能为null
+ * @return 时间(秒) 返回0代表为永久有效
+ */
+ public static long getExpire(String key) {
+ return getStringRedisTemplate().getExpire(key, TimeUnit.SECONDS);
+ }
+
+ /** 判断key是否存在 */
+ public static boolean hasKey(String key) {
+ return getStringRedisTemplate().hasKey(key);
+ }
+
+ /** 删除缓存 **/
+ public static void del(String... key) {
+ if (key != null && key.length > 0) {
+ if (key.length == 1) {
+ getStringRedisTemplate().delete(key[0]);
+ } else {
+ getStringRedisTemplate().delete(CollectionUtils.arrayToList(key));
+ }
+ }
+ }
+
+ /** 查询keys */
+ public static Collection keys(String pattern) {
+ return getStringRedisTemplate().keys(pattern);
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/constants/ApiCodeEnum.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/constants/ApiCodeEnum.java
new file mode 100644
index 00000000..5d338748
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/constants/ApiCodeEnum.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.constants;
+
+/*
+* 接口返回码
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/5/24 17:07
+*/
+public enum ApiCodeEnum{
+
+ SUCCESS(0, "SUCCESS"), //请求成功
+
+ CUSTOM_FAIL(9999, "自定义业务异常"), //自定义业务异常
+
+ SYSTEM_ERROR(10, "系统异常[%s]"),
+ PARAMS_ERROR(11, "参数有误[%s]"),
+ DB_ERROR(12, "数据库服务异常"),
+
+ SYS_OPERATION_FAIL_CREATE(5000, "新增失败"),
+ SYS_OPERATION_FAIL_DELETE(5001, "删除失败"),
+ SYS_OPERATION_FAIL_UPDATE(5002, "修改失败"),
+ SYS_OPERATION_FAIL_SELETE(5003, "记录不存在"),
+ SYS_PERMISSION_ERROR(5004, "权限错误,当前用户不支持此操作");
+
+
+ private int code;
+
+ private String msg;
+
+ ApiCodeEnum(int code, String msg) {
+ this.code = code;
+ this.msg = msg;
+ }
+
+ public int getCode(){
+ return this.code;
+ }
+
+ public String getMsg() {
+ return this.msg;
+ }
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/constants/CS.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/constants/CS.java
new file mode 100644
index 00000000..09547916
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/constants/CS.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.constants;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @Author terrfly
+ * @Date 2019/11/16 15:09
+ * @Description Constants 常量对象
+ **/
+public class CS {
+
+ /** 系统类型定义 **/
+ public interface SYS_TYPE{
+ String MCH = "MCH";
+ String MGR = "MGR";
+ Map SYS_TYPE_MAP = new HashMap<>();
+ }
+ static {
+ SYS_TYPE.SYS_TYPE_MAP.put(SYS_TYPE.MCH, "商户系统");
+ SYS_TYPE.SYS_TYPE_MAP.put(SYS_TYPE.MGR, "运营平台");
+ }
+
+ /** yes or no **/
+ public static final byte NO = 0;
+ public static final byte YES = 1;
+
+ /** 通用 可用 / 禁用 **/
+ public static final int PUB_USABLE = 1;
+ public static final int PUB_DISABLE = 0;
+
+ public static final Map PUB_USABLE_MAP = new HashMap<>();
+ static {
+ PUB_USABLE_MAP.put(PUB_USABLE, "正常");
+ PUB_USABLE_MAP.put(PUB_DISABLE, "停用");
+ }
+
+ /**
+ * 账号类型:1-服务商 2-商户
+ */
+ public static final byte INFO_TYPE_ISV = 1;
+ public static final byte INFO_TYPE_MCH = 2;
+
+
+ /**
+ * 商户类型:1-普通商户 2-特约商户
+ */
+ public static final byte MCH_TYPE_NORMAL = 1;
+ public static final byte MCH_TYPE_ISVSUB = 2;
+
+ /**
+ * 性别 1- 男, 2-女
+ */
+ public static final byte SEX_UNKNOWN = 0;
+ public static final byte SEX_MALE = 1;
+ public static final byte SEX_FEMALE = 2;
+
+ /** 默认密码 */
+ public static final String DEFAULT_PWD = "jeepay666";
+
+
+ /**
+ * 允许上传的的图片文件格式,需要与 WebSecurityConfig对应
+ */
+ public static final Set ALLOW_UPLOAD_IMG_SUFFIX = new HashSet<>();
+ static{
+ ALLOW_UPLOAD_IMG_SUFFIX.add("jpg");
+ ALLOW_UPLOAD_IMG_SUFFIX.add("png");
+ ALLOW_UPLOAD_IMG_SUFFIX.add("jpeg");
+ ALLOW_UPLOAD_IMG_SUFFIX.add("gif");
+ ALLOW_UPLOAD_IMG_SUFFIX.add("mp4");
+ }
+
+
+ public static final long TOKEN_TIME = 60 * 60 * 2; //单位:s, 两小时
+
+
+ //access_token 名称
+ public static final String ACCESS_TOKEN_NAME = "iToken";
+
+ /** !!不同系统请放置不同的redis库 !! **/
+ /** 缓存key: 当前用户所有用户的token集合 example: TOKEN_1001_HcNheNDqHzhTIrT0lUXikm7xU5XY4Q */
+ public static final String CACHE_KEY_TOKEN = "TOKEN_%s_%s";
+ public static String getCacheKeyToken(Long sysUserId, String uuid){
+ return String.format(CACHE_KEY_TOKEN, sysUserId, uuid);
+ }
+
+ /** 图片验证码 缓存key **/
+ public static final String CACHE_KEY_IMG_CODE = "img_code_%s";
+ public static String getCacheKeyImgCode(String imgToken){
+ return String.format(CACHE_KEY_IMG_CODE, imgToken);
+ }
+
+
+ /** 登录认证类型 **/
+ public interface AUTH_TYPE{
+
+ byte LOGIN_USER_NAME = 1; //登录用户名
+ byte TELPHONE = 2; //手机号
+ byte EMAIL = 3; //邮箱
+
+ byte WX_UNION_ID = 10; //微信unionId
+ byte WX_MINI = 11; //微信小程序
+ byte WX_MP = 12; //微信公众号
+
+ byte QQ = 20; //QQ
+ }
+
+
+ public interface MQ{
+
+ /** 更新配置的通知消息 **/
+ String TOPIC_MODIFY_SYS_CONFIG = "topic.modify.sys.config";
+
+ /** 更新商户配置信息 **/
+ String TOPIC_MODIFY_MCH_INFO = "topic.modify.mch.info";
+
+ /** 更新服务商配置信息 **/
+ String TOPIC_MODIFY_ISV_INFO = "topic.modify.isv.info";
+
+ /** 支付订单 商户通知MQ **/
+ String QUEUE_PAYORDER_MCH_NOTIFY = "queue.payorder.mch.notify";
+
+ /** 轮询查单 MQ **/
+ String QUEUE_CHANNEL_ORDER_QUERY = "queue.channel.order.query";
+
+ /** 清除商户登录用户信息 **/
+ String QUEUE_MODIFY_MCH_USER_REMOVE = "queue.modify.mch.user.remove";
+
+ }
+
+
+ //菜单类型
+ public interface ENT_TYPE{
+
+ String MENU_LEFT = "ML"; //左侧显示菜单
+ String MENU_OTHER = "MO"; //其他菜单
+ String PAGE_OR_BTN = "PB"; //页面 or 按钮
+
+ }
+
+ //接口类型
+ public interface IF_CODE{
+
+ String ALIPAY = "alipay"; //支付宝官方支付
+ String WXPAY = "wxpay"; //微信官方支付
+ String YSFPAY = "ysfpay"; //云闪付开放平台
+
+ }
+
+
+ //支付方式代码
+ public interface PAY_WAY_CODE{
+
+ // 特殊支付方式
+ String QR_CASHIER = "QR_CASHIER"; // ( 通过二维码跳转到收银台完成支付, 已集成获取用户ID的实现。 )
+ String AUTO_BAR = "AUTO_BAR"; // 条码聚合支付(自动分类条码类型)
+
+ String ALI_BAR = "ALI_BAR"; //支付宝条码支付
+ String ALI_JSAPI = "ALI_JSAPI"; //支付宝服务窗支付
+ String ALI_APP = "ALI_APP"; //支付宝 app支付
+ String ALI_PC = "ALI_PC"; //支付宝 电脑网站支付
+ String ALI_WAP = "ALI_WAP"; //支付宝 wap支付
+ String ALI_QR = "ALI_QR"; //支付宝 二维码付款
+
+ String YSF_BAR = "YSF_BAR"; //云闪付条码支付
+ String YSF_JSAPI = "YSF_JSAPI"; //云闪付服务窗支付
+
+ String WX_JSAPI = "WX_JSAPI"; //微信jsapi支付
+ String WX_LITE = "WX_LITE"; //微信小程序支付
+ String WX_BAR = "WX_BAR"; //微信条码支付
+ String WX_H5 = "WX_H5"; //微信H5支付
+ String WX_NATIVE = "WX_NATIVE"; //微信扫码支付
+ }
+
+ //支付数据包 类型
+ public interface PAY_DATA_TYPE {
+ String PAY_URL = "payurl"; //跳转链接的方式 redirectUrl
+ String FORM = "form"; //表单提交
+ String WX_APP = "wxapp"; //微信app参数
+ String ALI_APP = "aliapp"; //支付宝app参数
+ String YSF_APP = "ysfapp"; //云闪付app参数
+ String CODE_URL = "codeUrl"; //二维码URL
+ String CODE_IMG_URL = "codeImgUrl"; //二维码图片显示URL
+ String NONE = "none"; //无参数
+// String QR_CONTENT = "qrContent"; //二维码实际内容
+ }
+
+
+ //接口版本
+ public interface PAY_IF_VERSION{
+ String WX_V2 = "V2"; //微信接口版本V2
+ String WX_V3 = "V3"; //微信接口版本V3
+ }
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/ctrls/AbstractCtrl.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/ctrls/AbstractCtrl.java
new file mode 100644
index 00000000..8393f1ef
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/ctrls/AbstractCtrl.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.ctrls;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jeequan.jeepay.core.beans.RequestKitBean;
+import com.jeequan.jeepay.core.constants.ApiCodeEnum;
+import com.jeequan.jeepay.core.exception.BizException;
+import com.jeequan.jeepay.core.model.BaseModel;
+import com.jeequan.jeepay.core.utils.DateKit;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/*
+* 抽象公共Ctrl
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2020/02/18 17:28
+*/
+public abstract class AbstractCtrl {
+
+ protected static final Logger logger = LoggerFactory.getLogger(AbstractCtrl.class);
+
+ private static final String PAGE_INDEX_PARAM_NAME = "pageNumber"; //分页页码 参数名
+ private static final String PAGE_SIZE_PARAM_NAME = "pageSize"; //分页条数 参数名
+ private static final int DEFAULT_PAGE_INDEX = 1; // 默认页码: 第一页
+ private static final int DEFAULT_PAGE_SIZE = 20; // 默认条数: 20
+
+ private static final String SORT_FIELD_PARAM_NAME = "sortField"; //排序字段
+ private static final String SORT_ORDER_FLAG_PARAM_NAME = "sortOrder"; // 排序正序, 倒序标志
+
+ @Autowired
+ protected HttpServletRequest request; //自动注入request
+
+ @Autowired
+ protected HttpServletResponse response; //自动注入response
+
+ @Autowired
+ protected RequestKitBean requestKitBean;
+
+ /** 获取json格式的请求参数 **/
+ protected JSONObject getReqParamJSON(){
+ return requestKitBean.getReqParamJSON();
+ }
+
+ /** 获取页码 **/
+ protected int getPageIndex() {
+ Integer pageIndex = getReqParamJSON().getInteger(PAGE_INDEX_PARAM_NAME);
+ if(pageIndex == null) return DEFAULT_PAGE_INDEX;
+ return pageIndex;
+ }
+
+ /** 获取条数, 默认不允许查询全部数据 **/
+ protected int getPageSize() {
+ return getPageSize(false);
+ }
+
+ /** 获取条数, 加入条件:是否允许获取全部数据 **/
+ protected int getPageSize(boolean allowQueryAll) {
+ Integer pageSize = getReqParamJSON().getInteger(PAGE_SIZE_PARAM_NAME);
+
+ if(allowQueryAll && pageSize != null && pageSize == -1) return Integer.MAX_VALUE; // -1代表获取全部数据,查询int最大值的数据
+ if(pageSize == null || pageSize < 0) return DEFAULT_PAGE_SIZE;
+ return pageSize;
+ }
+
+ /** 获取Ipage分页信息, 默认不允许获取全部数据 **/
+ protected IPage getIPage(){
+ return new Page(getPageIndex(), getPageSize());
+ }
+
+ /** 获取Ipage分页信息, 加入条件:是否允许获取全部数据 **/
+ protected IPage getIPage(boolean allowQueryAll){
+ return new Page(getPageIndex(), getPageSize(allowQueryAll));
+ }
+
+ /** 获取排序字段 MutablePair<是否正序, 排序字段> **/
+ protected MutablePair getSortInfo() {
+
+ String sortField = getReqParamJSON().getString(SORT_FIELD_PARAM_NAME);
+ String sortOrderFlag = getReqParamJSON().getString(SORT_ORDER_FLAG_PARAM_NAME);
+ if(StringUtils.isAllEmpty(sortField, sortField)){
+ return null;
+ }
+
+ return MutablePair.of("ascend".equalsIgnoreCase(sortOrderFlag), StrUtil.toUnderlineCase(sortField).toLowerCase());
+ }
+
+
+ /** 获取请求参数值 [ T 类型 ], [ 非必填 ] **/
+ protected T getVal(String key, Class cls) {
+ return getReqParamJSON().getObject(key, cls);
+ }
+
+ /** 获取请求参数值 [ T 类型 ], [ 必填 ] **/
+ protected T getValRequired(String key, Class cls) {
+ T value = getVal(key, cls);
+ if(ObjectUtils.isEmpty(value)) {
+ throw new BizException(ApiCodeEnum.PARAMS_ERROR, genParamRequiredMsg(key));
+ }
+ return value;
+ }
+
+ /** 获取请求参数值 [ T 类型 ], [ 如为null返回默认值 ] **/
+ protected T getValDefault(String key, T defaultValue, Class cls) {
+ T value = getVal(key, cls);
+ if(value == null) return defaultValue;
+ return value;
+ }
+
+ /** 获取请求参数值 String 类型相关函数 **/
+ protected String getValString(String key) {
+ return getVal(key, String.class);
+ }
+ protected String getValStringRequired(String key) {
+ return getValRequired(key, String.class);
+ }
+ protected String getValStringDefault(String key, String defaultValue) {
+ return getValDefault(key, defaultValue, String.class);
+ }
+
+ /** 获取请求参数值 Byte 类型相关函数 **/
+ protected Byte getValByte(String key) {
+ return getVal(key, Byte.class);
+ }
+ protected Byte getValByteRequired(String key) {
+ return getValRequired(key, Byte.class);
+ }
+ protected Byte getValByteDefault(String key, Byte defaultValue) {
+ return getValDefault(key, defaultValue, Byte.class);
+ }
+
+ /** 获取请求参数值 Integer 类型相关函数 **/
+ protected Integer getValInteger(String key) {
+ return getVal(key, Integer.class);
+ }
+ protected Integer getValIntegerRequired(String key) {
+ return getValRequired(key, Integer.class);
+ }
+ protected Integer getValIntegerDefault(String key, Integer defaultValue) {
+ return getValDefault(key, defaultValue, Integer.class);
+ }
+
+ /** 获取请求参数值 Long 类型相关函数 **/
+ protected Long getValLong(String key) {
+ return getVal(key, Long.class);
+ }
+ protected Long getValLongRequired(String key) {
+ return getValRequired(key, Long.class);
+ }
+ protected Long getValLongDefault(String key, Long defaultValue) {
+ return getValDefault(key, defaultValue, Long.class);
+ }
+
+ /** 获取请求参数值 BigDecimal 类型相关函数 **/
+ protected BigDecimal getValBigDecimal(String key) {
+ return getVal(key, BigDecimal.class);
+ }
+ protected BigDecimal getValBigDecimalRequired(String key) {
+ return getValRequired(key, BigDecimal.class);
+ }
+ protected BigDecimal getValBigDecimalDefault(String key, BigDecimal defaultValue) {
+ return getValDefault(key, defaultValue, BigDecimal.class);
+ }
+
+ /** 获取对象类型 **/
+ protected T getObject(Class clazz) {
+
+ JSONObject params = getReqParamJSON();
+ T result = params.toJavaObject(clazz);
+
+ if(result instanceof BaseModel){ //如果属于BaseModel, 处理apiExtVal
+ JSONObject resultTemp = (JSONObject) JSON.toJSON(result);
+ for (String key : params.keySet()) { //遍历原始参数
+ if(!resultTemp.containsKey(key)){
+ ((BaseModel) result).addExt(key, params.get(key));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /** 生成参数必填错误信息 **/
+ private String genParamRequiredMsg(String key) {
+ return "参数" + key + "必填";
+ }
+
+ /** 校验参数值不能为空 */
+ protected void checkRequired(String... keys) {
+
+ for(String key : keys) {
+ String value = getReqParamJSON().getString(key);
+ if(StringUtils.isEmpty(value)) throw new BizException(ApiCodeEnum.PARAMS_ERROR, genParamRequiredMsg(key));
+ }
+ }
+
+ /** 得到前端传入的金额元,转换成长整型分 **/
+ public Long getRequiredAmountL(String name) {
+ String amountStr = getValStringRequired(name); // 前端填写的为元,可以为小数点2位
+ Long amountL = new BigDecimal(amountStr.trim()).multiply(new BigDecimal(100)).longValue(); // // 转成分
+ return amountL;
+ }
+
+ /** 得到前端传入的金额元,转换成长整型分 (非必填) **/
+ public Long getAmountL(String name) {
+ String amountStr = getValString(name); // 前端填写的为元,可以为小数点2位
+ if(StringUtils.isEmpty(amountStr)) return null;
+ Long amountL = new BigDecimal(amountStr.trim()).multiply(new BigDecimal(100)).longValue(); // // 转成分
+ return amountL;
+ }
+
+ /**
+ * 处理参数中的金额(将前端传入金额元转成分)
+ * modify: 20181206 添加JSON对象中的对象属性转换为分 格式[xxx.xxx]
+ * @param names
+ */
+ public void handleParamAmount(String... names) {
+ for(String name : names) {
+ String amountStr = getValString(name); // 前端填写的为元,可以为小数点2位
+ if(StringUtils.isNotBlank(amountStr)) {
+ Long amountL = new BigDecimal(amountStr.trim()).multiply(new BigDecimal(100)).longValue(); // // 转成分
+ if(name.indexOf(".") < 0 ){
+ getReqParamJSON().put(name, amountL);
+ continue;
+ }
+ getReqParamJSON().getJSONObject(name.substring(0, name.indexOf("."))).put(name.substring(name.indexOf(".")+1), amountL);
+ }
+ }
+ }
+
+ /**
+ * 获取查询的时间范围
+ * @return
+ */
+ protected Date[] getQueryDateRange(){
+ return DateKit.getQueryDateRange(getReqParamJSON().getString("queryDateRange")); //默认参数为 queryDateRange
+ }
+
+ /** 请求参数转换为map格式 **/
+ public Map request2payResponseMap(HttpServletRequest request, String[] paramArray) {
+ Map responseMap = new HashMap<>();
+ for (int i = 0;i < paramArray.length; i++) {
+ String key = paramArray[i];
+ String v = request.getParameter(key);
+ if (v != null) {
+ responseMap.put(key, v);
+ }
+ }
+ return responseMap;
+ }
+
+ /** 将上传的文件进行保存 - 公共函数 **/
+ protected void saveFile(MultipartFile file, String savePath) throws Exception {
+
+ File saveFile = new File(savePath);
+
+ //如果文件夹不存在则创建文件夹
+ File dir = saveFile.getParentFile();
+ if(!dir.exists()) dir.mkdirs();
+ file.transferTo(saveFile);
+ }
+
+ /** 获取客户端ip地址 **/
+ public String getClientIp() {
+ return requestKitBean.getClientIp();
+ }
+
+ public String getUserAgent(){
+ String userAgent = request.getHeader("User-Agent");
+ return StringUtils.isNotEmpty(userAgent) ? userAgent: "未知";
+ }
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/IsvInfo.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/IsvInfo.java
new file mode 100644
index 00000000..588fa838
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/IsvInfo.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 服务商信息表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_isv_info")
+public class IsvInfo extends BaseModel implements Serializable {
+
+ //gw
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 服务商号
+ */
+ @TableId(value = "isv_no", type = IdType.INPUT)
+ private String isvNo;
+
+ /**
+ * 服务商名称
+ */
+ private String isvName;
+
+ /**
+ * 服务商简称
+ */
+ private String isvShortName;
+
+ /**
+ * 联系人姓名
+ */
+ private String contactName;
+
+ /**
+ * 联系人手机号
+ */
+ private String contactTel;
+
+ /**
+ * 联系人邮箱
+ */
+ private String contactEmail;
+
+ /**
+ * 状态: 0-停用, 1-正常
+ */
+ private Byte state;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 创建者用户ID
+ */
+ private Long createdUid;
+
+ /**
+ * 创建者姓名
+ */
+ private String createdBy;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/MchInfo.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/MchInfo.java
new file mode 100644
index 00000000..9fe342a7
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/MchInfo.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 商户信息表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_mch_info")
+public class MchInfo extends BaseModel implements Serializable {
+
+ //gw
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ public static final byte TYPE_NORMAL = 1; //商户类型: 1-普通商户
+ public static final byte TYPE_ISVSUB = 2; //商户类型: 2-特约商户
+
+
+ /**
+ * 商户号
+ */
+ @TableId(value = "mch_no", type = IdType.INPUT)
+ private String mchNo;
+
+ /**
+ * 商户名称
+ */
+ private String mchName;
+
+ /**
+ * 商户简称
+ */
+ private String mchShortName;
+
+ /**
+ * 类型: 1-普通商户, 2-特约商户(服务商模式)
+ */
+ private Byte type;
+
+ /**
+ * 服务商号
+ */
+ private String isvNo;
+
+ /**
+ * 联系人姓名
+ */
+ private String contactName;
+
+ /**
+ * 联系人手机号
+ */
+ private String contactTel;
+
+ /**
+ * 联系人邮箱
+ */
+ private String contactEmail;
+
+ /**
+ * 私钥
+ */
+ private String privateKey;
+
+ /**
+ * 商户状态: 0-停用, 1-正常
+ */
+ private Byte state;
+
+ /**
+ * 商户备注
+ */
+ private String remark;
+
+ /**
+ * 初始用户ID(创建商户时,允许商户登录的用户)
+ */
+ private Long initUserId;
+
+ /**
+ * 创建者用户ID
+ */
+ private Long createdUid;
+
+ /**
+ * 创建者姓名
+ */
+ private String createdBy;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/MchNotifyRecord.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/MchNotifyRecord.java
new file mode 100644
index 00000000..4f570f2c
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/MchNotifyRecord.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 商户通知记录表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_mch_notify_record")
+public class MchNotifyRecord extends BaseModel implements Serializable {
+
+ //订单类型:1-支付,2-退款
+ public static final Byte TYPE_PAY_ORDER = 1;
+ public static final Byte TYPE_REFUND_ORDER = 2;
+
+ //通知状态
+ public static final Byte STATE_ING = 1;
+ public static final Byte STATE_SUCCESS = 2;
+ public static final Byte STATE_FAIL = 3;
+
+ //gw
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 商户通知记录ID
+ */
+ @TableId(value = "notify_id", type = IdType.AUTO)
+ private Long notifyId;
+
+ /**
+ * 订单ID
+ */
+ private String orderId;
+
+ /**
+ * 订单类型:1-支付,2-退款
+ */
+ private Byte orderType;
+
+ /**
+ * 商户订单号
+ */
+ private String mchOrderNo;
+
+ /**
+ * 商户号
+ */
+ private String mchNo;
+
+ /**
+ * 服务商号
+ */
+ private String isvNo;
+
+ /**
+ * 通知地址
+ */
+ private String notifyUrl;
+
+ /**
+ * 通知响应结果
+ */
+ private String resResult;
+
+ /**
+ * 通知次数
+ */
+ private Integer notifyCount;
+
+ /**
+ * 通知状态,1-通知中,2-通知成功,3-通知失败
+ */
+ private Byte state;
+
+ /**
+ * 最后一次通知时间
+ */
+ private Date lastNotifyTime;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/MchPayPassage.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/MchPayPassage.java
new file mode 100644
index 00000000..033ff2e6
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/MchPayPassage.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ *
+ * 商户支付通道表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_mch_pay_passage")
+public class MchPayPassage extends BaseModel implements Serializable {
+
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * ID
+ */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 商户号
+ */
+ private String mchNo;
+
+ /**
+ * 支付接口
+ */
+ private String ifCode;
+
+ /**
+ * 支付方式
+ */
+ private String wayCode;
+
+ /**
+ * 支付方式费率
+ */
+ private BigDecimal rate;
+
+ /**
+ * 风控数据
+ */
+ private String riskConfig;
+
+ /**
+ * 状态: 0-停用, 1-启用
+ */
+ private Byte state;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayInterfaceConfig.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayInterfaceConfig.java
new file mode 100644
index 00000000..e36b05b6
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayInterfaceConfig.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ *
+ * 支付接口配置参数表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_pay_interface_config")
+public class PayInterfaceConfig extends BaseModel implements Serializable {
+
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * ID
+ */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 账号类型:1-服务商 2-商户
+ */
+ private Byte infoType;
+
+ /**
+ * 服务商或商户No
+ */
+ private String infoId;
+
+ /**
+ * 支付接口代码
+ */
+ private String ifCode;
+
+ /**
+ * 接口配置参数,json字符串
+ */
+ private String ifParams;
+
+ /**
+ * 支付接口费率
+ */
+ private BigDecimal ifRate;
+
+ /**
+ * 状态: 0-停用, 1-启用
+ */
+ private Byte state;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 创建者用户ID
+ */
+ private Long createdUid;
+
+ /**
+ * 创建者姓名
+ */
+ private String createdBy;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新者用户ID
+ */
+ private Long updatedUid;
+
+ /**
+ * 更新者姓名
+ */
+ private String updatedBy;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayInterfaceDefine.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayInterfaceDefine.java
new file mode 100644
index 00000000..ba39465b
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayInterfaceDefine.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.alibaba.fastjson.JSONArray;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 支付接口定义表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName(value = "t_pay_interface_define", autoResultMap = true)
+public class PayInterfaceDefine extends BaseModel implements Serializable {
+
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 接口代码 全小写 wxpay alipay
+ */
+ @TableId
+ private String ifCode;
+
+ /**
+ * 接口名称
+ */
+ private String ifName;
+
+ /**
+ * 是否支持普通商户模式: 0-不支持, 1-支持
+ */
+ private Byte isMchMode;
+
+ /**
+ * 是否支持服务商子商户模式: 0-不支持, 1-支持
+ */
+ private Byte isIsvMode;
+
+ /**
+ * ISV接口配置定义描述,json字符串
+ */
+ private String isvParams;
+
+ /**
+ * 特约商户接口配置定义描述,json字符串
+ */
+ private String isvsubMchParams;
+
+ /**
+ * 普通商户接口配置定义描述,json字符串
+ */
+ private String normalMchParams;
+
+ /**
+ * 支持的支付方式 ["wxpay_jsapi", "wxpay_bar"]
+ */
+ @TableField(typeHandler = FastjsonTypeHandler.class)
+ private JSONArray wayCodes;
+
+ /**
+ * 页面展示:卡片-图标
+ */
+ private String icon;
+
+ /**
+ * 页面展示:卡片-背景色
+ */
+ private String bgColor;
+
+ /**
+ * 状态: 0-停用, 1-启用
+ */
+ private Byte state;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayOrder.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayOrder.java
new file mode 100644
index 00000000..b68ae9ca
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayOrder.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 支付订单表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_pay_order")
+public class PayOrder extends BaseModel implements Serializable {
+
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+
+ public static final byte STATE_INIT = 0; //订单生成
+ public static final byte STATE_ING = 1; //支付中
+ public static final byte STATE_SUCCESS = 2; //支付成功
+ public static final byte STATE_FAIL = 3; //支付失败
+ public static final byte STATE_CANCEL = 4; //已撤销
+ public static final byte STATE_REFUND = 5; //已退款
+ public static final byte STATE_CLOSED = 6; //订单关闭
+
+
+ /**
+ * 支付订单号
+ */
+ @TableId
+ private String payOrderId;
+
+ /**
+ * 商户号
+ */
+ private String mchNo;
+
+ /**
+ * 服务商号
+ */
+ private String isvNo;
+
+ /**
+ * 商户名称
+ */
+ private String mchName;
+
+ /**
+ * 类型: 1-普通商户, 2-特约商户(服务商模式)
+ */
+ private Byte mchType;
+
+ /**
+ * 商户订单号
+ */
+ private String mchOrderNo;
+
+ /**
+ * 支付接口代码
+ */
+ private String ifCode;
+
+ /**
+ * 支付方式代码
+ */
+ private String wayCode;
+
+ /**
+ * 支付金额,单位分
+ */
+ private Long amount;
+
+ /**
+ * 三位货币代码,人民币:cny
+ */
+ private String currency;
+
+ /**
+ * 支付状态: 0-订单生成, 1-支付中, 2-支付成功, 3-支付失败, 4-已撤销, 5-已退款, 6-订单关闭
+ */
+ private Byte state;
+
+ /**
+ * 向下游回调状态, 0-未发送, 1-已发送
+ */
+ private Byte notifyState;
+
+ /**
+ * 客户端IP
+ */
+ private String clientIp;
+
+ /**
+ * 商品标题
+ */
+ private String subject;
+
+ /**
+ * 商品描述信息
+ */
+ private String body;
+
+ /**
+ * 特定渠道发起额外参数
+ */
+ private String channelExtra;
+
+ /**
+ * 渠道用户标识,如微信openId,支付宝账号
+ */
+ private String channelUser;
+
+ /**
+ * 渠道订单号
+ */
+ private String channelOrderNo;
+
+ /**
+ * 退款次数
+ */
+ private Integer refundTimes;
+
+ /**
+ * 退款总金额,单位分
+ */
+ private Long refundAmount;
+
+ /**
+ * 订单分账标志:0-否 1-是
+ */
+ private Byte divisionFlag;
+
+ /**
+ * 预计分账发起时间
+ */
+ private Date divisionTime;
+
+ /**
+ * 渠道支付错误码
+ */
+ private String errCode;
+
+ /**
+ * 渠道支付错误描述
+ */
+ private String errMsg;
+
+ /**
+ * 商户扩展参数
+ */
+ private String extParam;
+
+ /**
+ * 异步通知地址
+ */
+ private String notifyUrl;
+
+ /**
+ * 页面跳转地址
+ */
+ private String returnUrl;
+
+ /**
+ * 订单失效时间
+ */
+ private Date expiredTime;
+
+ /**
+ * 订单支付成功时间
+ */
+ private Date successTime;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayWay.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayWay.java
new file mode 100644
index 00000000..41704a90
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/PayWay.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 支付方式表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_pay_way")
+public class PayWay extends BaseModel implements Serializable {
+
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 支付方式代码 例如: wxpay_jsapi
+ */
+ @TableId
+ private String wayCode;
+
+ /**
+ * 支付方式名称
+ */
+ private String wayName;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/RefundOrder.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/RefundOrder.java
new file mode 100644
index 00000000..ae159f9d
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/RefundOrder.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 退款订单表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_refund_order")
+public class RefundOrder extends BaseModel implements Serializable {
+
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 退款订单号
+ */
+ @TableId
+ private String refundOrderId;
+
+ /**
+ * 支付订单号
+ */
+ private String payOrderId;
+
+ /**
+ * 渠道支付单号
+ */
+ private String channelPayOrderNo;
+
+ /**
+ * 商户号
+ */
+ private String mchNo;
+
+ /**
+ * 类型: 1-普通商户, 2-特约商户(服务商模式)
+ */
+ private Byte mchType;
+
+ /**
+ * 商户退款单号
+ */
+ private String mchRefundNo;
+
+ /**
+ * 服务商号
+ */
+ private String isvNo;
+
+ /**
+ * 支付方式代码
+ */
+ private String wayCode;
+
+ /**
+ * 支付接口代码
+ */
+ private String ifCode;
+
+ /**
+ * 支付金额,单位分
+ */
+ private Long payAmount;
+
+ /**
+ * 退款金额,单位分
+ */
+ private Long refundAmount;
+
+ /**
+ * 三位货币代码,人民币:cny
+ */
+ private String currency;
+
+ /**
+ * 退款状态:0-订单生成,1-退款中,2-退款成功,3-退款失败
+ */
+ private Byte state;
+
+ /**
+ * 退款结果:0-不确认结果,1-等待手动处理,2-确认成功,3-确认失败
+ */
+ private Byte result;
+
+ /**
+ * 客户端IP
+ */
+ private String clientIp;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 渠道订单号
+ */
+ private String channelOrderNo;
+
+ /**
+ * 渠道错误码
+ */
+ private String channelErrCode;
+
+ /**
+ * 渠道错误描述
+ */
+ private String channelErrMsg;
+
+ /**
+ * 特定渠道发起时额外参数
+ */
+ private String channelExtra;
+
+ /**
+ * 通知地址
+ */
+ private String notifyUrl;
+
+ /**
+ * 扩展参数
+ */
+ private String extParam;
+
+ /**
+ * 订单退款成功时间
+ */
+ private Date successTime;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysConfig.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysConfig.java
new file mode 100644
index 00000000..5290dead
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysConfig.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 系统配置表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-23
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_sys_config")
+public class SysConfig extends BaseModel implements Serializable {
+
+ //gw
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 配置KEY
+ */
+ @TableId(value = "config_key", type = IdType.INPUT)
+ private String configKey;
+
+ /**
+ * 配置名称
+ */
+ private String configName;
+
+ /**
+ * 描述信息
+ */
+ private String configDesc;
+
+ /**
+ * 分组key
+ */
+ private String groupKey;
+
+ /**
+ * 分组名称
+ */
+ private String groupName;
+
+ /**
+ * 配置内容项
+ */
+ private String configVal;
+
+ /**
+ * 类型: text-输入框, textarea-多行文本, uploadImg-上传图片, switch-开关
+ */
+ private String type;
+
+ /**
+ * 显示顺序
+ */
+ private Long sortNum;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysEntitlement.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysEntitlement.java
new file mode 100644
index 00000000..49402188
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysEntitlement.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ *
+ * 系统权限表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-23
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_sys_entitlement")
+public class SysEntitlement extends BaseModel {
+
+ //gw
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 权限ID[ENT_功能模块_子模块_操作], eg: ENT_ROLE_LIST_ADD
+ */
+ @TableId
+ private String entId;
+
+ /**
+ * 权限名称
+ */
+ private String entName;
+
+ /**
+ * 菜单图标
+ */
+ private String menuIcon;
+
+ /**
+ * 菜单uri/路由地址
+ */
+ private String menuUri;
+
+ /**
+ * 组件Name(前后端分离使用)
+ */
+ private String componentName;
+
+ /**
+ * 权限类型 ML-左侧显示菜单, MO-其他菜单, PB-页面/按钮
+ */
+ private String entType;
+
+ /**
+ * 快速开始菜单 0-否, 1-是
+ */
+ private Byte quickJump;
+
+ /**
+ * 状态 0-停用, 1-启用
+ */
+ private Byte state;
+
+ /**
+ * 父ID
+ */
+ private String pid;
+
+ /**
+ * 排序字段, 规则:正序
+ */
+ private Integer entSort;
+
+ /**
+ * 所属系统: MGR-运营平台, MCH-商户中心
+ */
+ private String system;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysLog.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysLog.java
new file mode 100644
index 00000000..4a71e137
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysLog.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 系统操作日志表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_sys_log")
+public class SysLog implements Serializable {
+
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * id
+ */
+ @TableId(value = "sys_log_id", type = IdType.AUTO)
+ private Integer sysLogId;
+
+ /**
+ * 系统用户ID
+ */
+ private Long userId;
+
+ /**
+ * 用户姓名
+ */
+ private String userName;
+
+ /**
+ * 用户IP
+ */
+ private String userIp;
+
+ /**
+ * 所属系统: MGR-运营平台, MCH-商户中心
+ */
+ private String system;
+
+ /**
+ * 方法名
+ */
+ private String methodName;
+
+ /**
+ * 方法描述
+ */
+ private String methodRemark;
+
+ /**
+ * 请求地址
+ */
+ private String reqUrl;
+
+ /**
+ * 操作请求参数
+ */
+ private String optReqParam;
+
+ /**
+ * 操作响应结果
+ */
+ private String optResInfo;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysRole.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysRole.java
new file mode 100644
index 00000000..5e15a5f4
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysRole.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 系统角色表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-23
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_sys_role")
+public class SysRole implements Serializable {
+
+ //gw
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 角色ID, ROLE_开头
+ */
+ @TableId
+ private String roleId;
+
+ /**
+ * 角色名称
+ */
+ private String roleName;
+
+ /**
+ * 所属系统: MGR-运营平台, MCH-商户中心
+ */
+ private String system;
+
+ /**
+ * 所属商户ID / 0(平台)
+ */
+ private String belongInfoId;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysRoleEntRela.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysRoleEntRela.java
new file mode 100644
index 00000000..7ca508e8
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysRoleEntRela.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ *
+ * 系统角色权限关联表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-23
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_sys_role_ent_rela")
+public class SysRoleEntRela implements Serializable {
+
+ //gw
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 角色ID
+ */
+ private String roleId;
+
+ /**
+ * 权限ID
+ */
+ private String entId;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysUser.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysUser.java
new file mode 100644
index 00000000..2c3be4b4
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysUser.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeequan.jeepay.core.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ *
+ * 系统用户表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-23
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_sys_user")
+public class SysUser extends BaseModel {
+
+ //gw
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 系统用户ID
+ */
+ @TableId(value = "sys_user_id", type = IdType.AUTO)
+ private Long sysUserId;
+
+ /**
+ * 登录用户名
+ */
+ private String loginUsername;
+
+ /**
+ * 真实姓名
+ */
+ private String realname;
+
+ /**
+ * 手机号
+ */
+ private String telphone;
+
+ /**
+ * 性别 0-未知, 1-男, 2-女
+ */
+ private Byte sex;
+
+ /**
+ * 头像地址
+ */
+ private String avatarUrl;
+
+ /**
+ * 员工编号
+ */
+ private String userNo;
+
+ /**
+ * 是否超管(超管拥有全部权限) 0-否 1-是
+ */
+ private Byte isAdmin;
+
+ /**
+ * 状态 0-停用 1-启用
+ */
+ private Byte state;
+
+ /**
+ * 所属系统: MGR-运营平台, MCH-商户中心
+ */
+ private String system;
+
+ /**
+ * 所属商户ID / 0(平台)
+ */
+ private String belongInfoId;
+
+ /**
+ * 创建时间
+ */
+ private Date createdAt;
+
+ /**
+ * 更新时间
+ */
+ private Date updatedAt;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysUserAuth.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysUserAuth.java
new file mode 100644
index 00000000..4c9857a3
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysUserAuth.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ *
+ * 系统用户认证表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-23
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_sys_user_auth")
+public class SysUserAuth implements Serializable {
+
+ //gw
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * ID
+ */
+ @TableId(value = "auth_id", type = IdType.AUTO)
+ private Long authId;
+
+ /**
+ * user_id
+ */
+ private Long userId;
+
+ /**
+ * 登录类型 1-昵称 2-手机号 3-邮箱 10-微信 11-QQ 12-支付宝 13-微博
+ */
+ private Byte identityType;
+
+ /**
+ * 认证标识 ( 用户名 | open_id )
+ */
+ private String identifier;
+
+ /**
+ * 密码凭证
+ */
+ private String credential;
+
+ /**
+ * salt
+ */
+ private String salt;
+
+ /**
+ * 所属系统: MGR-运营平台, MCH-商户中心
+ */
+ private String system;
+
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysUserRoleRela.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysUserRoleRela.java
new file mode 100644
index 00000000..5b15b0c0
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/entity/SysUserRoleRela.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ *
+ * 操作员<->角色 关联表
+ *
+ *
+ * @author [mybatis plus generator]
+ * @since 2021-04-23
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("t_sys_user_role_rela")
+public class SysUserRoleRela implements Serializable {
+
+ //gw
+ public static final LambdaQueryWrapper gw(){
+ return new LambdaQueryWrapper<>();
+ }
+
+ private static final long serialVersionUID=1L;
+
+ /**
+ * 用户ID
+ */
+ private Long userId;
+
+ /**
+ * 角色ID
+ */
+ private String roleId;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/exception/BizException.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/exception/BizException.java
new file mode 100644
index 00000000..a6cb8d20
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/exception/BizException.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.exception;
+
+import com.jeequan.jeepay.core.constants.ApiCodeEnum;
+import com.jeequan.jeepay.core.model.ApiRes;
+import lombok.Getter;
+/*
+* 自定义业务异常
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:33
+*/
+@Getter
+public class BizException extends RuntimeException{
+
+ private static final long serialVersionUID = 1L;
+
+ private ApiRes apiRes;
+
+ /** 业务自定义异常 **/
+ public BizException(String msg) {
+ super(msg);
+ this.apiRes = ApiRes.customFail(msg);
+ }
+
+ public BizException(ApiCodeEnum apiCodeEnum, String... params) {
+ super();
+ apiRes = ApiRes.fail(apiCodeEnum, params);
+ }
+
+ public BizException(ApiRes apiRes) {
+ super(apiRes.getMsg());
+ this.apiRes = apiRes;
+ }
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/exception/BizExceptionResolver.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/exception/BizExceptionResolver.java
new file mode 100644
index 00000000..83396032
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/exception/BizExceptionResolver.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.exception;
+
+import com.jeequan.jeepay.core.constants.ApiCodeEnum;
+import com.jeequan.jeepay.core.model.ApiRes;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.dao.DataAccessException;
+import org.springframework.web.servlet.HandlerExceptionResolver;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/*
+* 异常信息自定义返回数据
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:30
+*/
+@Configuration
+public class BizExceptionResolver implements HandlerExceptionResolver {
+
+ private Logger logger = LogManager.getLogger(BizExceptionResolver.class);
+
+ @Override
+ public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
+ Exception ex) {
+
+
+ // 是否包含ss框架
+ boolean hasSpringSecurity = false;
+ try {
+ hasSpringSecurity = Class.forName("org.springframework.security.access.AccessDeniedException") != null;
+ } catch (Exception e) {
+ }
+
+ String outPutJson;
+
+ //业务异常
+ if(ex instanceof BizException) {
+ logger.error("公共捕捉[Biz]异常:{}",ex.getMessage());
+ outPutJson = ((BizException) ex).getApiRes().toJSONString();
+ }else if(ex instanceof DataAccessException){
+ logger.error("公共捕捉[DataAccessException]异常:",ex);
+ outPutJson = ApiRes.fail(ApiCodeEnum.DB_ERROR).toJSONString();
+ }else if(hasSpringSecurity && ex instanceof org.springframework.security.access.AccessDeniedException) {
+ logger.error("公共捕捉[AccessDeniedException]异常:", ex);
+ outPutJson = ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR, ex.getMessage()).toJSONString();
+ }else{
+ logger.error("公共捕捉[Exception]异常:",ex);
+ outPutJson = ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, ex.getMessage()).toJSONString();
+ }
+
+ try {
+ this.outPutJson(response, outPutJson);
+ } catch (IOException e) {
+ logger.error("输出错误信息异常:", e);
+ }
+
+ return new ModelAndView();
+ }
+
+
+ public void outPutJson(HttpServletResponse res, String jsonStr) throws IOException {
+ res.setContentType("text/json;charset=utf-8");
+ res.getWriter().write(jsonStr);
+ res.getWriter().flush();
+ res.getWriter().close();
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/exception/ResponseException.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/exception/ResponseException.java
new file mode 100644
index 00000000..89fbfb63
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/exception/ResponseException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.exception;
+
+import lombok.Getter;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+
+/*
+* 响应异常, 一般用于支付接口回调函数
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:31
+*/
+@Getter
+public class ResponseException extends RuntimeException{
+
+ private static final long serialVersionUID = 1L;
+
+ private ResponseEntity responseEntity;
+
+ /** 业务自定义异常 **/
+ public ResponseException(ResponseEntity resp) {
+ super();
+ this.responseEntity = resp;
+ }
+
+ /** 生成文本类型的响应 **/
+ public static ResponseException buildText(String text){
+
+ HttpHeaders httpHeaders = new HttpHeaders();
+ httpHeaders.setContentType(MediaType.TEXT_HTML);
+ ResponseEntity entity = new ResponseEntity(text, httpHeaders, HttpStatus.OK);
+ return new ResponseException(entity);
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/jwt/JWTPayload.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/jwt/JWTPayload.java
new file mode 100644
index 00000000..4801d976
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/jwt/JWTPayload.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.jwt;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.model.security.JeeUserDetails;
+import lombok.Data;
+
+import java.util.Map;
+
+/*
+* JWT payload 载体
+* 格式:
+ {
+ "sysUserId": "10001",
+ "created": "1568250147846",
+ "cacheKey": "KEYKEYKEYKEY",
+ }
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 18:01
+*/
+@Data
+public class JWTPayload {
+
+ private Long sysUserId; //登录用户ID
+ private Long created; //创建时间, 格式:13位时间戳
+ private String cacheKey; //redis保存的key
+
+ protected JWTPayload(){}
+
+ public JWTPayload(JeeUserDetails jeeUserDetails){
+
+ this.setSysUserId(jeeUserDetails.getSysUser().getSysUserId());
+ this.setCreated(System.currentTimeMillis());
+ this.setCacheKey(jeeUserDetails.getCacheKey());
+ }
+
+
+ /** toMap **/
+ public Map toMap(){
+ JSONObject json = (JSONObject)JSONObject.toJSON(this);
+ return json.toJavaObject(Map.class);
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/jwt/JWTUtils.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/jwt/JWTUtils.java
new file mode 100644
index 00000000..62addeab
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/jwt/JWTUtils.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.jwt;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+
+/*
+* JWT工具包
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:32
+*/
+public class JWTUtils {
+
+ /** 生成token **/
+ public static String generateToken(JWTPayload jwtPayload, String jwtSecret) {
+ return Jwts.builder()
+ .setClaims(jwtPayload.toMap())
+ //过期时间 = 当前时间 + (设置过期时间[单位 :s ] ) token放置redis 过期时间无意义
+ //.setExpiration(new Date(System.currentTimeMillis() + (jwtExpiration * 1000) ))
+ .signWith(SignatureAlgorithm.HS512, jwtSecret)
+ .compact();
+ }
+
+ /** 根据token与秘钥 解析token并转换为 JWTPayload **/
+ public static JWTPayload parseToken(String token, String secret){
+ try {
+ Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
+
+ JWTPayload result = new JWTPayload();
+ result.setSysUserId(claims.get("sysUserId", Long.class));
+ result.setCreated(claims.get("created", Long.class));
+ result.setCacheKey(claims.get("cacheKey", String.class));
+ return result;
+
+
+ } catch (Exception e) {
+ return null; //解析失败
+ }
+ }
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/ApiRes.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/ApiRes.java
new file mode 100644
index 00000000..be728b45
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/ApiRes.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.jeequan.jeepay.core.constants.ApiCodeEnum;
+import com.jeequan.jeepay.core.utils.JeepayKit;
+import com.jeequan.jeepay.core.utils.JsonKit;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/*
+* 接口返回对象
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:35
+*/
+@Data
+@AllArgsConstructor
+public class ApiRes {
+
+ /** 业务响应码 **/
+ private Integer code;
+
+ /** 业务响应信息 **/
+ private String msg;
+
+ /** 数据对象 **/
+ private Object data;
+
+ /** 签名值 **/
+ private String sign;
+
+ /** 输出json格式字符串 **/
+ public String toJSONString(){
+ return JSON.toJSONString(this);
+ }
+
+ /** 业务处理成功 **/
+ public static ApiRes ok(){
+ return ok(null);
+ }
+
+ /** 业务处理成功 **/
+ public static ApiRes ok(Object data){
+ return new ApiRes(ApiCodeEnum.SUCCESS.getCode(), ApiCodeEnum.SUCCESS.getMsg(), data, null);
+ }
+
+ /** 业务处理成功, 自动签名 **/
+ public static ApiRes okWithSign(Object data, String mchKey){
+
+ if(data == null){
+ return new ApiRes(ApiCodeEnum.SUCCESS.getCode(), ApiCodeEnum.SUCCESS.getMsg(), null, null);
+ }
+
+ JSONObject jsonObject = (JSONObject)JSONObject.toJSON(data);
+ String sign = JeepayKit.getSign(jsonObject, mchKey);
+ return new ApiRes(ApiCodeEnum.SUCCESS.getCode(), ApiCodeEnum.SUCCESS.getMsg(), data, sign);
+ }
+
+ /** 业务处理成功, 返回简单json格式 **/
+ public static ApiRes ok4newJson(String key, Object val){
+ return ok(JsonKit.newJson(key, val));
+ }
+
+ /** 业务处理成功, 封装分页数据, 仅返回必要参数 **/
+ public static ApiRes page(IPage iPage){
+
+ JSONObject result = new JSONObject();
+ result.put("records", iPage.getRecords()); //记录明细
+ result.put("total", iPage.getTotal()); //总条数
+ result.put("current", iPage.getCurrent()); //当前页码
+ result.put("hasNext", iPage.getPages() > iPage.getCurrent() ); //是否有下一页
+ return ok(result);
+ }
+
+ /** 业务处理失败 **/
+ public static ApiRes fail(ApiCodeEnum apiCodeEnum, String... params){
+
+ if(params == null || params.length <= 0){
+ return new ApiRes(apiCodeEnum.getCode(), apiCodeEnum.getMsg(), null, null);
+ }
+ return new ApiRes(apiCodeEnum.getCode(), String.format(apiCodeEnum.getMsg(), params), null, null);
+ }
+
+ /** 自定义错误信息, 原封不用的返回输入的错误信息 **/
+ public static ApiRes customFail(String customMsg){
+ return new ApiRes(ApiCodeEnum.CUSTOM_FAIL.getCode(), customMsg, null, null);
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/BaseModel.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/BaseModel.java
new file mode 100644
index 00000000..654c2a69
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/BaseModel.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
+
+import java.io.Serializable;
+
+/*
+* BaseModel 封装公共处理函数
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:49
+*/
+public class BaseModel implements Serializable{
+
+ private static final long serialVersionUID = 1L;
+
+ /** ext参数, 用作扩展参数, 会在转换为api数据时自动将ext全部属性放置在对象的主属性上, 并且不包含ext属性 **/
+
+ /** api接口扩展字段, 当包含该字段时 将自动填充到实体对象属性中如{id:1, ext:{abc:222}} 则自动转换为: {id:1, abc:222},
+ * 需配合ResponseBodyAdvice使用
+ * **/
+ @TableField(exist = false)
+ private JSONObject ext;
+
+ //获取的时候设置默认值
+ public JSONObject getExt() {
+ return ext;
+ }
+
+ //设置扩展字段
+ public BaseModel addExt(String key, Object val) {
+
+ if(ext == null) ext = new JSONObject();
+ ext.put(key,val);
+ return this;
+ }
+
+ /** get ext value 可直接使用JSONObject对象的函数 **/
+ public JSONObject extv() {
+ return ext == null ? new JSONObject() : ext;
+ }
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/DBApplicationConfig.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/DBApplicationConfig.java
new file mode 100644
index 00000000..627565aa
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/DBApplicationConfig.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model;
+
+import cn.hutool.core.util.URLUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.utils.JeepayKit;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/*
+* 系统应用配置项定义Bean
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:35
+*/
+@Data
+public class DBApplicationConfig implements Serializable {
+
+ /** 运营系统地址 **/
+ private String mgrSiteUrl;
+
+ /** 商户系统地址 **/
+ private String mchSiteUrl;
+
+ /** 支付网关地址 **/
+ private String paySiteUrl;
+
+ /** oss公共读文件地址 **/
+ private String ossPublicSiteUrl;
+
+ /** 生成 【jsapi统一收银台跳转地址】 **/
+ public String genUniJsapiPayUrl(String payOrderId){
+ return getPaySiteUrl() + "/cashier/index.html#/hub/" + JeepayKit.aesEncode(payOrderId);
+ }
+
+ /** 生成 【jsapi统一收银台】oauth2获取用户ID回调地址 **/
+ public String genOauth2RedirectUrlEncode(String payOrderId){
+ return URLUtil.encode(getPaySiteUrl() + "/cashier/index.html#/oauth2Callback/" + JeepayKit.aesEncode(payOrderId));
+ }
+
+ /** 生成 【商户获取渠道用户ID接口】oauth2获取用户ID回调地址 **/
+ public String genMchChannelUserIdApiOauth2RedirectUrlEncode(JSONObject param){
+ return URLUtil.encode(getPaySiteUrl() + "/api/channelUserId/oauth2Callback/" + JeepayKit.aesEncode(param.toJSONString()));
+ }
+
+ /** 生成 【jsapi统一收银台二维码图片地址】 **/
+ public String genScanImgUrl(String url){
+ return getPaySiteUrl() + "/api/scan/imgs/" + JeepayKit.aesEncode(url) + ".png";
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/OriginalRes.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/OriginalRes.java
new file mode 100644
index 00000000..8918e303
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/OriginalRes.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/*
+* 返回原始数据
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:37
+*/
+@Data
+@AllArgsConstructor
+public class OriginalRes {
+
+ /** 返回数据 **/
+ private Object data;
+
+ public static OriginalRes ok(Object data){
+ return new OriginalRes(data);
+ }
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/OssFileConfig.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/OssFileConfig.java
new file mode 100644
index 00000000..ca95db81
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/OssFileConfig.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
+
+/*
+* 定义文件上传的配置信息
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:38
+*/
+@Data
+@AllArgsConstructor
+public class OssFileConfig {
+
+ /** 用户头像 **/
+ interface BIZ_TYPE {
+ String AVATAR = "avatar"; /** 用户头像 **/
+ String IF_BG = "ifBG"; /** 接口类型卡片背景图片 **/
+ String CERT = "cert"; /** 接口参数 **/
+ }
+
+ /** 图片类型后缀格式 **/
+ public static final Set IMG_SUFFIX = new HashSet(Arrays.asList("jpg", "png", "jpeg", "gif"));
+
+ /** 全部后缀格式的文件标识符 **/
+ public static final String ALL_SUFFIX_FLAG = "*";
+
+ /** 不校验文件大小标识符 **/
+ public static final Long ALL_MAX_SIZE = -1L;
+
+ /** 允许上传的最大文件大小的默认值 **/
+ public static final Long DEFAULT_MAX_SIZE = 5 * 1024 * 1024L;
+
+ private static final Map ALL_BIZ_TYPE_MAP = new HashMap<>();
+ static{
+ ALL_BIZ_TYPE_MAP.put(BIZ_TYPE.AVATAR, new OssFileConfig(true, IMG_SUFFIX, DEFAULT_MAX_SIZE) );
+ ALL_BIZ_TYPE_MAP.put(BIZ_TYPE.IF_BG, new OssFileConfig(true, IMG_SUFFIX, DEFAULT_MAX_SIZE) );
+ ALL_BIZ_TYPE_MAP.put(BIZ_TYPE.CERT, new OssFileConfig(false, new HashSet<>(Arrays.asList(ALL_SUFFIX_FLAG)), DEFAULT_MAX_SIZE) );
+ }
+
+ /** 是否允许公共读 **/
+ private boolean allowPublicRead = false;
+
+ /** 允许的文件后缀, 默认全部类型 **/
+ private Set allowFileSuffix = new HashSet<>(Arrays.asList(ALL_SUFFIX_FLAG));
+
+ /** 允许的文件大小, 单位: Byte **/
+ private Long maxSize = DEFAULT_MAX_SIZE;
+
+
+ /** 是否在允许的文件类型后缀内 **/
+ public boolean isAllowFileSuffix(String fixSuffix){
+
+ if(this.allowFileSuffix.contains(ALL_SUFFIX_FLAG)){ //允许全部
+ return true;
+ }
+
+ return this.allowFileSuffix.contains(StringUtils.defaultIfEmpty(fixSuffix, "").toLowerCase());
+ }
+
+ /** 是否在允许的大小范围内 **/
+ public boolean isMaxSizeLimit(Long fileSize){
+
+ if(ALL_MAX_SIZE.equals(this.maxSize)){ //允许全部大小
+ return true;
+ }
+
+ return this.maxSize >= ( fileSize == null ? 0L : fileSize);
+ }
+
+
+ public static OssFileConfig getOssFileConfigByBizType(String bizType){
+ return ALL_BIZ_TYPE_MAP.get(bizType);
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/IsvParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/IsvParams.java
new file mode 100644
index 00000000..2165224d
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/IsvParams.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.constants.CS;
+import com.jeequan.jeepay.core.model.params.alipay.AlipayIsvParams;
+import com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvParams;
+import com.jeequan.jeepay.core.model.params.ysf.YsfpayIsvParams;
+
+/*
+ * 抽象类 isv参数定义
+ *
+ * @author terrfly
+ * @site https://www.jeepay.vip
+ * @date 2021/6/8 16:33
+ */
+public abstract class IsvParams {
+
+ public static IsvParams factory(String ifCode, String paramsStr){
+
+ if(CS.IF_CODE.WXPAY.equals(ifCode)){
+ return JSONObject.parseObject(paramsStr, WxpayIsvParams.class);
+ }else if(CS.IF_CODE.ALIPAY.equals(ifCode)){
+ return JSONObject.parseObject(paramsStr, AlipayIsvParams.class);
+ }else if(CS.IF_CODE.YSFPAY.equals(ifCode)){
+ return JSONObject.parseObject(paramsStr, YsfpayIsvParams.class);
+ }
+ return null;
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/IsvsubMchParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/IsvsubMchParams.java
new file mode 100644
index 00000000..b6b43d15
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/IsvsubMchParams.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.constants.CS;
+import com.jeequan.jeepay.core.model.params.alipay.AlipayIsvsubMchParams;
+import com.jeequan.jeepay.core.model.params.wxpay.WxpayIsvsubMchParams;
+import com.jeequan.jeepay.core.model.params.ysf.YsfpayIsvsubMchParams;
+
+/*
+ * 抽象类 特约商户参数定义
+ *
+ * @author terrfly
+ * @site https://www.jeepay.vip
+ * @date 2021/6/8 16:33
+ */
+public abstract class IsvsubMchParams {
+
+ public static IsvsubMchParams factory(String ifCode, String paramsStr){
+
+ if(CS.IF_CODE.WXPAY.equals(ifCode)){
+ return JSONObject.parseObject(paramsStr, WxpayIsvsubMchParams.class);
+ }else if(CS.IF_CODE.ALIPAY.equals(ifCode)){
+ return JSONObject.parseObject(paramsStr, AlipayIsvsubMchParams.class);
+ }else if(CS.IF_CODE.YSFPAY.equals(ifCode)){
+ return JSONObject.parseObject(paramsStr, YsfpayIsvsubMchParams.class);
+ }
+ return null;
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/NormalMchParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/NormalMchParams.java
new file mode 100644
index 00000000..f292e8fe
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/NormalMchParams.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.constants.CS;
+import com.jeequan.jeepay.core.model.params.alipay.AlipayNormalMchParams;
+import com.jeequan.jeepay.core.model.params.wxpay.WxpayNormalMchParams;
+
+/*
+ * 抽象类 普通商户参数定义
+ *
+ * @author terrfly
+ * @site https://www.jeepay.vip
+ * @date 2021/6/8 16:33
+ */
+public abstract class NormalMchParams {
+
+ public static NormalMchParams factory(String ifCode, String paramsStr){
+
+ if(CS.IF_CODE.WXPAY.equals(ifCode)){
+ return JSONObject.parseObject(paramsStr, WxpayNormalMchParams.class);
+ }else if(CS.IF_CODE.ALIPAY.equals(ifCode)){
+ return JSONObject.parseObject(paramsStr, AlipayNormalMchParams.class);
+ }
+ return null;
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayConfig.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayConfig.java
new file mode 100644
index 00000000..5038bacc
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayConfig.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params.alipay;
+
+import lombok.Data;
+
+/*
+* 支付宝, 通用配置信息
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:32
+*/
+@Data
+public class AlipayConfig{
+
+ public static final String SIGN_TYPE_RSA = "RSA";
+ public static final String SIGN_TYPE_RSA2 = "RSA2";
+
+
+ /** 网关地址 */
+ public static String PROD_SERVER_URL = "https://openapi.alipay.com/gateway.do";
+ public static String SANDBOX_SERVER_URL = "https://openapi.alipaydev.com/gateway.do";
+
+ public static String PROD_OAUTH_URL = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=%s&scope=auth_base&state=&redirect_uri=%s";
+ public static String SANDBOX_OAUTH_URL = "https://openauth.alipaydev.com/oauth2/publicAppAuthorize.htm?app_id=%s&scope=auth_base&state=&redirect_uri=%s";
+
+ public static String FORMAT = "json";
+
+ public static String CHARSET = "UTF-8";
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayIsvParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayIsvParams.java
new file mode 100644
index 00000000..105075d2
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayIsvParams.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params.alipay;
+
+import com.jeequan.jeepay.core.model.params.IsvParams;
+import lombok.Data;
+
+/*
+* 支付宝 isv参数定义
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:34
+*/
+@Data
+public class AlipayIsvParams extends IsvParams {
+
+ /** 是否沙箱环境 */
+ private Byte sandbox;
+
+ /** pid */
+ private String pid;
+
+ /** appId */
+ private String appId;
+
+ /** privateKey */
+ private String privateKey;
+
+ /** alipayPublicKey */
+ private String alipayPublicKey;
+
+ /** 签名方式 **/
+ private String signType;
+
+ /** 是否使用证书方式 **/
+ private Byte useCert;
+
+ /** app 证书 **/
+ private String appPublicCert;
+
+ /** 支付宝公钥证书(.crt格式) **/
+ private String alipayPublicCert;
+
+ /** 支付宝根证书 **/
+ private String alipayRootCert;
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayIsvsubMchParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayIsvsubMchParams.java
new file mode 100644
index 00000000..13d7cd73
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayIsvsubMchParams.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params.alipay;
+
+import com.jeequan.jeepay.core.model.params.IsvsubMchParams;
+import lombok.Data;
+
+/*
+ * 支付宝 特约商户参数定义
+ *
+ * @author terrfly
+ * @site https://www.jeepay.vip
+ * @date 2021/6/8 16:33
+ */
+@Data
+public class AlipayIsvsubMchParams extends IsvsubMchParams {
+
+ private String appAuthToken;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayNormalMchParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayNormalMchParams.java
new file mode 100644
index 00000000..2f540993
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/alipay/AlipayNormalMchParams.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params.alipay;
+
+import com.jeequan.jeepay.core.model.params.NormalMchParams;
+import lombok.Data;
+
+/*
+ * 支付宝 普通商户参数定义
+ *
+ * @author terrfly
+ * @site https://www.jeepay.vip
+ * @date 2021/6/8 16:33
+ */
+@Data
+public class AlipayNormalMchParams extends NormalMchParams {
+
+ /** 是否沙箱环境 */
+ private Byte sandbox;
+
+ /** appId */
+ private String appId;
+
+ /** privateKey */
+ private String privateKey;
+
+ /** alipayPublicKey */
+ private String alipayPublicKey;
+
+ /** 签名方式 **/
+ private String signType;
+
+ /** 是否使用证书方式 **/
+ private Byte useCert;
+
+ /** app 证书 **/
+ private String appPublicCert;
+
+ /** 支付宝公钥证书(.crt格式) **/
+ private String alipayPublicCert;
+
+ /** 支付宝根证书 **/
+ private String alipayRootCert;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/wxpay/WxpayIsvParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/wxpay/WxpayIsvParams.java
new file mode 100644
index 00000000..45775e6b
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/wxpay/WxpayIsvParams.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params.wxpay;
+
+import com.jeequan.jeepay.core.model.params.IsvParams;
+import lombok.Data;
+
+/*
+* 微信官方支付 配置参数
+*
+* @author zhuxiao
+* @site https://www.jeepay.vip
+* @date 2021/6/8 18:02
+*/
+@Data
+public class WxpayIsvParams extends IsvParams {
+
+ /** 应用App ID */
+ private String appId;
+
+ /** 应用AppSecret */
+ private String appSecret;
+
+ /** 微信支付商户号 */
+ private String mchId;
+
+ /** oauth2地址 */
+ private String oauth2Url;
+
+ /** API密钥 */
+ private String key;
+
+ /** 签名方式 **/
+ private String signType;
+
+ /** 微信支付API版本 **/
+ private String apiVersion;
+
+ /** API V3秘钥 **/
+ private String apiV3Key;
+
+ /** 序列号 **/
+ private String serialNo;
+
+ /** API证书(.p12格式)**/
+ private String cert;
+
+ /** 私钥文件(.pem格式) **/
+ private String apiClientKey;
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/wxpay/WxpayIsvsubMchParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/wxpay/WxpayIsvsubMchParams.java
new file mode 100644
index 00000000..f6f29a5a
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/wxpay/WxpayIsvsubMchParams.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params.wxpay;
+
+import com.jeequan.jeepay.core.model.params.IsvsubMchParams;
+import lombok.Data;
+
+/*
+ * 微信官方支付 配置参数
+ *
+ * @author zhuxiao
+ * @site https://www.jeepay.vip
+ * @date 2021/6/8 18:02
+ */
+@Data
+public class WxpayIsvsubMchParams extends IsvsubMchParams {
+
+ /** 子商户ID **/
+ private String subMchId;
+
+ /** 子账户appID **/
+ private String subMchAppId;
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/wxpay/WxpayNormalMchParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/wxpay/WxpayNormalMchParams.java
new file mode 100644
index 00000000..ca58ff95
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/wxpay/WxpayNormalMchParams.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params.wxpay;
+
+import com.jeequan.jeepay.core.model.params.NormalMchParams;
+import lombok.Data;
+
+/*
+ * 微信官方支付 配置参数
+ *
+ * @author zhuxiao
+ * @site https://www.jeepay.vip
+ * @date 2021/6/8 18:02
+ */
+@Data
+public class WxpayNormalMchParams extends NormalMchParams {
+
+ /** 应用App ID */
+ private String appId;
+
+ /** 应用AppSecret */
+ private String appSecret;
+
+ /** 微信支付商户号 */
+ private String mchId;
+
+ /** oauth2地址 */
+ private String oauth2Url;
+
+ /** API密钥 */
+ private String key;
+
+ /** 微信支付API版本 **/
+ private String apiVersion;
+
+ /** API V3秘钥 **/
+ private String apiV3Key;
+
+ /** 序列号 **/
+ private String serialNo;
+
+ /** API证书(.p12格式)**/
+ private String cert;
+
+ /** 私钥文件(.pem格式) **/
+ private String apiClientKey;
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/ysf/YsfpayConfig.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/ysf/YsfpayConfig.java
new file mode 100644
index 00000000..a5fafbcd
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/ysf/YsfpayConfig.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params.ysf;
+
+import lombok.Data;
+
+/*
+ * 云闪付 通用配置信息
+ *
+ * @author pangxiaoyu
+ * @site https://www.jeepay.vip
+ * @date 2021/6/8 18:02
+ */
+@Data
+public class YsfpayConfig {
+
+
+ /** 网关地址 */
+ public static String PROD_SERVER_URL = "https://partner.95516.com";
+ public static String SANDBOX_SERVER_URL = "http://ysf.bcbip.cn:10240";
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/ysf/YsfpayIsvParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/ysf/YsfpayIsvParams.java
new file mode 100644
index 00000000..86f89346
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/ysf/YsfpayIsvParams.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params.ysf;
+
+import com.jeequan.jeepay.core.model.params.IsvParams;
+import lombok.Data;
+
+/*
+ * 云闪付 配置信息
+ *
+ * @author pangxiaoyu
+ * @site https://www.jeepay.vip
+ * @date 2021/6/8 18:02
+ */
+@Data
+public class YsfpayIsvParams extends IsvParams {
+
+ /** 是否沙箱环境 */
+ private Byte sandbox;
+
+ /** serProvId **/
+ private String serProvId;
+
+ /** isvPrivateCertFile 证书 **/
+ private String isvPrivateCertFile;
+
+ /** isvPrivateCertPwd **/
+ private String isvPrivateCertPwd;
+
+ /** ysfpayPublicKey **/
+ private String ysfpayPublicKey;
+
+ /** acqOrgCodeList 支付机构号 **/
+ private String acqOrgCode;
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/ysf/YsfpayIsvsubMchParams.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/ysf/YsfpayIsvsubMchParams.java
new file mode 100644
index 00000000..3bae96ff
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/params/ysf/YsfpayIsvsubMchParams.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.params.ysf;
+
+import com.jeequan.jeepay.core.model.params.IsvsubMchParams;
+import lombok.Data;
+
+/*
+ * 云闪付 配置信息
+ *
+ * @author pangxiaoyu
+ * @site https://www.jeepay.vip
+ * @date 2021/6/8 18:02
+ */
+@Data
+public class YsfpayIsvsubMchParams extends IsvsubMchParams {
+
+ private String merId; // 商户编号
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/security/JeeUserDetails.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/security/JeeUserDetails.java
new file mode 100644
index 00000000..0d4cca2d
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/model/security/JeeUserDetails.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.model.security;
+
+import com.jeequan.jeepay.core.entity.SysUser;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/*
+* 实现Spring Security的UserDetails接口
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:34
+*/
+@Slf4j
+@Data
+public class JeeUserDetails implements UserDetails {
+
+ /** 系统用户信息 **/
+ private SysUser sysUser;
+
+ /** 密码 **/
+ private String credential;
+
+ /** 角色+权限 集合 (角色必须以: ROLE_ 开头) **/
+ private Collection authorities = new ArrayList<>();
+
+ /** 缓存标志 **/
+ private String cacheKey;
+
+ /** 登录IP **/
+ private String loginIp;
+
+ //此处的无参构造,为json反序列化提供
+ public JeeUserDetails() {
+ }
+
+ public JeeUserDetails(SysUser sysUser, String credential) {
+
+ this.setSysUser(sysUser);
+ this.setCredential(credential);
+
+ //TODO ....
+ //做一些初始化操作
+ }
+
+ /** spring-security 需要验证的密码 **/
+ @Override
+ public String getPassword() {
+ return getCredential();
+ }
+
+ /** spring-security 登录名 **/
+ @Override
+ public String getUsername() {
+ return getSysUser().getSysUserId() + "";
+ }
+
+ /** 账户是否过期 **/
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ /** 账户是否已解锁 **/
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ /** 密码是否过期 **/
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ /** 账户是否开启 **/
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ /** 获取权限集合 **/
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ return authorities;
+ }
+
+ public static JeeUserDetails getCurrentUserDetails() {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (authentication == null) return null;
+
+ try {
+ return (JeeUserDetails) authentication.getPrincipal();
+ }catch (Exception e) {
+ return null;
+ }
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/AmountUtil.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/AmountUtil.java
new file mode 100644
index 00000000..f56e8850
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/AmountUtil.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.FieldPosition;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description: 金额工具类
+ * @author dingzhiwei jmdhappy@126.com
+ * @date 2017-07-05
+ * @version V1.0
+ * @Copyright: www.xxpay.org
+ */
+public class AmountUtil {
+
+ /**
+ * 将字符串"元"转换成"分"
+ * @param str
+ * @return
+ */
+ public static String convertDollar2Cent(String str) {
+ DecimalFormat df = new DecimalFormat("0.00");
+ StringBuffer sb = df.format(Double.parseDouble(str),
+ new StringBuffer(), new FieldPosition(0));
+ int idx = sb.toString().indexOf(".");
+ sb.deleteCharAt(idx);
+ for (; sb.length() != 1;) {
+ if(sb.charAt(0) == '0') {
+ sb.deleteCharAt(0);
+ } else {
+ break;
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 将字符串"分"转换成"元"(长格式),如:100分被转换为1.00元。
+ * @param s
+ * @return
+ */
+ public static String convertCent2Dollar(String s) {
+ if("".equals(s) || s ==null){
+ return "";
+ }
+ long l;
+ if(s.length() != 0) {
+ if(s.charAt(0) == '+') {
+ s = s.substring(1);
+ }
+ l = Long.parseLong(s);
+ } else {
+ return "";
+ }
+ boolean negative = false;
+ if(l < 0) {
+ negative = true;
+ l = Math.abs(l);
+ }
+ s = Long.toString(l);
+ if(s.length() == 1)
+ return(negative ? ("-0.0" + s) : ("0.0" + s));
+ if(s.length() == 2)
+ return(negative ? ("-0." + s) : ("0." + s));
+ else
+ return(negative ? ("-" + s.substring(0, s.length() - 2) + "." + s
+ .substring(s.length() - 2)) : (s.substring(0,
+ s.length() - 2)
+ + "." + s.substring(s.length() - 2)));
+ }
+
+
+
+ /**
+ * 将Long "分"转换成"元"(长格式),如:100分被转换为1.00元。
+ * @param s
+ * @return
+ */
+ public static String convertCent2Dollar(Long s){
+ if(s == null) return "";
+ return new BigDecimal(s).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
+ }
+
+ /**
+ * 将字符串"分"转换成"元"(短格式),如:100分被转换为1元。
+ * @param s
+ * @return
+ */
+ public static String convertCent2DollarShort(String s) {
+ String ss = convertCent2Dollar(s);
+ ss = "" + Double.parseDouble(ss);
+ if(ss.endsWith(".0"))
+ return ss.substring(0, ss.length() - 2);
+ if(ss.endsWith(".00"))
+ return ss.substring(0, ss.length() - 3);
+ else
+ return ss;
+ }
+
+ /**
+ * 判断金额为2位小数
+ * @param str
+ * @return
+ */
+ public static boolean isAmount(String str){
+ if(str == null) return false;
+ Pattern pattern = Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$"); // 判断小数点后2位的数字的正则表达式
+ Matcher match = pattern.matcher(str);
+ return match.matches();
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/ApiResBodyAdviceKit.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/ApiResBodyAdviceKit.java
new file mode 100644
index 00000000..51fc27cb
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/ApiResBodyAdviceKit.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.model.OriginalRes;
+import com.jeequan.jeepay.core.model.ApiRes;
+import org.springframework.core.io.InputStreamResource;
+
+import java.util.Collection;
+
+/*
+* 自定义springMVC的controller的返回值
+ * 功能:
+ * 1. 自动添加ApiRes.ok();
+ * 2. 处理model的扩展字段 (只需要在model中设置[ext]参数, 可以实现json自动转换为外层字段。 )
+ * 比如 model为 {id:1, ext:{abc:222}} 则自动转换为: {id:1, abc:222}
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:49
+*/
+public class ApiResBodyAdviceKit {
+
+ /** 扩展字段的key名称 **/
+ private static final String API_EXTEND_FIELD_NAME = "ext";
+
+ public static Object beforeBodyWrite(Object body) {
+
+ //空的情况 不处理
+ if(body == null ) return null;
+
+ if(body instanceof OriginalRes){
+ return ((OriginalRes) body).getData();
+ }
+
+ //返回文件流不处理
+ if(body instanceof InputStreamResource){
+ return body;
+ }
+
+ //返回二进制文件不处理
+ if(body instanceof byte[]){
+ return body;
+ }
+
+ //如果为ApiRes类型则仅处理扩展字段
+ if(body instanceof ApiRes) {
+ return procAndConvertJSON(body);
+ }else{
+
+ //ctrl返回其他非[ApiRes]认为处理成功, 先转换为成功状态, 在处理字段
+ return procAndConvertJSON(ApiRes.ok(body));
+ }
+ }
+
+ /** 处理扩展字段 and 转换为json格式 **/
+ private static Object procAndConvertJSON(Object object){
+
+ Object json = JSON.toJSON(object); //转换为JSON格式
+
+ if(json instanceof JSONObject){ //对象类型
+ processExtFieldByJSONObject((JSONObject) json);
+ return json;
+ }
+
+ if(json instanceof Collection){ //数组类型
+
+ JSONArray result = new JSONArray();
+ for (Object itemObj : (Collection) json) {
+ result.add(procAndConvertJSON(itemObj));
+ }
+ return result;
+ }
+
+ return json;
+ }
+
+
+ /** 处理jsonObject格式 **/
+ private static void processExtFieldByJSONObject(JSONObject jsonObject){
+
+ //如果包含字段, 则赋值到外层然后删除该字段
+ if(jsonObject.containsKey(API_EXTEND_FIELD_NAME)){
+ JSONObject exFieldMap = jsonObject.getJSONObject(API_EXTEND_FIELD_NAME);
+ if(exFieldMap != null){ //包含字段
+ for (String s : exFieldMap.keySet()) { //遍历赋值到外层
+ jsonObject.put(s, exFieldMap.get(s));
+ }
+ }
+ jsonObject.remove(API_EXTEND_FIELD_NAME); //删除字段
+ }
+
+ //处理所有值
+ for (String key : jsonObject.keySet()) {
+ jsonObject.put(key, procAndConvertJSON(jsonObject.get(key)));
+ }
+ }
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/DateKit.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/DateKit.java
new file mode 100644
index 00000000..1145d2c2
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/DateKit.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+import cn.hutool.core.date.DateUtil;
+import com.jeequan.jeepay.core.exception.BizException;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+
+/*
+* 时间工具类
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:58
+*/
+public class DateKit {
+
+ /** 获取参数时间当天的开始时间 **/
+ public static Date getBegin(Date date){
+
+ if(date == null) return null;
+ return DateUtil.beginOfDay(date).toJdkDate();
+ }
+
+ /** 获取参数时间当天的结束时间 **/
+ public static Date getEnd(Date date){
+ if(date == null) return null;
+ return DateUtil.endOfDay(date).toJdkDate();
+ }
+
+
+ /**
+ * 获取自定义查询时间
+ * today|0 -- 今天
+ * yesterday|0 -- 昨天
+ * near2now|7 -- 近xx天, 到今天
+ * near2yesterday|30 -- 近xx天, 到昨天
+ * customDate|2020-01-01,N -- 自定义日期格式 N表示为空, 占位使用
+ * customDateTime|2020-01-01 23:00:00,2020-01-01 23:00:00 -- 自定义日期时间格式
+ *
+ * @return
+ */
+ public static Date[] getQueryDateRange(String queryParamVal){
+
+ //查询全部
+ if(StringUtils.isEmpty(queryParamVal)){
+ return new Date[]{null, null};
+ }
+
+ //根据 | 分割
+ String[] valArray = queryParamVal.split("\\|");
+ if(valArray.length != 2){ //参数有误
+ throw new BizException("查询时间参数有误");
+ }
+ String dateType = valArray[0]; //时间类型
+ String dateVal = valArray[1]; //搜索时间值
+
+ Date nowDateTime = new Date(); //当前时间
+
+ if("today".equals(dateType)){ //今天
+
+ return new Date[]{getBegin(nowDateTime), getEnd(nowDateTime)};
+
+ }else if("yesterday".equals(dateType)){ //昨天
+
+ Date yesterdayDateTime = DateUtil.offsetDay(nowDateTime, -1).toJdkDate(); //昨天
+ return new Date[]{getBegin(yesterdayDateTime), getEnd(yesterdayDateTime)};
+
+ }else if("near2now".equals(dateType)){ //近xx天, xx天之前 ~ 当前时间
+
+ Integer offsetDay = 1 - Integer.parseInt(dateVal); //获取时间偏移量
+ Date offsetDayDate = DateUtil.offsetDay(nowDateTime, offsetDay).toJdkDate();
+ return new Date[]{getBegin(offsetDayDate), getEnd(nowDateTime)};
+
+ }else if("near2yesterday".equals(dateType)){ //近xx天, xx天之前 ~ 昨天
+
+ Date yesterdayDateTime = DateUtil.offsetDay(nowDateTime, -1).toJdkDate(); //昨天
+
+ Integer offsetDay = 1 - Integer.parseInt(dateVal); //获取时间偏移量
+ Date offsetDayDate = DateUtil.offsetDay(yesterdayDateTime, offsetDay).toJdkDate();
+ return new Date[]{getBegin(offsetDayDate), getEnd(yesterdayDateTime)};
+
+ }else if("customDate".equals(dateType) || "customDateTime".equals(dateType)){ //自定义格式
+
+ String[] timeArray = dateVal.split(","); //以逗号分割
+ if(timeArray.length != 2) throw new BizException("查询自定义时间参数有误");
+
+ String timeStr1 = "N".equalsIgnoreCase(timeArray[0]) ? null : timeArray[0] ; //开始时间,
+ String timeStr2 = "N".equalsIgnoreCase(timeArray[1]) ? null : timeArray[1]; //结束时间, N表示为空, 占位使用
+
+ Date time1 = null;
+ Date time2 = null;
+
+ if(StringUtils.isNotEmpty(timeStr1)){
+ time1 = DateUtil.parseDateTime("customDate".equals(dateType) ? (timeStr1 + " 00:00:00" ) : timeStr1);
+ }
+ if(StringUtils.isNotEmpty(timeStr2)){
+ time2 = DateUtil.parseDateTime("customDate".equals(dateType) ? (timeStr2 + " 23:59:59" ) : timeStr2);
+ }
+ return new Date[]{time1, time2};
+
+ }else{
+ throw new BizException("查询时间参数有误");
+ }
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/FileKit.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/FileKit.java
new file mode 100644
index 00000000..6a831538
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/FileKit.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+import com.jeequan.jeepay.core.constants.CS;
+import com.jeequan.jeepay.core.exception.BizException;
+
+/*
+* 文件工具类
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:50
+*/
+public class FileKit {
+
+
+ /**
+ * 获取文件的后缀名
+ * @param appendDot 是否拼接.
+ * @return
+ */
+ public static String getFileSuffix(String fullFileName, boolean appendDot){
+ if(fullFileName == null || fullFileName.indexOf(".") < 0 || fullFileName.length() <= 1) return "";
+ return (appendDot? "." : "") + fullFileName.substring(fullFileName.lastIndexOf(".") + 1);
+ }
+
+
+ /** 获取有效的图片格式, 返回null: 不支持的图片类型 **/
+ public static String getImgSuffix(String filePath){
+
+ String suffix = getFileSuffix(filePath, false).toLowerCase();
+ if(CS.ALLOW_UPLOAD_IMG_SUFFIX.contains(suffix)){
+ return suffix;
+ }
+ throw new BizException("不支持的图片类型");
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/JeepayKit.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/JeepayKit.java
new file mode 100644
index 00000000..05d4ca3e
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/JeepayKit.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+import cn.hutool.crypto.SecureUtil;
+import com.jeequan.jeepay.core.constants.CS;
+import com.jeequan.jeepay.core.exception.BizException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import sun.misc.BASE64Decoder;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/*
+* jeepay工具类
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:50
+*/
+@Slf4j
+public class JeepayKit {
+
+ public static byte[] AES_KEY = null;
+ static{
+ try {
+ AES_KEY = new BASE64Decoder().decodeBuffer("4ChT08phkz59hquD795X7w==");
+ } catch (IOException e) {
+ }
+ }
+
+ /** 加密 **/
+ public static String aesEncode(String str){
+ return SecureUtil.aes(JeepayKit.AES_KEY).encryptHex(str);
+ }
+
+ public static String aesDecode(String str){
+ return SecureUtil.aes(JeepayKit.AES_KEY).decryptStr(str);
+ }
+
+
+
+ private static String encodingCharset = "UTF-8";
+
+ /**
+ *
Description: 计算签名摘要
+ *
2018年9月30日 上午11:32:46
+ * @param map 参数Map
+ * @param key 商户秘钥
+ * @return
+ */
+ public static String getSign(Map map, String key){
+ ArrayList list = new ArrayList();
+ for(Map.Entry entry:map.entrySet()){
+ if(null != entry.getValue() && !"".equals(entry.getValue())){
+ list.add(entry.getKey() + "=" + entry.getValue() + "&");
+ }
+ }
+ int size = list.size();
+ String [] arrayToSort = list.toArray(new String[size]);
+ Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
+ StringBuilder sb = new StringBuilder();
+ for(int i = 0; i < size; i ++) {
+ sb.append(arrayToSort[i]);
+ }
+ String result = sb.toString();
+ result += "key=" + key;
+ log.info("signStr:{}", result);
+ result = md5(result, encodingCharset).toUpperCase();
+ log.info("sign:{}", result);
+ return result;
+ }
+
+
+ /**
+ * Description: MD5
+ *
2018年9月30日 上午11:33:19
+ * @param value
+ * @param charset
+ * @return
+ */
+ public static String md5(String value, String charset) {
+ MessageDigest md = null;
+ try {
+ byte[] data = value.getBytes(charset);
+ md = MessageDigest.getInstance("MD5");
+ byte[] digestData = md.digest(data);
+ return toHex(digestData);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ return null;
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static String toHex(byte input[]) {
+ if (input == null)
+ return null;
+ StringBuffer output = new StringBuffer(input.length * 2);
+ for (int i = 0; i < input.length; i++) {
+ int current = input[i] & 0xff;
+ if (current < 16)
+ output.append("0");
+ output.append(Integer.toString(current, 16));
+ }
+
+ return output.toString();
+ }
+
+ /** map 转换为 url参数 **/
+ public static String genUrlParams(Map paraMap) {
+ if(paraMap == null || paraMap.isEmpty()) return "";
+ StringBuffer urlParam = new StringBuffer();
+ Set keySet = paraMap.keySet();
+ int i = 0;
+ for(String key:keySet) {
+ urlParam.append(key).append("=").append( paraMap.get(key) == null ? "" : paraMap.get(key) );
+ if(++i == keySet.size()) break;
+ urlParam.append("&");
+ }
+ return urlParam.toString();
+ }
+
+ /** 校验微信/支付宝二维码是否符合规范, 并根据支付类型返回对应的支付方式 **/
+ public static String getPayWayCodeByBarCode(String barCode){
+
+ if(StringUtils.isEmpty(barCode)) throw new BizException("条码为空");
+
+ //微信 : 用户付款码条形码规则:18位纯数字,以10、11、12、13、14、15开头
+ //文档: https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=5_1
+ if(barCode.length() == 18 && Pattern.matches("^(10|11|12|13|14|15)(.*)", barCode)){
+ return CS.PAY_WAY_CODE.WX_BAR;
+ }
+ //支付宝: 25~30开头的长度为16~24位的数字
+ //文档: https://docs.open.alipay.com/api_1/alipay.trade.pay/
+ else if(barCode.length() >= 16 && barCode.length() <= 24 && Pattern.matches("^(25|26|27|28|29|30)(.*)", barCode)){
+ return CS.PAY_WAY_CODE.ALI_BAR;
+ }
+ //云闪付: 二维码标准: 19位 + 62开头
+ //文档:https://wenku.baidu.com/view/b2eddcd09a89680203d8ce2f0066f5335a8167fa.html
+ else if(barCode.length() == 19 && Pattern.matches("^(62)(.*)", barCode)){
+ return CS.PAY_WAY_CODE.YSF_BAR;
+ }
+ else{ //暂时不支持的条码类型
+ throw new BizException("不支持的条码");
+ }
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/JsonKit.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/JsonKit.java
new file mode 100644
index 00000000..04bb2b2f
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/JsonKit.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+import com.alibaba.fastjson.JSONObject;
+
+/*
+* json工具类
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:51
+*/
+public class JsonKit {
+
+ public static JSONObject newJson(String key, Object val){
+
+ JSONObject result = new JSONObject();
+ result.put(key, val);
+ return result;
+ }
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/RegKit.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/RegKit.java
new file mode 100644
index 00000000..fe7894da
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/RegKit.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+/*
+*
+* 正则验证kit
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:56
+*/
+public class RegKit {
+
+ public static final String REG_MOBILE = "^1\\d{10}$"; //判断是否是手机号
+ public static boolean isMobile(String str){
+ return match(str, REG_MOBILE);
+ }
+
+
+ /** 正则验证 */
+ public static boolean match(String text, String reg){
+ if(text == null) return false;
+ return text.matches(reg);
+ }
+
+
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/SeqKit.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/SeqKit.java
new file mode 100644
index 00000000..2c9bb782
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/SeqKit.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.DateUtil;
+
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicLong;
+
+/*
+* 序列号生成 工具类
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:56
+*/
+public class SeqKit {
+
+ private static final AtomicLong BUY_ORDER_SEQ = new AtomicLong(0L);
+ private static final String BUY_ORDER_SEQ_PREFIX = "P";
+
+ /** 生成购买订单ID **/
+ public static String genPayOrderId() {
+
+ return String.format("%s%s%04d",BUY_ORDER_SEQ_PREFIX,
+ DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN),
+ (int) BUY_ORDER_SEQ.getAndIncrement() % 10000);
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/SpringBeansUtil.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/SpringBeansUtil.java
new file mode 100644
index 00000000..6efdfde0
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/SpringBeansUtil.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * @description: Spring 框架下, 获取Beans静态函数方法。
+ * @Author terrfly
+ * @Date 2019/12/31 13:57
+ */
+@Component
+public class SpringBeansUtil implements ApplicationContextAware {
+
+ private static ApplicationContext applicationContext = null;
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ if(SpringBeansUtil.applicationContext == null){
+ SpringBeansUtil.applicationContext = applicationContext;
+ }
+ }
+
+ /** 获取applicationContext */
+ public static ApplicationContext getApplicationContext() {
+ return applicationContext;
+ }
+
+ /** 通过name获取 Bean. */
+ public static Object getBean(String name){
+
+ if(!getApplicationContext().containsBean(name)){
+ return null;
+ }
+
+ return getApplicationContext().getBean(name);
+
+ }
+
+ /** 通过class获取Bean. */
+ public static T getBean(Class clazz){
+ try {
+ return getApplicationContext().getBean(clazz);
+ } catch (BeansException e) {
+ return null;
+ }
+ }
+
+ /** 通过name,以及Clazz返回指定的Bean */
+ public static T getBean(String name, Class clazz){
+ if(!getApplicationContext().containsBean(name)){
+ return null;
+ }
+ return getApplicationContext().getBean(name, clazz);
+ }
+
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/StringKit.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/StringKit.java
new file mode 100644
index 00000000..095dd161
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/StringKit.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+import java.util.UUID;
+
+/*
+* String 工具类
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 16:58
+*/
+public class StringKit {
+
+ public static String getUUID(){
+ return UUID.randomUUID().toString().replace("-", "") + Thread.currentThread().getId();
+ }
+
+ public static String getUUID(int endAt){
+ return getUUID().substring(0, endAt);
+ }
+}
diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/TreeDataBuilder.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/TreeDataBuilder.java
new file mode 100644
index 00000000..24db437c
--- /dev/null
+++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/utils/TreeDataBuilder.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.core.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/*
+ * [ 通用树状结构构造器 ]
+ * 解决: 将数据库查询到的多行List, 转换为层级关系的树状结构。
+ * 使用方式:
+ * 1. 先将查询的到对象List转换为JSONObject List,
+ * 在转换过程中JSONObject中必须包含 [id, pid](字段名称可自定义) 【!!必须是String类型!!】 ;
+ * 2. 使用构造函数创建对象,参数为转换好的对象, 如果自定义字段key 则将字段名称一并传入;
+ * 3. 使用buildTreeString() 或者 buildTreeObject() 生成所需对象;
+ *
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2019/12/8 06:37
+*/
+public class TreeDataBuilder {
+
+
+ /** 私有构造器 + 指定参数构造器 **/
+ private TreeDataBuilder(){}
+ public TreeDataBuilder(Collection nodes) {
+ super();
+ this.nodes = nodes;
+ }
+
+ public TreeDataBuilder(Collection nodes, String idName, String pidName, String childrenName) {
+ super();
+ this.nodes = nodes;
+ this.idName = idName;
+ this.sortName = idName; //排序字段,按照idName
+ this.pidName = pidName;
+ this.childrenName = childrenName;
+ }
+
+ /** 自定义字段 + 排序标志 **/
+ public TreeDataBuilder(Collection nodes, String idName, String pidName, String childrenName, String sortName, boolean isAscSort) {
+ super();
+ this.nodes = nodes;
+ this.idName = idName;
+ this.pidName = pidName;
+ this.childrenName = childrenName;
+ this.sortName = sortName;
+ this.isAscSort = isAscSort;
+ }
+
+ /** 所有数据集合 **/
+ private Collection nodes;
+
+ /** 默认数据中的主键key */
+ private String idName = "id";
+
+ /** 默认数据中的父级id的key */
+ private String pidName = "pid";
+
+ /** 默认数据中的子类对象key */
+ private String childrenName = "children";
+
+ /** 排序字段, 默认按照ID排序 **/
+ private String sortName = idName;
+
+ /** 默认按照升序排序 **/
+ private boolean isAscSort = true;
+
+ // 构建JSON树形结构
+ public String buildTreeString() {
+ List nodeTree = buildTreeObject();
+ JSONArray jsonArray = new JSONArray();
+ nodeTree.stream().forEach(item -> jsonArray.add(item));
+ return jsonArray.toString();
+ }
+
+ // 构建树形结构
+ public List buildTreeObject() {
+
+ //定义待返回的对象
+ List resultNodes = new ArrayList<>();
+
+ //获取所有的根节点 (考虑根节点有多个的情况, 将根节点单独处理)
+ List rootNodes = getRootNodes();
+
+ listSort(rootNodes); //排序
+
+ //遍历根节点对象
+ for (JSONObject rootNode : rootNodes) {
+
+ buildChildNodes(rootNode); //递归查找子节点并设置
+
+ resultNodes.add(rootNode); //添加到对象信息
+ }
+ return resultNodes;
+ }
+
+ /** 递归查找并赋值子节点 **/
+ private void buildChildNodes(JSONObject node) {
+ List children = getChildNodes(node);
+ if (!children.isEmpty()) {
+ for (JSONObject child : children) {
+ buildChildNodes(child);
+ }
+
+ listSort(children); //排序
+ node.put(childrenName, children);
+ }
+ }
+
+ /** 查找当前节点的子节点 */
+ private List getChildNodes(JSONObject currentNode) {
+ List childNodes = new ArrayList<>();
+ for (JSONObject n : nodes) {
+ if (currentNode.getString(idName).equals(n.getString(pidName))) {
+ childNodes.add(n);
+ }
+ }
+ return childNodes;
+ }
+
+ /** 判断是否为根节点 */
+ private boolean isRootNode(JSONObject node) {
+ boolean isRootNode = true;
+ for (JSONObject n : nodes) {
+ if (node.getString(pidName) != null && node.getString(pidName).equals(n.getString(idName))) {
+ isRootNode = false;
+ break;
+ }
+ }
+ return isRootNode;
+ }
+
+ /** 获取集合中所有的根节点 */
+ private List getRootNodes() {
+ List rootNodes = new ArrayList<>();
+ for (JSONObject n : nodes) {
+ if (isRootNode(n)) {
+ rootNodes.add(n);
+ }
+ }
+ return rootNodes;
+ }
+
+ /** 将list进行排序 */
+ private void listSort(List list){
+ Collections.sort(list, (o1, o2) -> {
+
+ int result;
+ if(o1.get(sortName) instanceof Integer){
+ result = o1.getInteger(sortName).compareTo(o2.getInteger(sortName));
+ }else{
+ result = o1.get(sortName).toString().compareTo(o2.get(sortName).toString());
+ }
+
+ if(!isAscSort){ //倒序, 取反数
+ return -result;
+ }
+
+ return result;
+ });
+ }
+
+}
diff --git a/jeepay-core/src/test/java/com/.gitkeep b/jeepay-core/src/test/java/com/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/jeepay-core/src/test/resources/.gitkeep b/jeepay-core/src/test/resources/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/jeepay-manager/pom.xml b/jeepay-manager/pom.xml
new file mode 100644
index 00000000..9dfc0586
--- /dev/null
+++ b/jeepay-manager/pom.xml
@@ -0,0 +1,112 @@
+
+
+ 4.0.0
+
+ com.jeequan
+ jeepay-manager
+ jar
+ ${isys.version}
+ Jeepay计全支付系统 [运营后台管理端]
+ https://www.jeequan.com
+
+
+ com.jeequan
+ jeepay
+ 1.0.0
+
+
+
+
+
+
+ com.jeequan
+ jeepay-service
+ ${isys.version}
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jdk8
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ com.fasterxml.jackson.module
+ jackson-module-parameter-names
+
+
+ org.hibernate.validator
+ hibernate-validator
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+
+ io.jsonwebtoken
+ jjwt
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-freemarker
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-activemq
+
+
+
+
+
+
+
+ ${project.artifactId}
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ maven-resources-plugin
+
+
+
+
+
+
+
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/aop/MethodLogAop.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/aop/MethodLogAop.java
new file mode 100644
index 00000000..acbe2532
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/aop/MethodLogAop.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.aop;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.aop.MethodLog;
+import com.jeequan.jeepay.core.beans.RequestKitBean;
+import com.jeequan.jeepay.core.constants.CS;
+import com.jeequan.jeepay.core.entity.SysLog;
+import com.jeequan.jeepay.core.model.security.JeeUserDetails;
+import com.jeequan.jeepay.service.impl.SysLogService;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * 方法级日志切面组件
+ *
+ * @author terrfly
+ * @modify pangxiaoyu
+ * @site https://www.jeepay.vip
+ * @date 2021-06-07 07:15
+ */
+@Component
+@Aspect
+public class MethodLogAop {
+
+ private static final Logger logger = LoggerFactory.getLogger(MethodLogAop.class);
+
+ @Autowired
+ private SysLogService sysLogService;
+
+ @Autowired private RequestKitBean requestKitBean;
+
+ /**
+ * 异步处理线程池
+ */
+ private final static ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);
+
+ /**
+ * 切点
+ */
+ @Pointcut("@annotation(com.jeequan.jeepay.core.aop.MethodLog)")
+ public void methodCachePointcut() { }
+
+ /**
+ * 切面
+ * @param point
+ * @return
+ * @throws Throwable
+ */
+ @Around("methodCachePointcut()")
+ public Object around(ProceedingJoinPoint point) throws Throwable {
+
+ final SysLog sysLog = new SysLog();
+ // 基础日志信息
+ setBaseLogInfo(point, sysLog);
+ //处理切面任务 发生异常将向外抛出 不记录日志
+ Object result = point.proceed();
+
+ try {
+ sysLog.setUserId(JeeUserDetails.getCurrentUserDetails().getSysUser().getSysUserId());
+ sysLog.setUserName(JeeUserDetails.getCurrentUserDetails().getSysUser().getRealname());
+ sysLog.setSystem(JeeUserDetails.getCurrentUserDetails().getSysUser().getSystem());
+ sysLog.setOptResInfo(JSONObject.toJSON(result).toString());
+
+ scheduledThreadPool.execute(() -> sysLogService.save(sysLog));
+ } catch (Exception e) {
+ logger.error("methodLogError", e);
+ }
+
+ return result;
+ }
+
+ /**
+ * @author: pangxiaoyu
+ * @date: 2021/6/7 14:04
+ * @describe: 记录异常操作请求信息
+ */
+ @AfterThrowing(pointcut = "methodCachePointcut()", throwing="e")
+ public void doException(JoinPoint joinPoint, Throwable e) throws Exception{
+ final SysLog sysLog = new SysLog();
+ // 基础日志信息
+ setBaseLogInfo(joinPoint, sysLog);
+ sysLog.setOptResInfo("请求异常");
+ scheduledThreadPool.execute(() -> sysLogService.save(sysLog));
+ }
+
+ /**
+ * 获取方法中的中文备注
+ * @param joinPoint
+ * @return
+ * @throws Exception
+ */
+ public static String getAnnotationRemark(JoinPoint joinPoint) throws Exception {
+
+ Signature sig = joinPoint.getSignature();
+ Method m = joinPoint.getTarget().getClass().getMethod(joinPoint.getSignature().getName(), ((MethodSignature) sig).getParameterTypes());
+
+ MethodLog methodCache = m.getAnnotation(MethodLog.class);
+ if (methodCache != null) {
+ return methodCache.remark();
+ }
+ return "";
+ }
+
+ /**
+ * @author: pangxiaoyu
+ * @date: 2021/6/7 14:12
+ * @describe: 日志基本信息 公共方法
+ */
+ private void setBaseLogInfo(JoinPoint joinPoint, SysLog sysLog) throws Exception {
+ // 使用point.getArgs()可获取request,仅限于spring MVC参数包含request,改为通过contextHolder获取。
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+ //请求参数
+ sysLog.setOptReqParam( requestKitBean.getReqParamJSON().toJSONString() );
+
+ //注解备注
+ sysLog.setMethodRemark(getAnnotationRemark(joinPoint));
+ //包名 方法名
+ String methodName = joinPoint.getSignature().getName();
+ String packageName = joinPoint.getThis().getClass().getName();
+ if (packageName.indexOf("$$EnhancerByCGLIB$$") > -1 || packageName.indexOf("$$EnhancerBySpringCGLIB$$") > -1) { // 如果是CGLIB动态生成的类
+ packageName = packageName.substring(0, packageName.indexOf("$$"));
+ }
+ sysLog.setMethodName(packageName + "." + methodName);
+ sysLog.setReqUrl(request.getRequestURL().toString());
+ sysLog.setUserIp(requestKitBean.getClientIp());
+ sysLog.setCreatedAt(new Date());
+ sysLog.setSystem(CS.SYS_TYPE.MGR);
+ }
+
+}
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/bootstrap/InitRunner.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/bootstrap/InitRunner.java
new file mode 100644
index 00000000..efb0b8b2
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/bootstrap/InitRunner.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.bootstrap;
+
+import cn.hutool.core.date.DatePattern;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializeConfig;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+/*
+ * 项目初始化操作
+ * 比如初始化配置文件, 读取基础数据, 资源初始化等。 避免在Main函数中写业务代码。
+ * CommandLineRunner / ApplicationRunner都可以达到要求, 只是调用参数有所不同。
+ *
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 17:04
+*/
+@Component
+public class InitRunner implements CommandLineRunner {
+
+
+ @Override
+ public void run(String... args) throws Exception {
+
+ //初始化处理fastjson格式
+ SerializeConfig serializeConfig = SerializeConfig.getGlobalInstance();
+ serializeConfig.put(Date.class, new SimpleDateFormatSerializer(DatePattern.NORM_DATETIME_PATTERN));
+
+ //解决json 序列化时候的 $ref:问题
+ JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
+
+ }
+}
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/bootstrap/JeepayMgrApplication.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/bootstrap/JeepayMgrApplication.java
new file mode 100644
index 00000000..d735c42e
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/bootstrap/JeepayMgrApplication.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.bootstrap;
+
+import com.alibaba.fastjson.support.config.FastJsonConfig;
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.MediaType;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import java.util.Arrays;
+
+/*
+* spring-boot 主启动程序
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2019/11/7 15:19
+*/
+@SpringBootApplication
+@EnableScheduling
+@MapperScan("com.jeequan.jeepay.service.mapper") //Mybatis mapper接口路径
+@ComponentScan(basePackages = "com.jeequan.jeepay.*") //由于MainApplication没有在项目根目录, 需要配置basePackages属性使得成功扫描所有Spring组件;
+@Configuration
+public class JeepayMgrApplication {
+
+ /** main启动函数 **/
+ public static void main(String[] args) {
+
+ //启动项目
+ SpringApplication.run(JeepayMgrApplication.class, args);
+
+ }
+
+
+ /** fastJson 配置信息 **/
+ @Bean
+ public HttpMessageConverters fastJsonConfig(){
+
+ //新建fast-json转换器
+ FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
+
+ //fast-json 配置信息
+ FastJsonConfig config = new FastJsonConfig();
+ config.setDateFormat("yyyy-MM-dd HH:mm:ss");
+ converter.setFastJsonConfig(config);
+
+ //设置响应的 Content-Type
+ converter.setSupportedMediaTypes(Arrays.asList(new MediaType[]{MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8}));
+ return new HttpMessageConverters(converter);
+ }
+
+ /** Mybatis plus 分页插件 **/
+ @Bean
+ public PaginationInterceptor paginationInterceptor() {
+ PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
+ // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
+ // paginationInterceptor.setOverflow(false);
+ // 设置最大单页限制数量,默认 500 条,-1 不受限制
+ // paginationInterceptor.setLimit(500);
+ return paginationInterceptor;
+ }
+
+}
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/config/RedisConfig.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/config/RedisConfig.java
new file mode 100644
index 00000000..59ab340d
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/config/RedisConfig.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.config;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+/*
+* Redis配置类
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 17:05
+*/
+@Configuration
+public class RedisConfig {
+
+ @Value("${spring.redis.host}")
+ private String host;
+
+ @Value("${spring.redis.port}")
+ private Integer port;
+
+ @Value("${spring.redis.timeout}")
+ private Integer timeout;
+
+ @Value("${spring.redis.database}")
+ private Integer defaultDatabase;
+
+ @Value("${spring.redis.password}")
+ private String password;
+
+ /** 当前系统的redis缓存操作对象 (主对象) **/
+ @Primary
+ @Bean(name = "defaultStringRedisTemplate")
+ public StringRedisTemplate sysStringRedisTemplate() {
+ StringRedisTemplate template = new StringRedisTemplate();
+
+ LettuceConnectionFactory jedisConnectionFactory = new LettuceConnectionFactory();
+ jedisConnectionFactory.setHostName(host);
+ jedisConnectionFactory.setPort(port);
+ jedisConnectionFactory.setTimeout(timeout);
+
+ if (!StringUtils.isEmpty(password)) {
+ jedisConnectionFactory.setPassword(password);
+ }
+
+ if (defaultDatabase != 0) {
+ jedisConnectionFactory.setDatabase(defaultDatabase);
+ }
+
+ jedisConnectionFactory.afterPropertiesSet();
+
+ template.setConnectionFactory(jedisConnectionFactory);
+ return template;
+ }
+
+}
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/config/SystemYmlConfig.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/config/SystemYmlConfig.java
new file mode 100644
index 00000000..d5a769ec
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/config/SystemYmlConfig.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+import org.springframework.stereotype.Component;
+
+/**
+ * 系统Yml配置参数定义Bean
+ *
+ * @author terrfly
+ * @site https://www.jeepay.vip
+ * @date 2021-04-27 15:50
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix="isys")
+public class SystemYmlConfig {
+
+ /** 是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时,应开启此配置或在nginx统一配置允许跨域] **/
+ private Boolean allowCors;
+
+ /** 生成jwt的秘钥。 要求每个系统有单独的秘钥管理机制。 **/
+ private String jwtSecret;
+
+ @NestedConfigurationProperty //指定该属性为嵌套值, 否则默认为简单值导致对象为空(外部类不存在该问题, 内部static需明确指定)
+ private OssFile ossFile;
+
+ /** 系统oss配置信息 **/
+ @Data
+ public static class OssFile{
+
+ /** 存储根路径 **/
+ private String rootPath;
+
+ /** 公共读取块 **/
+ private String publicPath;
+
+ /** 私有读取块 **/
+ private String privatePath;
+
+ }
+}
+
+
+
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/CommonCtrl.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/CommonCtrl.java
new file mode 100644
index 00000000..5cd29d6a
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/CommonCtrl.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.ctrl;
+
+import com.jeequan.jeepay.core.ctrls.AbstractCtrl;
+import com.jeequan.jeepay.core.model.security.JeeUserDetails;
+import com.jeequan.jeepay.mgr.config.SystemYmlConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+/*
+* 定义通用CommonCtrl
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 17:09
+*/
+public abstract class CommonCtrl extends AbstractCtrl {
+
+ @Autowired
+ protected SystemYmlConfig mainConfig;
+
+ /** 获取当前用户ID */
+ protected JeeUserDetails getCurrentUser(){
+
+ return (JeeUserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+ }
+
+ /**
+ * 获取当前用户登录IP
+ * @return
+ */
+ protected String getIp() {
+ return getClientIp();
+ }
+
+}
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/CurrentUserController.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/CurrentUserController.java
new file mode 100644
index 00000000..2ff90047
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/CurrentUserController.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.ctrl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.aop.MethodLog;
+import com.jeequan.jeepay.core.cache.ITokenService;
+import com.jeequan.jeepay.core.constants.CS;
+import com.jeequan.jeepay.core.entity.SysEntitlement;
+import com.jeequan.jeepay.core.entity.SysUser;
+import com.jeequan.jeepay.core.exception.BizException;
+import com.jeequan.jeepay.core.model.ApiRes;
+import com.jeequan.jeepay.core.utils.TreeDataBuilder;
+import com.jeequan.jeepay.core.model.security.JeeUserDetails;
+import com.jeequan.jeepay.service.impl.SysEntitlementService;
+import com.jeequan.jeepay.service.impl.SysUserAuthService;
+import com.jeequan.jeepay.service.impl.SysUserService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.*;
+
+/*
+* 当前登录者的信息相关接口
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 17:10
+*/
+@RestController
+@RequestMapping("api/current")
+public class CurrentUserController extends CommonCtrl{
+
+ @Autowired private SysEntitlementService sysEntitlementService;
+ @Autowired private SysUserService sysUserService;
+ @Autowired private SysUserAuthService sysUserAuthService;
+
+ @RequestMapping(value="/user", method = RequestMethod.GET)
+ public ApiRes currentUserInfo() {
+
+ ///当前用户信息
+ JeeUserDetails jeeUserDetails = getCurrentUser();
+ SysUser user = jeeUserDetails.getSysUser();
+
+ //1. 当前用户所有权限ID集合
+ List entIdList = new ArrayList<>();
+ jeeUserDetails.getAuthorities().stream().forEach(r->entIdList.add(r.getAuthority()));
+
+ List allMenuList = new ArrayList<>(); //所有菜单集合
+
+ //2. 查询出用户所有菜单集合 (包含左侧显示菜单 和 其他类型菜单 )
+ if(entIdList != null && !entIdList.isEmpty()){
+ allMenuList = sysEntitlementService.list(SysEntitlement.gw()
+ .in(SysEntitlement::getEntId, entIdList)
+ .in(SysEntitlement::getEntType, Arrays.asList(CS.ENT_TYPE.MENU_LEFT, CS.ENT_TYPE.MENU_OTHER))
+ .eq(SysEntitlement::getSystem, CS.SYS_TYPE.MGR)
+ .eq(SysEntitlement::getState, CS.PUB_USABLE));
+ }
+
+ //4. 转换为json树状结构
+ JSONArray jsonArray = (JSONArray) JSONArray.toJSON(allMenuList);
+ List allMenuRouteTree = new TreeDataBuilder(jsonArray,
+ "entId", "pid", "children", "entSort", true)
+ .buildTreeObject();
+
+ //1. 所有权限ID集合
+ user.addExt("entIdList", entIdList);
+ user.addExt("allMenuRouteTree", allMenuRouteTree);
+ return ApiRes.ok(getCurrentUser().getSysUser());
+ }
+
+
+ /** 修改个人信息 */
+ @RequestMapping(value="/user", method = RequestMethod.PUT)
+ @MethodLog(remark = "修改信息")
+ public ApiRes modifyCurrentUserInfo() {
+
+ //修改头像
+ String avatarUrl = getValString("avatarUrl");
+ String realname = getValString("realname");
+ Byte sex = getValByte("sex");
+ SysUser updateRecord = new SysUser();
+ updateRecord.setSysUserId(getCurrentUser().getSysUser().getSysUserId());
+ if (StringUtils.isNotEmpty(avatarUrl)) updateRecord.setAvatarUrl(avatarUrl);
+ if (StringUtils.isNotEmpty(realname)) updateRecord.setRealname(realname);
+ if (sex != null) updateRecord.setSex(sex);
+ sysUserService.updateById(updateRecord);
+
+
+ //保存redis最新数据
+ JeeUserDetails currentUser = getCurrentUser();
+ currentUser.setSysUser(sysUserService.getById(getCurrentUser().getSysUser().getSysUserId()));
+ ITokenService.refData(currentUser);
+
+ return ApiRes.ok();
+ }
+
+
+ /** 修改密码 */
+ @RequestMapping(value="modifyPwd", method = RequestMethod.PUT)
+ @MethodLog(remark = "修改密码")
+ public ApiRes modifyPwd() throws BizException{
+
+ //更改密码, 验证当前用户信息
+ String currentUserPwd = getValStringRequired("originalPwd"); //当前用户登录密码
+ //验证当前密码是否正确
+ if(!sysUserAuthService.validateCurrentUserPwd(currentUserPwd)){
+ throw new BizException("原密码验证失败!");
+ }
+
+ String opUserPwd = getValStringRequired("confirmPwd");
+
+ // 验证原密码与新密码是否相同
+ if (opUserPwd.equals(currentUserPwd)) {
+ throw new BizException("新密码与原密码不能相同!");
+ }
+
+ sysUserAuthService.resetAuthInfo(getCurrentUser().getSysUser().getSysUserId(), null, null, opUserPwd, CS.SYS_TYPE.MGR);
+ //调用登出接口
+ return logout();
+ }
+
+// /** 登出 */
+// @RequestMapping(value="logout", method = RequestMethod.POST)
+// @MethodLog(remark = "登出")
+ public ApiRes logout() throws BizException{
+
+ ITokenService.removeIToken(getCurrentUser().getCacheKey(), getCurrentUser().getSysUser().getSysUserId());
+ return ApiRes.ok();
+ }
+
+
+
+}
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/anon/AuthController.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/anon/AuthController.java
new file mode 100644
index 00000000..82a1507d
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/anon/AuthController.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.ctrl.anon;
+
+import cn.hutool.captcha.CaptchaUtil;
+import cn.hutool.captcha.LineCaptcha;
+import cn.hutool.core.codec.Base64;
+import cn.hutool.core.lang.UUID;
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.aop.MethodLog;
+import com.jeequan.jeepay.core.cache.RedisUtil;
+import com.jeequan.jeepay.core.constants.CS;
+import com.jeequan.jeepay.core.exception.BizException;
+import com.jeequan.jeepay.core.model.ApiRes;
+import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
+import com.jeequan.jeepay.mgr.service.AuthService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/*
+* 认证接口
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 17:09
+*/
+@RestController
+@RequestMapping("/api/anon/auth")
+public class AuthController extends CommonCtrl {
+
+ @Autowired private AuthService authService;
+
+ /** 用户信息认证 获取iToken **/
+ @RequestMapping(value = "/validate", method = RequestMethod.POST)
+ @MethodLog(remark = "登录认证")
+ public ApiRes validate() throws BizException {
+
+
+ String account = Base64.decodeStr(getValStringRequired("ia")); //用户名 i account, 已做base64处理
+ String ipassport = Base64.decodeStr(getValStringRequired("ip")); //密码 i passport, 已做base64处理
+ String vercode = Base64.decodeStr(getValStringRequired("vc")); //验证码 vercode, 已做base64处理
+ String vercodeToken = Base64.decodeStr(getValStringRequired("vt")); //验证码token, vercode token , 已做base64处理
+
+ String cacheCode = RedisUtil.getString(CS.getCacheKeyImgCode(vercodeToken));
+ if(StringUtils.isEmpty(cacheCode) || !cacheCode.equalsIgnoreCase(vercode)){
+ throw new BizException("验证码有误!");
+ }
+
+ // 返回前端 accessToken
+ String accessToken = authService.auth(account, ipassport);
+
+ // 删除图形验证码缓存数据
+ RedisUtil.del(CS.getCacheKeyImgCode(vercodeToken));
+
+ return ApiRes.ok4newJson(CS.ACCESS_TOKEN_NAME, accessToken);
+ }
+
+ /** 图片验证码 **/
+ @RequestMapping(value = "/vercode", method = RequestMethod.GET)
+ public ApiRes vercode() throws BizException {
+
+ //定义图形验证码的长和宽 // 4位验证码
+ LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(137, 40, 4, 80);
+ lineCaptcha.createCode(); //生成code
+
+ //redis
+ String vercodeToken = UUID.fastUUID().toString();
+ RedisUtil.setString(CS.getCacheKeyImgCode(vercodeToken), lineCaptcha.getCode(), 60 ); //图片验证码缓存时间: 1分钟
+
+ JSONObject result = new JSONObject();
+ result.put("imageBase64Data", lineCaptcha.getImageBase64Data());
+ result.put("vercodeToken", vercodeToken);
+
+ return ApiRes.ok(result);
+ }
+
+}
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/common/OssFileController.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/common/OssFileController.java
new file mode 100644
index 00000000..837e5918
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/common/OssFileController.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.ctrl.common;
+
+import cn.hutool.core.lang.UUID;
+import com.jeequan.jeepay.core.constants.ApiCodeEnum;
+import com.jeequan.jeepay.core.exception.BizException;
+import com.jeequan.jeepay.core.model.ApiRes;
+import com.jeequan.jeepay.core.model.OssFileConfig;
+import com.jeequan.jeepay.core.utils.FileKit;
+import com.jeequan.jeepay.mgr.config.SystemYmlConfig;
+import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
+import com.jeequan.jeepay.service.impl.SysConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+
+/*
+* 统一文件上传接口(ossFile)
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 17:07
+*/
+@RestController
+@RequestMapping("/api/ossFiles")
+public class OssFileController extends CommonCtrl {
+
+ @Autowired private SystemYmlConfig systemYmlConfig;
+ @Autowired private SysConfigService sysConfigService;
+
+ /** 上传文件 (单文件上传) */
+ @PostMapping("/{bizType}")
+ public ApiRes singleFileUpload(@RequestParam("file") MultipartFile file, @PathVariable("bizType") String bizType) {
+
+ if( file == null ) return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "选择文件不存在");
+ try {
+
+
+ OssFileConfig ossFileConfig = OssFileConfig.getOssFileConfigByBizType(bizType);
+
+ //1. 判断bizType 是否可用
+ if(ossFileConfig == null){
+ throw new BizException("类型有误");
+ }
+
+ // 2. 判断文件是否支持
+ String fileSuffix = FileKit.getFileSuffix(file.getOriginalFilename(), false);
+ if( !ossFileConfig.isAllowFileSuffix(fileSuffix) ){
+ throw new BizException("上传文件格式不支持!");
+ }
+
+ // 3. 判断文件大小是否超限
+ if( !ossFileConfig.isMaxSizeLimit(file.getSize()) ){
+ throw new BizException("上传大小请限制在["+ossFileConfig.getMaxSize() / 1024 / 1024 +"M]以内!");
+ }
+
+
+ boolean isAllowPublicRead = ossFileConfig.isAllowPublicRead(); //是否允许公共读, true:公共读, false:私有文件
+
+ //公共读 & 是否上传到oss
+ boolean isYunOss = false; //TODO 暂时不支持云oss方式
+ if(isAllowPublicRead && isYunOss){
+ return null;
+ }
+
+ //以下为文件上传到本地
+
+ // 新文件地址
+ String newFileName = UUID.fastUUID() + "." + fileSuffix;
+
+ // 保存的文件夹名称
+ String saveFilePath = isAllowPublicRead ? systemYmlConfig.getOssFile().getPublicPath() : systemYmlConfig.getOssFile().getPrivatePath();
+ saveFilePath = saveFilePath + File.separator + bizType + File.separator + newFileName;
+
+
+ //保存文件
+ saveFile(file, saveFilePath);
+
+ //返回响应结果
+ String resultUrl = bizType + "/" + newFileName;
+ if(isAllowPublicRead){ //允许公共读取
+ resultUrl = sysConfigService.getDBApplicationConfig().getOssPublicSiteUrl() + "/" + resultUrl;
+ }
+
+ return ApiRes.ok(resultUrl);
+
+ } catch (BizException biz) {
+ throw biz;
+ } catch (Exception e) {
+ logger.error("upload error, fileName = {}", file == null ? null :file.getOriginalFilename(), e);
+ throw new BizException(ApiCodeEnum.SYSTEM_ERROR);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/common/StaticController.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/common/StaticController.java
new file mode 100644
index 00000000..45b5d21d
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/common/StaticController.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.ctrl.common;
+
+import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+/*
+* 静态文件下载/预览 ctrl
+*
+* @author terrfly
+* @site https://www.jeepay.vip
+* @date 2021/6/8 17:08
+*/
+@Controller
+public class StaticController extends CommonCtrl {
+
+ /** 图片预览 **/
+ @GetMapping("/api/anon/localOssFiles/**/*.*")
+ public ResponseEntity> imgView() {
+
+ try {
+
+ //查找图片文件
+ File imgFile = new File(mainConfig.getOssFile().getPublicPath() + File.separator + request.getRequestURI().substring(24));
+ if(!imgFile.isFile() || !imgFile.exists()) return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+
+ //输出文件流(图片格式)
+ HttpHeaders httpHeaders = new HttpHeaders();
+// httpHeaders.setContentType(MediaType.IMAGE_JPEG); //图片格式
+ InputStream inputStream = new FileInputStream(imgFile);
+ return new ResponseEntity<>(new InputStreamResource(inputStream), httpHeaders, HttpStatus.OK);
+
+ } catch (FileNotFoundException e) {
+ logger.error("static file error", e);
+ return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+
+}
diff --git a/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/config/MainChartController.java b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/config/MainChartController.java
new file mode 100644
index 00000000..04fc86ff
--- /dev/null
+++ b/jeepay-manager/src/main/java/com/jeequan/jeepay/mgr/ctrl/config/MainChartController.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jeequan.jeepay.mgr.ctrl.config;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jeequan.jeepay.core.model.ApiRes;
+import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
+import com.jeequan.jeepay.service.impl.PayOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 首页统计类
+ *
+ * @author pangxiaoyu
+ * @site https://www.jeepay.vip
+ * @date 2021-06-07 07:15
+ */
+@Slf4j
+@RestController
+@RequestMapping("api/mainChart")
+public class MainChartController extends CommonCtrl {
+
+ @Autowired private PayOrderService payOrderService;
+
+ /**
+ * @author: pangxiaoyu
+ * @date: 2021/6/7 16:18
+ * @describe: 周交易总金额
+ */
+ @PreAuthorize("hasAuthority('ENT_C_MAIN_PAY_AMOUNT_WEEK')")
+ @RequestMapping(value="/payAmountWeek", method = RequestMethod.GET)
+ public ApiRes payAmountWeek() {
+ return ApiRes.ok(payOrderService.mainPageWeekCount(null));
+ }
+
+ /**
+ * @author: pangxiaoyu
+ * @date: 2021/6/7 16:18
+ * @describe: 商户总数量、服务商总数量、总交易金额、总交易笔数
+ */
+ @PreAuthorize("hasAuthority('ENT_C_MAIN_NUMBER_COUNT')")
+ @RequestMapping(value="/numCount", method = RequestMethod.GET)
+ public ApiRes numCount() {
+ JSONObject json = payOrderService.mainPageNumCount(null);
+ //返回数据
+ return ApiRes.ok(json);
+ }
+
+ /**
+ * @author: pangxiaoyu
+ * @date: 2021/6/7 16:18
+ * @describe: 交易统计
+ */
+ @PreAuthorize("hasAuthority('ENT_C_MAIN_PAY_COUNT')")
+ @RequestMapping(value="/payCount", method = RequestMethod.GET)
+ public ApiRes payCount() {
+ // 获取传入参数
+ JSONObject paramJSON = getReqParamJSON();
+ String createdStart = paramJSON.getString("createdStart");
+ String createdEnd = paramJSON.getString("createdEnd");
+ List