This commit is contained in:
韩鹏辉 2024-06-11 10:34:21 +08:00
parent 6bab32173f
commit 7894f47de4
2498 changed files with 442406 additions and 0 deletions

165
LICENSE Normal file
View File

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
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.

36
README.en.md Normal file
View File

@ -0,0 +1,36 @@
# yinshangfu_web
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

136
conf/agent/application.yml Normal file
View File

@ -0,0 +1,136 @@
#################################
# 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: 9219 #设置端口
servlet:
context-path: / #设置应用的目录. 前缀需要带/, 无需设置后缀, 示例 【 /xxx 】 or 【 / 】
# 数据库的配置项, 自定义配置放置在配置顶层
db-config:
master: #主库配置(必填)
# yml填写url连接串 无需将&符号进行转义
url: jdbc:mysql://127.0.0.1:3306/jeepayplus?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
username: root
password:
encrypt-account: false # 连接账号和密码是否已加密。 truedb的账密需配置密文函数详见 DBProp.main() false: db账密请填写明文
# 连接池配置项
initial-size: 5 #初始化时建立物理连接的个数
min-idle: 5 #最小连接池数量
max-active: 30 #最大连接池数量
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
# 检测相关
test-while-idle: true # 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
validation-query: SELECT 1 FROM DUAL
# 是否缓存preparedStatement
pool-prepared-statements: false # 是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache必须配置大于0当大于0时poolPreparedStatements自动触发修改为true。
# 配置监控统计拦截的filters去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能慢SQL记录
filters: stat,wall
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
# spring-boot组件配置
spring:
servlet:
multipart:
enabled: true #是否启用http上传处理
max-request-size: 10MB #最大请求文件的大小
max-file-size: 10MB #设置单个文件最大长度
resources:
static-locations: classpath:/static #项目静态资源路径 可直接通过http访问
freemarker:
template-loader-path: classpath:/templates #freemarker模板目录
template-encoding: UTF-8
suffix: .ftl
settings:
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
cache:
type: redis
redis:
host: 127.0.0.1
port: 6379
database: 4 #1库运营平台 #2库商户系统 #3库支付网关 #4库代理商
timeout: 1000
password:
sys-prefix-key: PKAGENT_ # 作用:不同系统的前缀。 a.当连接不同的database时可以为空(物理隔离) b.当redis集群时因为必须同一个database所以需通过前缀区分不同系统的业务。
# #activeMQ配置 ( 注意: activeMQ配置项需在spring的下级 )
activemq:
broker-url: failover:(tcp://127.0.0.1:61616?wireFormat.maxInactivityDuration=0) #连接地址
in-memory: false # Jeepay项目不可使用内存模式 需要连接多个消费者。
user: system # activeMQ默认无需账密认证。 打开认证activemq.xml添加simpleAuthenticationPlugin标签账密在credentials.properties文件。
password: manager
pool:
enabled: true
max-connections: 10
idle-timeout: 30000 # 空闲的连接过期时间默认为30秒
#
# #rabbitmq配置 ( 注意: rabbitmq配置项需在spring的下级 )
# rabbitmq:
# addresses: 127.0.0.1:5672
# username: guest
# password: guest
# dynamic: true
# virtual-host: /
## rocketmq配置 ( 注意rocketmq配置项请放置到根目录 不是spring的二级配置 )
#rocketmq:
# name-server: 127.0.0.1:9876
# producer:
# group: JEEPAY-GROUP
## 阿里云rocketmq配置 ( 注意aliyun-rocketmq配置项请放置到根目录 不是spring的二级配置需要阿里云开通rocketMQ产品创建Group和Topic )
#aliyun-rocketmq:
# namesrvAddr: xxx
# accessKey: xxx
# secretKey: xxx
# groupIdPrefix: GID_JEEPAY_ # (分组前缀, 具体名称详见AliyunRocketMQFactory.java )
#日志配置参数。
# 当存在logback-spring.xml文件时 该配置将引进到logback配置 springboot配置不生效。
# 不存在logback-spring.xml 文件时, 使用springboot的配置 同样可用。
logging:
level:
root: info #主日志级别
#系统业务参数
isys:
jwt-secret: N7qDoevBDZYIfHTq #生成jwt的秘钥。 要求每个系统有单独的秘钥管理机制。
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
http-message-encrypt-secret: 1234567890123456 #web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
# 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更!
sys-RSA2-private-key: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCLU0lXJu9vcJCwrwFGwT1CqXUSY+JMW2iSRPtgLw6lxjU403hS1VyKxA5uTZokv80Wd+bcxDMrM9DwHeGqhjlWvbB/lqaRliJJRdgLVUedrDY+3YSN75uHBtLmxZbnaUpV6/aWA/a+lkNqHxYCWB1jggFB9DhVg2SgoMGDOYHDNA5ZDl47sKpanW0kfG9lINSV4xgDPmAJxUnhkG/7eVEBDev9EIhc+LIMC7Zj+UYc+s/TK4c31fFTW4dZAp3LVEdct9qXU5qm/fXIXxeo3E0bWyOP3VL4Xmx2S9Host1YzjzXPSi1TJjX7rxQkhmbE/dQJ+ws/VvKPuUpmLEPGsm/AgMBAAECggEBAIONCFq58KoQZw3ssA/WtbkTt+69URc31+0EJTYUOIheNjKJubq8qrx7kgSkUT8RutvUKq+YsZfBPS77h/Ay/EDiqpxN6sjcMVNuFyfcRdqimDWTg21hKEC+OLSdLHcj+4RVYGcVJw2dY9n3sBhWiqlCP12+8tILViA0qYL18YgVYJM3bL2MCXfUnm8/Rn1ut5LuDtU/UuaVz9vuCqNirZJedZx3WEq69ZRt9m44XN934NikbUGxQRlz32WRXDo+ssSTu3174UbDYc8nhqO0jUvuzfjOOMf9NYRJsgqVihxMLvvMaUhEE3w6qZPLMj6KhTiG5QHexBbyLgDxH4TZ4gECgYEAz7vZFMoKYifCi+eFykH/ad8QYYoYLlrU1EN2fpIJqwSHZbpBfB8NM5Ov26xU/aNHGKxtSOrUFva5sWub5f9OlsOAmaUOPuVuaJbsq+e3cNQ41jBcdppGJLNx1p/69zR1rF9TbI9Ambd8sOgX3OZmImA2Ldlk2KvMKRruxwc4uN8CgYEAq7J0u5KTwI3PxENLWQ/6tOBNdbCoyqFM+FdANVHRA4dhhdoJ1x0bpdt3tapPFJTBURSEspNxPl4iT+GdpoF6KwqTsQFmB5TLlfx8wY9SIc+sI/ifZvMA5Dv8vVfYWNig7rGV+vIyJCCNbJ5OMa1xvxTDc7Dx4XPxcJ4sR1ZyqyECgYAe447O8ZADsmfSR9X0EkY5ZurXpiIcWnNFMNbg0TRQ0raTYNO18iQTZEWFA6YLpQjAWXtSmWB6HavU/uxKkeEMt/taXVm17oWxVafRk/4J7/SXnM9S73O4p1opENbPhWRuAiq0fMSdVtRatdg+h5/uQqIrxSSit0D/Z7rTq3Y6vwKBgQCd8AlbJckOHiTZd8GOypkm2xHFydxqkJfZ9YCVy44Fvfnig5/7pcXx+oEStfgKiY+OQt6R2fkYksTjUDmRmZbEkvUqpIuzO5dOf7RO5MR7X6oMaL5QmAXg7KFflrfnelYHW4oIDdQ70UnmeXSaU97HE5V7DXBioCGfI5C9inLuoQKBgQCwJmQ2heyTbG1DIBuqf+GFXLuOp76M/7S9c+5R7yfxyTzAbiKRIPeSF5wlxNXEnGwK7qB9CmctlBdnV7A0qnZVFMXf7AbBDUzOCjiy1RSh04BNPnu0dTIygX2PE5inltrHiZtTgciKwj9MexT97F4mTR76kIMz5SGNZe3PscQr7g==
sys-RSA2-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1NJVybvb3CQsK8BRsE9Qql1EmPiTFtokkT7YC8OpcY1ONN4UtVcisQObk2aJL/NFnfm3MQzKzPQ8B3hqoY5Vr2wf5amkZYiSUXYC1VHnaw2Pt2Eje+bhwbS5sWW52lKVev2lgP2vpZDah8WAlgdY4IBQfQ4VYNkoKDBgzmBwzQOWQ5eO7CqWp1tJHxvZSDUleMYAz5gCcVJ4ZBv+3lRAQ3r/RCIXPiyDAu2Y/lGHPrP0yuHN9XxU1uHWQKdy1RHXLfal1Oapv31yF8XqNxNG1sjj91S+F5sdkvR6LLdWM481z0otUyY1+68UJIZmxP3UCfsLP1byj7lKZixDxrJvwIDAQAB
#是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时应开启此配置或在nginx统一配置允许跨域]
allow-cors: true
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常 false表示直接查询DB.
cache-config: false
oss:
file-root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
file-private-path: ${isys.oss.file-root-path}/private #私有化本地访问不允许url方式公共读取 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
mq:
vender: activeMQ # 切换MQ厂商 支持:【 activeMQ rabbitMQ rocketMQ aliYunRocketMQ 】, 需正确配置 【对应的yml参数】 和 【jeepay-components-mq项目下pom.xml中的依赖包】。

128
conf/bill/application.yml Normal file
View File

@ -0,0 +1,128 @@
#################################
# 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: 9220 #设置端口
servlet:
context-path: / #设置应用的目录. 前缀需要带/, 无需设置后缀, 示例 【 /xxx 】 or 【 / 】
# 数据库的配置项, 自定义配置放置在配置顶层
db-config:
master: #主库配置(必填)
# yml填写url连接串 无需将&符号进行转义
url: jdbc:mysql://127.0.0.1:3306/jeepayplus?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
username: root
password:
encrypt-account: false # 连接账号和密码是否已加密。 truedb的账密需配置密文函数详见 DBProp.main() false: db账密请填写明文
# 连接池配置项
initial-size: 5 #初始化时建立物理连接的个数
min-idle: 5 #最小连接池数量
max-active: 30 #最大连接池数量
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
# 检测相关
test-while-idle: true # 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
validation-query: SELECT 1 FROM DUAL
# 是否缓存preparedStatement
pool-prepared-statements: false # 是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache必须配置大于0当大于0时poolPreparedStatements自动触发修改为true。
# 配置监控统计拦截的filters去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能慢SQL记录
filters: stat,wall
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
# spring-boot组件配置
spring:
servlet:
multipart:
enabled: true #是否启用http上传处理
max-request-size: 10MB #最大请求文件的大小
max-file-size: 10MB #设置单个文件最大长度
resources:
static-locations: classpath:/static #项目静态资源路径 可直接通过http访问
freemarker:
template-loader-path: classpath:/templates #freemarker模板目录
template-encoding: UTF-8
suffix: .ftl
settings:
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
# #activeMQ配置 ( 注意: activeMQ配置项需在spring的下级 )
activemq:
broker-url: failover:(tcp://127.0.0.1:61616?wireFormat.maxInactivityDuration=0) #连接地址
in-memory: false # Jeepay项目不可使用内存模式 需要连接多个消费者。
user: system # activeMQ默认无需账密认证。 打开认证activemq.xml添加simpleAuthenticationPlugin标签账密在credentials.properties文件。
password: manager
pool:
enabled: true
max-connections: 10
idle-timeout: 30000 # 空闲的连接过期时间默认为30秒
#
# #rabbitmq配置 ( 注意: rabbitmq配置项需在spring的下级 )
# rabbitmq:
# addresses: 127.0.0.1:5672
# username: guest
# password: guest
# dynamic: true
# virtual-host: /
## rocketmq配置 ( 注意rocketmq配置项请放置到根目录 不是spring的二级配置 )
#rocketmq:
# name-server: 127.0.0.1:9876
# producer:
# group: JEEPAY-GROUP
## 阿里云rocketmq配置 ( 注意aliyun-rocketmq配置项请放置到根目录 不是spring的二级配置需要阿里云开通rocketMQ产品创建Group和Topic )
#aliyun-rocketmq:
# namesrvAddr: xxx
# accessKey: xxx
# secretKey: xxx
# groupIdPrefix: GID_JEEPAY_ # (分组前缀, 具体名称详见AliyunRocketMQFactory.java )
#日志配置参数。
# 当存在logback-spring.xml文件时 该配置将引进到logback配置 springboot配置不生效。
# 不存在logback-spring.xml 文件时, 使用springboot的配置 同样可用。
logging:
level:
root: info #主日志级别
# xxl-job 执行器配置项
xxl-job:
executor:
admin-address: http://127.0.0.1:9300/xxl-job-admin # 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
access-token: jeepayTaskToken@2022 # 执行器通讯TOKEN
appname: jeepay-plus-bill-executor # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
port: 9320 # 执行器端口号 [选填]小于等于0则自动获取默认端口为9999单机部署多个执行器时注意要配置不同执行器端口
log-path: ${logging.file.path} # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
logretentiondays: 7 # 执行器日志文件保存天数 [选填] 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
#系统业务参数
isys:
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常 false表示直接查询DB.
cache-config: false
oss:
file-root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
file-private-path: ${isys.oss.file-root-path}/private #私有化本地访问不允许url方式公共读取 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
mq:
vender: activeMQ # 切换MQ厂商 支持:【 activeMQ rabbitMQ rocketMQ aliYunRocketMQ 】, 需正确配置 【对应的yml参数】 和 【jeepay-components-mq项目下pom.xml中的依赖包】。

View File

@ -0,0 +1,131 @@
#################################
# 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文件只配置与环境相关的参数 其他配置读取项目下的配置项
#
#################################
# 数据库的配置项, 自定义配置放置在配置顶层
db-config:
master: #主库配置(必填)
# yml填写url连接串 无需将&符号进行转义
url: jdbc:mysql://rm-bp15xh3v2211zo51f.mysql.rds.aliyuncs.com/ql_saas?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
username: ql_saas
password: fb4y6JcB
encrypt-account: false # 连接账号和密码是否已加密。 truedb的账密需配置密文函数详见 DBProp.main() false: db账密请填写明文
# 连接池配置项
initial-size: 5 #初始化时建立物理连接的个数
min-idle: 5 #最小连接池数量
max-active: 30 #最大连接池数量
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
# 检测相关
test-while-idle: true # 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
validation-query: SELECT 1 FROM DUAL
# 是否缓存preparedStatement
pool-prepared-statements: false # 是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache必须配置大于0当大于0时poolPreparedStatements自动触发修改为true。
# 配置监控统计拦截的filters去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能慢SQL记录
filters: stat,wall
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
# spring-boot组件配置
spring:
servlet:
multipart:
enabled: true #是否启用http上传处理
max-request-size: 10MB #最大请求文件的大小
max-file-size: 10MB #设置单个文件最大长度
freemarker:
template-loader-path: classpath:/templates #freemarker模板目录
template-encoding: UTF-8
suffix: .ftl
settings:
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
cache:
type: redis
redis:
host: 127.0.0.1
port: 6379
database: 1 #1库运营平台 #2库商户系统 #3库支付网关 #4库代理商
timeout: 1000
password:
sys-prefix-key: PKMGR_ # 作用:不同系统的前缀。 a.当连接不同的database时可以为空(物理隔离) b.当redis集群时因为必须同一个database所以需通过前缀区分不同系统的业务。
rabbitmq:
addresses: localhost:5672
username: admin
password: 123456
dynamic: true
virtual-host: /
web:
resources:
static-locations: classpath:/static
# #activeMQ配置 ( 注意: activeMQ配置项需在spring的下级 )
# activemq:
# broker-url: failover:(tcp://127.0.0.1:61616?wireFormat.maxInactivityDuration=0) #连接地址
# in-memory: false # Jeepay项目不可使用内存模式 需要连接多个消费者。
# user: system # activeMQ默认无需账密认证。 打开认证activemq.xml添加simpleAuthenticationPlugin标签账密在credentials.properties文件。
# password: manager
# pool:
# enabled: true
# max-connections: 10
# idle-timeout: 30000 # 空闲的连接过期时间默认为30秒
#
# #rabbitmq配置 ( 注意: rabbitmq配置项需在spring的下级 )
## rocketmq配置 ( 注意rocketmq配置项请放置到根目录 不是spring的二级配置 )
#rocketmq:
# name-server: 127.0.0.1:9876
# producer:
# group: JEEPAY-GROUP
## 阿里云rocketmq配置 ( 注意aliyun-rocketmq配置项请放置到根目录 不是spring的二级配置需要阿里云开通rocketMQ产品创建Group和Topic )
#aliyun-rocketmq:
# namesrvAddr: xxx
# accessKey: xxx
# secretKey: xxx
# groupIdPrefix: GID_JEEPAY_ # (分组前缀, 具体名称详见AliyunRocketMQFactory.java )
#日志配置参数。
# 当存在logback-spring.xml文件时 该配置将引进到logback配置 springboot配置不生效。
# 不存在logback-spring.xml 文件时, 使用springboot的配置 同样可用。
logging:
level:
root: INFO #主日志级别
com.jeequan.jeepay: DEBUG #该项目日志级别当需要打印sql时请开启为debug
#系统业务参数
isys:
jwt-secret: t7w3P8X6472qWc3u #生成jwt的秘钥。 要求每个系统有单独的秘钥管理机制。
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
http-message-encrypt-secret: 1234567890123456 #web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
# 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更!
sys-RSA2-private-key: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCLU0lXJu9vcJCwrwFGwT1CqXUSY+JMW2iSRPtgLw6lxjU403hS1VyKxA5uTZokv80Wd+bcxDMrM9DwHeGqhjlWvbB/lqaRliJJRdgLVUedrDY+3YSN75uHBtLmxZbnaUpV6/aWA/a+lkNqHxYCWB1jggFB9DhVg2SgoMGDOYHDNA5ZDl47sKpanW0kfG9lINSV4xgDPmAJxUnhkG/7eVEBDev9EIhc+LIMC7Zj+UYc+s/TK4c31fFTW4dZAp3LVEdct9qXU5qm/fXIXxeo3E0bWyOP3VL4Xmx2S9Host1YzjzXPSi1TJjX7rxQkhmbE/dQJ+ws/VvKPuUpmLEPGsm/AgMBAAECggEBAIONCFq58KoQZw3ssA/WtbkTt+69URc31+0EJTYUOIheNjKJubq8qrx7kgSkUT8RutvUKq+YsZfBPS77h/Ay/EDiqpxN6sjcMVNuFyfcRdqimDWTg21hKEC+OLSdLHcj+4RVYGcVJw2dY9n3sBhWiqlCP12+8tILViA0qYL18YgVYJM3bL2MCXfUnm8/Rn1ut5LuDtU/UuaVz9vuCqNirZJedZx3WEq69ZRt9m44XN934NikbUGxQRlz32WRXDo+ssSTu3174UbDYc8nhqO0jUvuzfjOOMf9NYRJsgqVihxMLvvMaUhEE3w6qZPLMj6KhTiG5QHexBbyLgDxH4TZ4gECgYEAz7vZFMoKYifCi+eFykH/ad8QYYoYLlrU1EN2fpIJqwSHZbpBfB8NM5Ov26xU/aNHGKxtSOrUFva5sWub5f9OlsOAmaUOPuVuaJbsq+e3cNQ41jBcdppGJLNx1p/69zR1rF9TbI9Ambd8sOgX3OZmImA2Ldlk2KvMKRruxwc4uN8CgYEAq7J0u5KTwI3PxENLWQ/6tOBNdbCoyqFM+FdANVHRA4dhhdoJ1x0bpdt3tapPFJTBURSEspNxPl4iT+GdpoF6KwqTsQFmB5TLlfx8wY9SIc+sI/ifZvMA5Dv8vVfYWNig7rGV+vIyJCCNbJ5OMa1xvxTDc7Dx4XPxcJ4sR1ZyqyECgYAe447O8ZADsmfSR9X0EkY5ZurXpiIcWnNFMNbg0TRQ0raTYNO18iQTZEWFA6YLpQjAWXtSmWB6HavU/uxKkeEMt/taXVm17oWxVafRk/4J7/SXnM9S73O4p1opENbPhWRuAiq0fMSdVtRatdg+h5/uQqIrxSSit0D/Z7rTq3Y6vwKBgQCd8AlbJckOHiTZd8GOypkm2xHFydxqkJfZ9YCVy44Fvfnig5/7pcXx+oEStfgKiY+OQt6R2fkYksTjUDmRmZbEkvUqpIuzO5dOf7RO5MR7X6oMaL5QmAXg7KFflrfnelYHW4oIDdQ70UnmeXSaU97HE5V7DXBioCGfI5C9inLuoQKBgQCwJmQ2heyTbG1DIBuqf+GFXLuOp76M/7S9c+5R7yfxyTzAbiKRIPeSF5wlxNXEnGwK7qB9CmctlBdnV7A0qnZVFMXf7AbBDUzOCjiy1RSh04BNPnu0dTIygX2PE5inltrHiZtTgciKwj9MexT97F4mTR76kIMz5SGNZe3PscQr7g==
sys-RSA2-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1NJVybvb3CQsK8BRsE9Qql1EmPiTFtokkT7YC8OpcY1ONN4UtVcisQObk2aJL/NFnfm3MQzKzPQ8B3hqoY5Vr2wf5amkZYiSUXYC1VHnaw2Pt2Eje+bhwbS5sWW52lKVev2lgP2vpZDah8WAlgdY4IBQfQ4VYNkoKDBgzmBwzQOWQ5eO7CqWp1tJHxvZSDUleMYAz5gCcVJ4ZBv+3lRAQ3r/RCIXPiyDAu2Y/lGHPrP0yuHN9XxU1uHWQKdy1RHXLfal1Oapv31yF8XqNxNG1sjj91S+F5sdkvR6LLdWM481z0otUyY1+68UJIZmxP3UCfsLP1byj7lKZixDxrJvwIDAQAB
#是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时应开启此配置或在nginx统一配置允许跨域]
allow-cors: true
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常 false表示直接查询DB.
cache-config: false
oss:
file-root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
file-private-path: ${isys.oss.file-root-path}/private #私有化本地访问不允许url方式公共读取 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
mq:
vender: rabbitMQ # 切换MQ厂商 支持:【 activeMQ rabbitMQ rocketMQ aliYunRocketMQ 】, 需正确配置 【对应的yml参数】 和 【jeepay-components-mq项目下pom.xml中的依赖包】。

View File

@ -0,0 +1,142 @@
#################################
# 开发环境通用配置文件(每个项目通用配置)
# 使用方法:
# 1. 将此文件在当前文件夹下copy一份并重命名为[ application.yml ]
# 2. application.yml 作为本地项目启动的通用配置文件;
# 3. application.yml 建议加入到.gitignore忽略 避免开发人员不经意的提交。
# 4. 若对通用配置进行变更请修改application.txt文件并提交git仓库 由开发人员自行合并到本地。
#################################
server:
servlet:
context-path: / #设置应用的目录. 前缀需要带/, 无需设置后缀, 示例 【 /xxx 】 or 【 / 】
# 数据库的配置项, 自定义配置放置在配置顶层
db-config:
master: #主库配置(必填)
# yml填写url连接串 无需将&符号进行转义
url: jdbc:mysql://127.0.0.1:3306/jeepayplus?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
username: root
password:
encrypt-account: false # 连接账号和密码是否已加密。 truedb的账密需配置密文函数详见 DBProp.main() false: db账密请填写明文
# 连接池配置项
initial-size: 5 #初始化时建立物理连接的个数
min-idle: 5 #最小连接池数量
max-active: 30 #最大连接池数量
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
# 检测相关
test-while-idle: true # 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
validation-query: SELECT 1 FROM DUAL
# 是否缓存preparedStatement
pool-prepared-statements: false # 是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache必须配置大于0当大于0时poolPreparedStatements自动触发修改为true。
# 配置监控统计拦截的filters去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能慢SQL记录
filters: stat,wall
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
# spring-boot组件配置
spring:
servlet:
multipart:
enabled: true #是否启用http上传处理
max-request-size: 10MB #最大请求文件的大小
max-file-size: 10MB #设置单个文件最大长度
resources:
static-locations: classpath:/static #项目静态资源路径 可直接通过http访问
freemarker:
template-loader-path: classpath:/templates #freemarker模板目录
template-encoding: UTF-8
suffix: .ftl
settings:
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
cache:
type: redis
redis:
host: 127.0.0.1
port: 6379
timeout: 1000
password:
# #activeMQ配置 ( 注意: activeMQ配置项需在spring的下级 )
activemq:
broker-url: failover:(tcp://127.0.0.1:61616?wireFormat.maxInactivityDuration=0) #连接地址
in-memory: false # Jeepay项目不可使用内存模式 需要连接多个消费者。
user: system # activeMQ默认无需账密认证。 打开认证activemq.xml添加simpleAuthenticationPlugin标签账密在credentials.properties文件。
password: manager
pool:
enabled: true
max-connections: 10
idle-timeout: 30000 # 空闲的连接过期时间默认为30秒
#
# #rabbitmq配置 ( 注意: rabbitmq配置项需在spring的下级 )
# rabbitmq:
# addresses: 127.0.0.1:5672
# username: guest
# password: guest
# dynamic: true
# virtual-host: /
## rocketmq配置 ( 注意rocketmq配置项请放置到根目录 不是spring的二级配置 )
#rocketmq:
# name-server: 127.0.0.1:9876
# producer:
# group: JEEPAY-GROUP
## 阿里云rocketmq配置 ( 注意aliyun-rocketmq配置项请放置到根目录 不是spring的二级配置需要阿里云开通rocketMQ产品创建Group和Topic )
#aliyun-rocketmq:
# namesrvAddr: xxx
# accessKey: xxx
# secretKey: xxx
# groupIdPrefix: GID_JEEPAY_ # (分组前缀, 具体名称详见AliyunRocketMQFactory.java )
#日志配置参数。
# 当存在logback-spring.xml文件时 该配置将引进到logback配置 springboot配置不生效。
# 不存在logback-spring.xml 文件时, 使用springboot的配置 同样可用。
logging:
level:
root: info #主日志级别
com.jeequan.jeepay: debug #该项目日志级别当需要打印sql时请开启为debug
file:
path: ./logs #日志存放地址
# xxl-job 执行器配置项
# xxl-job:
# executor:
# admin-address: http://127.0.0.1:9300/xxl-job-admin # 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
# access-token: jeepayTaskToken@2022 # 执行器通讯TOKEN
# # appname: jeepay-plus-bill-executor # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
# # port: # 执行器端口号 [选填]小于等于0则自动获取默认端口为9999单机部署多个执行器时注意要配置不同执行器端口
# log-path: ${logging.file.path} # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
# logretentiondays: 7 # 执行器日志文件保存天数 [选填] 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
#系统业务参数
isys:
#是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时应开启此配置或在nginx统一配置允许跨域]
allow-cors: true
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
http-message-encrypt-secret: 1234567890123456 #web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
# 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更!
sys-RSA2-private-key: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCLU0lXJu9vcJCwrwFGwT1CqXUSY+JMW2iSRPtgLw6lxjU403hS1VyKxA5uTZokv80Wd+bcxDMrM9DwHeGqhjlWvbB/lqaRliJJRdgLVUedrDY+3YSN75uHBtLmxZbnaUpV6/aWA/a+lkNqHxYCWB1jggFB9DhVg2SgoMGDOYHDNA5ZDl47sKpanW0kfG9lINSV4xgDPmAJxUnhkG/7eVEBDev9EIhc+LIMC7Zj+UYc+s/TK4c31fFTW4dZAp3LVEdct9qXU5qm/fXIXxeo3E0bWyOP3VL4Xmx2S9Host1YzjzXPSi1TJjX7rxQkhmbE/dQJ+ws/VvKPuUpmLEPGsm/AgMBAAECggEBAIONCFq58KoQZw3ssA/WtbkTt+69URc31+0EJTYUOIheNjKJubq8qrx7kgSkUT8RutvUKq+YsZfBPS77h/Ay/EDiqpxN6sjcMVNuFyfcRdqimDWTg21hKEC+OLSdLHcj+4RVYGcVJw2dY9n3sBhWiqlCP12+8tILViA0qYL18YgVYJM3bL2MCXfUnm8/Rn1ut5LuDtU/UuaVz9vuCqNirZJedZx3WEq69ZRt9m44XN934NikbUGxQRlz32WRXDo+ssSTu3174UbDYc8nhqO0jUvuzfjOOMf9NYRJsgqVihxMLvvMaUhEE3w6qZPLMj6KhTiG5QHexBbyLgDxH4TZ4gECgYEAz7vZFMoKYifCi+eFykH/ad8QYYoYLlrU1EN2fpIJqwSHZbpBfB8NM5Ov26xU/aNHGKxtSOrUFva5sWub5f9OlsOAmaUOPuVuaJbsq+e3cNQ41jBcdppGJLNx1p/69zR1rF9TbI9Ambd8sOgX3OZmImA2Ldlk2KvMKRruxwc4uN8CgYEAq7J0u5KTwI3PxENLWQ/6tOBNdbCoyqFM+FdANVHRA4dhhdoJ1x0bpdt3tapPFJTBURSEspNxPl4iT+GdpoF6KwqTsQFmB5TLlfx8wY9SIc+sI/ifZvMA5Dv8vVfYWNig7rGV+vIyJCCNbJ5OMa1xvxTDc7Dx4XPxcJ4sR1ZyqyECgYAe447O8ZADsmfSR9X0EkY5ZurXpiIcWnNFMNbg0TRQ0raTYNO18iQTZEWFA6YLpQjAWXtSmWB6HavU/uxKkeEMt/taXVm17oWxVafRk/4J7/SXnM9S73O4p1opENbPhWRuAiq0fMSdVtRatdg+h5/uQqIrxSSit0D/Z7rTq3Y6vwKBgQCd8AlbJckOHiTZd8GOypkm2xHFydxqkJfZ9YCVy44Fvfnig5/7pcXx+oEStfgKiY+OQt6R2fkYksTjUDmRmZbEkvUqpIuzO5dOf7RO5MR7X6oMaL5QmAXg7KFflrfnelYHW4oIDdQ70UnmeXSaU97HE5V7DXBioCGfI5C9inLuoQKBgQCwJmQ2heyTbG1DIBuqf+GFXLuOp76M/7S9c+5R7yfxyTzAbiKRIPeSF5wlxNXEnGwK7qB9CmctlBdnV7A0qnZVFMXf7AbBDUzOCjiy1RSh04BNPnu0dTIygX2PE5inltrHiZtTgciKwj9MexT97F4mTR76kIMz5SGNZe3PscQr7g==
sys-RSA2-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1NJVybvb3CQsK8BRsE9Qql1EmPiTFtokkT7YC8OpcY1ONN4UtVcisQObk2aJL/NFnfm3MQzKzPQ8B3hqoY5Vr2wf5amkZYiSUXYC1VHnaw2Pt2Eje+bhwbS5sWW52lKVev2lgP2vpZDah8WAlgdY4IBQfQ4VYNkoKDBgzmBwzQOWQ5eO7CqWp1tJHxvZSDUleMYAz5gCcVJ4ZBv+3lRAQ3r/RCIXPiyDAu2Y/lGHPrP0yuHN9XxU1uHWQKdy1RHXLfal1Oapv31yF8XqNxNG1sjj91S+F5sdkvR6LLdWM481z0otUyY1+68UJIZmxP3UCfsLP1byj7lKZixDxrJvwIDAQAB
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常 false表示直接查询DB.
cache-config: false
oss:
file-root-path: D:/jeepayFiles #存储根路径 ( 无需以‘/’结尾 )
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
file-private-path: ${isys.oss.file-root-path}/private #私有化本地访问不允许url方式公共读取 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
mq:
vender: activeMQ # 切换MQ厂商 支持:【 activeMQ rabbitMQ rocketMQ aliYunRocketMQ 】, 需正确配置 【对应的yml参数】 和 【jeepay-components-mq项目下pom.xml中的依赖包】。

View File

@ -0,0 +1,135 @@
#################################
# 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 #设置端口
servlet:
context-path: / #设置应用的目录. 前缀需要带/, 无需设置后缀, 示例 【 /xxx 】 or 【 / 】
# 数据库的配置项, 自定义配置放置在配置顶层
db-config:
master: #主库配置(必填)
# yml填写url连接串 无需将&符号进行转义
url: jdbc:mysql://127.0.0.1:3306/jeepayplus?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
username: root
password:
encrypt-account: false # 连接账号和密码是否已加密。 truedb的账密需配置密文函数详见 DBProp.main() false: db账密请填写明文
# 连接池配置项
initial-size: 5 #初始化时建立物理连接的个数
min-idle: 5 #最小连接池数量
max-active: 30 #最大连接池数量
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
# 检测相关
test-while-idle: true # 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
validation-query: SELECT 1 FROM DUAL
# 是否缓存preparedStatement
pool-prepared-statements: false # 是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache必须配置大于0当大于0时poolPreparedStatements自动触发修改为true。
# 配置监控统计拦截的filters去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能慢SQL记录
filters: stat,wall
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
# spring-boot组件配置
spring:
servlet:
multipart:
enabled: true #是否启用http上传处理
max-request-size: 10MB #最大请求文件的大小
max-file-size: 10MB #设置单个文件最大长度
resources:
static-locations: classpath:/static #项目静态资源路径 可直接通过http访问
freemarker:
template-loader-path: classpath:/templates #freemarker模板目录
template-encoding: UTF-8
suffix: .ftl
settings:
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
cache:
type: redis
redis:
host: 127.0.0.1
port: 6379
database: 1 #1库运营平台 #2库商户系统 #3库支付网关 #4库代理商
timeout: 1000
password:
sys-prefix-key: PKMGR_ # 作用:不同系统的前缀。 a.当连接不同的database时可以为空(物理隔离) b.当redis集群时因为必须同一个database所以需通过前缀区分不同系统的业务。
# #activeMQ配置 ( 注意: activeMQ配置项需在spring的下级 )
activemq:
broker-url: failover:(tcp://127.0.0.1:61616?wireFormat.maxInactivityDuration=0) #连接地址
in-memory: false # Jeepay项目不可使用内存模式 需要连接多个消费者。
user: system # activeMQ默认无需账密认证。 打开认证activemq.xml添加simpleAuthenticationPlugin标签账密在credentials.properties文件。
password: manager
pool:
enabled: true
max-connections: 10
idle-timeout: 30000 # 空闲的连接过期时间默认为30秒
#
# #rabbitmq配置 ( 注意: rabbitmq配置项需在spring的下级 )
# rabbitmq:
# addresses: 127.0.0.1:5672
# username: guest
# password: guest
# dynamic: true
# virtual-host: /
## rocketmq配置 ( 注意rocketmq配置项请放置到根目录 不是spring的二级配置 )
#rocketmq:
# name-server: 127.0.0.1:9876
# producer:
# group: JEEPAY-GROUP
## 阿里云rocketmq配置 ( 注意aliyun-rocketmq配置项请放置到根目录 不是spring的二级配置需要阿里云开通rocketMQ产品创建Group和Topic )
#aliyun-rocketmq:
# namesrvAddr: xxx
# accessKey: xxx
# secretKey: xxx
# groupIdPrefix: GID_JEEPAY_ # (分组前缀, 具体名称详见AliyunRocketMQFactory.java )
#日志配置参数。
# 当存在logback-spring.xml文件时 该配置将引进到logback配置 springboot配置不生效。
# 不存在logback-spring.xml 文件时, 使用springboot的配置 同样可用。
logging:
level:
root: info #主日志级别
#系统业务参数
isys:
jwt-secret: t7w3P8X6472qWc3u #生成jwt的秘钥。 要求每个系统有单独的秘钥管理机制。
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
http-message-encrypt-secret: 1234567890123456 #web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
# 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更!
sys-RSA2-private-key: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCLU0lXJu9vcJCwrwFGwT1CqXUSY+JMW2iSRPtgLw6lxjU403hS1VyKxA5uTZokv80Wd+bcxDMrM9DwHeGqhjlWvbB/lqaRliJJRdgLVUedrDY+3YSN75uHBtLmxZbnaUpV6/aWA/a+lkNqHxYCWB1jggFB9DhVg2SgoMGDOYHDNA5ZDl47sKpanW0kfG9lINSV4xgDPmAJxUnhkG/7eVEBDev9EIhc+LIMC7Zj+UYc+s/TK4c31fFTW4dZAp3LVEdct9qXU5qm/fXIXxeo3E0bWyOP3VL4Xmx2S9Host1YzjzXPSi1TJjX7rxQkhmbE/dQJ+ws/VvKPuUpmLEPGsm/AgMBAAECggEBAIONCFq58KoQZw3ssA/WtbkTt+69URc31+0EJTYUOIheNjKJubq8qrx7kgSkUT8RutvUKq+YsZfBPS77h/Ay/EDiqpxN6sjcMVNuFyfcRdqimDWTg21hKEC+OLSdLHcj+4RVYGcVJw2dY9n3sBhWiqlCP12+8tILViA0qYL18YgVYJM3bL2MCXfUnm8/Rn1ut5LuDtU/UuaVz9vuCqNirZJedZx3WEq69ZRt9m44XN934NikbUGxQRlz32WRXDo+ssSTu3174UbDYc8nhqO0jUvuzfjOOMf9NYRJsgqVihxMLvvMaUhEE3w6qZPLMj6KhTiG5QHexBbyLgDxH4TZ4gECgYEAz7vZFMoKYifCi+eFykH/ad8QYYoYLlrU1EN2fpIJqwSHZbpBfB8NM5Ov26xU/aNHGKxtSOrUFva5sWub5f9OlsOAmaUOPuVuaJbsq+e3cNQ41jBcdppGJLNx1p/69zR1rF9TbI9Ambd8sOgX3OZmImA2Ldlk2KvMKRruxwc4uN8CgYEAq7J0u5KTwI3PxENLWQ/6tOBNdbCoyqFM+FdANVHRA4dhhdoJ1x0bpdt3tapPFJTBURSEspNxPl4iT+GdpoF6KwqTsQFmB5TLlfx8wY9SIc+sI/ifZvMA5Dv8vVfYWNig7rGV+vIyJCCNbJ5OMa1xvxTDc7Dx4XPxcJ4sR1ZyqyECgYAe447O8ZADsmfSR9X0EkY5ZurXpiIcWnNFMNbg0TRQ0raTYNO18iQTZEWFA6YLpQjAWXtSmWB6HavU/uxKkeEMt/taXVm17oWxVafRk/4J7/SXnM9S73O4p1opENbPhWRuAiq0fMSdVtRatdg+h5/uQqIrxSSit0D/Z7rTq3Y6vwKBgQCd8AlbJckOHiTZd8GOypkm2xHFydxqkJfZ9YCVy44Fvfnig5/7pcXx+oEStfgKiY+OQt6R2fkYksTjUDmRmZbEkvUqpIuzO5dOf7RO5MR7X6oMaL5QmAXg7KFflrfnelYHW4oIDdQ70UnmeXSaU97HE5V7DXBioCGfI5C9inLuoQKBgQCwJmQ2heyTbG1DIBuqf+GFXLuOp76M/7S9c+5R7yfxyTzAbiKRIPeSF5wlxNXEnGwK7qB9CmctlBdnV7A0qnZVFMXf7AbBDUzOCjiy1RSh04BNPnu0dTIygX2PE5inltrHiZtTgciKwj9MexT97F4mTR76kIMz5SGNZe3PscQr7g==
sys-RSA2-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1NJVybvb3CQsK8BRsE9Qql1EmPiTFtokkT7YC8OpcY1ONN4UtVcisQObk2aJL/NFnfm3MQzKzPQ8B3hqoY5Vr2wf5amkZYiSUXYC1VHnaw2Pt2Eje+bhwbS5sWW52lKVev2lgP2vpZDah8WAlgdY4IBQfQ4VYNkoKDBgzmBwzQOWQ5eO7CqWp1tJHxvZSDUleMYAz5gCcVJ4ZBv+3lRAQ3r/RCIXPiyDAu2Y/lGHPrP0yuHN9XxU1uHWQKdy1RHXLfal1Oapv31yF8XqNxNG1sjj91S+F5sdkvR6LLdWM481z0otUyY1+68UJIZmxP3UCfsLP1byj7lKZixDxrJvwIDAQAB
#是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时应开启此配置或在nginx统一配置允许跨域]
allow-cors: true
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常 false表示直接查询DB.
cache-config: false
oss:
file-root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
file-private-path: ${isys.oss.file-root-path}/private #私有化本地访问不允许url方式公共读取 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
mq:
vender: activeMQ # 切换MQ厂商 支持:【 activeMQ rabbitMQ rocketMQ aliYunRocketMQ 】, 需正确配置 【对应的yml参数】 和 【jeepay-components-mq项目下pom.xml中的依赖包】。

146
conf/member/application.yml Normal file
View File

@ -0,0 +1,146 @@
#################################
# 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: 9221 #设置端口
servlet:
context-path: / #设置应用的目录. 前缀需要带/, 无需设置后缀, 示例 【 /xxx 】 or 【 / 】
# 数据库的配置项, 自定义配置放置在配置顶层
db-config:
master: #主库配置(必填)
# yml填写url连接串 无需将&符号进行转义
url: jdbc:mysql://127.0.0.1:3306/jeepayplus?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
username: root
password:
encrypt-account: false # 连接账号和密码是否已加密。 truedb的账密需配置密文函数详见 DBProp.main() false: db账密请填写明文
# 连接池配置项
initial-size: 5 #初始化时建立物理连接的个数
min-idle: 5 #最小连接池数量
max-active: 30 #最大连接池数量
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
# 检测相关
test-while-idle: true # 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
validation-query: SELECT 1 FROM DUAL
# 是否缓存preparedStatement
pool-prepared-statements: false # 是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache必须配置大于0当大于0时poolPreparedStatements自动触发修改为true。
# 配置监控统计拦截的filters去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能慢SQL记录
filters: stat,wall
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
# spring-boot组件配置
spring:
servlet:
multipart:
enabled: true #是否启用http上传处理
max-request-size: 10MB #最大请求文件的大小
max-file-size: 10MB #设置单个文件最大长度
resources:
static-locations: classpath:/static #项目静态资源路径 可直接通过http访问
freemarker:
template-loader-path: classpath:/templates #freemarker模板目录
template-encoding: UTF-8
suffix: .ftl
settings:
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
cache:
type: redis
redis:
host: 127.0.0.1
port: 6379
database: 5 #1库运营平台 #2库商户系统 #3库支付网关 #4库代理商 #5库会员
timeout: 1000
password:
sys-prefix-key: PKMBR_ # 作用:不同系统的前缀。 a.当连接不同的database时可以为空(物理隔离) b.当redis集群时因为必须同一个database所以需通过前缀区分不同系统的业务。
# #activeMQ配置 ( 注意: activeMQ配置项需在spring的下级 )
activemq:
broker-url: failover:(tcp://127.0.0.1:61616?wireFormat.maxInactivityDuration=0) #连接地址
in-memory: false # Jeepay项目不可使用内存模式 需要连接多个消费者。
user: system # activeMQ默认无需账密认证。 打开认证activemq.xml添加simpleAuthenticationPlugin标签账密在credentials.properties文件。
password: manager
pool:
enabled: true
max-connections: 10
idle-timeout: 30000 # 空闲的连接过期时间默认为30秒
#
# #rabbitmq配置 ( 注意: rabbitmq配置项需在spring的下级 )
# rabbitmq:
# addresses: 127.0.0.1:5672
# username: guest
# password: guest
# dynamic: true
# virtual-host: /
## rocketmq配置 ( 注意rocketmq配置项请放置到根目录 不是spring的二级配置 )
#rocketmq:
# name-server: 127.0.0.1:9876
# producer:
# group: JEEPAY-GROUP
## 阿里云rocketmq配置 ( 注意aliyun-rocketmq配置项请放置到根目录 不是spring的二级配置需要阿里云开通rocketMQ产品创建Group和Topic )
#aliyun-rocketmq:
# namesrvAddr: xxx
# accessKey: xxx
# secretKey: xxx
# groupIdPrefix: GID_JEEPAY_ # (分组前缀, 具体名称详见AliyunRocketMQFactory.java )
#日志配置参数。
# 当存在logback-spring.xml文件时 该配置将引进到logback配置 springboot配置不生效。
# 不存在logback-spring.xml 文件时, 使用springboot的配置 同样可用。
logging:
level:
root: info #主日志级别
# xxl-job 执行器配置项
xxl-job:
executor:
admin-address: http://127.0.0.1:9300/xxl-job-admin # 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
access-token: jeepayTaskToken@2022 # 执行器通讯TOKEN
appname: jeepay-plus-member-executor # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
port: 9321 # 执行器端口号 [选填]小于等于0则自动获取默认端口为9999单机部署多个执行器时注意要配置不同执行器端口
log-path: ${logging.file.path} # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
logretentiondays: 7 # 执行器日志文件保存天数 [选填] 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
#系统业务参数
isys:
jwt-secret: zCfdYJepLgVLBw3c #生成jwt的秘钥。 要求每个系统有单独的秘钥管理机制。
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
http-message-encrypt-secret: 1234567890123456 #web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
# 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更!
sys-RSA2-private-key: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCLU0lXJu9vcJCwrwFGwT1CqXUSY+JMW2iSRPtgLw6lxjU403hS1VyKxA5uTZokv80Wd+bcxDMrM9DwHeGqhjlWvbB/lqaRliJJRdgLVUedrDY+3YSN75uHBtLmxZbnaUpV6/aWA/a+lkNqHxYCWB1jggFB9DhVg2SgoMGDOYHDNA5ZDl47sKpanW0kfG9lINSV4xgDPmAJxUnhkG/7eVEBDev9EIhc+LIMC7Zj+UYc+s/TK4c31fFTW4dZAp3LVEdct9qXU5qm/fXIXxeo3E0bWyOP3VL4Xmx2S9Host1YzjzXPSi1TJjX7rxQkhmbE/dQJ+ws/VvKPuUpmLEPGsm/AgMBAAECggEBAIONCFq58KoQZw3ssA/WtbkTt+69URc31+0EJTYUOIheNjKJubq8qrx7kgSkUT8RutvUKq+YsZfBPS77h/Ay/EDiqpxN6sjcMVNuFyfcRdqimDWTg21hKEC+OLSdLHcj+4RVYGcVJw2dY9n3sBhWiqlCP12+8tILViA0qYL18YgVYJM3bL2MCXfUnm8/Rn1ut5LuDtU/UuaVz9vuCqNirZJedZx3WEq69ZRt9m44XN934NikbUGxQRlz32WRXDo+ssSTu3174UbDYc8nhqO0jUvuzfjOOMf9NYRJsgqVihxMLvvMaUhEE3w6qZPLMj6KhTiG5QHexBbyLgDxH4TZ4gECgYEAz7vZFMoKYifCi+eFykH/ad8QYYoYLlrU1EN2fpIJqwSHZbpBfB8NM5Ov26xU/aNHGKxtSOrUFva5sWub5f9OlsOAmaUOPuVuaJbsq+e3cNQ41jBcdppGJLNx1p/69zR1rF9TbI9Ambd8sOgX3OZmImA2Ldlk2KvMKRruxwc4uN8CgYEAq7J0u5KTwI3PxENLWQ/6tOBNdbCoyqFM+FdANVHRA4dhhdoJ1x0bpdt3tapPFJTBURSEspNxPl4iT+GdpoF6KwqTsQFmB5TLlfx8wY9SIc+sI/ifZvMA5Dv8vVfYWNig7rGV+vIyJCCNbJ5OMa1xvxTDc7Dx4XPxcJ4sR1ZyqyECgYAe447O8ZADsmfSR9X0EkY5ZurXpiIcWnNFMNbg0TRQ0raTYNO18iQTZEWFA6YLpQjAWXtSmWB6HavU/uxKkeEMt/taXVm17oWxVafRk/4J7/SXnM9S73O4p1opENbPhWRuAiq0fMSdVtRatdg+h5/uQqIrxSSit0D/Z7rTq3Y6vwKBgQCd8AlbJckOHiTZd8GOypkm2xHFydxqkJfZ9YCVy44Fvfnig5/7pcXx+oEStfgKiY+OQt6R2fkYksTjUDmRmZbEkvUqpIuzO5dOf7RO5MR7X6oMaL5QmAXg7KFflrfnelYHW4oIDdQ70UnmeXSaU97HE5V7DXBioCGfI5C9inLuoQKBgQCwJmQ2heyTbG1DIBuqf+GFXLuOp76M/7S9c+5R7yfxyTzAbiKRIPeSF5wlxNXEnGwK7qB9CmctlBdnV7A0qnZVFMXf7AbBDUzOCjiy1RSh04BNPnu0dTIygX2PE5inltrHiZtTgciKwj9MexT97F4mTR76kIMz5SGNZe3PscQr7g==
sys-RSA2-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1NJVybvb3CQsK8BRsE9Qql1EmPiTFtokkT7YC8OpcY1ONN4UtVcisQObk2aJL/NFnfm3MQzKzPQ8B3hqoY5Vr2wf5amkZYiSUXYC1VHnaw2Pt2Eje+bhwbS5sWW52lKVev2lgP2vpZDah8WAlgdY4IBQfQ4VYNkoKDBgzmBwzQOWQ5eO7CqWp1tJHxvZSDUleMYAz5gCcVJ4ZBv+3lRAQ3r/RCIXPiyDAu2Y/lGHPrP0yuHN9XxU1uHWQKdy1RHXLfal1Oapv31yF8XqNxNG1sjj91S+F5sdkvR6LLdWM481z0otUyY1+68UJIZmxP3UCfsLP1byj7lKZixDxrJvwIDAQAB
#是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时应开启此配置或在nginx统一配置允许跨域]
allow-cors: true
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常 false表示直接查询DB.
cache-config: false
oss:
file-root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
file-private-path: ${isys.oss.file-root-path}/private #私有化本地访问不允许url方式公共读取 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
mq:
vender: activeMQ # 切换MQ厂商 支持:【 activeMQ rabbitMQ rocketMQ aliYunRocketMQ 】, 需正确配置 【对应的yml参数】 和 【jeepay-components-mq项目下pom.xml中的依赖包】。

View File

@ -0,0 +1,136 @@
#################################
# 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 #设置端口
servlet:
context-path: / #设置应用的目录. 前缀需要带/, 无需设置后缀, 示例 【 /xxx 】 or 【 / 】
# 数据库的配置项, 自定义配置放置在配置顶层
db-config:
master: #主库配置(必填)
# yml填写url连接串 无需将&符号进行转义
url: jdbc:mysql://127.0.0.1:3306/jeepayplus?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
username: root
password:
encrypt-account: false # 连接账号和密码是否已加密。 truedb的账密需配置密文函数详见 DBProp.main() false: db账密请填写明文
# 连接池配置项
initial-size: 5 #初始化时建立物理连接的个数
min-idle: 5 #最小连接池数量
max-active: 30 #最大连接池数量
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
# 检测相关
test-while-idle: true # 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
validation-query: SELECT 1 FROM DUAL
# 是否缓存preparedStatement
pool-prepared-statements: false # 是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache必须配置大于0当大于0时poolPreparedStatements自动触发修改为true。
# 配置监控统计拦截的filters去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能慢SQL记录
filters: stat,wall
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
# spring-boot组件配置
spring:
servlet:
multipart:
enabled: true #是否启用http上传处理
max-request-size: 10MB #最大请求文件的大小
max-file-size: 10MB #设置单个文件最大长度
resources:
static-locations: classpath:/static #项目静态资源路径 可直接通过http访问
freemarker:
template-loader-path: classpath:/templates #freemarker模板目录
template-encoding: UTF-8
suffix: .ftl
settings:
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
cache:
type: redis
redis:
host: 127.0.0.1
port: 6379
database: 2 #1库运营平台 #2库商户系统 #3库支付网关 #4库代理商
timeout: 1000
password:
sys-prefix-key: PKMCH_ # 作用:不同系统的前缀。 a.当连接不同的database时可以为空(物理隔离) b.当redis集群时因为必须同一个database所以需通过前缀区分不同系统的业务。
# #activeMQ配置 ( 注意: activeMQ配置项需在spring的下级 )
activemq:
broker-url: failover:(tcp://127.0.0.1:61616?wireFormat.maxInactivityDuration=0) #连接地址
in-memory: false # Jeepay项目不可使用内存模式 需要连接多个消费者。
user: system # activeMQ默认无需账密认证。 打开认证activemq.xml添加simpleAuthenticationPlugin标签账密在credentials.properties文件。
password: manager
pool:
enabled: true
max-connections: 10
idle-timeout: 30000 # 空闲的连接过期时间默认为30秒
#
# #rabbitmq配置 ( 注意: rabbitmq配置项需在spring的下级 )
# rabbitmq:
# addresses: 127.0.0.1:5672
# username: guest
# password: guest
# dynamic: true
# virtual-host: /
## rocketmq配置 ( 注意rocketmq配置项请放置到根目录 不是spring的二级配置 )
#rocketmq:
# name-server: 127.0.0.1:9876
# producer:
# group: JEEPAY-GROUP
## 阿里云rocketmq配置 ( 注意aliyun-rocketmq配置项请放置到根目录 不是spring的二级配置需要阿里云开通rocketMQ产品创建Group和Topic )
#aliyun-rocketmq:
# namesrvAddr: xxx
# accessKey: xxx
# secretKey: xxx
# groupIdPrefix: GID_JEEPAY_ # (分组前缀, 具体名称详见AliyunRocketMQFactory.java )
#日志配置参数。
# 当存在logback-spring.xml文件时 该配置将引进到logback配置 springboot配置不生效。
# 不存在logback-spring.xml 文件时, 使用springboot的配置 同样可用。
logging:
level:
root: info #主日志级别
#系统业务参数
isys:
jwt-secret: ARNXp4MzjOOQqxtv #生成jwt的秘钥。 要求每个系统有单独的秘钥管理机制。
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
http-message-encrypt-secret: 1234567890123456 #web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
# 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更!
sys-RSA2-private-key: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCLU0lXJu9vcJCwrwFGwT1CqXUSY+JMW2iSRPtgLw6lxjU403hS1VyKxA5uTZokv80Wd+bcxDMrM9DwHeGqhjlWvbB/lqaRliJJRdgLVUedrDY+3YSN75uHBtLmxZbnaUpV6/aWA/a+lkNqHxYCWB1jggFB9DhVg2SgoMGDOYHDNA5ZDl47sKpanW0kfG9lINSV4xgDPmAJxUnhkG/7eVEBDev9EIhc+LIMC7Zj+UYc+s/TK4c31fFTW4dZAp3LVEdct9qXU5qm/fXIXxeo3E0bWyOP3VL4Xmx2S9Host1YzjzXPSi1TJjX7rxQkhmbE/dQJ+ws/VvKPuUpmLEPGsm/AgMBAAECggEBAIONCFq58KoQZw3ssA/WtbkTt+69URc31+0EJTYUOIheNjKJubq8qrx7kgSkUT8RutvUKq+YsZfBPS77h/Ay/EDiqpxN6sjcMVNuFyfcRdqimDWTg21hKEC+OLSdLHcj+4RVYGcVJw2dY9n3sBhWiqlCP12+8tILViA0qYL18YgVYJM3bL2MCXfUnm8/Rn1ut5LuDtU/UuaVz9vuCqNirZJedZx3WEq69ZRt9m44XN934NikbUGxQRlz32WRXDo+ssSTu3174UbDYc8nhqO0jUvuzfjOOMf9NYRJsgqVihxMLvvMaUhEE3w6qZPLMj6KhTiG5QHexBbyLgDxH4TZ4gECgYEAz7vZFMoKYifCi+eFykH/ad8QYYoYLlrU1EN2fpIJqwSHZbpBfB8NM5Ov26xU/aNHGKxtSOrUFva5sWub5f9OlsOAmaUOPuVuaJbsq+e3cNQ41jBcdppGJLNx1p/69zR1rF9TbI9Ambd8sOgX3OZmImA2Ldlk2KvMKRruxwc4uN8CgYEAq7J0u5KTwI3PxENLWQ/6tOBNdbCoyqFM+FdANVHRA4dhhdoJ1x0bpdt3tapPFJTBURSEspNxPl4iT+GdpoF6KwqTsQFmB5TLlfx8wY9SIc+sI/ifZvMA5Dv8vVfYWNig7rGV+vIyJCCNbJ5OMa1xvxTDc7Dx4XPxcJ4sR1ZyqyECgYAe447O8ZADsmfSR9X0EkY5ZurXpiIcWnNFMNbg0TRQ0raTYNO18iQTZEWFA6YLpQjAWXtSmWB6HavU/uxKkeEMt/taXVm17oWxVafRk/4J7/SXnM9S73O4p1opENbPhWRuAiq0fMSdVtRatdg+h5/uQqIrxSSit0D/Z7rTq3Y6vwKBgQCd8AlbJckOHiTZd8GOypkm2xHFydxqkJfZ9YCVy44Fvfnig5/7pcXx+oEStfgKiY+OQt6R2fkYksTjUDmRmZbEkvUqpIuzO5dOf7RO5MR7X6oMaL5QmAXg7KFflrfnelYHW4oIDdQ70UnmeXSaU97HE5V7DXBioCGfI5C9inLuoQKBgQCwJmQ2heyTbG1DIBuqf+GFXLuOp76M/7S9c+5R7yfxyTzAbiKRIPeSF5wlxNXEnGwK7qB9CmctlBdnV7A0qnZVFMXf7AbBDUzOCjiy1RSh04BNPnu0dTIygX2PE5inltrHiZtTgciKwj9MexT97F4mTR76kIMz5SGNZe3PscQr7g==
sys-RSA2-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1NJVybvb3CQsK8BRsE9Qql1EmPiTFtokkT7YC8OpcY1ONN4UtVcisQObk2aJL/NFnfm3MQzKzPQ8B3hqoY5Vr2wf5amkZYiSUXYC1VHnaw2Pt2Eje+bhwbS5sWW52lKVev2lgP2vpZDah8WAlgdY4IBQfQ4VYNkoKDBgzmBwzQOWQ5eO7CqWp1tJHxvZSDUleMYAz5gCcVJ4ZBv+3lRAQ3r/RCIXPiyDAu2Y/lGHPrP0yuHN9XxU1uHWQKdy1RHXLfal1Oapv31yF8XqNxNG1sjj91S+F5sdkvR6LLdWM481z0otUyY1+68UJIZmxP3UCfsLP1byj7lKZixDxrJvwIDAQAB
#是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时应开启此配置或在nginx统一配置允许跨域]
allow-cors: true
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常 false表示直接查询DB.
cache-config: false
oss:
file-root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
file-private-path: ${isys.oss.file-root-path}/private #私有化本地访问不允许url方式公共读取 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
mq:
vender: activeMQ # 切换MQ厂商 支持:【 activeMQ rabbitMQ rocketMQ aliYunRocketMQ 】, 需正确配置 【对应的yml参数】 和 【jeepay-components-mq项目下pom.xml中的依赖包】。

View File

@ -0,0 +1,146 @@
#################################
# 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 #设置端口
servlet:
context-path: / #设置应用的目录. 前缀需要带/, 无需设置后缀, 示例 【 /xxx 】 or 【 / 】
# 数据库的配置项, 自定义配置放置在配置顶层
db-config:
master: #主库配置(必填)
# yml填写url连接串 无需将&符号进行转义
url: jdbc:mysql://127.0.0.1:3306/jeepayplus?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
username: root
password:
encrypt-account: false # 连接账号和密码是否已加密。 truedb的账密需配置密文函数详见 DBProp.main() false: db账密请填写明文
# 连接池配置项
initial-size: 5 #初始化时建立物理连接的个数
min-idle: 5 #最小连接池数量
max-active: 30 #最大连接池数量
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
# 检测相关
test-while-idle: true # 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
validation-query: SELECT 1 FROM DUAL
# 是否缓存preparedStatement
pool-prepared-statements: false # 是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache必须配置大于0当大于0时poolPreparedStatements自动触发修改为true。
# 配置监控统计拦截的filters去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能慢SQL记录
filters: stat,wall
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
# spring-boot组件配置
spring:
servlet:
multipart:
enabled: true #是否启用http上传处理
max-request-size: 10MB #最大请求文件的大小
max-file-size: 10MB #设置单个文件最大长度
resources:
static-locations: classpath:/static #项目静态资源路径 可直接通过http访问
freemarker:
template-loader-path: classpath:/templates #freemarker模板目录
template-encoding: UTF-8
suffix: .ftl
settings:
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
cache:
type: redis
redis:
host: 127.0.0.1
port: 6379
database: 3 #1库运营平台 #2库商户系统 #3库支付网关 #4库代理商
timeout: 1000
password:
sys-prefix-key: PKPAY_ # 作用:不同系统的前缀。 a.当连接不同的database时可以为空(物理隔离) b.当redis集群时因为必须同一个database所以需通过前缀区分不同系统的业务。
# #activeMQ配置 ( 注意: activeMQ配置项需在spring的下级 )
activemq:
broker-url: failover:(tcp://127.0.0.1:61616?wireFormat.maxInactivityDuration=0) #连接地址
in-memory: false # Jeepay项目不可使用内存模式 需要连接多个消费者。
user: system # activeMQ默认无需账密认证。 打开认证activemq.xml添加simpleAuthenticationPlugin标签账密在credentials.properties文件。
password: manager
pool:
enabled: true
max-connections: 10
idle-timeout: 30000 # 空闲的连接过期时间默认为30秒
#
# #rabbitmq配置 ( 注意: rabbitmq配置项需在spring的下级 )
# rabbitmq:
# addresses: 127.0.0.1:5672
# username: guest
# password: guest
# dynamic: true
# virtual-host: /
## rocketmq配置 ( 注意rocketmq配置项请放置到根目录 不是spring的二级配置 )
#rocketmq:
# name-server: 127.0.0.1:9876
# producer:
# group: JEEPAY-GROUP
## 阿里云rocketmq配置 ( 注意aliyun-rocketmq配置项请放置到根目录 不是spring的二级配置需要阿里云开通rocketMQ产品创建Group和Topic )
#aliyun-rocketmq:
# namesrvAddr: xxx
# accessKey: xxx
# secretKey: xxx
# groupIdPrefix: GID_JEEPAY_ # (分组前缀, 具体名称详见AliyunRocketMQFactory.java )
#日志配置参数。
# 当存在logback-spring.xml文件时 该配置将引进到logback配置 springboot配置不生效。
# 不存在logback-spring.xml 文件时, 使用springboot的配置 同样可用。
logging:
level:
root: info #主日志级别
# xxl-job 执行器配置项
xxl-job:
executor:
admin-address: http://127.0.0.1:9300/xxl-job-admin # 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
access-token: jeepayTaskToken@2022 # 执行器通讯TOKEN
appname: jeepay-plus-executor # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
port: 9316 # 执行器端口号 [选填]小于等于0则自动获取默认端口为9999单机部署多个执行器时注意要配置不同执行器端口
log-path: ${logging.file.path} # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
logretentiondays: 7 # 执行器日志文件保存天数 [选填] 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
#系统业务参数
isys:
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
http-message-encrypt-secret: 1234567890123456 #web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
# 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更!
sys-RSA2-private-key: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCLU0lXJu9vcJCwrwFGwT1CqXUSY+JMW2iSRPtgLw6lxjU403hS1VyKxA5uTZokv80Wd+bcxDMrM9DwHeGqhjlWvbB/lqaRliJJRdgLVUedrDY+3YSN75uHBtLmxZbnaUpV6/aWA/a+lkNqHxYCWB1jggFB9DhVg2SgoMGDOYHDNA5ZDl47sKpanW0kfG9lINSV4xgDPmAJxUnhkG/7eVEBDev9EIhc+LIMC7Zj+UYc+s/TK4c31fFTW4dZAp3LVEdct9qXU5qm/fXIXxeo3E0bWyOP3VL4Xmx2S9Host1YzjzXPSi1TJjX7rxQkhmbE/dQJ+ws/VvKPuUpmLEPGsm/AgMBAAECggEBAIONCFq58KoQZw3ssA/WtbkTt+69URc31+0EJTYUOIheNjKJubq8qrx7kgSkUT8RutvUKq+YsZfBPS77h/Ay/EDiqpxN6sjcMVNuFyfcRdqimDWTg21hKEC+OLSdLHcj+4RVYGcVJw2dY9n3sBhWiqlCP12+8tILViA0qYL18YgVYJM3bL2MCXfUnm8/Rn1ut5LuDtU/UuaVz9vuCqNirZJedZx3WEq69ZRt9m44XN934NikbUGxQRlz32WRXDo+ssSTu3174UbDYc8nhqO0jUvuzfjOOMf9NYRJsgqVihxMLvvMaUhEE3w6qZPLMj6KhTiG5QHexBbyLgDxH4TZ4gECgYEAz7vZFMoKYifCi+eFykH/ad8QYYoYLlrU1EN2fpIJqwSHZbpBfB8NM5Ov26xU/aNHGKxtSOrUFva5sWub5f9OlsOAmaUOPuVuaJbsq+e3cNQ41jBcdppGJLNx1p/69zR1rF9TbI9Ambd8sOgX3OZmImA2Ldlk2KvMKRruxwc4uN8CgYEAq7J0u5KTwI3PxENLWQ/6tOBNdbCoyqFM+FdANVHRA4dhhdoJ1x0bpdt3tapPFJTBURSEspNxPl4iT+GdpoF6KwqTsQFmB5TLlfx8wY9SIc+sI/ifZvMA5Dv8vVfYWNig7rGV+vIyJCCNbJ5OMa1xvxTDc7Dx4XPxcJ4sR1ZyqyECgYAe447O8ZADsmfSR9X0EkY5ZurXpiIcWnNFMNbg0TRQ0raTYNO18iQTZEWFA6YLpQjAWXtSmWB6HavU/uxKkeEMt/taXVm17oWxVafRk/4J7/SXnM9S73O4p1opENbPhWRuAiq0fMSdVtRatdg+h5/uQqIrxSSit0D/Z7rTq3Y6vwKBgQCd8AlbJckOHiTZd8GOypkm2xHFydxqkJfZ9YCVy44Fvfnig5/7pcXx+oEStfgKiY+OQt6R2fkYksTjUDmRmZbEkvUqpIuzO5dOf7RO5MR7X6oMaL5QmAXg7KFflrfnelYHW4oIDdQ70UnmeXSaU97HE5V7DXBioCGfI5C9inLuoQKBgQCwJmQ2heyTbG1DIBuqf+GFXLuOp76M/7S9c+5R7yfxyTzAbiKRIPeSF5wlxNXEnGwK7qB9CmctlBdnV7A0qnZVFMXf7AbBDUzOCjiy1RSh04BNPnu0dTIygX2PE5inltrHiZtTgciKwj9MexT97F4mTR76kIMz5SGNZe3PscQr7g==
sys-RSA2-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1NJVybvb3CQsK8BRsE9Qql1EmPiTFtokkT7YC8OpcY1ONN4UtVcisQObk2aJL/NFnfm3MQzKzPQ8B3hqoY5Vr2wf5amkZYiSUXYC1VHnaw2Pt2Eje+bhwbS5sWW52lKVev2lgP2vpZDah8WAlgdY4IBQfQ4VYNkoKDBgzmBwzQOWQ5eO7CqWp1tJHxvZSDUleMYAz5gCcVJ4ZBv+3lRAQ3r/RCIXPiyDAu2Y/lGHPrP0yuHN9XxU1uHWQKdy1RHXLfal1Oapv31yF8XqNxNG1sjj91S+F5sdkvR6LLdWM481z0otUyY1+68UJIZmxP3UCfsLP1byj7lKZixDxrJvwIDAQAB
#是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时应开启此配置或在nginx统一配置允许跨域]
allow-cors: true
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常 false表示直接查询DB.
cache-config: false
oss:
file-root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
file-private-path: ${isys.oss.file-root-path}/private #私有化本地访问不允许url方式公共读取 ( 一般配合root-path参数进行设置需以/ 开头, 无需以‘/’结尾 )
mq:
vender: activeMQ # 切换MQ厂商 支持:【 activeMQ rabbitMQ rocketMQ aliYunRocketMQ 】, 需正确配置 【对应的yml参数】 和 【jeepay-components-mq项目下pom.xml中的依赖包】。

20
conf/readme.md Normal file
View File

@ -0,0 +1,20 @@
文件夹用途: 用于放置开发环境的通用配置项和生产环境下的项目配置模板。
1. 【devCommons】
开发环境通用配置文件放置目录。 更改此目录后将覆写 manager/merchant/payment 项目下的application.yml文件对应参数从而达到每个项目不必单独配置的目的更加节约开发时间。
2. 该文件夹下的【manager/merchant/payment】
文件为上线部署时与jar同级目录下的application.yml建议配置项的模板。 需更改为实际参数, 也可按需添加。
扩展知识:
#####################################################
# spring boot支持外部application.yml 读取优先级为:
# 1、file:./config/当前目录下的config文件夹
# 2、file:./(当前目录)
# 3、classpath:/config/classpath下的config目录
# 4、classpath:/classpath根目录
#####################################################

View File

@ -0,0 +1,78 @@
## \u4F7F\u7528\u65B9\u5F0F\uFF1A
# 1. \u8BF7\u590D\u5236\u4E00\u4EFD\u5230\u5F53\u524D\u76EE\u5F55\uFF0C \u5E76\u91CD\u547D\u540D\u4E3A application.properties
# 2. application.properties \u5EFA\u8BAE\u6DFB\u52A0\u5230 gitignore, \u907F\u514D\u6BCF\u4E2A\u5F00\u53D1\u4EBA\u5458\u7684\u73AF\u5883\u4E0D\u540C\u5BFC\u81F4\u591A\u6B21\u65E0\u7528\u63D0\u4EA4\u3002
### web
server.port=9300
server.servlet.context-path=/xxl-job-admin
### xxl-job, datasource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/jeepayplus?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
### xxl-job, access token
xxl.job.accessToken=jeepayTaskToken@2022
### xxl-job, log retention days
xxl.job.logretentiondays=30
### log file path
logging.file.path=./logs
### xxl-job, email
spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=xxx@qq.com
spring.mail.from=xxx@qq.com
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
# \u4EE5\u4E0B\u914D\u7F6E\u6309\u9700\u66F4\u6539
### actuator
management.server.servlet.context-path=/actuator
management.health.mail.enabled=false
### resources
spring.mvc.servlet.load-on-startup=0
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/
### freemarker
spring.freemarker.templateLoaderPath=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8
spring.freemarker.request-context-attribute=request
spring.freemarker.settings.number_format=0.##########
### mybatis
mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml
#mybatis.type-aliases-package=com.xxl.job.admin.core.model
### datasource-pool
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=HikariCP
spring.datasource.hikari.max-lifetime=900000
spring.datasource.hikari.connection-timeout=10000
spring.datasource.hikari.connection-test-query=SELECT 1
spring.datasource.hikari.validation-timeout=1000
### xxl-job, i18n (default is zh_CN, and you can choose "zh_CN", "zh_TC" and "en")
xxl.job.i18n=zh_CN
## xxl-job, triggerpool max size
xxl.job.triggerpool.fast.max=200
xxl.job.triggerpool.slow.max=100

BIN
docs/fonts/字体.7z Normal file

Binary file not shown.

135
docs/script/app.sh Normal file
View File

@ -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 ''

151202
docs/sql/bankBranch.sql Normal file

File diff suppressed because it is too large Load Diff

61
docs/sql/channel.sql Normal file
View File

@ -0,0 +1,61 @@
##### jeeppay-plus S3 支付渠道初始化SQL #####
-- 模拟测试, 会直接响应成功
DELETE FROM t_pay_interface_define WHERE if_code = 'demomockpay';
INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, is_support_applyment, is_open_applyment, is_support_check_bill, is_open_check_bill, is_support_cashout, is_open_cashout, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
VALUES ('demomockpay', '【本地模拟支付通道】', 1, 1, 1, 1, 0, 0, 0, 0, 1,
'[{"name":"accountId","desc":"账号ID","type":"text","verify":"required"}]',
'[{"name":"paySuccessTime","desc":"支付成功时间:: -1失败 0直接成功 5/10/15/20/25/30: 多少x后成功 >30表示等待补单时成功","type":"text","verify":"required"}]',
'[{"name":"paySuccessTime","desc":"支付成功时间:: -1失败 0直接成功 5/10/15/20/25/30: 多少x后成功 >30表示等待补单时成功","type":"text","verify":"required"}]',
'[{"wayCode": "WX_APP"}, {"wayCode": "WX_H5"}, {"wayCode": "WX_NATIVE"}, {"wayCode": "WX_JSAPI"}, {"wayCode": "WX_BAR"}, {"wayCode": "WX_LITE"}, {"wayCode": "ALI_JSAPI"}, {"wayCode": "ALI_WAP"}, {"wayCode": "ALI_BAR"}, {"wayCode": "ALI_APP"}, {"wayCode": "ALI_PC"}, {"wayCode": "ALI_QR"}, {"wayCode": "ALI_LITE"} ]',
'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/xxxxxxx.png', '#04BE02', 1, '【本地模拟支付通道】');
-- 微信官方
DELETE FROM t_pay_interface_define WHERE if_code = 'wxpay';
INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, is_support_applyment, is_open_applyment, is_support_check_bill, is_open_check_bill, is_support_cashout, is_open_cashout, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
VALUES ('wxpay', '微信支付官方', 1, 1, 1, 1, 0, 0, 0, 0, 2,
'[{"name":"mchId", "desc":"微信支付商户号", "type": "text","verify":"required"},{"name":"appId","desc":"应用App ID","type":"text","verify":"required"},{"name":"key", "desc":"API密钥", "type": "textarea","verify":"required","star":"1"},{"name":"apiVersion", "desc":"微信支付API版本", "type": "radio","values":"V2,V3","titles":"V2,V3","verify":"required"},{"name":"apiV3Key", "desc":"API V3秘钥V3接口必填", "type": "textarea","verify":"","star":"1"},{"name":"serialNo", "desc":"序列号V3接口必填", "type": "textarea","verify":"","star":"1"},{"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"},{"name":"subMchLiteAppId","desc":"子商户小程序AppId(置空表示使用服务商)","type":"text"},{"name":"subMchOpenAppId","desc":"子商户App软件微信开放平台中AppId(使用app支付必填)","type":"text"}]',
'[{"name":"mchId", "desc":"微信支付商户号", "type": "text","verify":"required"},{"name":"appId","desc":"应用App ID","type":"text","verify":"required"},{"name":"key", "desc":"API密钥", "type": "textarea","verify":"required","star":"1"},{"name":"apiVersion", "desc":"微信支付API版本", "type": "radio","values":"V2,V3","titles":"V2,V3","verify":"required"},{"name":"apiV3Key", "desc":"API V3秘钥V3接口必填", "type": "textarea","verify":"","star":"1"},{"name":"serialNo", "desc":"序列号V3接口必填", "type": "textarea","verify":"","star":"1" },{"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, '微信官方通道');
-- 支付宝官方
DELETE FROM t_pay_interface_define WHERE if_code = 'alipay';
INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, is_support_applyment, is_open_applyment, is_support_check_bill, is_open_check_bill, is_support_cashout, is_open_cashout, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
VALUES ('alipay', '支付宝官方', 1, 1, 1, 1, 0, 0, 0, 0, 2,
'[{"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","star":"1"},{"name":"alipayPublicKey", "desc":"支付宝公钥(不使用证书时必填)", "type": "textarea","star":"1"},{"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","star":"1"},{"name":"alipayPublicKey", "desc":"支付宝公钥(不使用证书时必填)", "type": "textarea","star":"1"},{"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"}, {"wayCode": "ALI_LITE"}]',
'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/alipay.png', '#1779FF', 1, '支付宝官方通道');
-- 杉德支付
DELETE FROM t_pay_interface_define WHERE if_code = 'sandpay';
INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, is_support_applyment, is_open_applyment, is_support_check_bill, is_open_check_bill, is_support_cashout, is_open_cashout, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
VALUES ('sandpay', '杉德支付', 1, 0, 0, 0, 0, 0, 0, 0, 1,
NULL,
NULL,
'[{"name":"mid","desc":"商户ID","type":"text","verify":"required"},{"name":"publicCert","desc":"杉德公钥文件","type":"file","verify":"required"},{"name":"privateCert","desc":"商户私钥文件","type":"file","verify":"required"},{"name":"privatePassword","desc":"商户私钥密码","type":"text","verify":"required","star":"1"},{"name":"md5Key","desc":"MD5签名key","type":"text","star":"1"},{"name":"key1","desc":"手机APK工具生成的key1","type":"text"}]',
'[{"wayCode":"ALI_BAR"},{"wayCode":"ALI_JSAPI"},{"wayCode":"SAND_H5"}]', 'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/sandpay.png', '#1A2131', 1, '杉德支付');
INSERT INTO t_pay_way (way_code, way_name, way_type) VALUES ('SAND_H5', '杉德H5收银台', 'OTHER');
-- 斗拱支付
DELETE FROM t_pay_interface_define WHERE if_code = 'dgpay';
INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, is_support_applyment, is_open_applyment, is_support_check_bill, is_open_check_bill, is_support_cashout, is_open_cashout, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
VALUES ('dgpay', '斗拱支付', 1, 1, 1, 1, 0, 0, 1, 0, 1,
'[{"name":"payScene","desc":"进件默认支付场景","type":"radio","verify":"required","values":"1,2","titles":"线下,线上"},{"name":"settleCycle","desc":"商户结算周期","type":"radio","verify":"required","values":"T1,D1","titles":"T1,D1"},{"name":"settleFee","desc":"D1结算费率填写值为 0.00-100.00 之间)","type":"text","verify":""},{"name":"mchSettManual","desc":"商户手动取现","type":"radio","verify":"required","values":"0,T1,D1,D0","titles":"关闭,T1,D1,D0"},{"name":"cashFee","desc":"取现费率(填写值为 0.00-100.00 之间)","type":"text","verify":""},{"name":"productId","desc":"产品ID","type":"radio","verify":"required","values":"PAYUN,EDUSTD,KAZX","titles":"PAYUN,EDUSTD,KAZX"},{"name":"sysId","desc":"服务商号","type":"text","verify":"required"},{"name":"wxOpenUrl","desc":"微信渠道拓展二维码URL","type":"text","verify":""},{"name":"aliChannelExtUrl","desc":"支付宝渠道拓展二维码URL","type":"text","verify":""},{"name":"channelNo","desc":"微信渠道号(汇付自定义,指定线上或线下支付场景时必填)","type":"text","verify":""},{"name":"agreementModel","desc":"【电子协议】协议模板号","type":"text","verify":""},{"name":"agreementName","desc":"【电子协议】协议模板名称","type":"text","verify":""},{"name":"rsaPrivateKey","desc":"商户私钥","type":"textarea","verify":"required","star":"1"},{"name":"rsaPublicKey","desc":"斗拱公钥","type":"textarea","verify":"required","star":"1"},{"name":"webhookPrivateKey","desc":"webhook终端秘钥智能POS需配置此项","type":"textarea","verify":"","star":"1"},{"name":"posPublicKey","desc":"智能POS公钥智能POS需配置此项","type":"textarea","verify":"","star":"1"}]',
'[{"name":"payScene","desc":"支付场景","type":"radio","verify":"required","values":"01,02","titles":"线上,线下"},{"name":"huifuId","desc":"商户号","type":"text","verify":"required"},{"name":"tokenNo","desc":"取现卡序列号(提现功能使用)","type":"text","verify":""}]',
'[{"name":"payScene","desc":"支付场景","type":"radio","verify":"required","values":"01,02","titles":"线上,线下"},{"name":"huifuId","desc":"商户号","type":"text","verify":"required"},{"name":"productId","desc":"产品ID","type":"text","verify":"required"},{"name":"rsaPrivateKey","desc":"商户私钥","type":"textarea","verify":"required","star":"1"},{"name":"rsaPublicKey","desc":"斗拱公钥","type":"textarea","verify":"required","star":"1"}]',
'[{"wayCode": "ALI_BAR"}, {"wayCode": "ALI_JSAPI"}, {"wayCode": "ALI_LITE"}, {"wayCode": "ALI_QR"}, {"wayCode": "UP_QR"}, {"wayCode": "WX_BAR"}, {"wayCode": "WX_JSAPI"}, {"wayCode": "WX_LITE"}, {"wayCode": "YSF_JSAPI"}, {"wayCode": "AUTO_POS"}]', 'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/dgpay.svg', '#B5DCFF', 1, '斗拱支付');
-- 银盛支付
DELETE FROM t_pay_interface_define WHERE if_code = 'yspay';
INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, is_support_applyment, is_open_applyment, is_support_check_bill, is_open_check_bill, is_support_cashout, is_open_cashout, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark)
VALUES ('yspay', '银盛支付', 0, 1, 1, 1, 0, 0, 0, 0, 1,
'[{"name":"signType","desc":"加密方式","type":"radio","verify":"required","values":"RSA,SM","titles":"RSA,SM2"},{"name":"settType","desc":"到账方式","type":"radio","verify":"required","values":"1,2,3","titles":"T1,D1,D0"},{"name":"partnerId","desc":"服务商号","type":"text","verify":"required"},{"name":"agtMercId","desc":"代理商编号","type":"text","verify":"required"},{"name":"posPrivateKey","desc":"【智能POS】私钥","type":"text","verify":""},{"name":"wxOpenUrl","desc":"微信渠道拓展二维码URL","type":"text","verify":""},{"name":"wxAppId","desc":"微信公众号/小程序appId","type":"text","verify":""},{"name":"aliChannelExtUrl","desc":"支付宝渠道拓展二维码URL","type":"text","verify":""},{"name":"privateKeyPassword","desc":"私钥证书密码","type":"text","verify":"required"},{"name":"privateKeyFile","desc":"私钥证书(.pfx/.sm2","type":"file","verify":"required"},{"name":"publicKeyFile","desc":"银盛公钥证书(.cer","type":"file","verify":"required"}]',
'[{"name":"mercId","desc":"商户号","type":"text","verify":"required"},{"name":"payType","desc":"商户支付模式","type":"radio","verify":"","values":"1,2","titles":"支付,分账"}]',
'',
'[{"wayCode": "ALI_BAR"}, {"wayCode": "ALI_JSAPI"}, {"wayCode": "ALI_LITE"}, {"wayCode": "ALI_QR"}, {"wayCode": "UP_BAR"}, {"wayCode": "UP_QR"}, {"wayCode": "YSF_JSAPI"}, {"wayCode": "WX_BAR"}, {"wayCode": "WX_JSAPI"}, {"wayCode": "WX_LITE"}]', 'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yspay.svg', '#004DA0', 1, '银盛支付');

2385
docs/sql/init_0.sql Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,670 @@
##### jeeppay-plus S3 支付基础模块 菜单权限初始化SQL #####
-- delete from t_sys_entitlement;
-- 菜单权限表基础数据:
-- match_rule 过滤条件规则: 设置为空,表示没有任何过滤条件, 全部可见。
-- 根据商户级别过滤: {mchLevelArray: ["M1"]} , 设置几级商户可看
-- 商户类型: {mchType: 2} 设置哪种商户类型可见
-- 商户拥有分账管理权限才可见: {mchDivisionEnt: true} 设置哪种商户类型可见
-- 扩展员: { epUserEnt: true } 设置是否扩展员菜单: 当扩展员登录的时候根据此菜单过滤范围进行筛选。
-- 商户便捷收银台菜单过滤配置项: {mchSelfCashierEnt: true} 拥有便捷收银台权限的用户才可见。
-- 商户广告配置菜单过滤配置项: {mchAdvertEnt: true} 拥有广告权限的用户才可见。
-- 商户会员菜单过滤配置项: {mchMemberEnt: true} 拥有会员权限的商户才可见。
-- userEntRules 比如商户用户需要动态切换时使用, 比如 店长、店员 + 动态特殊权限, 关联: t_sys_user_entrule_rela
-- 定义如下:
-- USER_TYPE_11_INIT : 店长默认权限
-- USER_TYPE_12_INIT: 店员默认权限
-- STORE 门店管理权限
-- QUICK_PAY: 快捷收银权限
-- REFUND: 退款权限
-- DEVICE: 设备管理权限
-- STATS: 统计报表权限
-- 运营平台
-- 权限表数据 不包含根目录
insert into t_sys_entitlement values('ENT_COMMONS', '系统通用菜单', 'no-icon', '', 'RouteView', 'MO', 0, 1, 'ROOT', '-1', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_C_USERINFO', '个人中心', 'no-icon', '/current/userinfo', 'CurrentUserInfo', 'MO', 0, 1, 'ENT_COMMONS', '-1', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_C_MAIN', '主页', 'home', '/main', 'MainPage', 'ML', 0, 1, 'ROOT', '1', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_C_MAIN_ISV_MCH_COUNT', '服务商/商户统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_C_MAIN_PAY_DAY_COUNT', '今日/昨日交易统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_C_MAIN_PAY_TREND_COUNT', '趋势图统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_C_MAIN_PAY_COUNT', '主页交易统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_C_MAIN_PAY_TYPE_COUNT', '主页交易方式统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'PLATFORM', null, now(), now());
-- 商户管理
insert into t_sys_entitlement values('ENT_MCH', '商户管理', 'shop', '', 'RouteView', 'ML', 0, 1, 'ROOT', '30', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO', '商户列表', 'profile', '/mch', 'MchListPage', 'ML', 0, 1, 'ENT_MCH', '10', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_LIST', '页面:商户列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_CONFIG_PAGE', '按钮:商户配置信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_CONFIG', '应用配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_CASHIER_URL', '便捷收银台', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SP_OPERATION', '支付宝代运营授权', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_CHANNEL_ACCOUNT', '三方账户管理', 'no-icon', '/channel/account', 'ChannelAccountPage', 'MO', 0, 1, 'ENT_MCH', '-1', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_CHANNEL_CASHOUT', '按钮:提现', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_CHANNEL_ACCOUNT', '0', 'PLATFORM', null, now(), now());
-- 应用管理
insert into t_sys_entitlement values('ENT_MCH_APP', '应用列表', 'appstore', '/apps', 'MchAppPage', 'ML', 0, 1, 'ENT_MCH', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_LIST', '页面:应用列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_PAY_CONFIG', '按钮:支付配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'PLATFORM', null, now(), now());
-- 进件管理
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT', '进件管理', 'schedule', '/applyments', 'MchApplymentListPage', 'ML', 0, 1, 'ENT_MCH', '30', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_LIST', '页面:进件管理列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_ADD', '按钮:发起进件', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_EDIT', '按钮:修改/继续填写', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_VIEW', '按钮:详细信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_PAY_CONFIG', '按钮:参数配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_SIGN', '按钮:自主签约', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_STORE', '按钮:门店入驻', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_GET_INFO', '按钮:获取最新结果', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_PRE_AUDIT', '按钮:预审核', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_IMG_OCR_DETAIL', '功能ocr图片识别', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
-- 门店管理
insert into t_sys_entitlement values('ENT_MCH_STORE', '门店管理', 'profile', '/store', 'StorePage', 'ML', 0, 1, 'ENT_MCH', '40', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_MAP', '按钮:地图配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
-- 蚂蚁店铺
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_STATUS', '按钮:查询审核状态', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
-- 服务商管理
insert into t_sys_entitlement values('ENT_ISV', '服务商管理', 'block', '', 'RouteView', 'ML', 0, 1, 'ROOT', '40', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ISV_INFO', '服务商列表', 'profile', '/isv', 'IsvListPage', 'ML', 0, 1, 'ENT_ISV', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ISV_LIST', '页面:服务商列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ISV_INFO_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ISV_INFO_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ISV_INFO_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ISV_INFO_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ISV_PAY_CONFIG', '按钮:支付配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ISV_INFO', '0', 'PLATFORM', null, now(), now());
-- 佣金管理
insert into t_sys_entitlement values('ENT_PROFIT', '佣金管理', 'wallet', '', 'RouteView', 'ML', 0, 1, 'ROOT', '40', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PROFIT_PLATFORM', '运营佣金统计', 'account-book', '/platformProfits', 'PlatformProfitPage', 'ML', 0, 1, 'ENT_PROFIT', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PROFIT_PLATFORM_LIST', '页面:运营佣金统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PROFIT_PLATFORM', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ACCOUNT_HISTORY', '钱包流水', 'fund-view', '/history', 'HistoryPage', 'ML', 0, 1, 'ENT_PROFIT', '30', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ACCOUNT_HISTORY_LIST', '页面:钱包流水列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ACCOUNT_HISTORY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ACCOUNT_HISTORY_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ACCOUNT_HISTORY', '0', 'PLATFORM', null, now(), now());
-- 订单管理
insert into t_sys_entitlement values('ENT_ORDER', '订单管理', 'transaction', '', 'RouteView', 'ML', 0, 1, 'ROOT', '50', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER', '支付订单', 'account-book', '/pay', 'PayOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ORDER_LIST', '页面:订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER_REFUND', '按钮:订单退款', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER_SEARCH_PAY_WAY', '筛选项:支付方式', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ORDER_COUNT', '支付统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_REFUND_ORDER', '退款订单', 'exception', '/refund', 'RefundOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_REFUND_LIST', '页面:退款订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_REFUND_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement
values ('ENT_REFUND_ORDER_COUNT', '退款统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'PLATFORM', null,
now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER', '转账订单', 'property-safety', '/transfer', 'TransferOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '25', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER_LIST', '页面:转账订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TRANSFER_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TRANSFER_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER_COUNT', '按钮:统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TRANSFER_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_NOTIFY', '商户通知', 'notification', '/notify', 'MchNotifyListPage', 'ML', 0, 1, 'ENT_ORDER', '30', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_NOTIFY_LIST', '页面:商户通知列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTIFY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_NOTIFY_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTIFY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_NOTIFY_RESEND', '按钮:重发通知', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTIFY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHANNEL_CASHOUT', '提现记录', 'pay-circle', '/channel/cashout', 'ChannelCashoutPage', 'ML', 0, 1, 'ENT_ORDER', '40', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHANNEL_CASHOUT_LIST', '页面:提现记录列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHANNEL_CASHOUT', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHANNEL_CASHOUT_RECORD_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHANNEL_CASHOUT', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ZFT_SETT_RECORD', '直付通结算订单', 'account-book', '/settle/zft', 'ZftSettRecordPage', 'ML', 0, 1, 'ENT_ORDER', '50', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ZFT_SETT_RECORD_LIST', '页面:提现记录列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ZFT_SETT_RECORD', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ZFT_SETT_RECORD_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ZFT_SETT_RECORD', '0', 'PLATFORM', null, now(), now());
-- 数据统计
insert into t_sys_entitlement values('ENT_ORDER_STATISTIC', '数据统计', 'bar-chart', '', 'RouteView', 'ML', 0, 1, 'ROOT', '55', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_TRANSACTION', '交易报表', 'account-book', '/statistic/transaction', 'TransactionPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH', '商户统计', 'line-chart', '/statistic/mch', 'MchCountPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH_STORE', '门店统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_STATISTIC_MCH', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH_WAY', '支付方式统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_STATISTIC_MCH', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH_TYPE', '支付类型统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_STATISTIC_MCH', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_ISV', '服务商统计', 'fund', '/statistic/isv', 'IsvCountPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '40', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_CHANNEL', '通道统计', 'project', '/statistic/channel', 'ChannelCountPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '50', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_DEVICE', '设备统计', 'mobile', '/statistic/device', 'DeviceCountPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '60', 'PLATFORM', null, now(), now());
-- 支付配置菜单
insert into t_sys_entitlement values('ENT_PC', '支付配置', 'file-done', '', 'RouteView', 'ML', 0, 1, 'ROOT', '60', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_IF_DEFINE', '支付接口', 'interaction', '/ifdefines', 'IfDefinePage', 'ML', 0, 1, 'ENT_PC', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_LIST', '页面:支付接口定义列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_SEARCH', '页面:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_IF_DEFINE_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_IF_DEFINE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_WAY', '支付方式', 'appstore', '/payways', 'PayWayPage', 'ML', 0, 1, 'ENT_PC', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_WAY_LIST', '页面:支付方式列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_WAY_SEARCH', '页面:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_WAY_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_WAY_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_WAY_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PC_WAY_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PC_WAY', '0', 'PLATFORM', null, now(), now());
-- 分账管理菜单
insert into t_sys_entitlement values('ENT_DIVISION', '分账管理', 'apartment', '', 'RouteView', 'ML', 0, 1, 'ROOT', '65', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP', '账号组管理', 'team', '/divisionReceiverGroup', 'DivisionReceiverGroupPage', 'ML', 0, 1, 'ENT_DIVISION', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER_GROUP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER_GROUP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER_GROUP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER_GROUP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER_GROUP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER', '收款账号管理', 'trademark', '/divisionReceiver', 'DivisionReceiverPage', 'ML', 0, 1, 'ENT_DIVISION', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_ADD', '按钮:新增收款账号', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_DELETE', '按钮:删除收款账号', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_EDIT', '按钮:修改账号信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_CHANNEL_USER', '按钮扫码获取userId', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECORD', '分账记录', 'unordered-list', '/divisionRecord', 'DivisionRecordPage', 'ML', 0, 1, 'ENT_DIVISION', '30', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECORD_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECORD', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECORD_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECORD', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECORD_RESEND', '按钮:重试', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECORD', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_REFUND_RECORD', '分账回退记录', 'node-collapse', '/divisionRefundRecord', 'DivisionRefundRecordPage', 'ML', 0, 1, 'ENT_DIVISION', '40', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_REFUND_RECORD_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_REFUND_RECORD', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_REFUND_RECORD_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_REFUND_RECORD', '0', 'PLATFORM', null, now(), now());
-- 对账管理菜单
insert into t_sys_entitlement values('ENT_CHECK', '对账管理', 'merge-cells', '', 'RouteView', 'ML', 0, 1, 'ROOT', '67', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_BATCH', '对账批次', 'control', '/checkBatch', 'CheckBatchPage', 'ML', 0, 1, 'ENT_CHECK', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_BATCH_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHECK_BATCH', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_BATCH_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHECK_BATCH', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_BATCH_RELOAD', '按钮:重新对账', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHECK_BATCH', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_CHANNEL_BILL', '渠道账单', 'container', '/channelBill', 'CheckChannelBillPage', 'ML', 0, 1, 'ENT_CHECK', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_CHANNEL_BILL_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHECK_CHANNEL_BILL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_CHANNEL_BILL_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHECK_CHANNEL_BILL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_CHANNEL_BILL_COUNT', '按钮:数据统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHECK_CHANNEL_BILL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_DIFF', '差异账单', 'file-unknown', '/diff', 'CheckDiffPage', 'ML', 0, 1, 'ENT_CHECK', '30', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_DIFF_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHECK_DIFF', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_DIFF_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHECK_DIFF', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_DIFF_REISSUE', '按钮:补单', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHECK_DIFF', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CHECK_DIFF_IGNORE', '按钮:忽略差异', 'no-icon', '', '', 'PB', 0, 1, 'ENT_CHECK_DIFF', '0', 'PLATFORM', null, now(), now());
-- 设备管理菜单
insert into t_sys_entitlement values('ENT_DEVICE', '设备配置', 'appstore', '', 'RouteView', 'ML', 0, 1, 'ROOT', '70', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_QRC', '码牌', 'shop', '', 'RouteView', 'ML', 0, 1, 'ENT_DEVICE', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_SHELL', '模板管理', 'file', '/shell', 'QrcodeShellPage', 'ML', 0, 1, 'ENT_QRC', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_SHELL_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC_SHELL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_SHELL_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC_SHELL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_SHELL_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC_SHELL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_SHELL_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC_SHELL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_SHELL_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC_SHELL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC', '码牌管理', 'qrcode', '/qrc', 'QrcodeCardPage', 'ML', 0, 1, 'ENT_QRC', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_ALLOT', '按钮:划拨', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_EXPORT', '按钮:导出', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_SPEAKER', '云喇叭', 'sound', '', 'RouteView', 'ML', 0, 1, 'ENT_DEVICE', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER', '厂商管理', 'setting', '/speaker', 'SpeakerPage', 'ML', 0, 1, 'ENT_SPEAKER', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_LIST', '页面:云喇叭厂商配置列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE', '云喇叭管理', 'file', '/speaker/device', 'SpeakerDevicePage', 'ML', 0, 1, 'ENT_SPEAKER', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_LIST', '页面:云喇叭设备列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_TEST', '按钮:播报测试', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PRINTER', '云打印', 'printer', '', 'RouteView', 'ML', 0, 1, 'ENT_DEVICE', '30', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER', '厂商管理', 'setting', '/printer', 'PrinterPage', 'ML', 0, 1, 'ENT_PRINTER', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_LIST', '页面:云打印列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE', '云打印管理', 'file', '/printer/device', 'PrinterDevicePage', 'ML', 0, 1, 'ENT_PRINTER', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_LIST', '页面:云打印设备列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_TEST', '按钮:打印测试', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_CLEAR', '按钮:清空打印队列', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PLUGIN', '收银插件', 'api', '', 'RouteView', 'ML', 0, 1, 'ENT_DEVICE', '35', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN', '厂商管理', 'setting', '/plugin', 'PluginPage', 'ML', 0, 1, 'ENT_PLUGIN', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY', '激活码管理', 'file', '/plugin/cdkey', 'PluginCdKeyPage', 'ML', 0, 1, 'ENT_PLUGIN', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_POS', '扫码POS', 'scan', '', 'RouteView', 'ML', 0, 1, 'ENT_DEVICE', '40', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS', '厂商管理', 'setting', '/pos', 'PosPage', 'ML', 0, 1, 'ENT_POS', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE', '扫码POS管理', 'file', '/pos/device', 'PosDevicePage', 'ML', 0, 1, 'ENT_POS', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS_DEVICE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS', '智能POS管理', 'file', '/auto/pos', 'AutoPosPage', 'ML', 0, 1, 'ENT_DEVICE', '45', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP', '刷脸设备管理', 'smile', '/face', 'FaceAppPage', 'ML', 0, 1, 'ENT_DEVICE', '47', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL', '辅助终端报备', 'issues-close', '/terminals', 'TerminalPage', 'ML', 0, 1, 'ENT_DEVICE', '50', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_SENDUP', '按钮:报备', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI', '如意Lite管理', 'file', '/ruyi', 'RuyiPage', 'ML', 0, 1, 'ENT_DEVICE', '60', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_BIND', '按钮:绑定蚂蚁店铺', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
-- 系统管理
insert into t_sys_entitlement values('ENT_SYS_CONFIG', '系统管理', 'setting', '', 'RouteView', 'ML', 0, 1, 'ROOT', '200', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR', '用户角色管理', 'team', '', 'RouteView', 'ML', 0, 1, 'ENT_SYS_CONFIG', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER', '操作员管理', 'contacts', '/users', 'SysUserPage', 'ML', 0, 1, 'ENT_UR', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_LIST', '页面:操作员列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_SEARCH', '按钮:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_ADD', '按钮:添加操作员', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_VIEW', '按钮: 详情', '', 'no-icon', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_EDIT', '按钮: 修改基本信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_DELETE', '按钮: 删除操作员', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_UPD_ROLE', '按钮: 角色分配', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_MFA_DELETE', '按钮: MFA解绑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_LOGIN_LIMIT_DELETE', '按钮: 解除登录限制', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM', '团队管理', 'team', '/teams', 'SysUserTeamPage', 'ML', 0, 1, 'ENT_UR', '15', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_LIST', '页面:团队列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_SEARCH', '按钮:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_ADD', '按钮:添加团队', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_VIEW', '按钮: 详情', '', 'no-icon', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_EDIT', '按钮: 修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_DELETE', '按钮: 删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE', '角色管理', 'user', '/roles', 'RolePage', 'ML', 0, 1, 'ENT_UR', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_LIST', '页面:角色列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_SEARCH', '页面:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_ADD', '按钮:添加角色', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_DIST', '按钮: 分配权限', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_EDIT', '按钮: 修改基本信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_DEL', '按钮: 删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_ENT', '权限管理', 'apartment', '/ents', 'EntPage', 'ML', 0, 1, 'ENT_UR', '30', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_ENT_LIST', '页面: 权限列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE_ENT', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_ENT_EDIT', '按钮: 权限变更', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE_ENT', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MANAGE', '数据管理', 'tool', '/statistic/repair', 'RepairPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '12', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_RECORD_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_STATISTIC_MANAGE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_RECORD_VIEW', '按钮:查看', 'no-icon', '', '', 'PB', 0, 1, 'ENT_STATISTIC_MANAGE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_REPAIR', '按钮:数据修复', 'no-icon', '', '', 'PB', 0, 1, 'ENT_STATISTIC_MANAGE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_SYS_CONFIG_INFO', '系统配置', 'setting', '/config', 'SysConfigPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '15', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_SYS_CONFIG_VIEW', '页面:查看', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_CONFIG_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_SYS_CONFIG_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_CONFIG_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_CONTROL', '广告管理', 'message', '/advert', 'AdvertInfoPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '17', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PUSH_CONFIG_INFO', '通知配置', 'notification', '/push', 'PushConfigPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '18', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PUSH_CONFIG_VIEW', '页面:查看', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PUSH_CONFIG_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PUSH_CONFIG_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PUSH_CONFIG_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ARTICLE_NOTICEINFO', '公告管理', 'message', '/notices', 'NoticeInfoPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '19', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_NOTICE_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ARTICLE_NOTICEINFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_NOTICE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ARTICLE_NOTICEINFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_NOTICE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ARTICLE_NOTICEINFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_NOTICE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ARTICLE_NOTICEINFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_NOTICE_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ARTICLE_NOTICEINFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_SYS_LOG', '系统日志', 'file-text', '/log', 'SysLogPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_LOG_LIST', '页面:系统日志列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_LOG', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_SYS_LOG_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_LOG', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_SYS_LOG_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_LOG', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_SYS_CLIENT_VERSION', '版本管理', 'flag', '/version', 'ClientVersionPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '30', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CLIENT_VERSION_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_CLIENT_VERSION', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CLIENT_VERSION_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_CLIENT_VERSION', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CLIENT_VERSION_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_CLIENT_VERSION', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CLIENT_VERSION_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_CLIENT_VERSION', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CLIENT_VERSION_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_SYS_CLIENT_VERSION', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement
values ('ENT_LEGAL_DAY', '节假日管理', 'table', '/legalday', 'LegalDayPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '40',
'PLATFORM', null, now(), now());
insert into t_sys_entitlement
values ('ENT_LEGAL_DAY_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_LEGAL_DAY', '0', 'PLATFORM', null, now(),
now());
insert into t_sys_entitlement
values ('ENT_LEGAL_DAY_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_LEGAL_DAY', '0', 'PLATFORM', null, now(),
now());
insert into t_sys_entitlement
values ('ENT_LEGAL_DAY_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_LEGAL_DAY', '0', 'PLATFORM', null, now(),
now());
-- 【商户系统】 主页
insert into t_sys_entitlement values('ENT_COMMONS', '系统通用菜单', 'no-icon', '', 'RouteView', 'MO', 0, 1, 'ROOT', '-1', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_C_USERINFO', '个人中心', 'no-icon', '/current/userinfo', 'CurrentUserInfo', 'MO', 0, 1, 'ENT_COMMONS', '-1', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_ARTICLE_NOTICEINFO', '公告管理', 'message', '/notices', 'NoticeInfoPage', 'MO', 0, 1, 'ENT_COMMONS', '-1', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_C_QUICKCASHIER', '快捷收银', 'no-icon', '', '', 'PB', 0, 1, 'ENT_COMMONS', '-1', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "QUICK_PAY"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_MAIN', '主页', 'home', '/main', 'MainPage', 'ML', 0, 1, 'ROOT', '1', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "STATS"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_MAIN_PAY_DAY_COUNT', '今日/昨日交易统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_MAIN_PAY_TREND_COUNT', '趋势图统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_MAIN_PAY_COUNT', '主页交易统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_MAIN_PAY_TYPE_COUNT', '主页交易方式统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
-- 【商户系统】 商户中心
insert into t_sys_entitlement values('ENT_MCH_CENTER', '商户中心', 'team', '', 'RouteView', 'ML', 0, 1, 'ROOT', '10', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SP_OPERATION', '支付宝代运营授权', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_CENTER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('AGREEMENT_PAGE_SIGN', '支付宝安全发', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_CENTER', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO', '商户信息', 'user', '/info', 'MchInfoPage', 'ML', 0, 1, 'ENT_MCH_CENTER', '5', 'MCH', '', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP', '应用管理', 'appstore', '/apps', 'MchAppPage', 'ML', 0, 1, 'ENT_MCH_CENTER', '10', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_LIST', '页面:应用列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'MCH', '{mchLevelArray: ["M1"], userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_PAY_CONFIG', '按钮:支付配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_SIGN', '按钮:签名配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_PAY_TEST', '支付测试', 'transaction', '/paytest', 'PayTestPage', 'ML', 0, 1, 'ENT_MCH_CENTER', '20', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_PAY_TEST_PAYWAY_LIST', '页面:获取全部支付方式', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_PAY_TEST', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_PAY_TEST_DO', '按钮:支付测试', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_PAY_TEST', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_CASHIER_URL', '便捷收银台', 'account-book', '/cashierUrl', 'CashierUrlPage', 'ML', 0, 1, 'ENT_MCH_CENTER', '25', 'MCH', '{mchLevelArray: ["M1"], mchSelfCashierEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_GET_CASHIER_URL', '按钮:获取收银台地址', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_CASHIER_URL', '0', 'MCH', '{mchLevelArray: ["M1"], mchSelfCashierEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_TRANSFER', '转账', 'property-safety', '/doTransfer', 'MchTransferPage', 'ML', 0, 1, 'ENT_MCH_CENTER', '30', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_TRANSFER_IF_CODE_LIST', '页面:获取全部代付通道', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_TRANSFER', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_TRANSFER_CHANNEL_USER', '按钮:获取渠道用户', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_TRANSFER', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_TRANSFER_DO', '按钮:发起转账', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_TRANSFER', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
-- 门店管理
insert into t_sys_entitlement values('ENT_MCH_STORE', '门店管理', 'shop', '/store', 'StorePage', 'ML', 0, 1, 'ENT_MCH_CENTER', '40', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_MAP', '按钮:地图配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_APP_DIS', '按钮:分配应用', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
-- 蚂蚁店铺
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_STATUS', '按钮:查询审核状态', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
-- 进件管理
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT', '进件管理', 'schedule', '/applyments', 'MchApplymentListPage', 'ML', 0, 1, 'ENT_MCH_CENTER', '40', 'MCH', '{mchType: 2}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_LIST', '页面:进件管理列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'MCH', '{mchType: 2}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_ADD', '按钮:发起进件', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'MCH', '{mchType: 2}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_EDIT', '按钮:修改/继续填写', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'MCH', '{mchType: 2}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_VIEW', '按钮:详细信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'MCH', '{mchType: 2}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_SIGN', '按钮:自主签约', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'MCH', '{mchType: 2}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_GET_INFO', '按钮:获取最新结果', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'MCH', '{mchType: 2}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_IMG_OCR_DETAIL', '功能ocr图片识别', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'MCH', '{mchType: 2}', now(), now());
-- 【商户系统】 订单管理
insert into t_sys_entitlement values('ENT_ORDER', '订单中心', 'transaction', '', 'RouteView', 'ML', 0, 1, 'ROOT', '20', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER', '订单管理', 'account-book', '/pay', 'PayOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '10', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_ORDER_LIST', '页面:订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER_SEARCH_PAY_WAY', '筛选项:支付方式', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER_REFUND', '按钮:订单退款', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "REFUND"]}', now(), now());
insert into t_sys_entitlement values('ENT_ORDER_COUNT', '支付统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_REFUND_ORDER', '退款记录', 'exception', '/refund', 'RefundOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '20', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_REFUND_LIST', '页面:退款订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_REFUND_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement
values ('ENT_REFUND_ORDER_COUNT', '退款统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'MCH',
'{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER', '转账订单', 'property-safety', '/transfer', 'TransferOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '30', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER_LIST', '页面:转账订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TRANSFER_ORDER', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TRANSFER_ORDER', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER_COUNT', '按钮:统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TRANSFER_ORDER', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
-- 数据统计
insert into t_sys_entitlement values('ENT_ORDER_STATISTIC', '数据统计', 'bar-chart', '', 'RouteView', 'ML', 0, 1, 'ROOT', '25', 'MCH', '{mchLevelArray: ["M1"],userEntRules: ["USER_TYPE_11_INIT", "STATS"]}', now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_TRANSACTION', '交易报表', 'account-book', '/statistic/transaction', 'TransactionPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '5', 'MCH', '{mchLevelArray: ["M1"],userEntRules: ["USER_TYPE_11_INIT", "STATS"]}', now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH_STORE', '门店统计', 'account-book', '/statistic/store', 'StatisticStorePage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '10', 'MCH', '{mchLevelArray: ["M1"],userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH_WAY', '支付方式统计', 'area-chart', '/statistic/way', 'StatisticWayPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '20', 'MCH', '{mchLevelArray: ["M1"],userEntRules: ["USER_TYPE_11_INIT", "STATS"]}', now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH_TYPE', '支付类型统计', 'fund', '/statistic/type', 'StatisticTypePage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '30', 'MCH', '{mchLevelArray: ["M1"],userEntRules: ["USER_TYPE_11_INIT", "STATS"]}', now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_DEVICE', '设备统计', 'mobile', '/statistic/device', 'DeviceCountPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '40', 'MCH', '{mchLevelArray: ["M1"],userEntRules: ["USER_TYPE_11_INIT", "STATS"]}', now(), now());
-- 【商户系统】 分账管理
insert into t_sys_entitlement values('ENT_DIVISION', '分账管理', 'apartment', '', 'RouteView', 'ML', 0, 1, 'ROOT', '30', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP', '账号组管理', 'team', '/divisionReceiverGroup', 'DivisionReceiverGroupPage', 'ML', 0, 1, 'ENT_DIVISION', '10', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER_GROUP', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER_GROUP', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER_GROUP', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER_GROUP', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_GROUP_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER_GROUP', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER', '收款账号管理', 'trademark', '/divisionReceiver', 'DivisionReceiverPage', 'ML', 0, 1, 'ENT_DIVISION', '20', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_ADD', '按钮:新增收款账号', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_DELETE', '按钮:删除收款账号', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECEIVER_EDIT', '按钮:修改账号信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECEIVER', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECORD', '分账记录', 'unordered-list', '/divisionRecord', 'DivisionRecordPage', 'ML', 0, 1, 'ENT_DIVISION', '30', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECORD_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECORD', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECORD_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECORD', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_RECORD_RESEND', '按钮:重试', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_RECORD', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_REFUND_RECORD', '分账回退记录', 'node-collapse', '/divisionRefundRecord', 'DivisionRefundRecordPage', 'ML', 0, 1, 'ENT_DIVISION', '40', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_REFUND_RECORD_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_REFUND_RECORD', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_DIVISION_REFUND_RECORD_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DIVISION_REFUND_RECORD', '0', 'MCH', '{mchLevelArray: ["M1"], mchDivisionEnt: true}', now(), now());
-- 设备管理菜单
insert into t_sys_entitlement values('ENT_DEVICE', '设备管理', 'appstore', '', 'RouteView', 'ML', 0, 1, 'ROOT', '40', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
-- 码牌
insert into t_sys_entitlement values('ENT_MCH_QR_CODE', '码牌', 'qrcode', '/qrCodes', 'MchQrCodePage', 'ML', 0, 1, 'ENT_DEVICE', '10', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_QR_CODE_LIST', '页面:码牌列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_QR_CODE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_QR_CODE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_QR_CODE', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_QR_CODE_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_QR_CODE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_QR_CODE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_QR_CODE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_QR_CODE_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_QR_CODE', '0', 'MCH', null, now(), now());
-- 云喇叭
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER', '云喇叭', 'sound', '/speaker', 'SpeakerPage', 'ML', 0, 1, 'ENT_DEVICE', '20', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_LIST', '页面:云喇叭列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_TEST', '按钮:播报测试', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER', '0', 'MCH', null, now(), now());
-- 云打印
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER', '云打印', 'printer', '/printer', 'PrinterPage', 'ML', 0, 1, 'ENT_DEVICE', '30', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_LIST', '页面:云打印列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVI·CE_PRINTER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_TEST', '按钮:打印测试', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_CLEAR', '按钮:清空打印队列', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER', '0', 'MCH', null, now(), now());
-- 收银插件激活码
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY', '收银插件激活码', 'file', '/plugin/cdkey', 'PluginCdKeyPage', 'ML', 0, 1, 'ENT_DEVICE', '35', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
-- 扫码POS
insert into t_sys_entitlement values('ENT_DEVICE_POS', '扫码POS', 'scan', '/pos', 'PosPage', 'ML', 0, 1, 'ENT_DEVICE', '40', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
-- 智能POS
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS', '智能POS', 'file', '/auto/pos', 'AutoPosPage', 'ML', 0, 1, 'ENT_DEVICE', '45', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
-- 刷脸设备
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP', '刷脸设备', 'smile', '/face', 'FaceAppPage', 'ML', 0, 1, 'ENT_DEVICE', '47', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL', '辅助终端报备', 'issues-close', '/terminals', 'TerminalPage', 'ML', 0, 1, 'ENT_DEVICE', '50', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_SENDUP', '按钮:报备', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'MCH', null, now(), now());
-- 如意Lite
insert into t_sys_entitlement values('ENT_DEVICE_RUYI', '如意Lite管理', 'file', '/ruyi', 'RuyiPage', 'ML', 0, 1, 'ENT_DEVICE', '60', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_BIND', '按钮:绑定蚂蚁店铺', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
-- 【商户系统】 系统管理
insert into t_sys_entitlement values('ENT_SYS_CONFIG', '系统管理', 'setting', '', 'RouteView', 'ML', 0, 1, 'ROOT', '200', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_UR', '用户角色管理', 'team', '', 'RouteView', 'ML', 0, 1, 'ENT_SYS_CONFIG', '10', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_UR_USER', '操作员管理', 'contacts', '/users', 'SysUserPage', 'ML', 0, 1, 'ENT_UR', '10', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_LIST', '页面:操作员列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_SEARCH', '按钮:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_ADD', '按钮:添加操作员', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_VIEW', '按钮: 详情', '', 'no-icon', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_EDIT', '按钮: 修改基本信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_DELETE', '按钮: 删除操作员', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_UPD_ROLE', '按钮: 角色分配', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_MFA_DELETE', '按钮: MFA解绑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_LOGIN_LIMIT_DELETE', '按钮: 解除登录限制', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE', '角色管理', 'user', '/roles', 'RolePage', 'ML', 0, 1, 'ENT_UR', '20', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_LIST', '页面:角色列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_SEARCH', '页面:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_ADD', '按钮:添加角色', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_DIST', '按钮: 分配权限', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_EDIT', '按钮: 修改名称', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_DEL', '按钮: 删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_NOTICE', '通知配置', 'notification', '/notice', 'NoticePage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '40', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_WXMP_USER_LIST', '页面:公众号消息接收人列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTICE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_WXMP_USER_ADD', '按钮:新增公众号消息接收人', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTICE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_WXMP_USER_DELETE', '按钮:删除公众号消息接收人', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTICE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_WXMP_USER_EDIT', '按钮:修改公众号消息接收人', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTICE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_CONTROL', '广告管理', 'message', '/advert', 'AdvertInfoPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '30', 'MCH', '{mchAdvertEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'MCH', '{mchAdvertEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'MCH', '{mchAdvertEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'MCH', '{mchAdvertEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'MCH', '{mchAdvertEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'MCH', '{mchAdvertEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_CONFIG', '系统配置', 'setting', '/config', 'MchConfigPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '50', 'MCH', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_CONFIG_EDIT', '按钮:修改系统配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_CONFIG', '0', 'MCH', null, now(), now());

2278
docs/sql/init_2024-01-10.sql Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,351 @@
##### jeeppay-plus S3 代理商模块 表结构及菜单权限初始化数据SQL #####
-- 代理商信息表
DROP TABLE IF EXISTS t_agent_info;
CREATE TABLE `t_agent_info` (
`agent_no` VARCHAR(64) NOT NULL COMMENT '代理商账号',
`agent_name` VARCHAR(64) NOT NULL COMMENT '代理商名称',
`agent_short_name` VARCHAR(32) NOT NULL COMMENT '代理商简称',
`isv_no` VARCHAR(64) NOT NULL COMMENT '服务商号',
`pid` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '上级代理商号, 空串表示顶级代理商',
`pname` VARCHAR(32) 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-正常, 2-待审核, 3-审核驳回, 4-未认证',
`level` INT(11) NOT NULL DEFAULT 1 COMMENT '代理商等级',
`add_agent_flag` TINYINT(6) NOT NULL DEFAULT 0 COMMENT '是否允许发展子代理: 0-不允许, 1-允许',
`add_mch_flag` TINYINT(6) NOT NULL DEFAULT 0 COMMENT '是否允许发展子商户: 0-不允许, 1-允许',
`remark` VARCHAR(128) COMMENT '代理商备注',
`audit_remark` VARCHAR(128) COMMENT '审核备注',
`cashout_fee_rule_type` TINYINT(6) NOT NULL DEFAULT 1 COMMENT '手续费计算公式类型: 1-使用系统默认配置, 2-自定义',
`cashout_fee_rule` VARCHAR(200) NOT NULL DEFAULT '{}' COMMENT '手续费计算公式',
`sett_account_type` VARCHAR(20) COMMENT '结算账户类型: WX_CASH-微信零钱; ALIPAY_CASH-支付宝转账; BANK_CARD-银行卡; BANK_PUBLIC-对公; BANK_PRIVATE-对私',
`sett_account_no` VARCHAR(64) COMMENT '结算账户账号',
`sett_account_name` VARCHAR(64) COMMENT '结算账户姓名',
`sett_account_bank` VARCHAR(32) COMMENT '结算账户开户行名称',
`sett_account_sub_bank` VARCHAR(32) COMMENT '开户行支行名称',
`sett_account_telphone` VARCHAR(32) COMMENT '结算账户联系人手机号(一般为代理商手机号)',
`license_img` VARCHAR(128) COMMENT '营业执照照片',
`idcard1_img` VARCHAR(128) COMMENT '身份证人像面照片',
`idcard2_img` VARCHAR(128) COMMENT '身份证国徽面照片',
`idcard_in_hand_img` VARCHAR(128) COMMENT '手持身份证照片',
`bank_card_img` VARCHAR(128) COMMENT '银行卡照片',
`permit_img` VARCHAR(128) COMMENT '许可证照片',
`agent_type` TINYINT(6) NOT NULL DEFAULT 1 COMMENT '代理商类型: 1-个人, 2-企业',
`init_user_id` BIGINT(20) DEFAULT NULL COMMENT '初始用户ID创建代理商时允许代理商登录的用户',
`login_username` varchar(32) NOT NULL COMMENT '登录用户名',
`sipw` VARCHAR(64) COMMENT '支付密码(敏感信息密码Sensitive information password)',
`freeze_amount` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '钱包冻结金额, 单位分',
`freeze_desc` VARCHAR(256) DEFAULT NULL COMMENT '冻结原因',
`created_uid` BIGINT(20) COMMENT '创建者用户ID',
`created_by` VARCHAR(64) COMMENT '创建者姓名',
`created_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (`agent_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='代理商信息表';
-- 提现结算记录表
DROP TABLE IF EXISTS t_cashout_record;
CREATE TABLE `t_cashout_record` (
`rid` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '提现记录ID',
`info_id` VARCHAR(64) NOT NULL COMMENT '代理商号等',
`info_type` VARCHAR(10) NOT NULL COMMENT '系统类型: 参考SYS_ROLE_TYPE ',
`info_name` VARCHAR(64) COMMENT '名称快照',
`apply_amount` BIGINT(20) NOT NULL COMMENT '申请金额,单位分',
`sett_fee_amount` BIGINT(20) NOT NULL COMMENT '手续费金额,单位分',
`sett_fee_rule` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '手续费计算公式(快照)',
`sett_amount` BIGINT(20) NOT NULL COMMENT '最终结算金额 (申请-手续费), 单位分',
`sett_account_type` VARCHAR(20) NOT NULL COMMENT '结算账户类型: WX_CASH-微信零钱; ALIPAY_CASH-支付宝转账; BANK_CARD-银行卡',
`sett_account_no` VARCHAR(64) NOT NULL COMMENT '结算账户账号',
`sett_account_name` VARCHAR(64) COMMENT '结算账户姓名',
`sett_account_bank` VARCHAR(32) COMMENT '结算账户开户行名称',
`sett_account_sub_bank` VARCHAR(32) COMMENT '开户行支行名称',
`sett_account_telphone` VARCHAR(32) COMMENT '结算账户联系人手机号(一般为代理商手机号)',
`apply_remark` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '用户提现备注',
`sett_info` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '结算备注[系统生成]',
`state` TINYINT(6) NOT NULL DEFAULT '1' COMMENT '结算状态: 1-审核中, 2-审核失败, 3-结算中, 4-结算成功, 5-结算失败',
`sett_cert_img` VARCHAR(256) COMMENT '申请资料',
`transfer_cert_img` VARCHAR(256) COMMENT '打款凭证(运营平台)',
`sett_type` TINYINT(6) NOT NULL COMMENT '提现类型: 1-佣金提现',
`transfer_mch_app_id` VARCHAR(64) COMMENT '发起转账的自营应用ID',
`transfer_order_id` VARCHAR(64) COMMENT '转账系统订单号',
`transfer_if_code` VARCHAR(64) COMMENT '转账接口类型',
`transfer_platform_mchfee_amount` BIGINT(20) COMMENT '自营商户费率费用',
`transfer_platform_cost_amount` BIGINT(20) COMMENT '平台真实成本费用( 来自转账订单数据 = 自营商户费率费用 - 平台利润 ',
`audit_time` DATETIME DEFAULT NULL COMMENT '审核时间',
`audit_remark` VARCHAR(100) COMMENT '审核备注',
`created_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (`rid`)
) ENGINE=InnoDB AUTO_INCREMENT=80000001 DEFAULT CHARSET=utf8mb4 COMMENT='提现结算记录表';
-- 代理商配置表
DROP TABLE IF EXISTS `t_agent_config`;
CREATE TABLE `t_agent_config` (
`agent_no` VARCHAR(64) NOT NULL COMMENT '代理商号',
`config_key` VARCHAR(50) NOT NULL COMMENT '配置KEY',
`config_val` TEXT NOT NULL COMMENT '配置内容项',
`group_key` TEXT NOT NULL COMMENT '配置分组',
`created_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (`config_key`, `agent_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='代理商配置表';
INSERT INTO `t_sys_config` VALUES ('agentSiteUrl', '代理商平台网址(不包含结尾/)', '代理商平台网址(不包含结尾/)', 'applicationConfig', '系统应用配置', 'http://127.0.0.1:9219', 'text', 2, '2021-5-18 14:46:10');
-- 代理商进件初始配置项
INSERT INTO `t_sys_config` VALUES ('agentApplymentPreAudit', '代理商进件是否需要运营平台预审核', '代理商进件是否需要运营平台预审核', 'defaultConfig', '进件初始配置', '0', 'text', 0, '2023-3-29 10:53:30');
INSERT INTO `t_sys_config` VALUES ('agentApplyTimeLimit', '代理商发起进件默认时间限制', '代理商发起进件默认时间限制', 'defaultConfig', '进件初始配置', '', 'text', 0, '2023-3-29 10:53:30');
-- 【运营平台】 代理商管理
insert into t_sys_entitlement values('ENT_AGENT', '代理商管理', 'shop', '', 'RouteView', 'ML', 0, 1, 'ROOT', '35', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO', '代理商列表', 'profile', '/agent', 'AgentListPage', 'ML', 0, 1, 'ENT_AGENT', '10', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_LIST', '页面:代理商列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_RATE_CONFIG', '按钮:费率配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_CONFIG_PAGE', '按钮:代理商配置信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_BALANCE_CHANGE', '按钮:调账', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO_AUDIT', '按钮:审核', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO_COUNT', '页面:统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
-- 提现管理
insert into t_sys_entitlement values('ENT_PROFIT_CASHOUT_RECORD', '提现申请管理', 'account-book', '/cashouts', 'CashoutRecordListPage', 'ML', 0, 1, 'ENT_PROFIT', '20', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PROFIT_CASHOUT_RECORD_LIST', '页面:提现单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PROFIT_CASHOUT_RECORD', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PROFIT_CASHOUT_RECORD_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PROFIT_CASHOUT_RECORD', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PROFIT_CASHOUT_RECORD_AUDIT', '按钮:审核', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PROFIT_CASHOUT_RECORD', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_PROFIT_CASHOUT_RECORD_COUNT', '页面:统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PROFIT_CASHOUT_RECORD', '0', 'PLATFORM', null, now(), now());
-- 代理商统计
insert into t_sys_entitlement values('ENT_STATISTIC_AGENT', '代理商统计', 'area-chart', '/statistic/agent', 'AgentCountPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '30', 'PLATFORM', null, now(), now());
-- 【代理商系统】 主页
insert into t_sys_entitlement values('ENT_COMMONS', '系统通用菜单', 'no-icon', '', 'RouteView', 'MO', 0, 1, 'ROOT', '-1', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_C_USERINFO', '个人中心', 'no-icon', '/current/userinfo', 'CurrentUserInfo', 'MO', 0, 1, 'ENT_COMMONS', '-1', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_ARTICLE_NOTICEINFO', '公告管理', 'message', '/notices', 'NoticeInfoPage', 'MO', 0, 1, 'ENT_COMMONS', '-1', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_C_MAIN_AGENT_COUNT', '接口:代理商/拓展员统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_COMMONS', '-1', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_AGENT_MAIN', '主页', 'home', '/main', 'MainPage', 'ML', 0, 1, 'ROOT', '1', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_MAIN_PAY_DAY_COUNT', '今日/昨日交易统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_MAIN_PAY_TREND_COUNT', '趋势图统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_MAIN_PAY_COUNT', '主页交易统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_MAIN_PAY_TYPE_COUNT', '主页交易方式统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_C_MAIN', '0', 'AGENT', null, now(), now());
-- 【代理商系统】 账户中心
insert into t_sys_entitlement values('ENT_AGENT_ACCOUNT_CENTER', '账户中心', 'wallet', '', 'RouteView', 'ML', 0, 1, 'ROOT', '20', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_WALLET', '钱包', 'wallet', '/wallet', 'WalletPage', 'ML', 0, 1, 'ENT_AGENT_ACCOUNT_CENTER', '10', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_CASHOUT_RECORD_LIST', '页面:提现记录列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_WALLET', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_CASHOUT_RECORD_DETAIL', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_WALLET', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_CASHOUT_RECORD_SETT', '按钮:发起提现', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_WALLET', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_CASHOUT_PAYWAY_FEE', '按钮:费率', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_WALLET', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_CASHOUT_RECORD_COUNT', '页面:统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_WALLET', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_STATISTIC', '数据统计', 'fund-view', '/statistic', 'StatisticsPage', 'ML', 0, 1, 'ENT_AGENT_ACCOUNT_CENTER', '20', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_STATISTIC_COUNT', '页面:代理商统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_STATISTIC', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_PC', '费率配置', 'file-done', '/passageConfig', 'PayConfigPage', 'ML', 0, 1, 'ENT_AGENT_ACCOUNT_CENTER', '30', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ACCOUNT_HISTORY', '钱包流水', 'fund-view', '/history', 'HistoryPage', 'ML', 0, 1, 'ENT_AGENT_ACCOUNT_CENTER', '40', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ACCOUNT_HISTORY_LIST', '页面:钱包流水列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ACCOUNT_HISTORY', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ACCOUNT_HISTORY_DETAIL', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ACCOUNT_HISTORY', '0', 'AGENT', null, now(), now());
-- 代理商管理
insert into t_sys_entitlement values('ENT_AGENT', '代理商管理', 'shop', '', 'RouteView', 'ML', 0, 1, 'ROOT', '25', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO', '代理商列表', 'profile', '/agent', 'AgentListPage', 'ML', 0, 1, 'ENT_AGENT', '10', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_LIST', '页面:代理商列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_INFO_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_RATE_CONFIG', '按钮:费率配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH', '商户管理', 'shop', '', 'RouteView', 'ML', 0, 1, 'ROOT', '30', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO', '商户列表', 'profile', '/mch', 'MchListPage', 'ML', 0, 1, 'ENT_MCH', '10', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_LIST', '页面:商户列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_INFO_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_CONFIG', '应用配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ISV_LIST', '服务商列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement
values ('ENT_MCH_CONFIG_PAGE', '按钮:商户配置信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'AGENT', null,
now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP', '应用管理', 'appstore', '/apps', 'MchAppPage', 'ML', 0, 1, 'ENT_MCH', '20', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_LIST', '页面:应用列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APP_PAY_CONFIG', '按钮:支付配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE', '门店管理', 'profile', '/store', 'StorePage', 'ML', 0, 1, 'ENT_MCH', '40', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_LIST', '页面:数据列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_STORE_MAP', '按钮:地图配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'AGENT', null, now(), now());
-- 进件管理
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT', '进件管理', 'schedule', '/applyments', 'MchApplymentListPage', 'ML', 0, 1, 'ENT_MCH', '40', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_LIST', '页面:进件管理列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_ADD', '按钮:发起进件', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_EDIT', '按钮:修改/继续填写', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_VIEW', '按钮:详细信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_PAY_CONFIG', '按钮:参数配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_SIGN', '按钮:自主签约', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_GET_INFO', '按钮:获取最新结果', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'AGENT', '{epUserEnt:true}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_IMG_OCR_DETAIL', '功能ocr图片识别', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'AGENT', '{epUserEnt:true}', now(), now());
-- 【代理商系统】 订单管理
insert into t_sys_entitlement values('ENT_ORDER', '订单管理', 'transaction', '', 'RouteView', 'ML', 0, 1, 'ROOT', '40', 'AGENT', null, now(), now());
-- 支付订单
insert into t_sys_entitlement values('ENT_PAY_ORDER', '支付订单', 'account-book', '/pay', 'PayOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '10', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ORDER_LIST', '页面:订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER_SEARCH_PAY_WAY', '筛选项:支付方式', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_PAY_ORDER_REFUND', '按钮:订单退款', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ORDER_COUNT', '支付统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PAY_ORDER', '0', 'AGENT', null, now(), now());
-- 退款订单
insert into t_sys_entitlement values('ENT_REFUND_ORDER', '退款订单', 'exception', '/refund', 'RefundOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '20', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_REFUND_LIST', '页面:退款订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_REFUND_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement
values ('ENT_REFUND_ORDER_COUNT', '退款统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'AGENT', null,
now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER', '转账订单', 'property-safety', '/transfer', 'TransferOrderListPage', 'ML', 0, 1, 'ENT_ORDER', '30', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER_LIST', '页面:转账订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TRANSFER_ORDER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TRANSFER_ORDER', '0', 'AGENT', null, now(), now());
-- 数据统计
insert into t_sys_entitlement values('ENT_ORDER_STATISTIC', '数据统计', 'bar-chart', '', 'RouteView', 'ML', 0, 1, 'ROOT', '50', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_TRANSACTION', '交易报表', 'account-book', '/statistic/transaction', 'TransactionPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '10', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH', '商户统计', 'line-chart', '/statistic/mch', 'MchCountPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '20', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH_STORE', '门店统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_STATISTIC_MCH', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH_WAY', '支付方式统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_STATISTIC_MCH', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_MCH_TYPE', '支付类型统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_STATISTIC_MCH', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_AGENT', '代理商统计', 'area-chart', '/statistic/agent', 'AgentCountPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '30', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_STATISTIC_DEVICE', '设备统计', 'mobile', '/statistic/device', 'DeviceCountPage', 'ML', 0, 1, 'ENT_ORDER_STATISTIC', '40', 'AGENT', null, now(), now());
-- 设备管理菜单
insert into t_sys_entitlement values('ENT_DEVICE', '设备管理', 'appstore', '', 'RouteView', 'ML', 0, 1, 'ROOT', '70', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC', '码牌', 'qrcode', '/qrc', 'QrcodeCardPage', 'ML', 0, 1, 'ENT_DEVICE', '5', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_EXPORT', '按钮:导出', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_QRC_ALLOT', '按钮:划拨', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement
values ('ENT_DEVICE_QRC_RELIEVE', '按钮:解除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'AGENT', null,
now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE', '云喇叭', 'sound', '/speaker/device', 'SpeakerDevicePage', 'ML', 0, 1, 'ENT_DEVICE', '15', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_LIST', '页面:云喇叭设备列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_TEST', '按钮:播报测试', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_SPEAKER_DEVICE_ALLOT', '按钮:划拨设备', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_SPEAKER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE', '云打印', 'printer', '/printer/device', 'PrinterDevicePage', 'ML', 0, 1, 'ENT_DEVICE', '25', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_LIST', '页面:云打印设备列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_TEST', '按钮:打印测试', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_CLEAR', '按钮:清空打印队列', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PRINTER_DEVICE_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PRINTER_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY', '收银插件激活码', 'file', '/plugin/cdkey', 'PluginCdKeyPage', 'ML', 0, 1, 'ENT_DEVICE', '30', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_PLUGIN_CDKEY_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_PLUGIN_CDKEY', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE', '扫码POS', 'scan', '/pos/device', 'PosDevicePage', 'ML', 0, 1, 'ENT_DEVICE', '35', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_POS_DEVICE_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_POS_DEVICE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS', '智能POS', 'file', '/auto/pos', 'AutoPosPage', 'ML', 0, 1, 'ENT_DEVICE', '45', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_AUTO_POS_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_AUTO_POS', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP', '刷脸设备', 'smile', '/face', 'FaceAppPage', 'ML', 0, 1, 'ENT_DEVICE', '47', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_FACE_APP_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_FACE_APP', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL', '辅助终端报备', 'issues-close', '/terminals', 'TerminalPage', 'ML', 0, 1, 'ENT_DEVICE', '50', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_TERMINAL_SENDUP', '按钮:报备', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TERMINAL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI', '如意Lite', 'file', '/ruyi', 'RuyiPage', 'ML', 0, 1, 'ENT_DEVICE', '60', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'AGENT', null, now(), now());
-- 系统管理
insert into t_sys_entitlement values('ENT_SYS_CONFIG', '系统管理', 'setting', '', 'RouteView', 'ML', 0, 1, 'ROOT', '200', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR', '用户角色管理', 'team', '', 'RouteView', 'ML', 0, 1, 'ENT_SYS_CONFIG', '10', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER', '操作员管理', 'contacts', '/users', 'SysUserPage', 'ML', 0, 1, 'ENT_UR', '10', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_LIST', '页面:操作员列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_SEARCH', '按钮:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_ADD', '按钮:添加操作员', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_VIEW', '按钮: 详情', '', 'no-icon', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_EDIT', '按钮: 修改基本信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_DELETE', '按钮: 删除操作员', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_UPD_ROLE', '按钮: 角色分配', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_MFA_DELETE', '按钮: MFA解绑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_USER_LOGIN_LIMIT_DELETE', '按钮: 解除登录限制', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_USER', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM', '团队管理', 'team', '/teams', 'SysUserTeamPage', 'ML', 0, 1, 'ENT_UR', '15', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_LIST', '页面:团队列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_SEARCH', '按钮:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_ADD', '按钮:添加团队', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_VIEW', '按钮: 详情', '', 'no-icon', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_EDIT', '按钮: 修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_TEAM_DELETE', '按钮: 删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_TEAM', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE', '角色管理', 'user', '/roles', 'RolePage', 'ML', 0, 1, 'ENT_UR', '20', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_LIST', '页面:角色列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_SEARCH', '页面:搜索', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_ADD', '按钮:添加角色', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_DIST', '按钮: 分配权限', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_EDIT', '按钮: 修改名称', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_UR_ROLE_DEL', '按钮: 删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_UR_ROLE', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_CONTROL', '广告管理', 'message', '/advert', 'AdvertInfoPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '15', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_ADVERT_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ADVERT_CONTROL', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_CONFIG', '系统配置', 'setting', '/config', 'AgentConfigPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '20', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_AGENT_CONFIG_EDIT', '按钮:修改系统配置', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_CONFIG', '0', 'AGENT', null, now(), now());

143
docs/sql/init_3_xxl_job.sql Normal file
View File

@ -0,0 +1,143 @@
# XXL-JOB v2.3.1
# Copyright (c) 2015-present, xuxueli.
# 以下仅保留create语句
CREATE TABLE `xxl_job_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_group` int(11) NOT NULL COMMENT '执行器主键ID',
`job_desc` varchar(255) NOT NULL,
`add_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`author` varchar(64) DEFAULT NULL COMMENT '作者',
`alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
`schedule_type` varchar(50) NOT NULL DEFAULT 'NONE' COMMENT '调度类型',
`schedule_conf` varchar(128) DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
`misfire_strategy` varchar(50) NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略',
`executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
`executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
`executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
`executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
`glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
`glue_source` mediumtext COMMENT 'GLUE源代码',
`glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
`glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
`child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID多个逗号分隔',
`trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '调度状态0-停止1-运行',
`trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',
`trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`job_group` int(11) NOT NULL COMMENT '执行器主键ID',
`job_id` int(11) NOT NULL COMMENT '任务主键ID',
`executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
`executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
`executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
`trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
`trigger_code` int(11) NOT NULL COMMENT '调度-结果',
`trigger_msg` text COMMENT '调度-日志',
`handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
`handle_code` int(11) NOT NULL COMMENT '执行-状态',
`handle_msg` text COMMENT '执行-日志',
`alarm_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '告警状态0-默认、1-无需告警、2-告警成功、3-告警失败',
PRIMARY KEY (`id`),
KEY `I_trigger_time` (`trigger_time`),
KEY `I_handle_code` (`handle_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_log_report` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`trigger_day` datetime DEFAULT NULL COMMENT '调度-时间',
`running_count` int(11) NOT NULL DEFAULT '0' COMMENT '运行中-日志数量',
`suc_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量',
`fail_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_logglue` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_id` int(11) NOT NULL COMMENT '任务主键ID',
`glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型',
`glue_source` mediumtext COMMENT 'GLUE源代码',
`glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注',
`add_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_registry` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`registry_group` varchar(50) NOT NULL,
`registry_key` varchar(255) NOT NULL,
`registry_value` varchar(255) NOT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_group` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`app_name` varchar(64) NOT NULL COMMENT '执行器AppName',
`title` varchar(12) NOT NULL COMMENT '执行器名称',
`address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型0=自动注册、1=手动录入',
`address_list` text COMMENT '执行器地址列表,多地址逗号分隔',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '账号',
`password` varchar(50) NOT NULL COMMENT '密码',
`role` tinyint(4) NOT NULL COMMENT '角色0-普通用户、1-管理员',
`permission` varchar(255) DEFAULT NULL COMMENT '权限执行器ID列表多个逗号分割',
PRIMARY KEY (`id`),
UNIQUE KEY `i_username` (`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_lock` (
`lock_name` varchar(50) NOT NULL COMMENT '锁名称',
PRIMARY KEY (`lock_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 初始用户: admin / 123456
INSERT INTO `xxl_job_user`(`id`, `username`, `password`, `role`, `permission`) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
-- 默认执行器 (appName)
INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`) VALUES (1, 'jeepay-plus-executor', 'jeepay-plus', 0, NULL, '2022-09-01 00:00:00' );
-- 对账模块执行器 (appName)
INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`) VALUES (2, 'jeepay-plus-bill-executor', '对账模块', 0, NULL, '2022-09-01 00:00:00' );
-- payment 定时任务 明细
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (1, 1, '处理支付订单超时', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/1 * * * ?', 'DO_NOTHING', 'FIRST', 'payOrderExpiredTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (2, 1, '处理支付订单补单任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/1 * * * ?', 'DO_NOTHING', 'FIRST', 'payOrderReissueTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (3, 1, '处理退款订单超时', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/1 * * * ?', 'DO_NOTHING', 'FIRST', 'refundOrderExpiredTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (4, 1, '处理退款订单补单(分钟)任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/1 * * * ?', 'DO_NOTHING', 'FIRST', 'refundOrderReissueMinTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (5, 1, '处理退款订单补单(小时)任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0 0/1 * * ?', 'DO_NOTHING', 'FIRST', 'refundOrderReissueHourTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (6, 1, '处理订单分润结算任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0 3 * * ?', 'DO_NOTHING', 'FIRST', 'orderProfitSettTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (14, 1, '修复订单分润数据任务', '2023-01-12 00:00:00', '2023-01-12 00:00:00', 'sys', '', 'CRON', '0 0 3 * * ?', 'DO_NOTHING', 'FIRST', 'fixOrderProfitTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2023-01-12 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (7, 1, '商户进件状态查询定时任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/1 * * * ?', 'DO_NOTHING', 'FIRST', 'mchApplymentQueryStateTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (10, 1, '处理三方账户自动提现任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/5 * * * ?', 'DO_NOTHING', 'FIRST', 'mchAutoCashoutTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (11, 1, '处理三方账户提现查询任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/1 * * * ?', 'DO_NOTHING', 'FIRST', 'mchChannelCashOutReissueTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (12, 1, '处理数据统计任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 1 0 * * ?', 'DO_NOTHING', 'FIRST', 'statisticsTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (13, 1, '处理转账订单补单任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/1 * * * ?', 'DO_NOTHING', 'FIRST', 'transferOrderReissueTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
-- 支付宝直付通结算、分账定时 (小时)
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (15, 1, '支付宝直付通结算分账定时任务(小时)', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0 0/1 * * ?', 'DO_NOTHING', 'FIRST', 'alizftSettReissueTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', '支付宝直付通结算分账定时任务(小时)', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (17, 1, '处理分账补单定时任务(分钟)', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/1 * * * ?', 'DO_NOTHING', 'FIRST', 'divisionRecordReissueTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', '处理分账补单定时任务(分钟)', '2022-09-01 00:00:00', '', 1, 0, 0);
-- 对账模块 定时任务 明细
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (8, 2, '处理渠道对账定时任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 15 10 ? * *', 'DO_NOTHING', 'FIRST', 'reconciliationTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (9, 2, '补充对账定时任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/30 11-18 * * ?', 'DO_NOTHING', 'FIRST', 'reconciliationStockTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', '补充对账定时任务每日11-18点 半小时执行一次', '2022-09-01 00:00:00', '', 1, 0, 0);
INSERT INTO `xxl_job_lock` ( `lock_name`) VALUES ( 'schedule_lock');

View File

@ -0,0 +1,176 @@
##### jeeppay-plus S3 会员模块 表结构及菜单权限初始化数据SQL #####
-- 会员充值规则表
DROP TABLE IF EXISTS `t_member_recharge_rule`;
CREATE TABLE `t_member_recharge_rule` (
`rule_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '规则ID',
`mch_no` VARCHAR(64) NOT NULL COMMENT '所属商户',
`recharge_amount` bigint(20) NOT NULL COMMENT '充值金额',
`give_amount` bigint(20) DEFAULT 0 COMMENT '赠送金额',
`state` tinyint(6) NOT NULL COMMENT '状态0-停用 1-启用 ',
`sort` int(11) NOT NULL DEFAULT 0 COMMENT '排序字段, 规则:正序',
`remark` VARCHAR(128) COMMENT '备注',
`created_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (`rule_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 COMMENT='会员充值规则表';
-- 会员信息表
DROP TABLE IF EXISTS t_member_info;
CREATE TABLE `t_member_info` (
`mbr_id` VARCHAR(64) NOT NULL COMMENT '会员ID',
`mbr_name` VARCHAR(64) NOT NULL COMMENT '会员名称',
`mbr_tel` VARCHAR(32) NOT NULL COMMENT '会员手机号',
`wx_mp_open_id` VARCHAR(128) COMMENT '微信公众号用户标识open_id',
`wx_lite_open_id` VARCHAR(128) COMMENT '微信小程序用户标识open_id',
`ali_user_id` VARCHAR(128) COMMENT '支付宝用户标识user_id',
`ysf_user_id` VARCHAR(128) COMMENT '云闪付用户标识user_id',
`mch_no` VARCHAR(64) NOT NULL COMMENT '所属商户',
`balance` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '账户余额 单位:分',
`safe_key` VARCHAR(128) NOT NULL COMMENT '数据安全保护秘钥',
`state` TINYINT(6) NOT NULL DEFAULT 1 COMMENT '状态: 0-停用, 1-正常',
`avatar_url` VARCHAR(128) COMMENT '头像地址',
`remark` VARCHAR(128) COMMENT '会员备注',
`created_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (`mbr_id`),
UNIQUE KEY `UQ_MBR_TEL`(`mch_no`, `mbr_tel`),
UNIQUE KEY `UQ_WX_MP_OPEN_ID`(`mch_no`, `wx_mp_open_id`),
UNIQUE KEY `UQ_WX_LITE_OPEN_ID`(`mch_no`, `wx_lite_open_id`),
UNIQUE KEY `UQ_ALI_USER_ID`(`mch_no`, `ali_user_id`),
UNIQUE KEY `UQ_YSF_USER_ID`(`mch_no`, `ysf_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员信息表';
-- 会员账户流水表
DROP TABLE IF EXISTS t_member_account_history;
CREATE TABLE `t_member_account_history` (
`hid` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '记录ID',
`mbr_id` VARCHAR(64) NOT NULL COMMENT '会员ID',
`mbr_name` varchar(64) NOT NULL DEFAULT '' COMMENT '会员名称 快照',
`mbr_tel` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '会员手机号 快照',
`mch_no` VARCHAR(64) NOT NULL COMMENT '所属商户',
`store_id` BIGINT(20) COMMENT '商户门店ID (快照)',
`qrc_id` BIGINT(20) COMMENT '码牌ID (快照)',
`before_amount` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '变动前账户余额, 单位:分',
`change_amount` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '变动金额, 单位:分',
`after_amount` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '变动后账户余额, 单位:分',
`biz_type` TINYINT(6) NOT NULL COMMENT '业务类型1-支付充值, 2-现金充值, 3-消费, 4-消费退款, 5-人工调账',
`rela_biz_order_id` VARCHAR(30) COMMENT '关联订单号',
`remark` VARCHAR(128) COMMENT '备注',
`created_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (`hid`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 COMMENT='会员账户流水表';
-- 会员充值记录表
DROP TABLE IF EXISTS t_member_recharge_record;
CREATE TABLE `t_member_recharge_record` (
`recharge_record_id` VARCHAR(30) COMMENT '充值记录ID',
`mbr_id` VARCHAR(64) NOT NULL COMMENT '会员ID',
`mbr_name` varchar(64) NOT NULL DEFAULT '' COMMENT '会员名称 快照',
`mbr_tel` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '会员手机号 快照',
`mch_no` VARCHAR(64) NOT NULL COMMENT '所属商户',
`pay_amount` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '支付金额, 单位:分',
`give_amount` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '赠送金额, 单位:分',
`entry_amount` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '会员入账金额, 单位:分',
`after_balance` BIGINT(20) DEFAULT NULL COMMENT '会员余额, 单位:分',
`way_code` VARCHAR(20) NOT NULL COMMENT '支付方式代码',
`way_code_type` VARCHAR(20) NOT NULL COMMENT '支付方式代码分类',
`state` TINYINT(6) NOT NULL COMMENT '充值状态0-初始化, 1-充值中, 2-充值成功, 3-充值失败',
`pay_order_id` VARCHAR(30) DEFAULT NULL COMMENT '支付订单号',
`success_time` DATETIME DEFAULT NULL COMMENT '订单支付成功时间',
`return_url` VARCHAR(256) NOT NULL default '' COMMENT '同步跳转地址',
`notify_url` VARCHAR(256) NOT NULL default '' COMMENT '异步通知地址',
`err_code` VARCHAR(128) DEFAULT NULL COMMENT '支付错误码',
`err_msg` VARCHAR(256) DEFAULT NULL COMMENT '支付错误描述',
`remark` VARCHAR(128) COMMENT '充值备注',
`created_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (`recharge_record_id`),
UNIQUE KEY `Uni_Pay_Order_Id` (`pay_order_id`),
INDEX(`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员充值记录表';
-- 会员网关网址系统配置
INSERT INTO `t_sys_config` VALUES ('memberSiteUrl', '会员网关网址(不包含结尾/)', '会员网关网址(不包含结尾/)', 'applicationConfig', '系统应用配置', 'http://127.0.0.1:9221', 'text', 5, '2021-5-18 14:46:10');
-- 会员模块执行器 (appName)
INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`) VALUES (3, 'jeepay-plus-member-executor', '会员模块', 0, NULL, '2022-09-01 00:00:00' );
-- 会员充值订单状态查询定时任务
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (16, 3, '会员充值订单状态查询定时任务', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/1 * * * ?', 'DO_NOTHING', 'FIRST', 'memberRechargeOrderTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2022-09-01 00:00:00', '', 1, 0, 0);
-- 会员短信发送 【需重新配置短信参数】手动增加mbrTelBindTemplateId属性
-- update `t_sys_config` set `config_val` = '{"accessKeyId":"","accessKeySecret":"","signName":"","forgetPwdTemplateId":"","registerMchTemplateId":"","loginMchTemplateId":"","accountOpenTemplateId":"","mbrTelBindTemplateId":""}' where config_key = 'smsConfigValue';
-- 新增商户时会员默认配置
INSERT INTO `t_sys_config` VALUES ('mchRegisterMemberState', '商户注册/创建时[会员功能]默认状态', '商户注册/创建时[会员功能]默认状态', 'defaultConfig', '商户注册/创建时[会员功能]默认状态', '1', 'text', 0, '2023-3-09 16:53:30');
-- 新增商户时 默认会员最大储值余额
INSERT INTO `t_sys_config` VALUES ('mchMbrMaxBalance', '商户会员最大储值余额', '商户会员最大储值余额', 'defaultConfig', '商户会员最大储值余额', '10000000', 'text', 0, '2023-3-09 16:53:30');
-- 商户会员开关配置 默认关闭状态
insert into t_mch_config select mch_no, 'memberModelState', '会员模块状态开关', '0', 'memberConfig', 'radio', now(), now() from t_mch_info;
-- 商户会员支付开关配置 默认关闭状态
insert into t_mch_config select mch_no, 'memberPayState', '会员支付开关', '0', 'memberConfig', 'radio', now(), now() from t_mch_info;
-- 商户会员支付自定义金额开关 默认开启
insert into t_mch_config select mch_no, 'memberCustomAmountState', '充值自定义金额', '1', 'memberConfig', 'radio', now(), now() from t_mch_info;
-- 【运营平台】会员管理
-- 商户会员管理菜单
insert into t_sys_entitlement values('ENT_MCH_MEMBER', '会员中心', 'team', '', 'RouteView', 'ML', 0, 1, 'ENT_MCH', '50', 'PLATFORM', NULL, now(), now());
-- 会员管理
insert into t_sys_entitlement values('ENT_MEMBER', '会员管理', 'user', '/member/memberInfo', 'MemberPage', 'ML', 0, 1, 'ENT_MCH_MEMBER', '10', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER', '0', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER', '0', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER', '0', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER', '0', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_MANUAL', '按钮:调账', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER', '0', 'PLATFORM', NULL, now(), now());
-- 充值规则
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_RULE', '充值规则', 'profile', '/member/rechargeRule', 'RechargeRulePage', 'ML', 0, 1, 'ENT_MCH_MEMBER', '20', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RULE', '0', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RULE', '0', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RULE', '0', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RULE', '0', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RULE', '0', 'PLATFORM', NULL, now(), now());
-- 账户流水
insert into t_sys_entitlement values('ENT_MEMBER_ACCOUNT_HISTORY', '账户流水', 'exception', '/member/account', 'MemberAccountPage', 'ML', 0, 1, 'ENT_MCH_MEMBER', '30', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_ACCOUNT_HISTORY_LIST', '页面:订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_ACCOUNT_HISTORY', '0', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_ACCOUNT_HISTORY_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_ACCOUNT_HISTORY', '0', 'PLATFORM', NULL, now(), now());
-- 充值记录
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_RECORD', '充值记录', 'transaction', '/member/recharge', 'MemberRechargePage', 'ML', 0, 1, 'ENT_MCH_MEMBER', '40', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_RECORD_LIST', '页面:订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RECORD', '0', 'PLATFORM', NULL, now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_RECORD_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RECORD', '0', 'PLATFORM', NULL, now(), now());
-- 【商户系统】 会员管理
-- 商户会员管理菜单
insert into t_sys_entitlement values('ENT_MCH_MEMBER', '会员中心', 'team', '', 'RouteView', 'ML', 0, 1, 'ROOT', '15', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
-- 会员配置
insert into t_sys_entitlement values('ENT_MEMBER_CONFIG', '会员配置', 'setting', '/member/memberConfig', 'MemberConfigPage', 'ML', 0, 1, 'ENT_MCH_MEMBER', '5', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
-- 会员管理
insert into t_sys_entitlement values('ENT_MEMBER', '会员管理', 'user', '/member/memberInfo', 'MemberPage', 'ML', 0, 1, 'ENT_MCH_MEMBER', '10', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_MANUAL', '按钮:调账', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
-- 充值规则
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_RULE', '充值规则', 'profile', '/member/rechargeRule', 'RechargeRulePage', 'ML', 0, 1, 'ENT_MCH_MEMBER', '20', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RULE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RULE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RULE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_EDIT', '按钮:编辑', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RULE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RULE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
-- 账户流水
insert into t_sys_entitlement values('ENT_MEMBER_ACCOUNT_HISTORY', '账户流水', 'exception', '/member/account', 'MemberAccountPage', 'ML', 0, 1, 'ENT_MCH_MEMBER', '30', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_ACCOUNT_HISTORY_LIST', '页面:订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_ACCOUNT_HISTORY', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_ACCOUNT_HISTORY_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_ACCOUNT_HISTORY', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
-- 充值记录
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_RECORD', '充值记录', 'transaction', '/member/recharge', 'MemberRechargePage', 'ML', 0, 1, 'ENT_MCH_MEMBER', '40', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_RECORD_LIST', '页面:订单列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RECORD', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());
insert into t_sys_entitlement values('ENT_MEMBER_RECHARGE_RECORD_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MEMBER_RECHARGE_RECORD', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"], mchLevelArray: ["M1"], mchMemberEnt: true}', now(), now());

315
docs/sql/patch_v3.sql Normal file
View File

@ -0,0 +1,315 @@
##### jeeppay-plus S3 支付基础模块 版本升级SQL #####
###### v3.0.0 ===> v3.1.0 ###### START ######
-- 增加删除进件记录菜单
insert into t_sys_entitlement values('ENT_MCH_APPLYMENT_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_APPLYMENT', '0', 'PLATFORM', '{epUserEnt:true}', now(), now());
-- 商户门店表新增蚂蚁店铺字段
ALTER TABLE t_mch_store ADD COLUMN `alipay_shop_id` VARCHAR(64) DEFAULT NULL COMMENT '蚂蚁店铺ID' AFTER `address`;
ALTER TABLE t_mch_store ADD COLUMN `alipay_shop_create_id` VARCHAR(64) DEFAULT NULL COMMENT '蚂蚁店铺申请单ID' AFTER `alipay_shop_id`;
ALTER TABLE t_mch_store ADD COLUMN `alipay_shop_status` VARCHAR(6) DEFAULT NULL COMMENT '蚂蚁店铺创建状态99已完结-1失败031已提交审核' AFTER `alipay_shop_create_id`;
-- 设备表新增蚂蚁店铺绑定状态字段
ALTER TABLE t_mch_store_device ADD COLUMN `alipay_bind_state` TINYINT(6) NOT NULL DEFAULT 0 COMMENT '蚂蚁店铺Iot设备绑定状态 0-未绑定1-已绑定' AFTER `unbind_time`;
-- 运营平台 如意设备菜单
ALTER TABLE t_device_provide_config MODIFY device_type TINYINT(6) NOT NULL COMMENT '设备类型1-云喇叭, 2-云打印, 3-扫码pos, 4-智能pos, 5-收银插件, 7-如意Lite';
INSERT INTO t_sys_entitlement VALUES('ENT_DEVICE_RUYI', '如意Lite管理', 'file', '/ruyi', 'RuyiPage', 'ML', 0, 1, 'ENT_DEVICE', '60', 'PLATFORM', null, now(), now());
INSERT INTO t_sys_entitlement VALUES('ENT_DEVICE_RUYI_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
INSERT INTO t_sys_entitlement VALUES('ENT_DEVICE_RUYI_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
INSERT INTO t_sys_entitlement VALUES('ENT_DEVICE_RUYI_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
INSERT INTO t_sys_entitlement VALUES('ENT_DEVICE_RUYI_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
INSERT INTO t_sys_entitlement VALUES('ENT_DEVICE_RUYI_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
INSERT INTO t_sys_entitlement VALUES('ENT_DEVICE_RUYI_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
-- 商户系统 如意设备菜单
insert into t_sys_entitlement values('ENT_DEVICE_RUYI', '如意Lite管理', 'file', '/ruyi', 'RuyiPage', 'ML', 0, 1, 'ENT_DEVICE', '60', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
-- web收银台 存量数据的移行。 默认 全部开启。
insert into t_mch_config select mch_no, 'webCashierState', 'web收银台开关', '1', 'webCashier', 'text', now(), now() from t_mch_info;
-- 运营平台便捷收银台权限
insert into t_sys_entitlement values('ENT_MCH_CASHIER_URL', '便捷收银台', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', null, now(), now());
-- 注册时 WEB收银台默认状态。
INSERT INTO `t_sys_config` VALUES ('mchRegisterWebCashierState', '商户注册/创建时[WEB收银台]默认状态', '商户注册/创建时[WEB收银台]默认状态', 'defaultConfig', '商户注册/创建时WEB收银台默认状态', '0', 'text', 0, '2023-3-09 16:53:30');
-- 商户门店表 修改蚂蚁店铺状态描述
ALTER TABLE t_mch_store MODIFY COLUMN `alipay_shop_status` VARCHAR(6) DEFAULT '0' COMMENT '蚂蚁店铺创建状态(与支付宝一致): 0-未创建; 99-已完结; -1-失败; 031-已提交审核';
update `t_mch_store` set `alipay_shop_status` = '0' where alipay_shop_status is null;
-- 【商户系统】支付宝代运营授权
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SP_OPERATION', '支付宝代运营授权', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_CENTER', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
-- 【商户系统】蚂蚁店铺按钮权限
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_STATUS', '按钮:查询审核状态', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT"]}', now(), now());
-- 【商户系统】设备绑定蚂蚁店铺按钮
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_BIND', '按钮:绑定蚂蚁店铺', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "DEVICE"]}', now(), now());
-- 【运营平台】支付宝代运营授权
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SP_OPERATION', '支付宝代运营授权', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'PLATFORM', null, now(), now());
-- 【运营平台】蚂蚁店铺按钮权限
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_STATUS', '按钮:查询审核状态', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_DELETE', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_MCH_ALIPAY_SHOP_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_STORE', '0', 'PLATFORM', null, now(), now());
-- 【运营平台】设备绑定蚂蚁店铺按钮
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_BIND', '按钮:绑定蚂蚁店铺', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'PLATFORM', null, now(), now());
-- 设备表新增绑定的蚂蚁店铺ID字段
ALTER TABLE t_mch_store_device ADD COLUMN `alipay_shop_id` VARCHAR(64) DEFAULT NULL COMMENT '蚂蚁店铺ID' AFTER `alipay_bind_state`;
###### v3.1.0 ===> v3.2.0 ###### START ######
-- 将“是否开启进件预审功能”改为“商户进件是否需要运营平台预审核”
UPDATE `t_sys_config` SET `config_name` = '商户进件是否需要运营平台预审核', `config_desc` = '商户进件是否需要运营平台预审核', `group_name` = '进件初始配置' WHERE `config_key` = 'mchApplymentPreAudit';
-- 进件初始配置:商户进件时间限制
INSERT INTO `t_sys_config` VALUES ('mchApplyTimeLimit', '商户自主进件时间限制', '商户自主进件时间限制', 'defaultConfig', '进件初始配置', '', 'text', 0, '2023-3-29 10:53:30');
-- 新增支付方式:外部订单
INSERT INTO t_pay_way (way_code, way_name, way_type) VALUES ('OUT_TRADE', '外部订单', 'OTHER');
-- 商户app推送设备表 新增设备cid类型
ALTER TABLE t_mch_app_push_info ADD COLUMN `cid_type` VARCHAR(20) NOT NULL DEFAULT 'app_plus' COMMENT '设备cid类型app端app_plus小程序端mp_weixin' AFTER `cid`;
-- 订单表 新增平台商户单号索引
ALTER TABLE t_pay_order ADD INDEX `Index_Platform_Mch_Order_No` (`platform_mch_order_no`) USING BTREE;
-- 订单分润结算记录 添加退款订单ID索引
ALTER TABLE t_order_profit_sett_record ADD INDEX `Index_Refund_Order_Id` (`refund_order_id`) USING BTREE;
-- 公众号消息用户表 新增系统用户ID
ALTER TABLE t_mch_wxmp_user ADD COLUMN `sys_user_id` BIGINT(20) NOT NULL COMMENT '系统用户ID' after `user_id`;
ALTER TABLE t_mch_wxmp_user DROP INDEX IDX_WxOpenId_WxAppId;
-- 执行后,原有公众号接收方将全部删除,重新授权后可使用(执行时需谨慎)
delete from t_mch_wxmp_user where 1=1;
ALTER TABLE t_mch_wxmp_user ADD UNIQUE IDX_SysUserId_WxOpenId_WxAppId(`sys_user_id`, `wx_open_id`, `wx_app_id`);
-- 执行后,原有公众号接收方将全部删除,重新授权后可使用(执行时需谨慎)
delete from t_mch_wxmp_user;
-- 商户通知配置 菜单 店长、店员权限优化
delete from t_sys_entitlement where ent_id = 'ENT_SYS_CONFIG' and sys_type = 'MCH';
delete from t_sys_entitlement where ent_id = 'ENT_MCH_NOTICE' and sys_type = 'MCH';
delete from t_sys_entitlement where ent_id = 'ENT_MCH_WXMP_USER_LIST' and sys_type = 'MCH';
delete from t_sys_entitlement where ent_id = 'ENT_MCH_WXMP_USER_ADD' and sys_type = 'MCH';
delete from t_sys_entitlement where ent_id = 'ENT_MCH_WXMP_USER_DELETE' and sys_type = 'MCH';
delete from t_sys_entitlement where ent_id = 'ENT_MCH_WXMP_USER_EDIT' and sys_type = 'MCH';
insert into t_sys_entitlement values('ENT_SYS_CONFIG', '系统管理', 'setting', '', 'RouteView', 'ML', 0, 1, 'ROOT', '200', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_NOTICE', '通知配置', 'notification', '/notice', 'NoticePage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '40', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_WXMP_USER_LIST', '页面:公众号消息接收人列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTICE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_WXMP_USER_ADD', '按钮:新增公众号消息接收人', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTICE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_WXMP_USER_DELETE', '按钮:删除公众号消息接收人', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTICE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
insert into t_sys_entitlement values('ENT_MCH_WXMP_USER_EDIT', '按钮:修改公众号消息接收人', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_NOTICE', '0', 'MCH', '{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
-- uniPush2.0 参数配置
INSERT INTO `t_sys_config` VALUES ('uniPushQueryInvalidatedCidsUrl', 'uniPush查询失效cid云函数URL', 'uniPush查询失效cid云函数URL', 'appPushConfig', 'app推送参数配置', '', 'text', 25, '2021-5-18 14:46:10');
###### v3.2.0 ===> v3.2.1 ###### START ######
-- 商户支付宝安全发权限
insert into t_sys_entitlement values('AGREEMENT_PAGE_SIGN', '支付宝安全发', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_CENTER', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
-- 支付订单表、退款订单表、转账订单表 IP字段扩充
alter table t_pay_order modify column `client_ip` VARCHAR(128) DEFAULT NULL COMMENT '客户端IP';
alter table t_refund_order modify column `client_ip` VARCHAR(128) DEFAULT NULL COMMENT '客户端IP';
alter table t_transfer_order modify column `client_ip` VARCHAR(128) DEFAULT NULL COMMENT '客户端IP';
-- 进件图片上传大小M配置
INSERT INTO `t_sys_config` VALUES ('applymentImgUploadSize', '进件图片上传大小M', '进件图片上传大小M', 'defaultConfig', '进件图片上传大小配置', '2', 'text', 0, '2023-3-29 10:53:30');
###### v3.2.1 ===> v3.3.0 ###### START ######
-- 订单表 增加索引
ALTER TABLE t_pay_order ADD INDEX `Index_Expired_Time` (`expired_time`) USING BTREE;
ALTER TABLE t_pay_order ADD INDEX `Index_State` (`state`) USING BTREE;
-- 分账订单表 增加索引
ALTER TABLE t_pay_order_division_record ADD INDEX `Index_Created_at` (`created_at`) USING BTREE;
ALTER TABLE t_pay_order_division_record ADD INDEX `Index_State` (`state`) USING BTREE;
ALTER TABLE t_pay_order_division_record ADD INDEX `Index_Pay_Order_Id` (`pay_order_id`) USING BTREE;
-- 转账订单表 增加索引
ALTER TABLE t_transfer_order ADD INDEX `Index_Created_at` (`created_at`) USING BTREE;
-- 钱包流水表 增加索引
ALTER TABLE t_info_account_history ADD INDEX `Index_Created_at` (`created_at`) USING BTREE;
ALTER TABLE t_info_account_history ADD INDEX `Index_Rela_Biz_Order_Id` (`rela_biz_order_id`) USING BTREE;
-- 商户通知记录表 增加索引
ALTER TABLE t_mch_notify_record ADD INDEX `Index_Created_at` (`created_at`) USING BTREE;
-- 退款订单表 增加索引
ALTER TABLE t_refund_order ADD INDEX `Index_Created_at` (`created_at`) USING BTREE;
ALTER TABLE t_refund_order ADD INDEX `Index_Pay_Order_Id` (`pay_order_id`) USING BTREE;
ALTER TABLE t_refund_order ADD INDEX `Index_Channel_Order_No` (`channel_order_no`) USING BTREE;
-- 支付订单表 returnUrl 字段扩充
alter table t_pay_order modify column `notify_url` VARCHAR(256) DEFAULT '' COMMENT '异步通知地址';
alter table t_pay_order modify column `return_url` VARCHAR(256) DEFAULT '' COMMENT '页面跳转地址';
-- 转账列表数据统计
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER_COUNT', '按钮:统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TRANSFER_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_TRANSFER_ORDER_COUNT', '按钮:统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_TRANSFER_ORDER', '0', 'MCH', '{mchLevelArray: ["M1"]}', now(), now());
-- 修改数据统计定时任务时间
UPDATE xxl_job_info SET schedule_conf = '0 1 0 * * ?' WHERE id = 12;
###### v3.3.0 ===> v3.3.1 ###### START ######
-- 订单表新增服务商机构号和子商户号、会员ID和会员手机号字段增加凭证交易单号索引
ALTER TABLE t_pay_order ADD INDEX `Index_Platform_Order_No` (`platform_order_no`) USING BTREE;
ALTER TABLE t_pay_order ADD COLUMN `mbr_id` VARCHAR(64) COMMENT '会员ID' after `store_user_id`;
ALTER TABLE t_pay_order ADD COLUMN `mbr_tel` VARCHAR(32) COMMENT '会员手机号' after `mbr_id`;
ALTER TABLE t_pay_order ADD COLUMN `channel_isv_no` VARCHAR(64) COMMENT '渠道服务商机构号' after `body`;
ALTER TABLE t_pay_order ADD COLUMN `channel_mch_no` VARCHAR(128) COMMENT '渠道子商户号' after `channel_isv_no`;
###### v3.3.1 ===> next ###### v3.3.2 ######
-- 新增数字人民币支付方式
INSERT INTO t_pay_way (way_code, way_name, way_type) VALUES ('DCEP_BAR', '数字人民币条码', 'DCEPPAY');
INSERT INTO t_pay_way (way_code, way_name, way_type) VALUES ('DCEP_QR', '数字人民币二维码', 'DCEPPAY');
-- 订单增加 手续费快照
alter table t_pay_order modify column `mch_fee_amount` BIGINT(20) NOT NULL COMMENT '商户实际手续费,单位分 ( 订单手续费 - 手续费退还金额 )' ;
alter table t_pay_order add column `mch_order_fee_amount` BIGINT(20) NOT NULL COMMENT '商户收单手续费,单位分 (订单快照)' after `mch_fee_amount`;
update t_pay_order set mch_order_fee_amount = mch_fee_amount;
alter table t_refund_order add column `refund_fee_amount` BIGINT(20) NOT NULL COMMENT '手续费退还金额, 单位:分' after `refund_amount`;
update t_refund_order set refund_fee_amount = 0;
-- 新增字段。
alter table t_pay_interface_define add column `channel_fee_cal_model` VARCHAR(256) COMMENT '渠道手续费计算方式, 包括: 手续费模式等' after `way_codes`;
-- 分账记录表 分账状态扩展
alter table t_pay_order_division_record modify column `state` TINYINT(6) NOT NULL COMMENT '状态: 0-待分账 1-分账成功(明确成功), 2-分账失败(明确失败), 3-分账处理中(一般为渠道侧或定时任务), 4-分账已受理(上游受理)';
-- 分账补单定时任务
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (17, 1, '处理分账补单定时任务(分钟)', '2022-09-01 00:00:00', '2022-09-01 00:00:00', 'sys', '', 'CRON', '0 0/1 * * * ?', 'DO_NOTHING', 'FIRST', 'divisionRecordReissueTaskHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', '处理分账补单定时任务(分钟)', '2022-09-01 00:00:00', '', 1, 0, 0);
###### v3.3.2 ===> next ###### v3.3.3 ######
-- 钱包流水表增加备注字段
ALTER TABLE t_info_account_history ADD COLUMN `remark` VARCHAR(128) DEFAULT NULL COMMENT '备注' after `sett_id`;
-- !!!!! 本期 DB时间有更改 建议通过 控制台 手动修改!!! TIMESTAMP(6) --> TIMESTAMP(3) !!!!! 不修改也不影响, 只是 页面查询到 23:59:59 999999 临界值时搜索不到!
###### v3.3.3 ===> next ###### v3.3.5 ######
-- 静态文件CDN域名
INSERT INTO `t_sys_config` VALUES ('staticCdnHost', '静态文件CDN域名(不包含结尾/)', '静态文件CDN域名(不包含结尾/)', 'applicationConfig', '系统应用配置', 'https://cdn.staticfile.org', 'text', 10, '2021-5-18 14:46:10');
INSERT INTO `t_sys_config` VALUES ('smsProvideKey', '短信使用厂商', '短信使用厂商', 'smsConfig', '短信使用厂商', 'jeepaydx', 'text', 0, '2023-8-17 11:02:00');
INSERT INTO `t_sys_config` VALUES ('jeepaydxSmsConfigValue', '[计全短信]短信配置', '[计全短信]短信配置', 'smsConfig', '[计全短信]短信配置', '{"userName": "", "accountPwd": "", "signName": ""}', 'text', 0, '2023-8-17 11:02:00');
INSERT INTO `t_sys_config` VALUES ('mocktestSmsConfigValue', '[模拟测试]短信配置', '[模拟测试]短信配置', 'smsConfig', '[模拟测试]短信配置', '{"mockCode": "111111"}', 'text', 0, '2023-8-18 11:02:00');
-- 更新名称
update t_sys_config set config_key = 'aliyundySmsConfigValue' where config_key = 'smsConfigValue';
-- 存量配置 默认使用 阿里云短信
update t_sys_config set config_val = 'aliyundy' where config_key = 'smsProvideKey';
###### v3.3.5 ===> next ###### v3.3.6 ######
-- 注意: redis配置有变化 appliaction.yml 新增: sys-prefix-key 有默认值, 可配置为空。 如不变更上线后所有的当前业务缓存失效
-- 建议保持当前的业务前缀, 即所有的key缓存失效 业务自动创建即可。
-- 码牌增加URL占位符
alter table `t_mch_qrcode_card` add column `url_placeholder` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'URL自定义占位符一般仅绑定多个小程序时需要' after `entry_page`;
-- 【运营平台】订单管理:直付通结算订单
insert into t_sys_entitlement values('ENT_ZFT_SETT_RECORD', '直付通结算订单', 'account-book', '/settle/zft', 'ZftSettRecordPage', 'ML', 0, 1, 'ENT_ORDER', '50', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ZFT_SETT_RECORD_LIST', '页面:提现记录列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ZFT_SETT_RECORD', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_ZFT_SETT_RECORD_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_ZFT_SETT_RECORD', '0', 'PLATFORM', null, now(), now());
######
v3.3.6 ===> v3.4.0 ###### START ######
alter table `t_pay_order_division_record`
add column `cal_base_amount_type` VARCHAR(16) NOT NULL DEFAULT 'INCOME_AMOUNT' COMMENT '计算分账金额的分账基数规则(退分使用) ORDER_AMOUNT-订单金额, INCOME_AMOUNT-入账金额(订单金额-手续费)' after `pay_order_division_amount`;
-- 进件自动配置
alter table `t_mch_applyment`
add column `auto_config_mch_app_id` VARCHAR(64) COMMENT '自动配置的应用ID不为空自动进行关联等一系列配置' after `apply_page_type`;
alter table `t_mch_applyment`
add column `auto_config_result_info` TEXT COMMENT '自动配置结果信息' after `auto_config_mch_app_id`;
-- 新增转账产品
INSERT INTO t_pay_way (way_code, way_name, way_type)
VALUES ('TRANSFER', '转账', 'TRANSFER');
-- 自营商户号
INSERT INTO `t_sys_config`
VALUES ('platformSelfMchNo', '自营商户号', '自营商户号', 'defaultConfig', '自营商户号', '', 'text', 0,
'2023-9-20 09:27:00');
-- 转账费率的计算
alter table `t_transfer_order`
add column `mch_fee_rate` VARCHAR(256) COMMENT '商户转账手续费费率快照, 空表示没有配置费率信息,但是不影响转账。 无非就是统计数据不准确+代理商无法计算分润。' after `if_code`;
alter table `t_transfer_order`
add column `mch_order_fee_amount` BIGINT(20) COMMENT '商户转账手续费,单位分 (订单快照)' after `mch_fee_rate`;
-- 直付通二级商户结算记录表新增字段
alter table `t_pay_alizft_sett_record`
add column `app_id` VARCHAR(64) NOT NULL COMMENT '应用ID' after `pay_order_id`;
alter table `t_pay_alizft_sett_record`
add column `mch_no` VARCHAR(64) NOT NULL COMMENT '商户号' after `app_id`;
alter table `t_pay_alizft_sett_record`
add column `mch_name` VARCHAR(30) NOT NULL COMMENT '商户名称' after `mch_no`;
alter table `t_pay_alizft_sett_record`
add column `agent_no` VARCHAR(64) COMMENT '代理商号' after `mch_name`;
alter table `t_pay_alizft_sett_record`
add column `isv_no` VARCHAR(64) COMMENT '服务商号' after `agent_no`;
alter table `t_pay_alizft_sett_record`
add column `sett_time` DATETIME COMMENT '结算时间' after `state`;
-- 代理商编号 快照
alter table `t_transfer_order`
add column `agent_no` VARCHAR(64) COMMENT '代理商号' after `isv_no`;
-- 直付通结算表增加索引
ALTER TABLE t_pay_alizft_sett_record
ADD INDEX `Index_State` (`state`) USING BTREE;
ALTER TABLE t_pay_alizft_sett_record
ADD INDEX `Index_Created_at` (`created_at`) USING BTREE;
-- 法定节假日配置表
DROP TABLE IF EXISTS `t_sys_legal_day`;
CREATE TABLE `t_sys_legal_day`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`date_type` VARCHAR(20) NOT NULL DEFAULT 'holiday' COMMENT '日期类型 holiday-节假日 workday-工作日',
`date_value` DATE NOT NULL COMMENT '日期',
`created_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP (3) COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `Uni_Date_Value` (`date_value`)
) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8mb4 COMMENT='法定节假日配置表';
-- 法定节假日配置菜单
insert into t_sys_entitlement
values ('ENT_LEGAL_DAY', '节假日管理', 'table', '/legalday', 'LegalDayPage', 'ML', 0, 1, 'ENT_SYS_CONFIG', '40',
'PLATFORM', null, now(), now());
insert into t_sys_entitlement
values ('ENT_LEGAL_DAY_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_LEGAL_DAY', '0', 'PLATFORM', null, now(),
now());
insert into t_sys_entitlement
values ('ENT_LEGAL_DAY_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_LEGAL_DAY', '0', 'PLATFORM', null, now(),
now());
insert into t_sys_entitlement
values ('ENT_LEGAL_DAY_DEL', '按钮:删除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_LEGAL_DAY', '0', 'PLATFORM', null, now(),
now());
-- 支付方式表新增产品类型字段
ALTER TABLE `t_pay_way`
ADD COLUMN `product_type` VARCHAR(20) NOT NULL DEFAULT 'PAY' COMMENT '产品类型PAY-支付产品, TRANSFER-转账产品' after `way_type`;
-- 修改转账产品
UPDATE t_pay_way
SET product_type = 'TRANSFER'
WHERE way_code = 'TRANSFER';
######
v3.4.0 ===> v3.4.1 ###### START ######
-- 订单退款统计权限
insert into t_sys_entitlement values('ENT_REFUND_ORDER_COUNT', '退款统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement
values ('ENT_REFUND_ORDER_COUNT', '退款统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'MCH',
'{userEntRules: ["USER_TYPE_11_INIT", "USER_TYPE_12_INIT"]}', now(), now());
######
v3.4.1 ===> next ###### START ######

View File

@ -0,0 +1,87 @@
##### jeeppay-plus S3 代理商模块 版本升级SQL #####
###### v3.0.0 ===> v3.1.0 ###### START ######
-- 代理商系统 如意设备菜单
insert into t_sys_entitlement values('ENT_DEVICE_RUYI', '如意Lite', 'file', '/ruyi', 'RuyiPage', 'ML', 0, 1, 'ENT_DEVICE', '60', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_LIST', '页面:列表', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_VIEW', '按钮:详情', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_ADD', '按钮:新增', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_EDIT', '按钮:修改', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'AGENT', null, now(), now());
insert into t_sys_entitlement values('ENT_DEVICE_RUYI_ALLOT', '按钮:划拨/收回', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_RUYI', '0', 'AGENT', null, now(), now());
###### v3.1.0 ===> v3.2.0 ###### START ######
-- 代理商配置表
DROP TABLE IF EXISTS `t_agent_config`;
CREATE TABLE `t_agent_config` (
`agent_no` VARCHAR(64) NOT NULL COMMENT '代理商号',
`config_key` VARCHAR(50) NOT NULL COMMENT '配置KEY',
`config_val` TEXT NOT NULL COMMENT '配置内容项',
`group_key` TEXT 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 (`config_key`, `agent_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='代理商配置表';
-- 代理商进件初始配置项
INSERT INTO `t_sys_config` VALUES ('agentApplymentPreAudit', '代理商进件是否需要运营平台预审核', '代理商进件是否需要运营平台预审核', 'defaultConfig', '进件初始配置', '0', 'text', 0, '2023-3-29 10:53:30');
INSERT INTO `t_sys_config` VALUES ('agentApplyTimeLimit', '代理商发起进件默认时间限制', '代理商发起进件默认时间限制', 'defaultConfig', '进件初始配置', '', 'text', 0, '2023-3-29 10:53:30');
-- 代理商高级配置权限
insert into t_sys_entitlement values('ENT_AGENT_CONFIG_PAGE', '按钮:代理商配置信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
###### v3.3.1 ===> v3.3.2 ###### START ######
-- 代理商提现结算记录表 申请资料和打款凭证
ALTER TABLE `t_cashout_record` MODIFY COLUMN `sett_cert_img` VARCHAR(256) COMMENT '申请资料';
ALTER TABLE t_cashout_record ADD COLUMN `transfer_cert_img` VARCHAR(256) COMMENT '打款凭证(运营平台)' after `sett_cert_img`;
###### v3.3.2 ===> v3.3.3 ###### START ######
insert into t_sys_entitlement values('ENT_PROFIT_CASHOUT_RECORD_COUNT', '页面:统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_PROFIT_CASHOUT_RECORD', '0', 'PLATFORM', null, now(), now());
insert into t_sys_entitlement values('ENT_CASHOUT_RECORD_COUNT', '页面:统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_WALLET', '0', 'AGENT', null, now(), now());
-- 代理商列表
insert into t_sys_entitlement values('ENT_AGENT_INFO_COUNT', '页面:统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_AGENT_INFO', '0', 'PLATFORM', null, now(), now());
###### v3.3.5 ===> v3.3.6 ###### START ######
-- 提现记录增加开户行支行名称
ALTER TABLE t_cashout_record ADD COLUMN `sett_account_sub_bank` VARCHAR(32) COMMENT '开户行支行名称' after `sett_account_bank`;
-- 代理商主表增加钱包冻结金额和冻结原因
ALTER TABLE t_agent_info ADD COLUMN `freeze_amount` BIGINT(20) NOT NULL DEFAULT 0 COMMENT '钱包冻结金额, 单位分' after `sipw`;
ALTER TABLE t_agent_info ADD COLUMN `freeze_desc` VARCHAR(256) DEFAULT NULL COMMENT '冻结原因' after `freeze_amount`;
######
v3.3.6 ===> v3.4.0 ###### START ######
-- 代理商提现增加转账接口信息
alter table `t_cashout_record`
add column `transfer_mch_app_id` VARCHAR(64) COMMENT '发起转账的自营应用ID' after `sett_type`;
alter table `t_cashout_record`
add column `transfer_order_id` VARCHAR(64) COMMENT '转账系统订单号' after `transfer_mch_app_id`;
alter table `t_cashout_record`
add column `transfer_if_code` VARCHAR(64) COMMENT '转账接口类型' after `transfer_order_id`;
alter table `t_cashout_record`
add column `transfer_platform_mchfee_amount` BIGINT(20) COMMENT '自营商户费率费用' after `transfer_if_code`;
alter table `t_cashout_record`
add column `transfer_platform_cost_amount` BIGINT(20) COMMENT '平台真实成本费用( 来自转账订单数据 = 自营商户费率费用 - 平台利润 ' after `transfer_platform_mchfee_amount`;
alter table `t_cashout_record`
add column `contact_name` varchar(32) DEFAULT NULL COMMENT '联系人姓名' after `sett_account_telphone`;
######
v3.4.0 ===> v3.4.1 ###### START ######
-- 订单退款统计权限
insert into t_sys_entitlement values('ENT_REFUND_ORDER_COUNT', '退款统计', 'no-icon', '', '', 'PB', 0, 1, 'ENT_REFUND_ORDER', '0', 'AGENT', null, now(), now());
-- 代理商解除码牌权限
insert into t_sys_entitlement
values ('ENT_DEVICE_QRC_RELIEVE', '按钮:解除', 'no-icon', '', '', 'PB', 0, 1, 'ENT_DEVICE_QRC', '0', 'AGENT', null,
now(), now());
-- 代理商子商户配置权限
insert into t_sys_entitlement
values ('ENT_MCH_CONFIG_PAGE', '按钮:商户配置信息', 'no-icon', '', '', 'PB', 0, 1, 'ENT_MCH_INFO', '0', 'AGENT', null,
now(), now());
######
v3.4.1 ===> next ###### START ######

View File

@ -0,0 +1,8 @@
##### jeeppay-plus S3 代理商模块 版本升级SQL #####
###### v3.3.2 ===> v3.3.3 ###### START ######
-- 会员账户流水表新增门店ID、码牌ID 快照
ALTER TABLE t_member_account_history ADD COLUMN `store_id` BIGINT(20) COMMENT '商户门店ID (快照)' after `mch_no`;
ALTER TABLE t_member_account_history ADD COLUMN `qrc_id` BIGINT(20) COMMENT '码牌ID (快照)' after `store_id`;
###### v3.3.3 ===> next ###### START ######

View File

@ -0,0 +1,36 @@
CREATE TABLE `t_product_info` (
`product_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '产品ID',
`product_name` varchar(32) NOT NULL COMMENT '产品名称',
`product_desc` varchar(300) NOT NULL COMMENT '产品简介',
`product_content` text DEFAULT NULL COMMENT '产品内容',
`product_url` varchar(300) DEFAULT NULL COMMENT '开发文档地址',
`product_type` tinyint(6) NOT NULL DEFAULT '1' COMMENT '产品分类 1-支付产品',
`product_state` tinyint(6) NOT NULL DEFAULT '0' COMMENT '产品状态 0-已下架 1-已上架 2-已删除',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建者',
`created_at` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='产品信息表';
CREATE TABLE `t_product_app` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`product_id` bigint(20) NOT NULL COMMENT '产品ID',
`app_id` varchar(64) DEFAULT NULL COMMENT '应用ID',
`mch_no` varchar(64) DEFAULT NULL COMMENT '商户号',
`state` tinyint(6) NOT NULL DEFAULT '0' COMMENT '状态 0-未开通 1-审核中 2-审核失败 3-已开通 4-已取消',
`state_desc` varchar(300) DEFAULT NULL COMMENT '审核原因',
`created_at` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `UQ_PRODUCT_APP` (`id`,`product_id`,`app_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商户产品审核表';
CREATE TABLE `t_product_type` (
`type_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类ID',
`type_name` varchar(32) NOT NULL COMMENT '分类名称',
`pid` tinyint(6) NOT NULL DEFAULT '0' COMMENT '父节点',
`created_by` varchar(32) DEFAULT NULL COMMENT '创建者',
`created_at` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`updated_at` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
PRIMARY KEY (`type_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='产品分类表';

14
docs/sql/readme.md Normal file
View File

@ -0,0 +1,14 @@
### sql说明
1. init_0.sql 必须执行支付基础模块所有的表结构以及基本的初始化语句有drop操作生产环境谨慎执行
2. init_1_t_sys_entitlement.sql 必须执行,支付基础模块的系统菜单权限初始化语句
3. init_2_agent_features.sql 按需执行,若采购项目中包含代理商模块则需要执行; 不执行不影响使用,但是会缺少代理商模块;
4. init_3_xxl_job.sql 必须执行,分布式定时任务初始化语句
5. init_4_member_features.sql 按需执行,若采购项目中包含会员模块则需要执行; 不执行不影响使用,但是会缺少会员模块;
6. channel.sql 按需执行,初始化支付渠道接口配置
7. test.sql 按需执行,测试数据
8. patch_v3.sql S3版本支付基础模块升级sql版本升级时对应执行升级版本的sql
9. patch_v3_agent.sql S3版本代理商模块升级sql针对代理商模块版本升级时对应执行升级版本的sql
bankBranch.sql是支行信息表取自随行付

11
docs/sql/test.sql Normal file
View File

@ -0,0 +1,11 @@
##### 测试数据 #####
##

View File

@ -0,0 +1,20 @@
ALTER TABLE `t_mch_applyment`
ADD COLUMN `remain_step` tinyint(1) NULL COMMENT '入网操作剩余步骤,总共有几步主要看通道' AFTER `state`;
ALTER TABLE `t_mch_app`
ADD COLUMN `extv` json DEFAULT NULL COMMENT '额外配置字段' AFTER `remark`;
ALTER TABLE `t_mch_applyment`
ADD COLUMN `cert_states` varchar(255) NULL COMMENT '子商户认证状态' AFTER `channel_var2`;
ALTER TABLE `t_mch_applyment`
ADD COLUMN `remark` text NULL COMMENT '备注信息' AFTER `state`;
ALTER TABLE `t_mch_applyment`
ADD COLUMN `channel_mch_no` varchar(64) CHARACTER SET utf8mb4 NULL DEFAULT NULL COMMENT '通道商户号,收单机构编号' AFTER `channel_diy_mch_no`;
ALTER TABLE `t_mch_applyment`
ADD COLUMN `settlement_type` varchar(2) CHARACTER SET utf8mb4 NULL DEFAULT NULL COMMENT 'D1、D0、T1' AFTER `apply_page_type`;
ALTER TABLE `t_mch_store`
ADD COLUMN `mch_apply_id` varchar(64) NULL COMMENT '商户号(原进件单号)' AFTER `bind_app_id`;

185
jeepay-agent/pom.xml Normal file
View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <!-- POM模型版本 -->
<groupId>com.jeequan</groupId> <!-- 组织名, 类似于包名 -->
<artifactId>jeepay-9219-agent</artifactId> <!-- 项目名称 -->
<packaging>jar</packaging> <!-- 项目的最终打包类型/发布形式, 可选[jar, war, pom, maven-plugin]等 -->
<version>${isys.version}</version> <!-- 项目当前版本号 -->
<description>Jeepay计全支付系统 [代理商后台管理端]</description> <!-- 项目描述 -->
<url>https://www.jeequan.com</url>
<parent>
<groupId>com.jeequan</groupId>
<artifactId>jeepay</artifactId>
<version>Final</version>
</parent>
<!-- 项目属性 -->
<properties>
<projectRootDir>${basedir}/../</projectRootDir>
</properties>
<!-- 项目依赖声明 -->
<dependencies>
<!-- 依赖[ service ]包, 会自动传递依赖[ core ]包。 -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-components-db</artifactId>
</dependency>
<!-- 依赖[ rpc-thirdparty ]包, 会自动传递依赖[ core , service ]包。 -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-components-3rd</artifactId>
</dependency>
<!-- 依赖[ oss ]包 -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-components-oss</artifactId>
</dependency>
<!-- 依赖[ mq ]包 -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-components-mq</artifactId>
</dependency>
<!-- 依赖[ bizcommons ]包 -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-components-bizcommons</artifactId>
</dependency>
<!-- 依赖 sping-boot-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion> <!-- 删除spring boot默认json映射器 Jackson 引入fastJSON -->
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</exclusion>
<exclusion> <!-- hibernate.validator插件一般不使用 -->
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- spring-security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- spring-aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<!-- freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- 添加redis支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 引入 jeepay-sdk-java -->
<dependency>
<groupId>com.jeequan</groupId>
<artifactId>jeepay-sdk-java</artifactId>
</dependency>
<!-- webSocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
</dependency>
<!--阿里云短信依赖-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
</dependency>
<!-- 阿里大于 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
</dependency>
<!-- 生成二维码工具包 zxing -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
</dependency>
</dependencies>
<!-- 作为可执行jar -->
<build>
<finalName>${project.artifactId}</finalName>
<!-- resources资源配置项 -->
<resources>
<!-- 通用资源文件 -->
<resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes></resource>
<!-- 放置通用配置yml文件 开发时仅配置一套参数即可。 实际生产环境下应在每个项目下 与jar同级目录下新建application.yml覆写对应参数。 -->
<resource>
<directory>../conf/devCommons</directory>
<includes><include>**/*.yml</include></includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
<outputDirectory>${session.executionRootDirectory}/target/</outputDirectory>
</configuration> <!-- 包含本地jar文件 -->
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,151 @@
package com.jeequan.jeepay.agent.aop;
import com.alibaba.fastjson.JSON;
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.exception.BizException;
import com.jeequan.jeepay.core.model.security.JeeUserDetails;
import com.jeequan.jeepay.db.entity.SysLog;
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
* @date 2021-04-27 15:50
*/
@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();
//处理切面任务 发生异常将向外抛出 不记录日志
Object result = point.proceed();
try {
// 基础日志信息
setBaseLogInfo(point, sysLog, JeeUserDetails.getCurrentUserDetails());
sysLog.setOptResInfo(JSON.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, JeeUserDetails.getCurrentUserDetails());
sysLog.setOptResInfo(e instanceof BizException ? e.getMessage() : "请求异常");
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, JeeUserDetails userDetails) 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.setSysType(CS.SYS_ROLE_TYPE.AGENT);
if (userDetails != null) {
sysLog.setUserId(JeeUserDetails.getCurrentUserDetails().getSysUser().getSysUserId());
sysLog.setUserName(JeeUserDetails.getCurrentUserDetails().getSysUser().getRealname());
sysLog.setSysType(JeeUserDetails.getCurrentUserDetails().getSysUser().getSysType());
}
}
}

View File

@ -0,0 +1,66 @@
package com.jeequan.jeepay.agent.bootstrap;
import cn.hutool.core.date.DatePattern;
import cn.hutool.crypto.SmUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.jeequan.jeepay.agent.config.SystemYmlConfig;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 项目初始化操作
* 比如初始化配置文件 读取基础数据 资源初始化等 避免在Main函数中写业务代码
* CommandLineRunner / ApplicationRunner都可以达到要求 只是调用参数有所不同
*
* @author terrfly
*
* @date 2021-04-27 15:50
*/
@Component
public class InitRunner implements CommandLineRunner {
@Autowired private SystemYmlConfig systemYmlConfig;
@Autowired private SysConfigService sysConfigService;
@Override
public void run(String... args) throws Exception {
// 配置是否使用缓存模式
SysConfigService.IS_USE_CACHE = systemYmlConfig.getCacheConfig();
// 初始化系统秘钥
SysConfigService.DB_ENCRYPT_SECRET = systemYmlConfig.getDbEncryptSecret();
SysConfigService.DB_ENCRYPT_SM4 = SmUtil.sm4(SysConfigService.DB_ENCRYPT_SECRET.getBytes());
SysConfigService.HTTP_MESSAGE_ENCRYPT_SECRET = systemYmlConfig.getHttpMessageEncryptSecret();
SysConfigService.HTTP_MESSAGE_ENCRYPT_SM4 = SmUtil.sm4(SysConfigService.HTTP_MESSAGE_ENCRYPT_SECRET.getBytes());
// 支持服务商
SysConfigService.IS_HAS_AGENT_ENT = true;
// 检查是否支持会员
SysConfigService.IS_HAS_MEMBER_ENT = sysConfigService.getById(SysConfigService.MEMBER_ENT_CONFIG) != null;
// 配置是否通信加密 密码修改
SysConfigService.HTTP_MSG_IS_ENCRYPT = sysConfigService.getDBSecurityConfig().httpMsgIsEncrypt();
SysConfigService.PWD_EXPIRED_MUST_RESET = sysConfigService.getDBSecurityConfig().passwordExpiredIsMustModify();
// 配置 平台通信秘钥
SysConfigService.PLATFORM_API_SECRET = sysConfigService.getDBSecurityConfig().getPlatformApiSecret();
//初始化处理fastjson格式
SerializeConfig serializeConfig = SerializeConfig.getGlobalInstance();
serializeConfig.put(Date.class, new SimpleDateFormatSerializer(DatePattern.NORM_DATETIME_PATTERN));
//解决json 序列化时候的 $ref问题
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
}
}

View File

@ -0,0 +1,85 @@
package com.jeequan.jeepay.agent.bootstrap;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
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.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
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
*
* @date 2022-03-14 08:50
*/
@SpringBootApplication
@EnableScheduling
@MapperScan("com.jeequan.jeepay.service.mapper") //Mybatis mapper接口路径
@ComponentScan(basePackages = "com.jeequan.jeepay.*") //由于MainApplication没有在项目根目录 需要配置basePackages属性使得成功扫描所有Spring组件
@Configuration
public class JeepayAgentApplication {
/** main启动函数 **/
public static void main(String[] args) {
//启动项目
SpringApplication.run(JeepayAgentApplication.class, args);
}
/** 支持搜索 {} [] 否则 springboot 提示 HTTP Status 400 Bad Request **/
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory (){
// 修改内置的 tomcat 容器配置
TomcatServletWebServerFactory tomcatServlet = new TomcatServletWebServerFactory();
tomcatServlet.addConnectorCustomizers( connector -> connector.setProperty("relaxedQueryChars", "[]{}") );
return tomcatServlet ;
}
/** fastJson 配置信息 **/
@Bean
public HttpMessageConverters fastJsonConfig(){
// 开启 FastJSON 安全模式
ParserConfig.getGlobalInstance().setSafeMode(true);
//新建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 MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 设置请求的页面大于最大页后操作 true调回到首页false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量默认 500 -1 不受限制
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
}

View File

@ -0,0 +1,70 @@
package com.jeequan.jeepay.agent.config;
import com.jeequan.jeepay.core.cache.RedisUtil;
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
*
* @date 2021-04-27 15:50
*/
@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;
/** 作用:不同系统的前缀。 a.当连接不同的database时可以为空(物理隔离) b.当redis集群时因为必须同一个database所以需通过前缀区分不同系统的业务。 **/
@Value("${spring.redis.sys-prefix-key}")
private String sysPrefixKey;
/** 当前系统的redis缓存操作对象 (主对象) **/
@Primary
@Bean(name = "defaultStringRedisTemplate")
public StringRedisTemplate sysStringRedisTemplate() {
// 赋值前缀key
RedisUtil.SYS_PREFIX_KEY = sysPrefixKey;
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;
}
}

View File

@ -0,0 +1,40 @@
package com.jeequan.jeepay.agent.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 系统Yml配置参数定义Bean
*
* @author terrfly
*
* @date 2021-04-27 15:50
*/
@Component
@ConfigurationProperties(prefix="isys")
@Data
public class SystemYmlConfig {
/** 是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时应开启此配置或在nginx统一配置允许跨域] **/
private Boolean allowCors;
/** 生成jwt的秘钥。 要求每个系统有单独的秘钥管理机制。 **/
private String jwtSecret;
/** DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!] **/
private String dbEncryptSecret;
/** web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!] **/
private String httpMessageEncryptSecret;
/** 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更! **/
private String sysRSA2PrivateKey;
/**支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更! **/
private String sysRSA2PublicKey;
/** 是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常 false表示直接查询DB. **/
private Boolean cacheConfig;
}

View File

@ -0,0 +1,225 @@
package com.jeequan.jeepay.agent.ctrl;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.config.SystemYmlConfig;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.ctrls.AbstractCtrl;
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.model.BaseModel;
import com.jeequan.jeepay.core.model.security.JeeUserDetails;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.MchStore;
import com.jeequan.jeepay.db.entity.PayInterfaceDefine;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* 通用ctrl类
*
* @author terrfly
* @modify zhuxiao
* @date 2021-04-27 15:50
*/
public abstract class CommonCtrl extends AbstractCtrl {
@Autowired protected SystemYmlConfig mainConfig;
@Autowired protected SysConfigService sysConfigService;
@Autowired protected MchInfoService mchInfoService;
@Autowired protected MchStoreService mchStoreService;
@Autowired protected PayInterfaceDefineService payInterfaceDefineService;
@Autowired protected AgentInfoService agentInfoService;
/** 获取当前用户ID */
protected JeeUserDetails getCurrentUser(){
return (JeeUserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
/** 获取当前商户ID **/
protected String getCurrentAgentNo() {
return getCurrentUser().getSysUser().getBelongInfoId();
}
/**
* 获取当前用户登录IP
* @return
*/
protected String getIp() {
return getClientIp();
}
/**
* 校验当前用户是否为超管
* @return
*/
protected ApiRes checkIsAdmin() {
SysUser sysUser = getCurrentUser().getSysUser();
if (sysUser.getUserType() != SysUser.UEST_TYPE_ADMIN) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}else {
return null;
}
}
/** model 存入服务商名称 **/
public void setAgentName(List<? extends BaseModel> modeList) {
if(modeList == null || modeList.isEmpty()){
return ;
}
ArrayList<String> agentNoList = new ArrayList<>();
for (BaseModel model:modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String agentNo = json.getString("agentNo");
agentNoList.add(agentNo);
}
List<AgentInfo> agentInfoList = agentInfoService.list(AgentInfo.gw().select(AgentInfo::getAgentNo, AgentInfo::getAgentName).in(AgentInfo::getAgentNo, agentNoList));
for (BaseModel model:modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String agentNo = json.getString("agentNo");
if(StringUtils.isBlank(agentNo)) {
continue;
}
for (AgentInfo info:agentInfoList) {
if (agentNo.equals(info.getAgentNo())) {
model.addExt("agentName", info.getAgentName());
}
}
}
}
/** model 存入商户名称 **/
public void setMchName(List<? extends BaseModel> modeList) {
if(modeList == null || modeList.isEmpty()){
return ;
}
ArrayList<String> mchNoList = new ArrayList<>();
for (BaseModel model:modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String mchNo = json.getString("mchNo");
mchNoList.add(mchNo);
}
List<MchInfo> mchInfoList = mchInfoService.list(MchInfo.gw().select(MchInfo::getMchNo, MchInfo::getMchName).in(MchInfo::getMchNo, mchNoList));
for (BaseModel model:modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String mchNo = json.getString("mchNo");
if(StringUtils.isBlank(mchNo)) {
continue;
}
for (MchInfo info:mchInfoList) {
if (mchNo.equals(info.getMchNo())) {
model.addExt("mchName", info.getMchName());
}
}
}
}
/** model 存入门店名称 **/
public void setStoreName(List<? extends BaseModel> modeList) {
if (modeList == null || modeList.isEmpty()) {
return;
}
ArrayList<String> storeIdList = new ArrayList<>();
for (BaseModel model : modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String storeId = json.getString("storeId");
storeIdList.add(storeId);
}
List<MchStore> mchInfoList = mchStoreService.list(MchStore.gw().select(MchStore::getStoreId, MchStore::getStoreName).in(MchStore::getStoreId, storeIdList));
for (BaseModel model : modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String storeId = json.getString("storeId");
if (storeId == null) {
continue;
}
for (MchStore store : mchInfoList) {
if (storeId.equals(store.getStoreId())) {
model.addExt("storeName", store.getStoreName());
}
}
}
}
/** model 存入支付接口名称 **/
public void setIfName(List<? extends BaseModel> modeList) {
if(modeList == null || modeList.isEmpty()){
return ;
}
ArrayList<String> ifCodeList = new ArrayList<>();
for (BaseModel model:modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String ifCode = json.getString("ifCode");
ifCodeList.add(ifCode);
}
List<PayInterfaceDefine> defineList = payInterfaceDefineService.list(PayInterfaceDefine.gw().select(PayInterfaceDefine::getIfCode, PayInterfaceDefine::getIfName).in(PayInterfaceDefine::getIfCode, ifCodeList));
for (BaseModel model : modeList) {
JSONObject json = (JSONObject) JSONObject.toJSON(model);
String ifCode = json.getString("ifCode");
if(StringUtils.isBlank(ifCode)) {
continue;
}
for (PayInterfaceDefine define : defineList) {
if (ifCode.equals(define.getIfCode())) {
model.addExt("ifName", define.getIfName());
}
}
}
}
/** 判断当前用户是否有某个权限 */
public boolean currentUserHasEnt(String ent){
return getCurrentUser().getAuthorities().contains(new SimpleGrantedAuthority("ENT_MCH_APPLYMENT_PAY_CONFIG"));
}
/** 根据服务商号查询服务商下的商户号List **/
public List<String> getMchNoListByAgentNo(String agentNo) {
if (StringUtils.isBlank(agentNo)) {
return null;
}
AgentInfo agentInfo = agentInfoService.getById(agentNo);
if (agentInfo == null || agentInfo.getState() != CS.YES) {
throw new BizException("服务商不存在或状态不正确");
}
List<MchInfo> list = mchInfoService.list(MchInfo.gw().eq(com.jeequan.jeepay.core.entity.MchInfo::getAgentNo, agentNo));
if (CollUtil.isEmpty(list)) {
return null;
}
List<String> mchNoList = new LinkedList<>();
list.forEach(mchInfo -> mchNoList.add(mchInfo.getMchNo()));
return mchNoList;
}
}

View File

@ -0,0 +1,267 @@
package com.jeequan.jeepay.agent.ctrl;
import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.service.AuthService;
import com.jeequan.jeepay.bizcommons.manage.auth.AuthByQrcodeManage;
import com.jeequan.jeepay.converter.BaseConverter;
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.exception.BizException;
import com.jeequan.jeepay.core.jwt.JWTPayload;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.security.JeeUserDetails;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.core.utils.TreeDataBuilder;
import com.jeequan.jeepay.core.utils.google.GoogleAuth;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.SysEntitlement;
import com.jeequan.jeepay.db.entity.SysUserEntity;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 当前登录者的信息相关接口
*
* @author terrfly
* @modify zhuxiao
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("api/current")
public class CurrentUserController extends CommonCtrl{
@Autowired private SysEntitlementService sysEntitlementService;
@Autowired private SysUserService sysUserService;
@Autowired private SysUserAuthService sysUserAuthService;
@Autowired private AgentInfoService agentInfoService;
@Autowired private BaseConverter baseConverter;
@RequestMapping(value="/user", method = RequestMethod.GET)
public ApiRes currentUserInfo() {
///当前用户信息
JeeUserDetails jeeUserDetails = getCurrentUser();
SysUserEntity user = sysUserService.getById(jeeUserDetails.getSysUser().getSysUserId());
//1. 当前用户所有权限ID集合
List<String> entIdList = new ArrayList<>();
jeeUserDetails.getAuthorities().forEach(r->entIdList.add(r.getAuthority()));
List<SysEntitlement> allMenuList = new ArrayList<>(); //所有菜单集合
//2. 查询出用户所有菜单集合 (包含左侧显示菜单 其他类型菜单 )
if(!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::getSysType, CS.SYS_ROLE_TYPE.AGENT)
.eq(SysEntitlement::getState, CS.PUB_USABLE));
}
//4. 转换为json树状结构
JSONArray jsonArray = (JSONArray) JSON.toJSON(allMenuList);
List<JSONObject> allMenuRouteTree = new TreeDataBuilder(jsonArray,
"entId", "pid", "children", "entSort", true)
.buildTreeObject();
//5. 所有权限ID集合
user.addExt("entIdList", entIdList);
user.addExt("allMenuRouteTree", allMenuRouteTree);
user.addExt("mchType", jeeUserDetails.getMchType());
//6. 获取服务商简称
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
user.addExt("shortName",agentInfo.getAgentShortName());
// 7. 程序是否支持会员
user.addExt("isHasMemberEnt", SysConfigService.IS_HAS_MEMBER_ENT);
//8.获取邀请码链接信息 商户注册
if (StringUtils.isNotEmpty(user.getInviteCode())) {
// 邀请码二维码地址
String mchRegisterUrl = String.format("%s/register", sysConfigService.getDBApplicationConfig().getMchSiteUrl());
user.addExt("inviteCodeUrl", String.format("%s?c=%s", mchRegisterUrl, user.getInviteCode()));
}
if (StringUtils.isNotEmpty(user.getInviteCode())) {
// 服务商邀请码二维码地址
String agtRegisterUrl = String.format("%s/register", sysConfigService.getDBApplicationConfig().getAgentSiteUrl());
user.addExt("agtInviteCodeUrl", String.format("%s?c=%s", agtRegisterUrl, user.getInviteCode()));
}
return ApiRes.ok(user);
}
/** 修改个人信息 */
@MethodLog(remark = "修改个人信息")
@RequestMapping(value="/user", method = RequestMethod.PUT)
public ApiRes modifyCurrentUserInfo() {
//修改头像
String avatarUrl = getValString("avatarUrl");
String realname = getValString("realname");
Byte sex = getValByte("sex");
//编辑预留信息
String safeWord = getValString("safeWord");
SysUserEntity updateRecord = new SysUserEntity();
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);
}
if (StringUtils.isNotEmpty(safeWord)) {
updateRecord.setSafeWord(safeWord);
}
sysUserService.updateById(updateRecord);
//保存redis最新数据
JeeUserDetails currentUser = getCurrentUser();
SysUserEntity sysUserEntity = sysUserService.getById(getCurrentUser().getSysUser().getSysUserId());
currentUser.setSysUser(baseConverter.toModel(sysUserEntity));
ITokenService.refData(currentUser);
return ApiRes.ok();
}
/** modifyPwd */
@MethodLog(remark = "修改密码")
@RequestMapping(value="modifyPwd", method = RequestMethod.PUT)
public ApiRes modifyPwd() throws BizException{
Long opSysUserId = getCurrentUser().getSysUser().getSysUserId();
//更改密码验证当前用户信息
String currentUserPwd = Base64.decodeStr(getValStringRequired("originalPwd")); //当前用户登录密码
//验证当前密码是否正确
if(!sysUserAuthService.validateCurrentUserPwd(currentUserPwd)){
throw new BizException("原密码验证失败!");
}
String opUserPwd = Base64.decodeStr(getValStringRequired("confirmPwd"));
// 验证原密码与新密码是否相同
if (opUserPwd.equals(currentUserPwd)) {
throw new BizException("新密码与原密码不能相同!");
}
sysUserAuthService.resetAuthInfo(opSysUserId, null, null, true, opUserPwd, CS.SYS_ROLE_TYPE.AGENT);
//调用登出接口
return logout();
}
/** 登出 */
@MethodLog(remark = "退出")
@RequestMapping(value="logout", method = RequestMethod.POST)
public ApiRes logout() throws BizException{
ITokenService.removeIToken(getCurrentUser().getCacheKey(), getCurrentUser().getSysUser().getSysUserId());
return ApiRes.ok();
}
/** MFA验证信息 */
@GetMapping("/mfaInfo")
@MethodLog(remark = "MFA验证信息")
public ApiRes mfaInfo() throws BizException{
SysUserEntity currentUser = sysUserService.getById(getCurrentUser().getSysUserId());
JSONObject resJson = new JSONObject();
resJson.put("mfaBindState", currentUser.getMfaBindState());
resJson.put("telPhone", currentUser.getTelphone());
// 是否展示MFA绑定信息 [未绑定时显示]
if (currentUser.getMfaBindState() == CS.NO) {
String secretKey = sysUserService.getById(currentUser.getSysUserId()).getMfaSecretKey();
// 更新用户验证秘钥
if (StringUtils.isEmpty(secretKey)) {
secretKey = GoogleAuth.generateSecretKey();
sysUserService.updateMFASecret(currentUser.getSysUserId(), secretKey, null);
}
String qrcodeUrl = GoogleAuth.getQRBarcode(
sysConfigService.getOemConfig().getSysName() + "_服务商" +"("+ currentUser.getTelphone() + ")"
, secretKey);
resJson.put("mfaBindUrl", qrcodeUrl);
resJson.put("mfaSecretKey", secretKey);
}
return ApiRes.ok(resJson);
}
/** MFA验证 绑定 */
@RequestMapping(value="mfaBind", method = RequestMethod.PUT)
@MethodLog(remark = "MFA验证绑定")
public ApiRes mfaBind() throws BizException{
String verCode = getValStringRequired("verCode");
Long userId = getCurrentUser().getSysUserId();
// 验证验证码
sysUserService.checkMFACode(userId, verCode);
// 绑定MFA验证
sysUserService.bindMFA(userId);
return ApiRes.ok();
}
/** MFA验证 解绑 */
@RequestMapping(value="mfaRelieve", method = RequestMethod.PUT)
@MethodLog(remark = "MFA验证解除")
public ApiRes mfaRelieve() throws BizException{
String verCode = getValStringRequired("verCode");
Long userId = getCurrentUser().getSysUserId();
// 验证验证码
sysUserService.checkMFACode(userId, verCode);
// 解除MFA验证
sysUserService.relieveMFA(userId, CS.SYS_ROLE_TYPE.AGENT);
return ApiRes.ok();
}
/** app扫码登录接口 */
@PostMapping("qrcode/login")
public ApiRes loginQrcodeConfirm(){
String qrcodeNo = getValStringRequired("qrcodeNo");
String qrCodeStatus = getValStringRequired("qrcodeStatus");
if (!StringUtils.equalsAny(qrCodeStatus, AuthByQrcodeManage.QRCODE_STATUS_SCANED, AuthByQrcodeManage.QRCODE_STATUS_CANCELED,
AuthByQrcodeManage.QRCODE_STATUS_CONFIRMED)) {
return ApiRes.customFail("二维码错误");
}
// 更新状态等待扫码 --> 已扫
if (qrCodeStatus.equals(AuthByQrcodeManage.QRCODE_STATUS_SCANED)) {
AuthByQrcodeManage.updateQrcodeStatusWaiting2Scaned(qrcodeNo);
return ApiRes.ok();
// 更新状态已扫 --> 取消
}else if (qrCodeStatus.equals(AuthByQrcodeManage.QRCODE_STATUS_CANCELED)) {
AuthByQrcodeManage.updateQrcodeStatusScaned2Canceled(CS.SYS_ROLE_TYPE.AGENT, qrcodeNo);
return ApiRes.ok();
}
// 更新状态已扫 --> 确认登录
JSONObject tokenJSON = SpringBeansUtil.getBean(AuthService.class).authByAppQrcode(getCurrentUser().getSysUserId(), JWTPayload.LOGIN_PAGE_TYPE.WEB);
// 更新状态已扫 --> 确认登录
AuthByQrcodeManage.updateQrcodeStatusScaned2Confirmed(qrcodeNo, tokenJSON.toJSONString());
return ApiRes.ok();
}
}

View File

@ -0,0 +1,239 @@
package com.jeequan.jeepay.agent.ctrl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
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.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 统计相关接口
*
* @author terrfly
* @date 2022-03-16 15:50
*/
@RestController
@RequestMapping("/api/stat")
public class StatController extends CommonCtrl{
@Autowired private InfoAccountService infoAccountService;
@Autowired private MchInfoService mchInfoService;
@Autowired private AgentInfoService agentInfoService;
@Autowired private PayOrderService payOrderService;
@Autowired private MchStoreDeviceService mchStoreDeviceService;
@Autowired private SysUserService sysUserService;
@Autowired private MchQrcodeCardService mchQrcodeCardService;
/** 统计数据 **/
@PreAuthorize("hasAnyAuthority('ENT_C_MAIN_AGENT_COUNT', 'ENT_AGENT_STATISTIC_COUNT')")
@RequestMapping(value="/index", method = RequestMethod.GET)
public ApiRes currentUserInfo() {
JSONObject paramJSON = getReqParamJSON();
String agentNo = null;
List<String> agentSubList = null;
// 统计数据类型countType 1-服务商本身数据 2-我与全部下级服务商数据 3-服务商号搜索
Byte countType = paramJSON.getByte("countType");
if (countType != null && countType == 2) {
agentSubList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
} else if (countType != null && countType == 3) {
agentNo = getValStringRequired("agentNo");
}else {
agentNo = getCurrentAgentNo();
}
// 拓展员参数
if (getCurrentUser().isEpUser()) {
paramJSON.put("epUserId", getCurrentUser().getSysUser().getSysUserId());
}
// 1. 钱包余额
InfoAccount infoAccount = infoAccountService.queryById(agentNo, CS.SYS_ROLE_TYPE.AGENT);
JSONObject result = new JSONObject();
result.put("realBalanceAmount", infoAccount == null ? 0L : infoAccount.getBalanceAmount());
result.put("unAmount", infoAccount == null ? 0L : infoAccount.getUnAmount());
result.put("auditProfitAmount", infoAccount == null ? 0L : infoAccount.getAuditProfitAmount());
// 页面上的钱包余额
Long availableBalanceAmount = infoAccount == null ? 0L : infoAccount.getBalanceAmount() - infoAccount.getUnAmount();
result.put("availableBalanceAmount", availableBalanceAmount);
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
// 冻结金额 冻结原因
Long freezeAmount = agentInfo == null ? 0L : agentInfo.getFreezeAmount();
result.put("freezeAmount", freezeAmount);
result.put("freezeDesc", agentInfo == null ? "" : agentInfo.getFreezeDesc());
// 可提现金额页面上的钱包余额-冻结金额
result.put("allowTakeAmount", Math.max(availableBalanceAmount - freezeAmount, 0L));
JSONObject mchJson = mchInfoService.mchCount(agentNo, agentSubList, paramJSON);
result.put("mchCount", mchJson);
JSONObject agentJson = agentInfoService.agentCount(agentNo, agentSubList, paramJSON);
result.put("agentCount", agentJson);
// 日交易统计
String mchNo = paramJSON.getString("mchNo");
Map<String, Object> countMap = payOrderService.tradeCount(mchNo, agentNo, agentSubList, paramJSON);
// 订单统计
result.put("orderCount", countMap);
// 今日交易笔数
result.put("orderTodayCount", countMap.get("payCount"));
// 今日交易金额
result.put("orderTodaySum", countMap.get("payAmount"));
// 码牌总数
long qrCodeCardAllCount = mchQrcodeCardService.count(
MchQrcodeCard.gw()
.eq(MchQrcodeCard::getAgentNo, getCurrentAgentNo())
.eq(MchQrcodeCard::getQrcState, CS.YES));
result.put("qrCodeCardAllCount", qrCodeCardAllCount);
// 已绑定的码牌
long qrCodeCardBindCount = mchQrcodeCardService.count(
MchQrcodeCard.gw()
.eq(MchQrcodeCard::getAgentNo, getCurrentAgentNo())
.eq(MchQrcodeCard::getQrcState, CS.YES)
.eq(MchQrcodeCard::getBindState, CS.YES));
result.put("qrCodeCardBindCount", qrCodeCardBindCount);
// 剩余空码
result.put("qrCodeCardUnBindCount", qrCodeCardAllCount - qrCodeCardBindCount);
// 云喇叭总数
long speakerAllCount = mchStoreDeviceService.count(MchStoreDevice.gw()
.eq(MchStoreDevice::getAgentNo, getCurrentAgentNo())
.eq(MchStoreDevice::getDeviceType, MchStoreDevice.DEVICE_TYPE_SPEAKER)
);
result.put("speakerAllCount", speakerAllCount);
// 未绑定喇叭数
long speakerUnCount = mchStoreDeviceService.count(MchStoreDevice.gw()
.eq(MchStoreDevice::getAgentNo, getCurrentAgentNo())
.eq(MchStoreDevice::getDeviceType, MchStoreDevice.DEVICE_TYPE_SPEAKER)
.eq(MchStoreDevice::getBindState, CS.NO)
);
result.put("speakerUnCount", speakerUnCount);
// 云打印总数
long printerAllCount = mchStoreDeviceService.count(MchStoreDevice.gw()
.eq(MchStoreDevice::getAgentNo, getCurrentAgentNo())
.eq(MchStoreDevice::getDeviceType, MchStoreDevice.DEVICE_TYPE_PRINTER)
);
result.put("printerAllCount", printerAllCount);
// 未绑定打印数
long printerUnCount = mchStoreDeviceService.count(MchStoreDevice.gw()
.eq(MchStoreDevice::getAgentNo, getCurrentAgentNo())
.eq(MchStoreDevice::getDeviceType, MchStoreDevice.DEVICE_TYPE_PRINTER)
.eq(MchStoreDevice::getBindState, CS.NO)
);
result.put("printerUnCount", printerUnCount);
// 扫码pos机总数
result.put("posAllCount", mchStoreDeviceService.count(MchStoreDevice.gw()
.eq(MchStoreDevice::getAgentNo, getCurrentAgentNo())
.eq(MchStoreDevice::getDeviceType, MchStoreDevice.DEVICE_TYPE_POS)
));
// 未绑定扫码pos数
result.put("posUnCount", mchStoreDeviceService.count(MchStoreDevice.gw()
.eq(MchStoreDevice::getAgentNo, getCurrentAgentNo())
.eq(MchStoreDevice::getDeviceType, MchStoreDevice.DEVICE_TYPE_POS)
.eq(MchStoreDevice::getBindState, CS.NO)
));
// 智能pos机总数
result.put("posAllCount", mchStoreDeviceService.count(MchStoreDevice.gw()
.eq(MchStoreDevice::getAgentNo, getCurrentAgentNo())
.eq(MchStoreDevice::getDeviceType, MchStoreDevice.DEVICE_TYPE_AUTO_POS)
));
// 未绑定智能pos数
result.put("posUnCount", mchStoreDeviceService.count(MchStoreDevice.gw()
.eq(MchStoreDevice::getAgentNo, getCurrentAgentNo())
.eq(MchStoreDevice::getDeviceType, MchStoreDevice.DEVICE_TYPE_AUTO_POS)
.eq(MchStoreDevice::getBindState, CS.NO)
));
return ApiRes.ok(result);
}
/**
* @author: xiaoyu
* @date: 2022/3/23 16:39
* @describe: 拓展员商户统计数据
*/
@RequestMapping(value="/userChart", method = RequestMethod.GET)
public ApiRes userChart() {
Long sysUserId = getValLongRequired("sysUserId");
String dateRange = getValString("queryDateRange");
SysUserEntity sysUserEntity = sysUserService.getById(sysUserId);
if (sysUserEntity == null || !sysUserEntity.getBelongInfoId().equals(getCurrentAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
// 返回数据
JSONObject result = new JSONObject();
result.put("mchAllCount", 0);
result.put("mchTodayAddCount", 0);
result.put("mchOnNetCount", 0);
result.put("mchOnNetNewCount", 0);
result.put("payAllAmount", 0);
result.put("payAmount", 0);
// 拓展员邀请的商户
List<MchInfo> list = mchInfoService.list(MchInfo.gw().eq(MchInfo::getCreatedUid, sysUserId));
if (CollUtil.isEmpty(list)) {
return ApiRes.ok(result);
}
String createdStart = null;
String createdEnd = null;
if (StringUtils.isNotEmpty(dateRange)) {
// 获取查询时间请求参数 [开始时间, 结束时间]
Date[] queryDateRangeArray = DateKit.getQueryDateRange(dateRange);
createdStart = DateUtil.formatDateTime(queryDateRangeArray[0]);
createdEnd = DateUtil.formatDateTime(queryDateRangeArray[1]);
}
// 商户总数
long mchAllCount = mchInfoService.mchCount(null, sysUserId, createdStart, createdEnd);
result.put("mchAllCount", mchAllCount);
// 按时间搜索商户数
long mchTodayAddCount = mchInfoService.mchCount(null, sysUserId, createdStart, createdEnd);
result.put("mchTodayAddCount", mchTodayAddCount);
// 商户入网总数
long mchOnNetCount = mchInfoService.mchApplyCount(null, sysUserId, createdStart, createdEnd);
result.put("mchOnNetCount", mchOnNetCount);
// 按时间搜索商户入网数
long mchOnNetNewCount = mchInfoService.mchApplyCount(null, sysUserId, createdStart, createdEnd);
result.put("mchOnNetNewCount", mchOnNetNewCount);
BigDecimal payAllAmount = payOrderService.totalAmount(null, sysUserId, createdStart, createdEnd);
result.put("payAllAmount", payAllAmount);
BigDecimal payAmount = payOrderService.totalAmount(null, sysUserId, createdStart, createdEnd);
result.put("payAmount", payAmount);
return ApiRes.ok(result);
}
}

View File

@ -0,0 +1,37 @@
package com.jeequan.jeepay.agent.ctrl.account;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.AccountChangeInfo;
import com.jeequan.jeepay.service.impl.AccountChangeInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* TODO
*
* @author crystal
* @date 2023/12/6 15:11
*/
@RestController
@RequestMapping("/api/accountChange")
public class AccountChangeInfoController extends CommonCtrl {
@Autowired private AccountChangeInfoService accountChangeInfoService;
@PreAuthorize("hasAuthority('ENT_ACCOUNT_CHANGE_LIST')")
@GetMapping
public ApiRes list() {
AccountChangeInfo info = getObject(AccountChangeInfo.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<AccountChangeInfo> wrapper = AccountChangeInfo.gw(info);
Page<AccountChangeInfo> pages = accountChangeInfoService.pageList(getIPage(),wrapper,info,paramJSON);
return ApiRes.page(pages);
}
}

View File

@ -0,0 +1,259 @@
package com.jeequan.jeepay.agent.ctrl.account;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.DesensitizedUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
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.core.model.applyment.CashoutFee;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.CashoutRecord;
import com.jeequan.jeepay.db.entity.InfoAccount;
import com.jeequan.jeepay.service.impl.AgentInfoService;
import com.jeequan.jeepay.service.impl.CashoutRecordService;
import com.jeequan.jeepay.service.impl.InfoAccountService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* 提现结算记录表
*
* @author xiaoyu
* @date 2022/3/21 10:00
*/
@RestController
@RequestMapping("/api/cashout")
public class CashoutRecordController extends CommonCtrl {
@Autowired private CashoutRecordService cashoutRecordService;
@Autowired private AgentInfoService agentInfoService;
@Autowired private SysConfigService sysConfigService;
@Autowired private InfoAccountService infoAccountService;
/**
* @author: xiaoyu
* @date: 2022/3/21 10:01
* @describe: 提现记录
*/
@PreAuthorize("hasAuthority('ENT_CASHOUT_RECORD_LIST')")
@GetMapping
public ApiRes list() {
CashoutRecord record = getObject(CashoutRecord.class);
JSONObject paramJSON = getReqParamJSON();
record.setInfoId(getCurrentAgentNo());
record.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
LambdaQueryWrapper<CashoutRecord> wrapper = CashoutRecord.gw();
IPage<CashoutRecord> pages = cashoutRecordService.listByPage(getIPage(), record, paramJSON, wrapper);
pages.getRecords().stream().forEach(i -> {
i.setSettAccountName(DesensitizedUtil.chineseName(i.getSettAccountName()));
i.setSettAccountTelphone(DesensitizedUtil.mobilePhone(i.getSettAccountTelphone()));
i.setSettAccountNo(DesensitizedUtil.bankCard(i.getSettAccountNo()));
// 平台手续费不对服务商显示
i.setTransferPlatformCostAmount(null); i.setTransferPlatformMchfeeAmount(null);
i.setTransferMchAppId(null);
i.setTransferIfCode(null);
i.setTransferOrderId(null);
});
return ApiRes.page(pages);
}
/**
* @author: xiaoyu
* @date: 2022/3/21 10:21
* @describe: 提现结算记录详情
*/
@PreAuthorize("hasAuthority('ENT_CASHOUT_RECORD_DETAIL')")
@GetMapping("/{rid}")
public ApiRes detail(@PathVariable("rid") String rid) {
Byte originData = getValByteDefault("originData", CS.YES);
CashoutRecord record = cashoutRecordService.getById(rid);
if (CS.NO == originData) {
// 数据脱敏
record.setSettAccountName(DesensitizedUtil.chineseName(record.getSettAccountName()));
record.setSettAccountTelphone(DesensitizedUtil.mobilePhone(record.getSettAccountTelphone()));
record.setSettAccountNo(DesensitizedUtil.bankCard(record.getSettAccountNo()));
}
if (record == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if (!record.getInfoId().equals(getCurrentAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
// 钱包余额
InfoAccount infoAccount = infoAccountService.queryById(getCurrentAgentNo(), CS.SYS_ROLE_TYPE.AGENT);
record.addExt("realBalanceAmount", infoAccount == null ? 0L : infoAccount.getBalanceAmount());
record.addExt("unAmount", infoAccount == null ? 0L : infoAccount.getUnAmount());
record.addExt("auditProfitAmount", infoAccount == null ? 0L : infoAccount.getAuditProfitAmount());
// 页面上的钱包余额
Long availableBalanceAmount = infoAccount == null ? 0L : infoAccount.getBalanceAmount() - infoAccount.getUnAmount();
record.addExt("availableBalanceAmount", availableBalanceAmount);
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
// 冻结金额 冻结原因
Long freezeAmount = agentInfo == null ? 0L : agentInfo.getFreezeAmount();
record.addExt("freezeAmount", freezeAmount);
record.addExt("freezeDesc", agentInfo == null ? "" : agentInfo.getFreezeDesc());
// 可提现金额页面上的钱包余额-冻结金额
record.addExt("allowTakeAmount", Math.max(availableBalanceAmount - freezeAmount, 0L));
// 平台手续费不对服务商显示
record.setTransferPlatformCostAmount(null); record.setTransferPlatformMchfeeAmount(null);
record.setTransferMchAppId(null);
record.setTransferIfCode(null);
record.setTransferOrderId(null);
return ApiRes.ok(record);
}
/**
* @author: xiaoyu
* @date: 2022/3/21 10:21
* @describe: 发起提现
*/
@MethodLog( remark = "佣金提现")
@PreAuthorize("hasAuthority('ENT_CASHOUT_RECORD_SETT')")
@PostMapping("/sett")
public ApiRes sett() {
String sipw = Base64.decodeStr(getValStringRequired("sipw"));
// 查询当前服务商结算信息
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
if(StringUtils.isEmpty(agentInfo.getSipw())){
throw new BizException("当前未设置支付密码,请进入[账号中心-系统配置-安全管理]设置支付密码");
}
if(!new BCryptPasswordEncoder().matches(sipw, agentInfo.getSipw())){
throw new BizException("支付密码验证失败!");
}
// 结算参数
AgentInfo infoParams = getObject(AgentInfo.class);
if (infoParams == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if (StringUtils.isEmpty(agentInfo.getSettAccountType()) || StringUtils.isEmpty(agentInfo.getSettAccountNo())) {
throw new BizException("请先联系平台配置结算账户信息");
}
if (StringUtils.isEmpty(infoParams.getContactTel()) || StringUtils.isEmpty(infoParams.getContactName())) {
throw new BizException("结算用户名/联系人手机号不可为空");
}
// 提现金额 元转分
Long applyAmount = Long.valueOf(AmountUtil.convertDollar2Cent(getValStringRequired("amount")));
// 提现金额小于最大可提现金额才允许发起提现
InfoAccount infoAccount = infoAccountService.queryById(agentInfo.getAgentNo(), CS.SYS_ROLE_TYPE.AGENT);
// 页面上的钱包余额
Long availableBalanceAmount = infoAccount == null ? 0L : infoAccount.getBalanceAmount() - infoAccount.getUnAmount();
// 可提现金额页面上的钱包余额-冻结金额单位
if (applyAmount > Math.max(availableBalanceAmount - agentInfo.getFreezeAmount(), 0L)) {
throw new BizException("提现金额超限,请刷新页面后重试");
}
CashoutRecord record = getObject(CashoutRecord.class);
record.setApplyAmount(applyAmount);
record.setState(CashoutRecord.CASHOUT_STATE_AUDIT_ING); // 待审核
record.setInfoId(getCurrentAgentNo());
record.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
record.setInfoName(agentInfo.getAgentShortName());
record.setSettType(CashoutRecord.SETT_TYPE_COMM);
CashoutFee cashoutFee = null;
// 使用默认
if(agentInfo.getCashoutFeeRuleType() == 1){
cashoutFee = JSON.parseObject(sysConfigService.getById("castOutFeeRule").getConfigVal(), CashoutFee.class);
}else{
cashoutFee = JSON.parseObject(agentInfo.getCashoutFeeRule(), CashoutFee.class);
}
if(cashoutFee.getApplyLimit() != null && record.getApplyAmount() < cashoutFee.getApplyLimit() ){
throw new BizException("提现额度不可小于" + AmountUtil.convertCent2Dollar(cashoutFee.getApplyLimit()) + "");
}
MutablePair<String, Long> feePair = cashoutFee.calFeeAndSnapshot(record.getApplyAmount());
record.setSettFeeRule(feePair.left);
record.setSettFeeAmount(feePair.right);
record.setSettAmount(record.getApplyAmount() - record.getSettFeeAmount());
if(record.getApplyAmount() <= 0 || record.getSettFeeAmount() < 0 || record.getSettAmount() <= 0){
throw new BizException(String.format("提现金额计算错误! 申请: %s元 手续费%s元 到账:%s元",
AmountUtil.convertCent2Dollar(record.getApplyAmount()),
AmountUtil.convertCent2Dollar(record.getSettFeeAmount()),
AmountUtil.convertCent2Dollar(record.getSettAmount())
));
}
// 结算账户信息
record.setSettAccountType(agentInfo.getSettAccountType());
// 结算人姓名 优先取值运营平台设置的费率 如果为空那么取 服务商申请时填入的
record.setSettAccountName(StringUtils.defaultIfEmpty(infoParams.getSettAccountName(), record.getContactName()));
record.setContactName(infoParams.getContactName());
record.setSettAccountBank(agentInfo.getSettAccountBank());
record.setSettAccountSubBank(agentInfo.getSettAccountSubBank());
record.setSettAccountNo(agentInfo.getSettAccountNo());
record.setSettAccountTelphone(infoParams.getContactTel());
// 发起提现
cashoutRecordService.settAmount(record);
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2022/3/29 16:54
* @describe: 获取当前服务商费率
*/
@PreAuthorize("hasAuthority('ENT_CASHOUT_PAYWAY_FEE')")
@GetMapping("/paywayFee")
public ApiRes getPaywayFee() {
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
CashoutFee cashoutFee = null;
// 使用默认
if(agentInfo.getCashoutFeeRuleType() == 1){
cashoutFee = JSON.parseObject(sysConfigService.getById("castOutFeeRule").getConfigVal(), CashoutFee.class);
}else{
cashoutFee = JSON.parseObject(agentInfo.getCashoutFeeRule(), CashoutFee.class);
}
return ApiRes.ok(cashoutFee);
}
/** 统计 **/
@PreAuthorize("hasAuthority('ENT_CASHOUT_RECORD_COUNT')")
@GetMapping(value="/count")
public ApiRes count() {
CashoutRecord record = getObject(CashoutRecord.class);
record.setInfoId(getCurrentAgentNo());
Map<String, Object> result = cashoutRecordService.countByCashout(record);
return ApiRes.ok(result);
}
}

View File

@ -0,0 +1,64 @@
package com.jeequan.jeepay.agent.ctrl.account;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.InfoAccountHistory;
import com.jeequan.jeepay.service.impl.InfoAccountHistoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 钱包流水
*
* @author xiaoyu
* @date 2022/3/23 14:20
*/
@RestController
@RequestMapping("/api/accountHistory")
public class InfoAccountHistoryController extends CommonCtrl {
@Autowired private InfoAccountHistoryService infoAccountHistoryService;
/**
* @author: xiaoyu
* @date: 2022/3/23 14:34
* @describe: 钱包流水
*/
@PreAuthorize("hasAuthority('ENT_ACCOUNT_HISTORY_LIST')")
@GetMapping
public ApiRes list() {
InfoAccountHistory history = getObject(InfoAccountHistory.class);
history.setInfoId(getCurrentAgentNo());
history.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
IPage<InfoAccountHistory> pages = infoAccountHistoryService.listByPage(getIPage(), history);
return ApiRes.page(pages);
}
/**
* @author: xiaoyu
* @date: 2022/3/23 14:34
* @describe: 钱包流水详情
*/
@PreAuthorize("hasAuthority('ENT_ACCOUNT_HISTORY_DETAIL')")
@GetMapping("/{hid}")
public ApiRes detail(@PathVariable("hid") String hid) {
InfoAccountHistory history = infoAccountHistoryService.getById(hid);
if (history == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if (!history.getInfoId().equals(getCurrentAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
return ApiRes.ok(history);
}
}

View File

@ -0,0 +1,130 @@
package com.jeequan.jeepay.agent.ctrl.agentconfig;
import cn.hutool.core.codec.Base64;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.AgentConfig;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.ThirdAuthDataEntity;
import com.jeequan.jeepay.service.impl.AgentConfigService;
import com.jeequan.jeepay.service.impl.AgentInfoService;
import com.jeequan.jeepay.service.impl.ThirdAuthDataService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
/***
* 服务商配置
*
* @author terrfly
*
* @date 2022/5/24 11:12
*/
@RestController
@RequestMapping("/api/agentConfig")
public class AgentConfigController extends CommonCtrl {
@Autowired private AgentInfoService agentInfoService;
@Autowired private AgentConfigService agentConfigService;
@Autowired
private ThirdAuthDataService thirdAuthDataService;
@MethodLog(remark = "更改支付密码")
@PutMapping("/agentSipw")
public ApiRes updateSipw() {
String confirmPwd = Base64.decodeStr(getValStringRequired("confirmPwd"));
// 验证原密码
AgentInfo dbAgentInfo = agentInfoService.getById(getCurrentAgentNo());
if(StringUtils.isNotEmpty(dbAgentInfo.getSipw())){
//当前旧密码
String originalPwd = Base64.decodeStr(getValStringRequired("originalPwd"));
if(!new BCryptPasswordEncoder().matches(originalPwd, dbAgentInfo.getSipw())){
throw new BizException("原支付验证失败!");
}
}
AgentInfo agentInfo = new AgentInfo();
agentInfo.setAgentNo(getCurrentAgentNo());
agentInfo.setSipw(new BCryptPasswordEncoder().encode(confirmPwd));
agentInfoService.updateById(agentInfo);
return ApiRes.ok();
}
/** 是否设置了支付密码 **/
@GetMapping("/hasSipwValidate")
public ApiRes hasSipwValidate() {
AgentInfo dbAgentInfo = agentInfoService.getById(getCurrentAgentNo());
return ApiRes.ok(StringUtils.isNotEmpty(dbAgentInfo.getSipw()));
}
/** 验证支付密码是否正确 **/
@PostMapping("/agentSipwValidate")
public ApiRes agentSipwValidate() {
//当前旧密码
String originalPwd = Base64.decodeStr(getValStringRequired("originalPwd"));
// 验证原密码
AgentInfo dbAgentInfo = agentInfoService.getById(getCurrentAgentNo());
return ApiRes.ok(StringUtils.isEmpty(dbAgentInfo.getSipw()) || new BCryptPasswordEncoder().matches(originalPwd, dbAgentInfo.getSipw()));
}
/**
* 根据configKey查询服务商配置
*/
@GetMapping("/{configKey}")
public ApiRes get(@PathVariable("configKey") String configKey) {
AgentConfig config = agentConfigService.getByAgentNoAndConfigKey(getCurrentAgentNo(), configKey);
return ApiRes.ok(config);
}
@PostMapping("/authData")
public ApiRes addAuthData() {
ThirdAuthDataEntity entity = getObject(ThirdAuthDataEntity.class);
Assert.notNull(entity.getType(), "授权渠道[type]不能为空");
Assert.notNull(entity.getSubType(), "授权类型[subType]不能为空");
Assert.notNull(entity.getAuthFileName(), "文件名称[authFileName]不能为空");
Assert.notNull(entity.getValue(), "文件内容[value]不能为空");
ThirdAuthDataEntity one = thirdAuthDataService.lambdaQuery()
.eq(ThirdAuthDataEntity::getAuthFileName, entity.getAuthFileName())
.one();
if (one != null) {
throw new BizException("数据已存在");
}
thirdAuthDataService.save(entity);
return ApiRes.ok();
}
@PostMapping("/config")
public ApiRes setConfig() {
AgentConfig reqParam = getObject(AgentConfig.class);
Assert.notNull(reqParam, "缺少参数");
Assert.notNull(reqParam.getGroupKey(), "配置分组名称代码[groupKey]不能为空");
Assert.notNull(reqParam.getConfigKey(), "配置名称代码[configKey]不能为空");
Assert.notNull(reqParam.getAgentNo(), "服务商编号[agentNo]不能为空");
Assert.notNull(reqParam.getConfigVal(), "配置项[configVal]未赋值");
agentConfigService.saveOrUpdateConfig(reqParam);
return ApiRes.ok();
}
}

View File

@ -0,0 +1,153 @@
package com.jeequan.jeepay.agent.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 cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.agent.service.AuthService;
import com.jeequan.jeepay.bizcommons.manage.auth.AuthByQrcodeManage;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
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.jwt.JWTPayload;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.JsonKit;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* 登录鉴权
*
* @author terrfly
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("/api/anon/auth")
public class AuthController extends CommonCtrl {
@Autowired private AuthService authService;
@Autowired private SmsManager smsManager;
/** 用户信息认证 获取iToken **/
@RequestMapping(value = "/validate", method = RequestMethod.POST)
@MethodLog(remark = "登录认证")
public ApiRes validate() throws BizException {
String loginPageType = Base64.decodeStr(getValStringRequired("lt")); //登录页面终端类型, 已做base64处理
// 是否app登录
boolean isApp = loginPageType.equals(JWTPayload.LOGIN_PAGE_TYPE.APP) || loginPageType.equals(JWTPayload.LOGIN_PAGE_TYPE.LITE);
String account = Base64.decodeStr(getValStringRequired("ia")); //用户名 i account, 已做base64处理
String ipassport = Base64.decodeStr(getValStringRequired("ip")); //密码 i passport, 已做base64处理
String vercode = isApp ? "" : Base64.decodeStr(getValStringRequired("vc")); // 验证码 vercode, 已做base64处理
String vercodeToken = isApp ? "" : Base64.decodeStr(getValStringRequired("vt")); //验证码token, vercode token , 已做base64处理
String mfaCode = StringUtils.isEmpty(getValString("mc")) ? null : Base64.decodeStr(getValString("mc")); // MFACode, 已做base64处理
// 验证码校验: WEB登录 & 第一次认证MFACode为空的情况
if(!isApp && StringUtils.isEmpty(mfaCode)){
String cacheCode = RedisUtil.getString(CS.getCacheKeyImgCode(vercodeToken));
if(StringUtils.isEmpty(cacheCode) || !cacheCode.equalsIgnoreCase(vercode)){
throw new BizException("验证码有误!");
}
}
// 返回前端 accessToken
return authService.authByAuthentication(account, ipassport, loginPageType, vercodeToken, mfaCode);
}
/** 用户信息认证[手机验证码登录] 获取iToken **/
@RequestMapping(value = "/phoneCode", method = RequestMethod.POST)
@MethodLog(remark = "手机验证码登录")
public ApiRes phoneCode() throws BizException {
String loginPageType = Base64.decodeStr(getValStringRequired("lt")); //登录页面终端类型, 已做base64处理
String phone = Base64.decodeStr(getValStringRequired("phone")); // 手机号, 已做base64处理
String code = Base64.decodeStr(getValStringRequired("code")); // 验证码 code, 已做base64处理
// 校验验证码 && 如果有异常 抛异常
smsManager.checkSmsVercodeThrowBizEx(phone, code, CS.SMS_TYPE_API_ENUM.TYPE_AUTH);
// 返回前端 accessToken
return authService.authByPhoneCode(phone, loginPageType);
}
/** 图片验证码 **/
@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(), CS.VERCODE_CACHE_TIME ); //图片验证码缓存时间: 1分钟
JSONObject result = new JSONObject();
result.put("imageBase64Data", lineCaptcha.getImageBase64Data());
result.put("vercodeToken", vercodeToken);
result.put("expireTime", CS.VERCODE_CACHE_TIME);
return ApiRes.ok(result);
}
/** 轮询 登录二维码状态 **/
@GetMapping("/qrcodeStatus")
public ApiRes qrcodeStatus() {
String qrcodeNo = getValString("qrcodeNo");
// 未传入qrcodeNo直接返回一个并存入rediskeyJEEPAY_LOGIN_QR_qrcodeNo
if (StringUtils.isBlank(qrcodeNo)) {
qrcodeNo = CS.getCacheKeyLoginQrcode(IdUtil.simpleUUID());
AuthByQrcodeManage.setQrcodeStatusWaiting(qrcodeNo);
return ApiRes.ok(JsonKit.newJson("qrcodeNo", qrcodeNo));
}
// 根据传入的qrcodeNo判断二维码被扫状态
String qrCodeStatus = RedisUtil.getString(qrcodeNo);
// redis未查询到qrcodeNo信息
if (StringUtils.isBlank(qrCodeStatus)) {
return ApiRes.ok(JsonKit.newJson("qrcodeStatus", AuthByQrcodeManage.QRCODE_STATUS_EXPRIED));
}
JSONObject resJSON = new JSONObject();
if (qrCodeStatus.startsWith(AuthByQrcodeManage.QRCODE_STATUS_CONFIRMED + "_")){
String tokenStr = qrCodeStatus.replaceFirst(AuthByQrcodeManage.QRCODE_STATUS_CONFIRMED + "_", "");
resJSON = JSONObject.parseObject(tokenStr);
resJSON.put("qrcodeStatus", AuthByQrcodeManage.QRCODE_STATUS_CONFIRMED);
// 清空二维码缓存
AuthByQrcodeManage.delQrcodeStatus(qrcodeNo);
}else if (qrCodeStatus.equals(AuthByQrcodeManage.QRCODE_STATUS_CANCELED)){
resJSON.put("qrcodeStatus", AuthByQrcodeManage.QRCODE_STATUS_CANCELED);
// 清空二维码缓存
AuthByQrcodeManage.delQrcodeStatus(qrcodeNo);
}else {
resJSON.put("qrcodeStatus", qrCodeStatus);
}
return ApiRes.ok(resJSON);
}
}

View File

@ -0,0 +1,110 @@
package com.jeequan.jeepay.agent.ctrl.anon;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.SysClientVersion;
import com.jeequan.jeepay.service.impl.SysClientVersionService;
import lombok.extern.slf4j.Slf4j;
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.List;
/**
* 版本管理
*
* @author xiaoyu
* @date 2021/12/31 11:11
*/
@Slf4j
@RestController
@RequestMapping("/api/anon/clientVersion")
public class ClientVersionController extends CommonCtrl {
@Autowired private SysClientVersionService sysClientVersionService;
/**
* @author: xiaoyu
* @date: 2021/12/31 11:28
* @describe: 版本信息
*/
@RequestMapping(value = "/versionInfo", method = RequestMethod.GET)
public ApiRes versionInfo() {
// 版本号
String versionNumber = getValStringRequired("versionNumber");
SysClientVersion dbClientVersion = sysClientVersionService.getOne(
SysClientVersion.gw()
.eq(SysClientVersion::getClientType, SysClientVersion.CLIENT_TYPE_AGENT)
.eq(SysClientVersion::getVersionSerialNumber, versionNumber)
);
//未查询到当前版本信息, 查询最新版本作为 [强制更新] 的版本
if(dbClientVersion == null){
List<SysClientVersion> newVersionList = sysClientVersionService.page(
new Page<>(1, 1),
new QueryWrapper<SysClientVersion>().lambda().eq(SysClientVersion:: getClientType, SysClientVersion.CLIENT_TYPE_AGENT).orderByDesc(SysClientVersion:: getVersionId)
).getRecords();
if(newVersionList != null && !newVersionList.isEmpty()){
SysClientVersion newVersion = newVersionList.get(0);
newVersion.setForceUpdate(CS.YES);
return ApiRes.ok(newVersion);
}else{
//未查询到 任何版本信息
return ApiRes.ok(new JSONObject());
}
}
// 查询到当前版本信息 需查询当前版本之后的最新版本信息
List<SysClientVersion> newVersionList = sysClientVersionService.page(
new Page<>(1, 1),
new QueryWrapper<SysClientVersion>().lambda()
.eq(SysClientVersion:: getClientType, SysClientVersion.CLIENT_TYPE_AGENT)
.gt(SysClientVersion:: getVersionId, dbClientVersion.getVersionId())
.orderByDesc(SysClientVersion:: getVersionId)
).getRecords();
if(newVersionList == null || newVersionList.isEmpty()){
//未查询到 任何版本信息
return ApiRes.ok(new JSONObject());
}
//最新版本信息
SysClientVersion newVersion = newVersionList.get(0);
//如果当前版本前包含强制更新 则更改当前版本为强制更新版本
long count = sysClientVersionService.count(
new QueryWrapper<SysClientVersion>().lambda()
.eq(SysClientVersion:: getClientType, SysClientVersion.CLIENT_TYPE_AGENT)
.eq(SysClientVersion:: getForceUpdate, CS.YES)
.gt(SysClientVersion:: getVersionId, dbClientVersion.getVersionId())
);
if(count > 0){
newVersion.setForceUpdate(CS.YES);
}
return ApiRes.ok(newVersion);
}
/**
* @author: yr
* @date: 2023/02/10 16:20
* @describe: 服务商App获取最新版下载url
*/
@RequestMapping(value = "/downloadUrl", method = RequestMethod.GET)
public ApiRes downloadUrl() {
LambdaQueryWrapper<SysClientVersion> wrapper = SysClientVersion.gw();
wrapper.eq(SysClientVersion::getClientType, SysClientVersion.CLIENT_TYPE_AGENT);
if (sysClientVersionService.count(wrapper) == 0){
return ApiRes.ok();
}
wrapper.orderByDesc(SysClientVersion::getVersionId);
wrapper.last("limit 1");
return ApiRes.ok(sysClientVersionService.getOne(wrapper).getDownloadUrl());
}
}

View File

@ -0,0 +1,51 @@
package com.jeequan.jeepay.agent.ctrl.anon;
import cn.hutool.core.codec.Base64;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 服务商注册
*
* @author xiaoyu
* @date 2021/12/30 14:59
*/
@RestController
@RequestMapping("/api/anon/register")
public class RegisterController extends CommonCtrl {
@Autowired private SmsManager smsManager;
/** 服务商注册接口 **/
@PostMapping(value = "/agentRegister")
@MethodLog(remark = "服务商注册")
public ApiRes retrieve() throws BizException {
// 服务商名称, 已做base64处理
String agentName = getValStringRequired("agentName");
// 手机号, 已做base64处理
String phone = Base64.decodeStr(getValStringRequired("phone"));
// 验证码, 已做base64处理
String code = Base64.decodeStr(getValStringRequired("code"));
// 确认密码 confirmPassword, 已做base64处理
String confirmPwd = Base64.decodeStr(getValStringRequired("confirmPwd"));
// 邀请码
String inviteCode = getValString("inviteCode");
// 校验验证码 && 如果有异常 抛异常
smsManager.checkSmsVercodeThrowBizEx(phone, code, CS.SMS_TYPE_API_ENUM.TYPE_REGISTER);
// 注册服务商
agentInfoService.mchRegister(phone, confirmPwd, agentName, inviteCode);
return ApiRes.ok();
}
}

View File

@ -0,0 +1,82 @@
package com.jeequan.jeepay.agent.ctrl.anon;
import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.core.aop.MethodLog;
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.core.model.DBsecurityConfig;
import com.jeequan.jeepay.db.entity.SysUserEntity;
import com.jeequan.jeepay.service.impl.SysConfigService;
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;
/*
* 登录密码接口
*
* @author xiaoyu
* @date 2021/6/8 17:09
*/
@RestController
@RequestMapping("/api/anon/cipher")
public class RetrieveController extends CommonCtrl {
@Autowired private SysUserService sysUserService;
@Autowired private SysUserAuthService sysUserAuthService;
@Autowired private SysConfigService sysConfigService;
@Autowired private SmsManager smsManager;
/** 密码找回接口 **/
@RequestMapping(value = "/retrieve", method = RequestMethod.POST)
@MethodLog(remark = "密码找回")
public ApiRes retrieve() throws BizException {
// 手机号, 已做base64处理
String phone = Base64.decodeStr(getValStringRequired("phone"));
// 验证码, 已做base64处理
String code = Base64.decodeStr(getValStringRequired("code"));
// 新密码 password, 已做base64处理
String newPwd = Base64.decodeStr(getValString("newPwd"));
// 验证手机号
smsManager.checkSmsVercodeThrowBizEx(phone, code, CS.SMS_TYPE_API_ENUM.TYPE_RETRIEVE);
SysUserEntity dbUser = sysUserService.getOne(SysUserEntity.gw().eq(SysUserEntity::getTelphone, phone).eq(SysUserEntity::getSysType, CS.SYS_ROLE_TYPE.AGENT));
if (dbUser == null) {
throw new BizException("用户不存在");
}
if (StringUtils.isNotEmpty(newPwd)) {
// 更新用户登录密码
sysUserAuthService.resetAuthInfo(dbUser.getSysUserId(), null, null, true, newPwd, CS.SYS_ROLE_TYPE.AGENT);
// TODO mq更新用户密码
}
return ApiRes.ok();
}
/** 获取密码校验规则正则 **/
@RequestMapping(value = "/pwdRulesRegexp", method = RequestMethod.GET)
public ApiRes getPwdRulesRegexp() throws BizException {
DBsecurityConfig.PasswordRegexp passwordRegexp = sysConfigService.getDBSecurityConfig().getPasswordRegexp();
JSONObject resultJson = null;
if (passwordRegexp != null) {
resultJson = (JSONObject) JSONObject.toJSON(passwordRegexp);
// 查询是否需要审核
String subIsAudit = sysConfigService.getDBDefaultConfig().getAgentNewSubIsAudit();
resultJson.put("subIsAudit", subIsAudit);
}
return ApiRes.ok(resultJson);
}
}

View File

@ -0,0 +1,80 @@
package com.jeequan.jeepay.agent.ctrl.anon;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBOEMConfig;
import com.jeequan.jeepay.core.service.ISysConfigService;
import com.jeequan.jeepay.core.utils.JsonKit;
import com.jeequan.jeepay.db.entity.AgentConfig;
import com.jeequan.jeepay.service.impl.AgentConfigService;
import com.jeequan.jeepay.service.impl.SysAdvertConfigService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 网站信息ctrl
*
* @author terrfly
* @date 2022/2/14 20:56
*/
@RestController
@RequestMapping("/api/anon/siteInfos")
public class SiteInfoController extends CommonCtrl {
@Autowired
private ISysConfigService sysConfigService;
@Autowired
private SysAdvertConfigService advertConfigService;
@Autowired
private AgentConfigService agentConfigService;
@GetMapping(value = "")
public ApiRes getSiteInfos() throws BizException {
JSONObject result = new JSONObject();
result.put("sysConfig", JsonKit.newJson("httpMsgIsEncrypt", SysConfigService.HTTP_MSG_IS_ENCRYPT));
DBOEMConfig dboemConfig = sysConfigService.getOemConfig();
//获取域名
String headerDomainName = getdomainName();
if (headerDomainName != null && headerDomainName.contains("//")) {
int startIndex = headerDomainName.indexOf("//") + 2; // 获取第一个 "//" 后的位置
int endIndex = headerDomainName.indexOf("/", startIndex); // 获取从 startIndex 开始的第一个 "/"
if (endIndex != -1) {
String domainName = headerDomainName.substring(startIndex, endIndex);
result.put("domainName", domainName);
AgentConfig agentConfig = agentConfigService.getOne(AgentConfig.gw().eq(AgentConfig::getGroupKey, "agentSiteConfig").eq(AgentConfig::getConfigVal, domainName).last("limit 1"));
if (agentConfig == null) {
//该域名没配置取总后台数据
result.put("siteInfo", dboemConfig);
return ApiRes.ok(result);
}
//获取商户域名
AgentConfig mchDomainName = agentConfigService.getOne(AgentConfig.gw().eq(AgentConfig::getGroupKey, "agentSiteConfig").eq(AgentConfig::getConfigKey, "mchSiteUrl").eq(AgentConfig::getAgentNo, agentConfig.getAgentNo()));
if (mchDomainName != null) {
result.put("mchDomainName", mchDomainName.getConfigVal());
}
//获取服务商域名
AgentConfig agentDomainName = agentConfigService.getOne(AgentConfig.gw().eq(AgentConfig::getGroupKey, "agentSiteConfig").eq(AgentConfig::getConfigKey, "agentSiteUrl").eq(AgentConfig::getAgentNo, agentConfig.getAgentNo()));
if (mchDomainName != null) {
result.put("agentDomainName", agentDomainName.getConfigVal());
}
AgentConfig oemConfig = agentConfigService.getOne(AgentConfig.gw().eq(AgentConfig::getConfigKey, "oemConfig").eq(AgentConfig::getAgentNo, agentConfig.getAgentNo()));
if (oemConfig == null) {
//贴牌数据为空取总后台数据
result.put("siteInfo", dboemConfig);
return ApiRes.ok(result);
}
result.put("siteInfo", JSONObject.parseObject(oemConfig.getConfigVal()));
}
}
return ApiRes.ok(result);
}
}

View File

@ -0,0 +1,75 @@
package com.jeequan.jeepay.agent.ctrl.anon;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
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.db.entity.SysUserEntity;
import com.jeequan.jeepay.service.impl.SysUserService;
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 xiaoyu
* @date 2021/6/8 17:09
*/
@RestController
@RequestMapping("/api/anon/sms")
public class SmsCodeController extends CommonCtrl {
@Autowired
private SysUserService sysUserService;
@Autowired
private SmsManager smsManager;
/**
* 发送短信验证码
**/
@RequestMapping(value = "/code", method = RequestMethod.POST)
public ApiRes code() throws BizException {
// 验证参数 手机号, 已做base64处理
String phone = getValStringRequired("phone");
String smsType = getValStringRequired("smsType");
String vercodeToken = getValStringRequired("vercodeToken");
String vercode = getValStringRequired("vercode");
String redisVercode = RedisUtil.getString(CS.getCacheKeyImgCode(vercodeToken));
if (!vercode.equalsIgnoreCase(redisVercode)) {
throw new BizException("验证码错误");
}
// 校验用户
checkUser(phone, smsType);
// 发送短信
smsManager.sendSmsVercode(phone, smsType);
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2022/1/14 9:01
* @describe: 校验用户是否存在
*/
private void checkUser(String phone, String smsType) {
SysUserEntity dbUser = sysUserService.getOne(SysUserEntity.gw().eq(SysUserEntity::getTelphone, phone).eq(SysUserEntity::getSysType, CS.SYS_ROLE_TYPE.AGENT));
if (CS.SMS_TYPE_API_ENUM.TYPE_REGISTER.equals(smsType)) {
if (dbUser != null) {
throw new BizException("当前用户已存在");
}
} else {
if (dbUser == null) {
throw new BizException("用户不存在");
}
}
}
}

View File

@ -0,0 +1,64 @@
package com.jeequan.jeepay.agent.ctrl.anon;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.AgentConfig;
import com.jeequan.jeepay.service.impl.AgentConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 服务政策 隐私协议ctrl
*
* @author xiaoyu
* @date 2022/2/16 14:51
*/
@RestController
@RequestMapping("/api/anon/treaty")
public class TreatyController extends CommonCtrl {
@Autowired private AgentConfigService agentConfigService;
@GetMapping(value = "")
public ApiRes getTreaty() throws BizException {
Map<String,Object> result = new HashMap<>();
//获取域名
String headerDomainName = getdomainName();
if (headerDomainName != null && headerDomainName.contains("//")) {
int startIndex = headerDomainName.indexOf("//") + 2; // 获取第一个 "//" 后的位置
int endIndex = headerDomainName.indexOf("/", startIndex); // 获取从 startIndex 开始的第一个 "/"
if (endIndex != -1) {
String domainName = headerDomainName.substring(startIndex, endIndex);
AgentConfig agentConfig = agentConfigService.getOne(AgentConfig.gw().eq(AgentConfig::getGroupKey, "agentSiteConfig")
.eq(AgentConfig::getConfigVal,domainName)
.last("limit 1"));
if (agentConfig == null){
//该域名没配置取总后台数据
return ApiRes.ok(sysConfigService.getTreatyConfig());
}
List<AgentConfig> treatyConfigList = agentConfigService.list(AgentConfig.gw().eq(AgentConfig::getGroupKey, "treatyConfig")
.eq(AgentConfig::getAgentNo,agentConfig.getAgentNo()));
if(treatyConfigList.isEmpty()){
//贴牌数据为空取总后台数据
return ApiRes.ok(sysConfigService.getTreatyConfig());
}else {
for (AgentConfig config : treatyConfigList) {
result.put(config.getConfigKey(), config.getConfigVal());
}
return ApiRes.ok(result);
}
}
}
return ApiRes.ok(sysConfigService.getTreatyConfig());
}
}

View File

@ -0,0 +1,34 @@
package com.jeequan.jeepay.agent.ctrl.applyment;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBDefaultConfig;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 系统默认配置
*
* @author xiaoyu
*
* @date 2023/4/11 9:38
*/
@RestController
@RequestMapping("/api/defaultConfig")
public class DefaultConfigController extends CommonCtrl {
/** 平台默认配置查询 **/
@GetMapping("")
public ApiRes getDefaultConfig() {
JSONObject result = new JSONObject();
// 进件图片大小默认配置
DBDefaultConfig defaultConfig = sysConfigService.getDBDefaultConfig();
result.put("applymentImgUploadSize", defaultConfig.getApplymentImgUploadSize());
return ApiRes.ok(result);
}
}

View File

@ -0,0 +1,54 @@
package com.jeequan.jeepay.agent.ctrl.applyment;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.thirdparty.channel.kqpay.KqpayMchApplymentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping("/api/mchApplyments")
public class KqpayMchApplymentController extends CommonCtrl {
@Autowired
private MchApplymentService mchApplymentService;
@Autowired
private KqpayMchApplymentService kqpayMchApplymentService;
@Autowired
private MchInfoConverter mchInfoConverter;
@PostMapping("/kqSignApply/{recordId}")
public ApiRes signApply(@PathVariable("recordId") String recordId) {
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
com.jeequan.jeepay.core.entity.MchApplyment mchApplyment = kqpayMchApplymentService.signApply(mchInfoConverter.toModel(dbRecord));
MchApplyment applymentResult = new MchApplyment();
BeanUtils.copyProperties(mchApplyment, applymentResult);
// 当状态发生了变化时
if (!dbRecord.getState().equals(applymentResult.getState())) {
// 更新数据
applymentResult.setApplyId(recordId);
applymentResult.setLastApplyAt(new Date());
mchApplymentService.updateById(applymentResult);
}
return ApiRes.ok(applymentResult);
}
}

View File

@ -0,0 +1,38 @@
package com.jeequan.jeepay.agent.ctrl.applyment;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/api/mchApplyments")
public class LklspayMchApplymentController {
/** 拉卡拉获取银行信息列表 **/
@GetMapping("/getLklBankList/{areaCode}/{branchName}")
public ApiRes getLklBankList(@PathVariable("areaCode") String areaCode, @PathVariable("branchName") String branchName) {
HttpResponse httpResponse = null;
try {
String result = null;
if (StringUtils.isNotEmpty(areaCode)) {
httpResponse = HttpRequest.get("https://tkapi.lakala.com/registration/bank?areaCode=" + areaCode + "&bankName=" + branchName).execute();
result = httpResponse.body();
}
return ApiRes.ok(result);
} catch (Exception e) {
throw new BizException(e.getMessage());
} finally {
if (httpResponse != null) {
httpResponse.close();
}
}
}
}

View File

@ -0,0 +1,282 @@
package com.jeequan.jeepay.agent.ctrl.applyment;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.components.mq.model.MchAuditThirdNotifyMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchModifyApplyment;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.IYsApplymentApiService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.db.entity.MchModifyApplymentEntity;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchModifyApplymentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/api/mchApplyments")
public class YspayMchApplymentController extends CommonCtrl {
@Autowired private MchApplymentService mchApplymentService;
@Autowired private MchModifyApplymentService mchModifyApplymentService;
@Autowired private MchAppService mchAppService;
@Autowired private MchInfoConverter mchInfoConverter;
@Autowired private IMQSender mqSender;
/** 银盛 上传图片 **/
@PostMapping("/yspayUpload/{recordId}")
public ApiRes yspayUpload(@PathVariable("recordId") String recordId) {
JSONObject paramJSON = getReqParamJSON();
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_AUDITING && dbRecord.getState() != MchApplyment.STATE_WAIT_VERIFY &&
dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
throw new BizException("当前申请单状态错误,无法继续。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
String respJSONStr = "";
try {
// 更新参数
dbRecord.setApplyDetailInfo(paramJSON.toJSONString());
// 调起接口
com.jeequan.jeepay.core.entity.MchApplyment mchApplymentImg = ysApplymentApiService.uploadImg(mchInfoConverter.toModel(dbRecord));
respJSONStr = mchApplymentImg.getChannelVar1();
MchApplyment updateRecord = new MchApplyment();
updateRecord.setApplyDetailInfo(dbRecord.getApplyDetailInfo());
BeanUtils.copyProperties(mchApplymentImg, updateRecord);
// 更新数据
updateRecord.setApplyId(recordId);
mchApplymentService.updateById(updateRecord);
} catch (BizException e) {
logger.info("请求异常", e);
throw e;
}
return ApiRes.ok(respJSONStr);
}
/** 银盛 资料确认 **/
@PostMapping("/yspayConfirm/{recordId}")
public ApiRes yspayConfirm(@PathVariable("recordId") String recordId) {
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_AUDITING && dbRecord.getState() != MchApplyment.STATE_WAIT_VERIFY &&
dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN && dbRecord.getState() != MchApplyment.STATE_FINISH_SIGN)) {
throw new BizException("当前申请单状态错误,无法继续。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
String respJSONStr = "";
try {
// 提交审核
com.jeequan.jeepay.core.entity.MchApplyment applymentResult = ysApplymentApiService.attachConfirm(mchInfoConverter.toModel(dbRecord));
respJSONStr = applymentResult.getApplyErrorInfo();
MchApplyment updateRecordAudit = new MchApplyment();
BeanUtils.copyProperties(applymentResult, updateRecordAudit);
// 更新数据
updateRecordAudit.setApplyId(recordId);
mchApplymentService.updateById(updateRecordAudit);
} catch (BizException e) {
logger.info("请求异常", e);
throw e;
}
return ApiRes.ok(respJSONStr);
}
/** 银盛 发起合同签约 **/
@PostMapping("/ysSignApply/{recordId}")
public ApiRes ysSignApply(@PathVariable("recordId") String recordId) {
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
// 调起接口
com.jeequan.jeepay.core.entity.MchApplyment applymentResult = ysApplymentApiService.signApply(getReqParamJSON(), mchInfoConverter.toModel(dbRecord));
// 更新商户费率配置
MchApplyment updateRecordAudit = new MchApplyment();
BeanUtils.copyProperties(applymentResult, updateRecordAudit);
// 更新数据
updateRecordAudit.setApplyId(recordId);
mchApplymentService.updateById(updateRecordAudit);
return ApiRes.ok(applymentResult.getChannelVar2());
}
/** 银盛 查询合同签约状态 **/
@PostMapping("/ysSignQuery/{recordId}")
public ApiRes ysSignQuery(@PathVariable("recordId") String recordId) {
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
// 获取当前进件签约信息未发起签约时为空
if (StringUtils.isBlank(dbRecord.getChannelVar2())) {
return ApiRes.ok();
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(IYsApplymentApiService.class);
// 调起接口
com.jeequan.jeepay.core.entity.MchApplyment applymentResult = ysApplymentApiService.signQuery(mchInfoConverter.toModel(dbRecord));
// 更新商户费率配置
MchApplyment updateRecordAudit = mchInfoConverter.toDbEntity(applymentResult);
// 更新数据
updateRecordAudit.setApplyId(recordId);
mchApplymentService.updateById(updateRecordAudit);
if (updateRecordAudit.getState() == MchApplyment.STATE_SUCCESS) {
mchApplymentService.onApplymentSuccess(updateRecordAudit.getApplyId());
mqSender.send(MchAuditThirdNotifyMQ.build(recordId, MchAuditThirdNotifyMQ.TYPE_AUDIT));
}
return ApiRes.ok(applymentResult.getChannelVar2());
}
/** 银盛 签约重发 **/
@PostMapping("/ysSignSendAgain/{recordId}")
public ApiRes ysSignSendAgain(@PathVariable("recordId") String recordId) {
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null) {
MchModifyApplymentEntity modifyApplyment = mchModifyApplymentService.getById(recordId);
if (modifyApplyment == null || modifyApplyment.getState() != MchApplyment.STATE_WAIT_SIGN) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(CS.IF_CODE.YSPAY + "ApplymentApiService", IYsApplymentApiService.class);
// 调起接口
MchModifyApplyment applymentResult = ysApplymentApiService.signSendAgain(getReqParamJSON(), mchInfoConverter.toModel(modifyApplyment));
// 更新数据
if (!StrUtil.isEmpty(applymentResult.getChannelVar1())) {
MchModifyApplymentEntity updateRecordAudit = new MchModifyApplymentEntity();
updateRecordAudit.setApplyId(recordId);
updateRecordAudit.setChannelVar1(applymentResult.getChannelVar1());
mchModifyApplymentService.updateById(updateRecordAudit);
}
return ApiRes.ok(applymentResult.getChannelVar1());
} else {
if (dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(CS.IF_CODE.YSPAY + "ApplymentApiService", IYsApplymentApiService.class);
// 调起接口
com.jeequan.jeepay.core.entity.MchApplyment applymentResult = ysApplymentApiService.signSendAgain(getReqParamJSON(), mchInfoConverter.toModel(dbRecord));
// 更新数据
if (!StrUtil.isEmpty(applymentResult.getChannelVar2())) {
MchApplyment updateRecordAudit = new MchApplyment();
updateRecordAudit.setApplyId(recordId);
updateRecordAudit.setChannelVar2(applymentResult.getChannelVar2());
mchApplymentService.updateById(updateRecordAudit);
}
return ApiRes.ok(applymentResult.getChannelVar2());
}
}
/** 银盛费率配置 **/
@PostMapping("/ysPayRateConfig/{recordId}")
public ApiRes ysPayRateConfig(@PathVariable("recordId") String recordId) {
JSONObject reqParamJSON = getReqParamJSON();
MchApplyment dbRecord = mchApplymentService.getById(recordId);
if (dbRecord == null || (dbRecord.getState() != MchApplyment.STATE_AUDITING && dbRecord.getState() != MchApplyment.STATE_REJECT_WAIT_MODIFY
&& dbRecord.getState() != MchApplyment.STATE_WAIT_SIGN)) {
throw new BizException("请刷新当前申请单状态,该申请单当前状态无法执行该操作。");
}
IYsApplymentApiService ysApplymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(dbRecord.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
// 调起接口
com.jeequan.jeepay.core.entity.MchApplyment applymentResult = ysApplymentApiService.payRateConfig(reqParamJSON, mchInfoConverter.toModel(dbRecord));
// 更新商户费率配置
MchApplyment updateRecordAudit = new MchApplyment();
// 配置成功更新费率
if (applymentResult.getState() != null && applymentResult.getState() == MchApplyment.STATE_SUCCESS) {
BeanUtils.copyProperties(applymentResult, updateRecordAudit);
} else {
applymentResult.setApplyDetailInfo(null);
applymentResult.setState(MchApplyment.STATE_AUDITING);
BeanUtils.copyProperties(applymentResult, updateRecordAudit);
}
// 更新数据
updateRecordAudit.setApplyId(recordId);
mchApplymentService.updateById(updateRecordAudit);
return ApiRes.ok(applymentResult.getChannelVar1());
}
/** 银盛 配置相关信息 **/
@PostMapping("/yspayInterfaceConfig/{applyId}/{mchAppId}")
public ApiRes yspayInterfaceConfig(@PathVariable("applyId") String applyId, @PathVariable("mchAppId") String mchAppId) {
String configType = getValStringRequired("configType"); // PAY_BASE_URL, BIND_APP_ID, SUBSCRIBE_APP_ID, QUERY
String configVal = getValStringRequired("configVal");
MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);
MchAppEntity mchAppEntity = mchAppService.getById(mchAppId);
IYsApplymentApiService applymentApiService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(tbMchApplyment.getIfCode()) + "ApplymentApiService", IYsApplymentApiService.class);
if ("PAY_BASE_URL".equals(configType)) {
return ApiRes.ok(applymentApiService.configPayBaseUrl(configVal, mchAppEntity.getAppId(), mchInfoConverter.toModel(tbMchApplyment)));
} else if ("BIND_APP_ID".equals(configType)) {
return ApiRes.ok(applymentApiService.configBindAppId(configVal, mchAppEntity.getAppId(), mchInfoConverter.toModel(tbMchApplyment)));
} else if ("SUBSCRIBE_APP_ID".equals(configType)) {
return ApiRes.ok(applymentApiService.configSubscribeAppId(configVal, mchAppEntity.getAppId(), mchInfoConverter.toModel(tbMchApplyment)));
}
return ApiRes.customFail("没有[" + configType + "]配置");
}
}

View File

@ -0,0 +1,395 @@
package com.jeequan.jeepay.agent.ctrl.aqf;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.response.AlipayFundAccountbookQueryResponse;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.cache.RedisUtil;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.TransferOrder;
import com.jeequan.jeepay.core.entity.TransferSubject;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.tranfer.TransferBasicInfo;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.impl.SysConfigService;
import com.jeequan.jeepay.service.impl.TransferSubjectService;
import com.jeequan.jeepay.service.impl.TransferWalletService;
import com.jeequan.jeepay.thirdparty.channel.alipay.AliAqfV2Service;
import com.jeequan.jeepay.thirdparty.util.ChannelCertConfigKitBean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@RestController
@RequestMapping("/api/aqfApi")
public class AqfApiController extends CommonCtrl {
@Autowired
private AliAqfV2Service aliAqfV2Service;
@Autowired
private SysConfigService sysConfigService;
@Autowired
private TransferSubjectService transferSubjectService;
@Autowired
private ChannelCertConfigKitBean channelCertConfigKitBean;
@Autowired
private TransferWalletService transferWalletService;
/**
* 签约
*
* @return
*/
@RequestMapping(value = "/signUrl", method = RequestMethod.GET)
public ApiRes signUrl() {
String subId = getValStringRequired("subId");
String resutUrl = aliAqfV2Service.userAgreementPageSign(subId);
return ApiRes.ok(resutUrl);
}
/**
* 支付宝个人代扣协议查询接口
*
* @return
*/
@RequestMapping(value = "/agreementQuery" , method = RequestMethod.GET)
public ApiRes agreementQuery(){
String subId = getValStringRequired("subId");
JSONObject alipayUserAgreementQueryResponse = aliAqfV2Service.userAgreementQuery(subId);
return ApiRes.ok(alipayUserAgreementQueryResponse);
}
/**
* 解约
*
* @return
*/
@RequestMapping(value = "/userAgreementUnsign" , method = RequestMethod.GET)
public ApiRes userAgreementUnsign(){
String subId = getValStringRequired("subId");
JSONObject alipayUserAgreementUnsignResponse = aliAqfV2Service.userAgreementUnsign(subId);
return ApiRes.ok(alipayUserAgreementUnsignResponse);
}
/**
* 记账本查询
*
* @return
*/
@RequestMapping(value = "/alipayFundAccountbookQuery", method = RequestMethod.GET)
public ApiRes alipayFundAccountbookQuery() {
String subId = getValStringRequired("subId");
String walletApplyId = getValString("walletApplyId");
// 设计上一个签约主体可以创建多个记账本实际使用的时候尽量保持一个签约主体只有一个账本
AlipayFundAccountbookQueryResponse alipayFundAccountbookQueryResponse = aliAqfV2Service.fundAccountbookQuery(walletApplyId);
return ApiRes.ok(JSON.parseObject(alipayFundAccountbookQueryResponse.getBody()).getJSONObject("alipay_fund_accountbook_query_response"));
}
/**
* 资金专款拨入商户自身给记账本充值
*
* @return
*/
@RequestMapping(value = "/transPage" , method = RequestMethod.GET)
public ApiRes transPage(){
String subId = getValStringRequired("subId");
String transAmount = getValStringRequired("transAmount");
String transferDesc = getValString("transferDesc");
String transedUrl = aliAqfV2Service.transPage(subId, transAmount,transferDesc);
return ApiRes.ok(transedUrl);
}
/**
* 单笔生成待发待结算信息
*
* @return
*/
@RequestMapping(value = "/settlementData", method = RequestMethod.POST)
public ApiRes settlementDate() {
String currentAgentNo = getCurrentAgentNo();
String transferSubjectIdFq = getValStringRequired("transferSubjectIdFq");
String vc = Base64.decodeStr(getValStringRequired("vc"));
String vt = Base64.decodeStr(getValStringRequired("vt"));
String sipw = Base64.decodeStr(getValStringRequired("sipw"));
// 验证码校验
String cacheCode = RedisUtil.getString(CS.getCacheKeyImgCode(vt));
if(StringUtils.isEmpty(cacheCode) || !cacheCode.equalsIgnoreCase(vc)){
throw new BizException("验证码有误!");
}
TransferSubjectEntity transferSubject = transferSubjectService.getById(transferSubjectIdFq);
if (!transferSubject.getInfoType().equals(CS.SYS_ROLE_TYPE.AGENT)
|| !currentAgentNo.equals(transferSubject.getAgentNo())) {
throw new BizException("非法操作");
}
AgentInfo agentInfo = agentInfoService.getById(transferSubject.getAgentNo());
if (!sipw.equals(agentInfo.getSipw())) {
throw new BizException("支付密码校验失败");
}
SettlementDataModel object = getObject(SettlementDataModel.class);
String date = aliAqfV2Service.settlementData(object.getTransferSubjectIdFq(), object.getTransferOrders());
return ApiRes.ok(date);
}
/**
* 批量生成待结算数据,先入库再发起结算
*/
@PostMapping("/batchSettlementData")
public ApiRes uploadExcel() {
String currentAgentNo = getCurrentAgentNo();
String transferSubjectIdFq = getValStringRequired("transferSubjectIdFq");
String excelFileName = getValStringRequired("excelFileName");
File excelFile = channelCertConfigKitBean.getCertFile(excelFileName);
SettlementDataModel params = getObject(SettlementDataModel.class);
String vc = Base64.decodeStr(getValStringRequired("vc"));
String vt = Base64.decodeStr(getValStringRequired("vt"));
String sipw = Base64.decodeStr(getValStringRequired("sipw"));
// 验证码校验
String cacheCode = RedisUtil.getString(CS.getCacheKeyImgCode(vt));
if(StringUtils.isEmpty(cacheCode) || !cacheCode.equalsIgnoreCase(vc)){
throw new BizException("验证码有误!");
}
TransferSubjectEntity transferSubject = transferSubjectService.getById(transferSubjectIdFq);
if (!transferSubject.getInfoType().equals(CS.SYS_ROLE_TYPE.AGENT)
|| !currentAgentNo.equals(transferSubject.getAgentNo())) {
throw new BizException("非法操作");
}
AgentInfo agentInfo = agentInfoService.getById(transferSubject.getAgentNo());
if (!sipw.equals(agentInfo.getSipw())) {
throw new BizException("支付密码校验失败");
}
List<SettleBatchExcel> dataList = new ArrayList<>();
List<TransferOrder> transferOrderList = new ArrayList<>();
String batch = "BATCH" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6);
try {
InputStream inputStream = Files.newInputStream(excelFile.toPath());
EasyExcel.read(inputStream, SettleBatchExcel.class, new AnalysisEventListener<SettleBatchExcel>() {
@Override
public void invoke(SettleBatchExcel settleBatchExcel, AnalysisContext analysisContext) {
dataList.add(settleBatchExcel);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 解析完成后的操作可以在这里进行一些清理工作
}
}).sheet().doRead();
//把数据新增到收款信息中
Assert.notEmpty(params.getTaskId(), "任务号不能为空");
TransferSubjectEntity sponsor = transferSubjectService.getById(params.getTransferSubjectIdFq());
if (!getCurrentAgentNo().equalsIgnoreCase(sponsor.getAgentNo())) {
throw new BizException("参数非法");
}
if (!Objects.equals(sponsor.getState(), TransferSubject.STATE_ENABLE)) {
throw new BizException("付款账户当前状态不可用");
}
if (!Objects.equals(sponsor.getSignState(), (int) TransferSubject.SIGN_STATE_SUCCESS)) {
throw new BizException("付款账户暂未完成签约");
}
TransferWalletEntity transferWallet = transferWalletService.getByApplyId(sponsor.getTransApplyId(), null);
String extCardInfo = transferWallet.getExtCardInfo();
JSONObject extCardJSON = JSONObject.parseObject(extCardInfo);
Assert.notNull(sponsor, "未获取到对应的转账发起方信息");
for (SettleBatchExcel settleBatchExcel : dataList) {
TransferSubjectEntity receiver = transferSubjectService.getReceiver(sponsor.getIsvNo(),
CS.IF_CODE.ALIAQF, CS.SYS_ROLE_TYPE.AGENT, getCurrentAgentNo(), settleBatchExcel.getAccountNo(),
settleBatchExcel.getEntryType(), settleBatchExcel.getAccountType());
if (receiver == null) {
// 先存储转账接受账户信息
receiver = new TransferSubjectEntity();
receiver.setId("SUB" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
receiver.setAccount(settleBatchExcel.getAccountNo());
receiver.setState(TransferSubject.STATE_ENABLE);
receiver.setSubjectType(TransferSubject.SUBJECT_TYPE_RECEIVER);
receiver.setIsvNo(sponsor.getIsvNo());
receiver.setInfoType(sponsor.getInfoType());
receiver.setMchNo(sponsor.getMchNo());
receiver.setAgentNo(sponsor.getAgentNo());
receiver.setAgentName(sponsor.getAgentName());
receiver.setTopAgentNo(sponsor.getTopAgentNo());
receiver.setTransIfCode(sponsor.getTransIfCode());
receiver.setSignState(sponsor.getSignState());
receiver.setAccountName(settleBatchExcel.getAccountName());
receiver.setAccountType(settleBatchExcel.getAccountType());
receiver.setEntryType(settleBatchExcel.getEntryType());
transferSubjectService.save(receiver);
if (TransferBasicInfo.ENTRY_TYPE_BANK.equalsIgnoreCase(settleBatchExcel.getEntryType())) {
// 保存银联支行信息
JSONObject bankCardBranchInfo = new JSONObject();
if (settleBatchExcel.getInstCity() != null) {
bankCardBranchInfo.put("instName", settleBatchExcel.getInstName());
bankCardBranchInfo.put("instProvince", settleBatchExcel.getInstProvince());
bankCardBranchInfo.put("instCity", settleBatchExcel.getInstCity());
bankCardBranchInfo.put("instBranchName", settleBatchExcel.getInstBranchName());
}
receiver.setAccountMessage(bankCardBranchInfo.toJSONString());
}
}
// 保存一些订单信息
TransferOrder transferOrder = new TransferOrder();
transferOrder.setMchNo(sponsor.getMchNo());
transferOrder.setIsvNo(sponsor.getIsvNo());
transferOrder.setAgentNo(sponsor.getAgentNo());
transferOrder.setTransferSubjectIdFq(params.getTransferSubjectIdFq());
transferOrder.setTransferSubjectIdJs(receiver.getId());
transferOrder.setIfCode(receiver.getTransIfCode());
transferOrder.setWalletId(transferWallet.getId());
transferOrder.setEntryType(settleBatchExcel.getEntryType());
transferOrder.setAccountType(settleBatchExcel.getAccountType());
transferOrder.setAccountName(settleBatchExcel.getAccountName());
transferOrder.setAccountNo(settleBatchExcel.getAccountNo());
transferOrder.setOriginAccountNo(sponsor.getAccount());
transferOrder.setOriginAccountName(sponsor.getAccountName());
transferOrder.setBatchId(batch);
transferOrderList.add(transferOrder);
}
//新增或更新完毕后发起结算
aliAqfV2Service.settlementData(params.getTransferSubjectIdFq(), transferOrderList);
} catch (IOException e) {
logger.info("批量导入安全发代发数据解析失败!");
// 处理异常
}
// dataList 进行后续操作如存储到数据库等
return ApiRes.ok();
}
// /**
// * 代发到户 --不直接调用
// * @return
// */
// @RequestMapping(value = "/transUniTransfer" , method = RequestMethod.GET)
// public ApiRes transUniTransfer(){
// String ersubId = getValStringRequired("ersubId");
// String eesubId = getValStringRequired("eesubId");
// String transAmount = getValStringRequired("transAmount");
// String taskId = getValStringRequired("taskId");
// String transferDesc = getValString("transferDesc");
// AlipayFundTransUniTransferResponse alipayFundTransUniTransferResponse = aliAqfV2Service.transUniTransfer(ersubId, eesubId, getDefaultIsvConfig(), transAmount,taskId,null,transferDesc);
// return ApiRes.ok(alipayFundTransUniTransferResponse);
// }
// /**
// * 代发到卡 --不直接调用
// * @return
// */
// @RequestMapping(value = "/transUniTransferCard" , method = RequestMethod.GET)
// public ApiRes transUniTransferCard(){
// String ersubId = getValStringRequired("ersubId");
// String eesubId = getValStringRequired("eesubId");
// String transAmount = getValStringRequired("transAmount");
// String taskId = getValStringRequired("taskId");
// String transferDesc = getValString("transferDesc");
// AlipayFundTransUniTransferResponse alipayFundTransUniTransferResponse = aliAqfV2Service.transUniTransferCard(ersubId, eesubId, getDefaultIsvConfig(), transAmount, taskId,null,transferDesc);
// return ApiRes.ok(alipayFundTransUniTransferResponse);
// }
/**
* 账单查询
*
* @return
*/
@RequestMapping(value = "/bizfundagentQuery", method = RequestMethod.GET)
public ApiRes bizfundagentQuery() {
String ersubId = getValStringRequired("ersubId");
String startTime = getValStringRequired("startTime");
String endTime = getValStringRequired("endTime");
String pageNo = getValStringRequired("pageNo");
String pageSize = getValStringRequired("pageSize");
JSONObject alipayDataBillBizfundagentQueryResponse = aliAqfV2Service.bizfundagentQuery(ersubId, startTime, endTime, pageNo, pageSize);
return ApiRes.ok(alipayDataBillBizfundagentQueryResponse);
}
/**
* 电子回单申请
*
* @return
*/
@RequestMapping(value = "/applicationForm", method = RequestMethod.GET)
public ApiRes applicationForm() {
String ersubId = getValStringRequired("ersubId");
String transferId = getValStringRequired("transferId");
JSONObject alipayDataBillEreceiptagentApplyResponse = aliAqfV2Service.applicationForm(ersubId, transferId);
return ApiRes.ok(alipayDataBillEreceiptagentApplyResponse);
}
/**
* 电子回单下载地址获取
*
* @return
*/
@RequestMapping(value = "/applicationFormDownload", method = RequestMethod.GET)
public ApiRes applicationFormDownload() {
String ersubId = getValStringRequired("ersubId");
String transferId = getValStringRequired("transferId");
JSONObject alipayDataBillAccountbookereceiptQueryResponse = aliAqfV2Service.applicationFormDownload(ersubId, transferId);
return ApiRes.ok(alipayDataBillAccountbookereceiptQueryResponse);
}
public String getDefaultIsvConfig() {
SysConfig serviceOne = sysConfigService.getOne(SysConfig.gw().eq(SysConfig::getGroupKey, "defaultConfig")
.eq(SysConfig::getConfigKey, "defaultIsvNo"));
if (serviceOne != null) {
return serviceOne.getConfigVal();
}
return null;
}
/**
* 根据付款人信息id获取详情
*/
public TransferSubjectEntity getSubjectOne(String subId){
TransferSubjectEntity transferSubjectEntity = transferSubjectService.getById(subId);
if (transferSubjectEntity != null){
return transferSubjectEntity;
}else {
throw new BizException("未查询到当前付款人信息!");
}
}
}

View File

@ -0,0 +1,254 @@
package com.jeequan.jeepay.agent.ctrl.aqf;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.entity.TransferSubject;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.PackageOrder;
import com.jeequan.jeepay.db.entity.ProductInfo;
import com.jeequan.jeepay.db.entity.TransferSubjectEntity;
import com.jeequan.jeepay.service.impl.AgentInfoService;
import com.jeequan.jeepay.service.impl.PackageOrderService;
import com.jeequan.jeepay.service.impl.ProductInfoService;
import com.jeequan.jeepay.service.impl.TransferSubjectService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* 转账对象信息
*/
@Slf4j
@RestController
@RequestMapping("/api/aqf")
public class AqfController extends CommonCtrl {
@Autowired
private TransferSubjectService transferSubjectService;
@Autowired
private AgentInfoService agentInfoService;
@Autowired
private PackageOrderService packageOrderService;
@Autowired
private ProductInfoService productInfoService;
/**
* 新增付款方账户信息
*
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
public ApiRes addTransferSubject() {
String currentAgentNo = getCurrentAgentNo();
AgentInfo agentInfo = agentInfoService.getById(currentAgentNo);
TransferSubjectEntity transferSubject = getObject(TransferSubjectEntity.class);
// 通过产品开通记录获取应用信息
String openOrderId = transferSubject.getOpenOrderId();
Assert.notNull(openOrderId, "产品开通记录不能为空");
PackageOrder packageOrder = packageOrderService.getById(openOrderId);
Assert.notNull(packageOrder, "未获取到产品开通记录");
ProductInfo productInfo = productInfoService.getDetailById(packageOrder.getProductId());
Assert.notNull(productInfo, "未获取到产品信息");
// 安全发的产品code
if (!"API_ANQUANFA_CP_PAY".equals(productInfo.getApiCode())) {
log.info("所选产品code为{}, 不属于安全发", productInfo.getApiCode());
throw new BizException("所选产品不支持该操作");
}
transferSubject.setAppId(packageOrder.getAppId());
// 当前登录用户信息
transferSubject.setId("SUB" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
SysUser sysUser = getCurrentUser().getSysUser();
transferSubject.setSubjectType(TransferSubject.SUBJECT_TYPE_SPONSOR);
transferSubject.setInfoType(CS.SYS_ROLE_TYPE.AGENT);
transferSubject.setTransApplyId(UUID.randomUUID().toString().replace("-", "").substring(0, 32));
//当前服务商
transferSubject.setAgentNo(getCurrentAgentNo());
if (ObjUtil.isEmpty(agentInfo.getPid())) {
transferSubject.setAgentNo(currentAgentNo);
} else {
String[] split = agentInfo.getPidArr().split(",");
transferSubject.setTopAgentNo(split[split.length - 1]);
}
//获取渠道信息
transferSubject.setIsvNo(agentInfo.getIsvNo());
transferSubject.setCreatedUid(sysUser.getSysUserId());
boolean save = transferSubjectService.save(transferSubject);
if (save) {
return ApiRes.ok();
} else {
return ApiRes.customFail("新增失败!");
}
}
/**
* 查询
*/
@GetMapping("/getPageList")
public ApiRes pageTransferSubject() {
TransferSubjectEntity transferSubject = getObject(TransferSubjectEntity.class);
// 时间搜索
Date[] searchDateRange = transferSubject.buildQueryDateRange();
transferSubject.setFirstDate(searchDateRange[0]);
transferSubject.setLastDate(searchDateRange[1]);
// 可查看自己和全部下级代理数据
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
// 自己和下级服务商
if (CollUtil.isNotEmpty(subAgentNoList)){
transferSubject.setSubAgentNoList(subAgentNoList);
}
IPage<TransferSubjectEntity> pageList = transferSubjectService.getPageList(getIPage(), transferSubject);
return ApiRes.page(pageList);
}
/**
* 查询详情
*/
@GetMapping(value = "/{id}")
public ApiRes getByIdTransferSubject(@PathVariable("id") String id) {
TransferSubjectEntity byId = transferSubjectService.getById(id);
return ApiRes.ok(byId);
}
/**
* 修改
*/
@PutMapping(value = "/{id}")
public ApiRes updateTransferSubject(@PathVariable("id") String id) {
TransferSubjectEntity transferSubject = getObject(TransferSubjectEntity.class);
transferSubject.setId(id);
//当前服务商
transferSubject.setAgentNo(getCurrentAgentNo());
//获取渠道信息
AgentInfo agentInfo = agentInfoService.getById(transferSubject.getAgentNo());
transferSubject.setIsvNo(agentInfo.getIsvNo());
boolean resut = transferSubjectService.updateById(transferSubject);
if (resut) {
return ApiRes.ok();
} else {
return ApiRes.customFail("修改失败!");
}
}
/**
* 删除
*/
@DeleteMapping("/{id}")
public ApiRes deleteTransferSubject(@PathVariable("id") String id) {
boolean resut = transferSubjectService.removeById(id);
if (resut) {
return ApiRes.ok();
} else {
return ApiRes.customFail("删除失败!");
}
}
/**
* 新增收款方账户信息
*/
@PostMapping("/addJs")
public ApiRes addJsTransferSubject() {
String currentAgentNo = getCurrentAgentNo();
AgentInfo agentInfo = agentInfoService.getById(currentAgentNo);
TransferSubjectEntity transferSubject = getObject(TransferSubjectEntity.class);
// 当前登录用户信息
transferSubject.setId("SUB" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
SysUser sysUser = getCurrentUser().getSysUser();
transferSubject.setSubjectType(TransferSubject.SUBJECT_TYPE_RECEIVER);
transferSubject.setCreatedUid(sysUser.getSysUserId());
//当前服务商
transferSubject.setAgentNo(currentAgentNo);
if (ObjUtil.isEmpty(agentInfo.getPid())) {
transferSubject.setAgentNo(currentAgentNo);
} else {
String[] split = agentInfo.getPidArr().split(",");
transferSubject.setTopAgentNo(split[split.length - 1]);
}
transferSubject.setTransIfCode(CS.IF_CODE.ALIAQF);
//获取渠道信息
transferSubject.setIsvNo(agentInfo.getIsvNo());
boolean save = transferSubjectService.save(transferSubject);
if (save) {
return ApiRes.ok();
} else {
return ApiRes.customFail("新增失败!");
}
}
@GetMapping("/getBatchData")
public ApiRes getBatchData() {
String transferSubjects = getValStringRequired("transferSubjects");
List<TransferSubjectEntity> transferSubjectEntityList = new ArrayList<>();
String[] transferSubjectSpli = transferSubjects.split(",");
for (String transferSubjectId : transferSubjectSpli) {
TransferSubjectEntity transferSubjectEntity = transferSubjectService.getById(transferSubjectId);
if (transferSubjectEntity != null) {
transferSubjectEntityList.add(transferSubjectEntity);
}
}
return ApiRes.ok(transferSubjectEntityList);
}
@PostMapping("/state")
public ApiRes exam() {
JSONObject reqParamJSON = getReqParamJSON();
Integer state = reqParamJSON.getInteger("state");
String id = reqParamJSON.getString("id");
String remark = reqParamJSON.getString("remark");
TransferSubjectEntity transferSubjectEntity = transferSubjectService.getById(id);
Assert.notNull(transferSubjectEntity, "付款账户信息不存在");
if (state == TransferSubject.STATE_DISABLE) {
transferSubjectEntity.setState(TransferSubject.STATE_DISABLE);
transferSubjectEntity.setRemark(remark);
transferSubjectService.updateById(transferSubjectEntity);
} else if (state == TransferSubject.STATE_ENABLE) {
transferSubjectEntity.setState(TransferSubject.STATE_ENABLE);
transferSubjectService.updateById(transferSubjectEntity);
} else if (state == TransferSubject.STATE_ENABLE_REVIEW) {
transferSubjectEntity.setState(TransferSubject.STATE_ENABLE_REVIEW);
transferSubjectService.updateById(transferSubjectEntity);
}
return ApiRes.ok();
}
/**
* 统计收款账户总成交金额和总成交笔数
*/
@GetMapping("/getSubStatistics")
public Map<String, Object> getSubStatistics(){
TransferSubjectEntity subject = getObject(TransferSubjectEntity.class);
// 可查看自己和全部下级代理数据
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
// 自己和下级服务商
if (CollUtil.isNotEmpty(subAgentNoList)){
subject.setSubAgentNoList(subAgentNoList);
}
return transferSubjectService.getSubStatistics(subject);
}
}

View File

@ -0,0 +1,120 @@
package com.jeequan.jeepay.agent.ctrl.aqf;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.TaskList;
import com.jeequan.jeepay.service.impl.MchInfoService;
import com.jeequan.jeepay.service.impl.TaskListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
/**
* 任务
*/
@RestController
@RequestMapping("/api/taskList")
public class TaskListController extends CommonCtrl {
@Autowired
private TaskListService taskListService;
@Autowired
private MchInfoService mchInfoService;
/**
* 新增任务
* @return
*/
@RequestMapping(value = "/add" ,method = RequestMethod.POST)
public ApiRes addTaskList(){
TaskList taskList = getObject(TaskList.class);
//当前服务商
taskList.setAgentNo(getCurrentAgentNo());
// 当前登录用户信息
SysUser sysUser = getCurrentUser().getSysUser();
taskList.setId(DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
taskList.setCreatedBy(String.valueOf(sysUser.getSysUserId()));
boolean save = taskListService.save(taskList);
if (save){
return ApiRes.ok();
}else {
return ApiRes.customFail("新增失败!");
}
}
/**
* 查询
* @return
*/
@RequestMapping(value = "/getPageList" ,method = RequestMethod.GET)
public ApiRes getlistTaskList(){
TaskList taskList = getObject(TaskList.class);
// 时间搜索
Date[] searchDateRange = taskList.buildQueryDateRange();
taskList.setFirstDate(searchDateRange[0]);
taskList.setLastDate(searchDateRange[1]);
taskList.setAgentNo(getCurrentAgentNo());
// 可查看自己和全部下级代理数据
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
// 自己和下级服务商
if (CollUtil.isNotEmpty(subAgentNoList)){
taskList.setSubAgentNoList(subAgentNoList);
}
IPage<TaskList> pageList = taskListService.getPageList(getIPage(), taskList);
//Page<TaskList> page = taskListService.page(getIPage(), TaskList.gw(taskList).orderByDesc(TaskList::getCreatedAt));
return ApiRes.page(pageList);
}
/**
* 查询详情
* @return
*/
@RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
public ApiRes getByIdTaskList(@PathVariable("id") Integer id){
TaskList byId = taskListService.getById(id);
return ApiRes.ok(byId);
}
/**
* 修改
* @return
*/
@RequestMapping(value = "/{id}" ,method = RequestMethod.PUT)
public ApiRes updateTaskList(@PathVariable("id") String id){
TaskList taskList = getObject(TaskList.class);
//当前服务商
taskList.setAgentNo(getCurrentAgentNo());
taskList.setId(id);
boolean resut = taskListService.updateById(taskList);
if (resut){
return ApiRes.ok();
}else {
return ApiRes.customFail("修改失败!");
}
}
/**
* 删除
* @return
*/
@RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
public ApiRes deleteTaskList(@PathVariable("id") Integer id){
boolean resut = taskListService.removeById(id);
if (resut){
return ApiRes.ok();
}else {
return ApiRes.customFail("删除失败!");
}
}
}

View File

@ -0,0 +1,122 @@
package com.jeequan.jeepay.agent.ctrl.aqf;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.converter.TransferConverter;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.SysUser;
import com.jeequan.jeepay.core.interfaces.paychannel.ITransferService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.service.ValidatorService;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.core.validate.Add;
import com.jeequan.jeepay.db.entity.SysConfig;
import com.jeequan.jeepay.db.entity.TransferInterfaceConfigEntity;
import com.jeequan.jeepay.db.entity.TransferSubjectEntity;
import com.jeequan.jeepay.db.entity.TransferWalletEntity;
import com.jeequan.jeepay.service.impl.TransferInterfaceConfigService;
import com.jeequan.jeepay.service.impl.TransferSubjectService;
import com.jeequan.jeepay.service.impl.TransferWalletService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.UUID;
/**
* 代付对象
*
* @author deng
* @since 2024/5/9
*/
@Slf4j
@RestController
@RequestMapping("/api/transferSubject")
public class TransferSubjectController extends CommonCtrl {
@Autowired
private TransferInterfaceConfigService transferInterfaceConfigService;
@Autowired
private ValidatorService validate;
@Autowired
private TransferSubjectService transferSubjectService;
@Autowired
private TransferWalletService transferWalletService;
@Autowired
private TransferConverter transferConverter;
/**
* 新增转账发起方
*/
@PostMapping("/sponsor")
public ApiRes sponsor() {
TransferSubjectEntity transferSubject = getObject(TransferSubjectEntity.class);
validate.validate(transferSubject, Add.class);
// 当前登录用户信息
transferSubject.setId("SUB" + DateUtil.format(new Date(), "yyMMdd") + RandomUtil.randomNumbers(6));
SysUser sysUser = getCurrentUser().getSysUser();
transferSubject.setSubjectType("FQ");
transferSubject.setTransApplyId(UUID.randomUUID().toString().replace("-", "").substring(0, 32));
//如果不传递取默认值
if (StringUtils.isEmpty(transferSubject.getIsvNo())) {
SysConfig serviceOne = sysConfigService.getOne(SysConfig.gw().eq(SysConfig::getGroupKey, "defaultConfig")
.eq(SysConfig::getConfigKey, "defaultIsvNo"));
if (serviceOne != null) {
transferSubject.setIsvNo(serviceOne.getConfigVal());
}
}
if (StringUtils.isNotEmpty(transferSubject.getIsvNo())) {
//取对应参数信息
//获取下发金额
TransferInterfaceConfigEntity configEntity = transferInterfaceConfigService.getTransferConfig(transferSubject.getTransIfCode(), transferSubject.getIsvNo(), CS.SYS_ROLE_TYPE.ISV);
if (configEntity != null && StringUtils.isNotEmpty(configEntity.getTransIfParams())) {
String zfbDayMax = JSONObject.parseObject(configEntity.getTransIfParams()).getString("zfbDayMax");
String bankCardDayMax = JSONObject.parseObject(configEntity.getTransIfParams()).getString("bankCardDayMax");
transferSubject.setZfbDayMax(Long.valueOf(zfbDayMax));
transferSubject.setBankCardDayMax(Long.valueOf(bankCardDayMax));
}
}
transferSubject.setCreatedUid(sysUser.getSysUserId());
boolean save = transferSubjectService.save(transferSubject);
if (save) {
return ApiRes.ok();
} else {
return ApiRes.customFail("新增失败!");
}
}
@PostMapping("/refreshBalance")
public ApiRes refreshBalance() {
String transferSubjectId = getValStringRequired("transferSubjectId");
TransferWalletEntity transferWallet = transferWalletService.getByApplyId(transferSubjectId, null);
SpringBeansUtil.getBean(transferWallet.getTransIfCode() + "Transfer");
// 刷新记账本余额
ITransferService transferService = SpringBeansUtil.getBean(transferWallet.getTransIfCode() + "TransferService", ITransferService.class);
MutablePair<String, Long> balanceResult = transferService.queryBalanceAmount(transferConverter.toModel(transferWallet));
// 查询更新余额
transferWallet.setAccountBookBalance(balanceResult.right);
transferWalletService.updateById(transferWallet);
transferWalletService.leftQuota(transferWallet);
return ApiRes.ok(transferWallet);
}
}

View File

@ -0,0 +1,66 @@
package com.jeequan.jeepay.agent.ctrl.article;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.SysArticle;
import com.jeequan.jeepay.service.impl.SysArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* 文章管理类
*
* @author yurong
* @date 2022-07-08 14:15
*/
@RestController
@RequestMapping("api/sysArticles")
public class SysArticleController extends CommonCtrl {
@Autowired private SysArticleService sysArticleService;
/**
* @author: yurong
* @date: 2022-07-08 14:15
* @describe: 文章列表 articleType 1公告
*/
@PreAuthorize("hasAuthority('ENT_ARTICLE_NOTICEINFO')")
@RequestMapping(value = "",method = RequestMethod.GET)
public ApiRes articleList(){
SysArticle sysArticle = getObject(SysArticle.class);
if (sysArticle.getArticleType() == null){
return ApiRes.customFail("文章类型不明确");
}
LambdaQueryWrapper<SysArticle> wrapper = SysArticle.gw();
wrapper.select(SysArticle::getArticleId,SysArticle::getTitle,SysArticle::getSubtitle,SysArticle::getPublisher,SysArticle::getCreatedAt)
.eq(SysArticle::getArticleType,sysArticle.getArticleType())
.apply("FIND_IN_SET('"+ CS.SYS_ROLE_TYPE.AGENT+"',"+SysArticle.ARTICLE_RANGE+")")
.orderByDesc(SysArticle::getPublishTime);
IPage<SysArticle> iPage = sysArticleService.page(getIPage(), wrapper);
return ApiRes.page(iPage);
}
/**
* @author: yurong
* @date: 2022-07-08 14:15
* @describe: 文章详情 articleType 1公告
*/
@PreAuthorize("hasAuthority('ENT_ARTICLE_NOTICEINFO')")
@RequestMapping(value = "/{articleId}",method = RequestMethod.GET)
public ApiRes detail(@PathVariable("articleId") Long articleId){
SysArticle sysArticle = sysArticleService.getById(articleId);
if (sysArticle == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(sysArticle);
}
}

View File

@ -0,0 +1,163 @@
package com.jeequan.jeepay.agent.ctrl.isv;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.IsvInfo;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.IsvInfoEntity;
import com.jeequan.jeepay.db.entity.MchConfig;
import com.jeequan.jeepay.service.impl.IsvInfoService;
import com.jeequan.jeepay.service.impl.PayInterfaceConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* 服务商管理类
*
* @author pangxiaoyu
* @date 2021-06-07 07:15
*/
@RestController
@RequestMapping("/api/isvInfo")
public class IsvInfoController extends CommonCtrl {
@Autowired
private IsvInfoService isvInfoService;
@Autowired
private PayInterfaceConfigService payInterfaceConfigService;
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:12
* @describe: 查询服务商信息列表
*/
@PreAuthorize("hasAuthority('ENT_ISV_LIST')")
@RequestMapping(value = "", method = RequestMethod.GET)
public ApiRes list() {
IsvInfoEntity isvInfoEntity = getObject(IsvInfoEntity.class);
LambdaQueryWrapper<IsvInfoEntity> wrapper = IsvInfoEntity.gw();
if (StringUtils.isNotEmpty(isvInfoEntity.getIsvNo())) {
wrapper.eq(IsvInfoEntity::getIsvNo, isvInfoEntity.getIsvNo());
}
if (StringUtils.isNotEmpty(isvInfoEntity.getIsvName())) {
wrapper.eq(IsvInfoEntity::getIsvName, isvInfoEntity.getIsvName());
}
if (isvInfoEntity.getState() != null) {
wrapper.eq(IsvInfoEntity::getState, isvInfoEntity.getState());
}
wrapper.orderByDesc(IsvInfoEntity::getCreatedAt);
IPage<IsvInfoEntity> pages = isvInfoService.page(getIPage(true), wrapper);
return ApiRes.page(pages);
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:13
* @describe: 查看服务商信息
*/
@PreAuthorize("hasAnyAuthority('ENT_ISV_INFO_VIEW', 'ENT_ISV_INFO_EDIT')")
@RequestMapping(value = "/{isvNo}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("isvNo") String isvNo) {
IsvInfoEntity isvInfoEntity = isvInfoService.getById(isvNo);
if (isvInfoEntity == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(isvInfoEntity);
}
@GetMapping("/isvInfoList")
public ApiRes getIsvInfoList() {
String ifCode = getValStringRequired("ifCode");
String infoType = getValStringRequired("infoType");
String infoId = getValStringRequired("infoId");
String range = getValString("range");
Integer state = getValInteger("state");
String isvName = getValString("isvName");
if ("CURRENTAGENT".equals(infoId)) {
infoId = getCurrentAgentNo();
}
List<IsvInfo> isvAndPayConfig = isvInfoService.getIsvAndPayConfig(infoType, isvName, infoId, ifCode, range, state);
Page<IsvInfo> page = new Page<>();
page.setRecords(isvAndPayConfig);
page.setSize(-1);
page.setPages(1);
if (!CS.SYS_ROLE_TYPE.MCH.equals(infoType)) {
return ApiRes.ok(page);
}
// 如果是查看商户数据则查询他的默认渠道
List<Map<String, String>> defIsv = mchInfoService.getDefIsv(infoId, ifCode);
if (!ObjectUtils.isEmpty(defIsv)) {
Map<String, String> defIsvItem = defIsv.get(0);
page.getRecords().forEach(r -> {
if (r.getIsvNo().equals(defIsvItem.get(MchConfig.getDefIsvKey(ifCode)))) {
r.addExt("defIsv", CS.YES);
}
});
}
return ApiRes.ok(page);
}
@PostMapping("/autoBindIsvConn")
public ApiRes autoBindIsvConn() {
String isvNo = getValStringRequired("isvNo");
String infoId = getValStringRequired("infoId");
String roleType = getValStringRequired("roleType");
Byte configStatus = getValByteRequired("configStatus");
isvInfoService.autoBindIsvConn(isvNo, infoId, roleType, configStatus);
return ApiRes.ok();
}
@PostMapping("/isvConn")
public ApiRes isvConn() {
String isvNo = getValStringRequired("isvNo");
String infoId = getValStringRequired("infoId");
String infoType = getValStringRequired("infoType");
isvInfoService.saveIsvConn(isvNo, infoType, infoId, getCurrentUser().getSysUser());
return ApiRes.ok();
}
@GetMapping("/getSettType")
public ApiRes getSettType() {
String ifCode = getValStringRequired("ifCode");
String infoId = getValStringRequired("infoId");
JSONArray settType = isvInfoService.getSettType(ifCode, infoId);
return ApiRes.ok(settType);
}
@PostMapping("/editStatus")
public ApiRes editStatus() {
String isvNo = getValStringRequired("isvNo");
String ifCode = getValStringRequired("ifCode");
String infoId = getValStringRequired("infoId");
String infoType = getValStringRequired("infoType");
Integer status = getValIntegerRequired("state");
isvInfoService.editConnStatus(isvNo, ifCode, infoId, infoType, status);
return ApiRes.ok();
}
}

View File

@ -0,0 +1,38 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.OCRImgParams;
import com.jeequan.jeepay.service.impl.ImgInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 图片信息OCR
*
* @author xiaoyu
*
* @date 2022/1/12 15:15
*/
@RestController
@RequestMapping("/api/imgInfo")
public class ImgInfoOCRController extends CommonCtrl {
@Autowired private ImgInfoService imgInfoService;
/** 图片信息 **/
@PreAuthorize("hasAuthority('ENT_MCH_IMG_OCR_DETAIL')")
@PostMapping("/detail")
public ApiRes detail() {
String imgUrl = getValStringRequired("imgUrl");
String type = getValStringRequired("type");
// 调用ocr接口
OCRImgParams imgParams = imgInfoService.getImgInfo(imgUrl, type);
return ApiRes.ok(imgParams);
}
}

View File

@ -0,0 +1,163 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBOEMConfig;
import com.jeequan.jeepay.core.service.ISysConfigService;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.SysUserEntity;
import com.jeequan.jeepay.db.entity.ToDoListModel;
import com.jeequan.jeepay.service.impl.AgentInfoService;
import com.jeequan.jeepay.service.impl.PayOrderService;
import com.jeequan.jeepay.service.impl.StatsTradeService;
import com.jeequan.jeepay.service.impl.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.HashMap;
import java.util.List;
import java.util.Map;
/**
* 主页数据类
*
* @author pangxiaoyu
*
* @date 2021-04-27 15:50
*/
@Slf4j
@RestController
@RequestMapping("/api/mainChart")
public class MainChartController extends CommonCtrl {
@Autowired private PayOrderService payOrderService;
@Autowired private SysUserService sysUserService;
@Autowired private AgentInfoService agentInfoService;
@Autowired private ISysConfigService sysConfigService;
@Autowired private StatsTradeService statsTradeService;
/**
* @author: xiaoyu
* @date: 2021/12/28 14:54
* @describe: 今日/昨日交易统计
*/
@PreAuthorize("hasAuthority('ENT_AGENT_MAIN_PAY_DAY_COUNT')")
@RequestMapping(value="/payDayCount", method = RequestMethod.GET)
public ApiRes payDayCount() {
JSONObject reqParamJSON = getReqParamJSON();
List<String> agentSubList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
// Map<String, String> agentNoMap = getAgentNo(reqParamJSON);
// JSONObject resJson = payOrderService.payDayCount(null, agentNoMap.get("agentNo"), agentNoMap.get("topAgentNo"), reqParamJSON);
JSONObject resJson = statsTradeService.payDayCount(null, agentSubList, reqParamJSON);
return ApiRes.ok(resJson);
}
/**
* @author: xiaoyu
* @date: 2021/12/28 14:53
* @describe: 趋势图数据
*/
@PreAuthorize("hasAuthority('ENT_AGENT_MAIN_PAY_TREND_COUNT')")
@RequestMapping(value="/payTrendCount", method = RequestMethod.GET)
public ApiRes payTrendCount() {
JSONObject paramJSON = getReqParamJSON();
int recentDay = paramJSON.getIntValue("recentDay");
if (recentDay == 0){
recentDay = 30; // 默认30天
}
paramJSON.put("recentDay", recentDay);
List<String> agentSubList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
JSONObject resJson = payOrderService.payTrendCount(paramJSON, null, agentSubList);
return ApiRes.ok(resJson);
}
/**
* @author: xiaoyu
* @date: 2021/12/28 14:54
* @describe: 交易统计
*/
@PreAuthorize("hasAuthority('ENT_AGENT_MAIN_PAY_COUNT')")
@RequestMapping(value="/payCount", method = RequestMethod.GET)
public ApiRes payCount() {
Map<String, String> agentNoMap = getAgentNo(getReqParamJSON());
List<String> agentSubList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
// 获取传入参数
JSONObject resJson = payOrderService.mainPagePayCount(null, agentSubList, getReqParamJSON());
return ApiRes.ok(resJson);
}
/**
* @author: xiaoyu
* @date: 2021/12/28 14:54
* @describe: 支付方式统计
*/
@PreAuthorize("hasAuthority('ENT_AGENT_MAIN_PAY_TYPE_COUNT')")
@RequestMapping(value="/payTypeCount", method = RequestMethod.GET)
public ApiRes payWayCount() {
Map<String, String> agentNoMap = getAgentNo(getReqParamJSON());
List<String> agentSubList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
ArrayList arrayResult = payOrderService.mainPagePayTypeCount(null, agentSubList, getReqParamJSON());
return ApiRes.ok(arrayResult);
}
/**
* @author: xiaoyu
* @date: 2021/12/28 14:54
* @describe: 服务商基本信息用户基本信息
*/
@PreAuthorize("hasAuthority('ENT_C_USERINFO')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes userDetail() {
SysUserEntity sysUserEntity = sysUserService.getById(getCurrentUser().getSysUser().getSysUserId());
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
Byte infoState = getCurrentUser().getInfoState();
DBOEMConfig dboemConfig = sysConfigService.getOemConfig();
JSONObject json = (JSONObject) JSON.toJSON(agentInfo);
json.put("promiseFile", dboemConfig.getPromiseFile());
json.put("loginUsername", sysUserEntity.getLoginUsername());
json.put("realname", sysUserEntity.getRealname());
json.put("infoState", infoState);
return ApiRes.ok(json);
}
/**
* @author: xiaoyu
* @date: 2022/3/18 16:20
* @describe: 与app共用接口返回服务商号
*/
public Map<String, String> getAgentNo(JSONObject paramJSON) {
HashMap<String, String> AgentNoMap = new HashMap<>();
String agentNo = null;
String topAgentNo = getCurrentAgentNo();
if (StringUtils.isNotEmpty(paramJSON.getString("agentNo"))) {
agentNo = paramJSON.getString("agentNo");
}
AgentNoMap.put("agentNo", agentNo);
AgentNoMap.put("topAgentNo", topAgentNo);
return AgentNoMap;
}
/**
*
* @describe 待办事项汇总待审核或者待操作的事件数量
*
* @return
*/
@RequestMapping(value = "/getWaitOperationNumber",method = RequestMethod.GET)
public ApiRes getWaitOperationNumber(){
List<ToDoListModel> waitOperationNumber = new ArrayList<>();
return ApiRes.ok(waitOperationNumber);
}
}

View File

@ -0,0 +1,186 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.config.SystemYmlConfig;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
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.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.MchInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 商户应用管理类
*
* @author zhuxiao
*
* @date 2021-06-16 09:15
*/
@RestController
@RequestMapping("/api/mchApps")
public class MchAppController extends CommonCtrl {
@Autowired private MchAppService mchAppService;
@Autowired private MchInfoService mchInfoService;
@Autowired private SystemYmlConfig systemYmlConfig;
@Autowired private IMQSender mqSender;
/**
* @Author: ZhuXiao
* @Description: 应用列表
* @Date: 9:59 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_APP_LIST')")
@GetMapping
public ApiRes list() {
MchAppEntity mchAppEntity = getObject(MchAppEntity.class);
mchAppEntity.setAgentNo(getCurrentAgentNo());
// app融合搜索appId appName mchNo mchName
mchAppEntity.addExt("unionSearchId", getValStringDefault("unionSearchId", ""));
// 可查看自己和全部下级代理数据
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
// 自己和下级服务商
if (CollUtil.isNotEmpty(subAgentNoList)){
mchAppEntity.setSubAgentNoList(subAgentNoList);
}
IPage<MchAppEntity> pages = mchAppService.selectPage(getIPage(true), mchAppEntity);
return ApiRes.page(pages);
}
/**
* @Author: ZhuXiao
* @Description: 新建应用
* @Date: 10:05 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_APP_ADD')")
@MethodLog(remark = "新建应用")
@PostMapping
public ApiRes add() {
MchAppEntity mchAppEntity = getObject(MchAppEntity.class);
if (StringUtils.isEmpty(mchAppEntity.getMchNo())) {
throw new BizException("商户号不能为空");
}
MchInfo mchInfo = mchInfoService.getById(mchAppEntity.getMchNo());
if (mchInfo == null || !mchInfo.getAgentNo().equals(getCurrentAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
mchAppEntity.setMchNo(mchInfo.getMchNo());
mchAppEntity.setAgentNo(getCurrentAgentNo());
mchAppEntity.setTopAgentNo(mchInfo.getTopAgentNo());
mchAppEntity.setAppId(SeqKit.getMchAppId());
//默认设置为审核中
mchAppEntity.setState(MchAppEntity.AUDIT);
// 如果当前为默认
if (mchAppEntity.getDefaultFlag() == CS.YES) {
mchAppService.update(new LambdaUpdateWrapper<MchAppEntity>()
.set(MchAppEntity::getDefaultFlag, CS.NO)
.eq(MchAppEntity::getMchNo, mchAppEntity.getMchNo())
);
}
boolean result = mchAppService.save(mchAppEntity);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/**
* @Author: ZhuXiao
* @Description: 应用详情
* @Date: 10:13 2021/6/16
*/
@PreAuthorize("hasAnyAuthority('ENT_MCH_APP_VIEW', 'ENT_MCH_APP_EDIT')")
@GetMapping("/{appId}")
public ApiRes detail(@PathVariable("appId") String appId) {
MchAppEntity mchAppEntity = mchAppService.selectById(appId);
if (mchAppEntity == null || !mchAppEntity.getAgentNo().equals(getCurrentAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(mchAppEntity);
}
/**
* @Author: ZhuXiao
* @Description: 更新应用信息
* @Date: 10:11 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_APP_EDIT')")
@MethodLog(remark = "更新应用信息")
@PutMapping("/{appId}")
public ApiRes update(@PathVariable("appId") String appId) {
MchAppEntity mchAppEntity = getObject(MchAppEntity.class);
mchAppEntity.setAppId(appId);
MchAppEntity dbMchAppEntity = mchAppService.getById(appId);
if (!dbMchAppEntity.getAgentNo().equals(getCurrentAgentNo())) {
throw new BizException("无权操作!");
}
if (mchAppEntity.getDefaultFlag() != null && !dbMchAppEntity.getDefaultFlag().equals(mchAppEntity.getDefaultFlag())) {
// 如果修改当前为默认
if (mchAppEntity.getDefaultFlag() == CS.YES) {
mchAppService.update(new LambdaUpdateWrapper<MchAppEntity>()
.set(MchAppEntity::getDefaultFlag, CS.NO)
.eq(MchAppEntity::getMchNo, dbMchAppEntity.getMchNo())
);
}else {
throw new BizException("应用不可修改为非默认!");
}
}
boolean result = mchAppService.updateById(mchAppEntity);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @Author: ZhuXiao
* @Description: 删除应用
* @Date: 10:14 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_APP_DEL')")
@MethodLog(remark = "删除应用")
@DeleteMapping("/{appId}")
public ApiRes delete(@PathVariable("appId") String appId) {
MchAppEntity mchAppEntity = mchAppService.getById(appId);
if (!mchAppEntity.getAgentNo().equals(getCurrentAgentNo())) {
throw new BizException("无权操作!");
}
mchAppService.removeByAppId(appId);
return ApiRes.ok();
}
/** 功能描述: 查询系统公钥 */
@PreAuthorize("hasAnyAuthority('ENT_MCH_APP_ADD', 'ENT_MCH_APP_EDIT')")
@GetMapping("/sysRSA2PublicKey")
public ApiRes sysRSA2PublicKey() {
return ApiRes.ok(systemYmlConfig.getSysRSA2PublicKey());
}
}

View File

@ -0,0 +1,120 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchConfig;
import com.jeequan.jeepay.service.impl.MchConfigService;
import com.jeequan.jeepay.service.impl.MchInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 商户配置管理类
*
* @author zx
* @date 2021-06-16 09:15
*/
@RestController
@RequestMapping("/api/mchConfig")
public class MchConfigController extends CommonCtrl {
@Autowired
private MchConfigService mchConfigService;
@Autowired
private MchInfoService mchInfoService;
/**
* @Author: zx
* @Description: 查询商户配置
* @Date: 9:59 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_CONFIG_PAGE')")
@GetMapping
public ApiRes list() {
String groupKey = getValString("groupKey");
String mchNo = getValStringRequired("mchNo");
String mchAppId = getValString("mchAppId");
String mchApplyId = getValString("mchApplyId");
LambdaQueryWrapper<MchConfig> queryWrapper = MchConfig.gw()
.eq(MchConfig::getMchNo, mchNo)
.eq(!ObjUtil.isEmpty(mchAppId), MchConfig::getMchAppId, mchAppId)
.eq(!ObjUtil.isEmpty(mchApplyId), MchConfig::getMchApplyId, mchApplyId);
if (StringUtils.isNotBlank(groupKey)) {
queryWrapper.eq(MchConfig::getGroupKey, groupKey);
}
List<MchConfig> list = mchConfigService.list(queryWrapper);
return ApiRes.ok(list);
}
/**
* @Author: zx
* @Description: 根据configKey查询商户配置
* @Date: 9:59 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_CONFIG_EDIT')")
@GetMapping("/{configKey}")
public ApiRes get(@PathVariable("configKey") String configKey) {
MchConfig mchConfig = mchConfigService.getOne(MchConfig.gw().eq(MchConfig::getMchNo, getValStringRequired("mchNo")).eq(MchConfig::getConfigKey, configKey));
return ApiRes.ok(mchConfig);
}
/**
* @Author: zx
* @Description: 根据configKey更新商户配置信息
* @Date: 10:11 2021/6/16
*/
/*@PreAuthorize("hasAuthority('ENT_MCH_CONFIG_EDIT')")
@MethodLog(remark = "更新商户配置")
@PutMapping("/{configKey}")
public ApiRes updateByConfigKey(@PathVariable("configKey") String configKey) {
MchConfig mchConfig = getObject(MchConfig.class);
mchConfig.setConfigKey(configKey);
int count = mchConfigService.saveOrUpdateConfig(mchConfig, getCurrentMchNo());
if(count <= 0) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}*/
/**
* @author: zx
* @Description: 批量更新商户配置信息
* @Date: 10:11 2021/6/16
*/
@PreAuthorize("hasAuthority('ENT_MCH_CONFIG_PAGE')")
@MethodLog(remark = "批量更新商户配置信息")
@PutMapping("/{groupKey}")
public ApiRes updateBatch(@PathVariable("groupKey") String groupKey) {
String params = getValStringRequired("configData");
List<MchConfig> mchConfigList = JSONArray.parseArray(params, MchConfig.class);
String mchNo = getValStringRequired("mchNo");
String mchAppId = getValString("mchAppId");
String mchApplyId = getValString("mchApplyId");
int update = mchConfigService.updateBatch(mchConfigList, mchNo, mchAppId, mchApplyId, groupKey);
if (update <= 0) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
}

View File

@ -0,0 +1,221 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.DesensitizedUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.components.mq.model.CleanMchLoginAuthCacheMQ;
import com.jeequan.jeepay.components.mq.model.ResetIsvMchAppInfoConfigMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
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.model.PrefixConfig;
import com.jeequan.jeepay.core.model.smsconfig.SmsBizDiyContentModel;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.service.impl.MchInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 商户管理类
*
* @author pangxiaoyu
* @site https://www.jeequan.com
* @date 2021-06-07 07:15
*/
@RestController
@RequestMapping("/api/mchInfo")
public class MchInfoController extends CommonCtrl {
@Autowired private IMQSender mqSender;
@Autowired private SmsManager smsManager;
@Autowired private PrefixConfig prefixConfig;
@Autowired private MchInfoService mchInfoService;
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 商户信息列表
*/
@PreAuthorize("hasAuthority('ENT_MCH_LIST')")
@GetMapping(value = "")
public ApiRes list() {
MchInfo mchInfo = getObject(MchInfo.class);
// 仅查询当前服务商数据
mchInfo.setAgentNo(getCurrentAgentNo());
// 扩展员仅查询自己的数据
if (getCurrentUser().isEpUser()){
mchInfo.setCreatedUid(getCurrentUser().getSysUser().getSysUserId());
}
Page<MchInfo> listPage = mchInfoService.getListPage(getIPage(), mchInfo);
return ApiRes.page(listPage);
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 新增商户信息
*/
@PreAuthorize("hasAuthority('ENT_MCH_INFO_ADD')")
@MethodLog(remark = "新增商户")
@PostMapping
public ApiRes add() {
AgentInfo pAgentInfo = agentInfoService.getById(getCurrentAgentNo());
// 当前服务商是否允许发展下级商户
if (pAgentInfo.getAddMchFlag() != CS.YES) {
throw new BizException("当前服务商不可发展下级商户");
}
MchInfo mchInfo = getObject(MchInfo.class);
// 获取传入的商户登录名登录密码
String loginPassword = getValString("loginPassword");
Byte isNotify = getValByteRequired("isNotify");
if (StringUtils.isBlank(loginPassword)) {
loginPassword = null;
}
mchInfo.setMchNo(SeqKit.genMchNo());
// 当前服务商
mchInfo.setAgentNo(getCurrentAgentNo());
mchInfo.setTopAgentNo(agentInfoService.queryTopAgentNo(getCurrentAgentNo()));
// 商户类型
mchInfo.setType(MchInfo.TYPE_ISVSUB);
// 商户级别
mchInfo.setMchLevel(MchInfo.MCH_LEVEL_M0);
// 商户退款权限
JSONArray refundModeArray = new JSONArray();
refundModeArray.add(MchInfo.REFUND_MODEL_PLAT);
refundModeArray.add(MchInfo.REFUND_MODEL_API);
mchInfo.setRefundMode(refundModeArray);
// 当前登录用户信息
SysUser sysUser = getCurrentUser().getSysUser();
mchInfo.setCreatedUid(sysUser.getSysUserId());
mchInfo.setCreatedBy(sysUser.getRealname());
mchInfoService.addMch(mchInfo, loginPassword);
// 发送短信通知
if (isNotify == CS.YES) {
smsManager.sendDiyContentSms(SmsBizDiyContentModel.genUserOpenAccount(mchInfo.getContactTel(), mchInfo.getLoginUsername(), loginPassword));
}
return ApiRes.ok();
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 删除商户信息
*/
@PreAuthorize("hasAuthority('ENT_MCH_INFO_DEL')")
@MethodLog(remark = "删除商户")
@RequestMapping(value="/{mchNo}", method = RequestMethod.DELETE)
public ApiRes delete(@PathVariable("mchNo") String mchNo) {
MchInfo mchInfo = mchInfoService.getById(mchNo);
if (mchInfo == null) {
throw new BizException("该商户不存在");
}
if (!mchInfo.getAgentNo().equals(getCurrentAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
List<Long> userIdList = mchInfoService.removeByMchNo(mchNo);
// 推送mq删除redis用户缓存
mqSender.send(CleanMchLoginAuthCacheMQ.build(userIdList));
// 推送mq到目前节点进行更新数据
mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_MCH_INFO, null, mchNo, null));
return ApiRes.ok();
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 更新商户信息
*/
@PreAuthorize("hasAuthority('ENT_MCH_INFO_EDIT')")
@MethodLog(remark = "更新商户信息")
@RequestMapping(value="/{mchNo}", method = RequestMethod.PUT)
public ApiRes update(@PathVariable("mchNo") String mchNo) {
//获取查询条件
MchInfo mchInfo = getObject(MchInfo.class);
mchInfo.setMchNo(mchNo); //设置商户号主键
mchInfo.setType(null); //防止变更商户类型
mchInfo.setAgentNo(null);
// mchInfo.setIsvNo(null); // 防止变更服务商ID
mchInfo.setTopAgentNo(null); // 防止变更顶级代理ID
mchInfo.setRefundMode(null); // 防止变更退款权限
mchInfo.setLoginUsername(null); // 防止修改用户登录名
MchInfo dbRecord = mchInfoService.getById(mchNo);
if (dbRecord == null || !getCurrentAgentNo().equals(dbRecord.getAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
// 状态禁止操作平台停用 -> 启用
if (mchInfo.getState() != null && mchInfo.getState() == CS.YES && dbRecord.getState() == MchInfo.STATE_NO_MGR) {
throw new BizException("商户状态停用,请联系运营平台处理");
}
// 数据库状态为 由平台停用的不可修改
if (dbRecord.getState() == MchInfo.STATE_NO_MGR) {
mchInfo.setState(null);
}
boolean resetPass = getReqParamJSON().getBooleanValue("resetPass");
String confirmPwd = null;
if(resetPass){
confirmPwd = getReqParamJSON().getBoolean("defaultPass") ? null : Base64.decodeStr(getValStringRequired("confirmPwd"));
}
// 更新商户 & 得到需要删除的商户用户ID的记录
Set<Long> removeCacheUserIdList = mchInfoService.updateMch(mchInfo, resetPass, confirmPwd);
// 推送mq删除redis用户认证信息
if (!removeCacheUserIdList.isEmpty()) {
mqSender.send(CleanMchLoginAuthCacheMQ.build(new ArrayList<>(removeCacheUserIdList)));
}
// 推送mq到目前节点进行更新数据
mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_MCH_INFO, null, mchNo, null));
return ApiRes.ok();
}
/**
* @author: pangxiaoyu
* @date: 2021/6/7 16:14
* @describe: 查询商户信息
*/
@PreAuthorize("hasAnyAuthority('ENT_MCH_INFO_VIEW', 'ENT_MCH_INFO_EDIT')")
@RequestMapping(value="/{mchNo}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("mchNo") String mchNo) {
MchInfo mchInfo = mchInfoService.getById(mchNo);
if (mchInfo == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if (mchInfo.getState() == MchInfo.STATE_NO_MGR) {
mchInfo.setState(CS.NO);
}
return ApiRes.ok(mchInfo);
}
}

View File

@ -0,0 +1,71 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.MchModifyApplymentEntity;
import com.jeequan.jeepay.service.impl.MchModifyApplymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;
/**
* TODO
*
* @author crystal
* @date 2023/12/27 15:36
*/
@RestController
@RequestMapping("/api/mchModifyApplyment")
public class MchModifyApplymentController extends CommonCtrl {
@Autowired private MchModifyApplymentService modifyApplymentService;
@GetMapping
public ApiRes list() {
MchModifyApplymentEntity modifyApplyment = getObject(MchModifyApplymentEntity.class);
JSONObject paramJSON = getReqParamJSON();
//查询该服务商下的所有用户数据包括自己和下级服务商
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
List<String> mchInfoList = mchInfoService.list(MchInfo.gw()
.in(MchInfo::getAgentNo, subAgentNoList)
.eq(MchInfo::getState,1))
.stream()
.map(MchInfo::getMchNo).collect(Collectors.toList());
modifyApplyment.setMchInfoList(mchInfoList);
Page<MchModifyApplymentEntity> pages = modifyApplymentService.pageList(getIPage(), modifyApplyment,paramJSON);
return ApiRes.page(pages);
}
@GetMapping("/result/{modifyApplyId}")
public ApiRes getResult(@PathVariable("modifyApplyId") String modifyApplyId) {
modifyApplymentService.getResult(modifyApplyId);
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_MCH_APPLYMENT_VIEW')")
@GetMapping("/{recordId}")
public ApiRes detail(@PathVariable("recordId") String recordId) {
Byte originData = getValByteDefault("originData", CS.NO);
MchModifyApplymentEntity record;
if (CS.NO == originData) {
record = modifyApplymentService.getInfoById(recordId);
} else {
record = modifyApplymentService.getById(recordId);
}
return ApiRes.ok(record);
}
}

View File

@ -0,0 +1,89 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
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.core.model.DBApplicationConfig;
import com.jeequan.jeepay.db.entity.MchAppEntity;
import com.jeequan.jeepay.db.entity.PayInterfaceConfig;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.MchInfoService;
import com.jeequan.jeepay.service.impl.PayInterfaceConfigService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.HashSet;
import java.util.Set;
/**
* 商户支付接口配置类
*
* @author zhuxiao
*
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("/api/mch/payConfigs")
public class MchPayInterfaceConfigController extends CommonCtrl {
@Autowired
private PayInterfaceConfigService payInterfaceConfigService;
@Autowired
private MchInfoService mchInfoService;
@Autowired
private MchAppService mchAppService;
@Autowired
private SysConfigService sysConfigService;
@Autowired
private IMQSender mqSender;
/**
* 查询支付宝商户授权URL
**/
@GetMapping("/alipayIsvsubMchAuthUrls/{mchAppId}/{isvNo}")
public ApiRes queryAlipayIsvsubMchAuthUrl(@PathVariable("mchAppId") String mchAppId,
@PathVariable("isvNo") String isvNo) {
MchAppEntity mchAppEntity = mchAppService.getById(mchAppId);
DBApplicationConfig dbApplicationConfig = sysConfigService.getDBApplicationConfig();
String authUrl = dbApplicationConfig.genAlipayIsvsubMchAuthUrl(isvNo, mchAppId);
String authQrImgUrl = dbApplicationConfig.genScanImgUrl(authUrl);
JSONObject result = new JSONObject();
result.put("authUrl", authUrl);
result.put("authQrImgUrl", authQrImgUrl);
return ApiRes.ok(result);
}
/**
* 查询当前应用支持的支付接口
*/
@PreAuthorize("hasAuthority( 'ENT_DIVISION_RECEIVER_ADD' )")
@RequestMapping(value = "ifCodes/{appId}", method = RequestMethod.GET)
public ApiRes getIfCodeByAppId(@PathVariable("appId") String appId) {
if (mchAppService.lambdaQuery().eq(MchAppEntity::getMchNo, getCurrentAgentNo()).eq(MchAppEntity::getAppId, appId).count() <= 0) {
throw new BizException("商户应用不存在");
}
Set<String> result = new HashSet<>();
payInterfaceConfigService.lambdaQuery().select(PayInterfaceConfig::getIfCode)
.eq(PayInterfaceConfig::getState, CS.PUB_USABLE)
.eq(PayInterfaceConfig::getInfoId, appId)
.eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.MCH_APP)
.list().forEach(r -> result.add(r.getIfCode()));
return ApiRes.ok(result);
}
}

View File

@ -0,0 +1,77 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.ctrls.AbstractCtrl;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchVideoCacheEntity;
import com.jeequan.jeepay.service.impl.MchVideoCacheService;
import com.jeequan.jeepay.thirdparty.service.wxchannel.WechatChannelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/mchVideo")
public class MchVideoController extends AbstractCtrl {
@Autowired
private WechatChannelService wechatChannelService;
@Autowired
private MchVideoCacheService mchVideoCacheService;
@PostMapping("/authTask")
public ApiRes auth() {
String mchNo = getValStringRequired("mchNo");
JSONObject task = wechatChannelService.createTask(mchNo);
return ApiRes.ok(task);
}
@GetMapping("/authTask")
public ApiRes taskResult() {
String taskId = getValStringRequired("taskId");
JSONObject taskResult = wechatChannelService.queryTask(taskId);
return ApiRes.ok(taskResult);
}
@GetMapping("/dataList")
public ApiRes cacheList() {
Page<MchVideoCacheEntity> iPage = getIPage();
MchVideoCacheEntity mchInfo = getObject(MchVideoCacheEntity.class);
LambdaQueryWrapper<MchVideoCacheEntity> wrapper = Wrappers.lambdaQuery(mchInfo);
Page<MchVideoCacheEntity> page = mchVideoCacheService.page(iPage, wrapper);
return ApiRes.ok(page);
}
@GetMapping("/randomOne")
public ApiRes randomOne() {
String mchNo = getValStringRequired("mchNo");
MchVideoCacheEntity result = mchVideoCacheService.getRandomOne(mchNo);
return ApiRes.ok(result);
}
@DeleteMapping("/{id}")
public ApiRes remove(@PathVariable("id") Long id) {
mchVideoCacheService.removeById(id);
return ApiRes.ok();
}
@PostMapping("/choiceFlag/{id}")
public ApiRes choiceFlag(@PathVariable("id") Long id) {
String choiceFlag = getValStringRequired("choiceFlag");
mchVideoCacheService.lambdaUpdate()
.eq(MchVideoCacheEntity::getId, id)
.set(MchVideoCacheEntity::getChoiceFlag, choiceFlag)
.update();
return ApiRes.ok();
}
}

View File

@ -0,0 +1,100 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.PackageInfo;
import com.jeequan.jeepay.db.entity.PackageOrder;
import com.jeequan.jeepay.service.impl.PackageInfoService;
import com.jeequan.jeepay.service.impl.PackageOrderService;
import com.jeequan.jeepay.service.impl.PackageTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/packageInfo")
public class PackageInfoController extends CommonCtrl {
@Autowired private PackageInfoService packageInfoService;
@Autowired private PackageOrderService packageOrderService;
@Autowired private PackageTypeService packageTypeService;
@RequestMapping(value = "/getPackageList", method = RequestMethod.GET)
@MethodLog(remark = "方案中心列表")
public ApiRes getPackageList() throws BizException {
PackageInfo packageInfo = getObject(PackageInfo.class);
Page<PackageInfo> page = new Page<>();
List<PackageInfo> packageInfoList = packageInfoService.getPackageList(packageInfo.getName(),packageInfo.getState(),packageInfo.getPackageType());
page.setRecords(packageInfoList);
page.setTotal(packageInfoList.size());
page.setCurrent(1);
return ApiRes.ok(page);
}
@RequestMapping(value = "/getPackageById", method = RequestMethod.GET)
@MethodLog(remark = "商户端方案详情")
public ApiRes getPackageById() throws BizException {
//获取查询条件
PackageInfo packageInfo = getObject(PackageInfo.class);
PackageInfo info = packageInfoService.getPackageById(packageInfo.getPackageId());
return ApiRes.ok(info);
}
@GetMapping("/getPackageOder")
@MethodLog(remark = "开通记录")
public ApiRes getPackageOder(){
Page<PackageOrder> page=getIPage(true);
PackageOrder packageOrder = getObject(PackageOrder.class);
// 时间搜索
Date[] searchDateRange = packageOrder.buildQueryDateRange();
packageOrder.setFirstDate(searchDateRange[0]);
packageOrder.setLastDate(searchDateRange[1]);
//packageOrder.setCreatedUid(getCurrentUser().getSysUserId());
//查询该服务商下的所有用户数据包括自己和下级服务商
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
List<String> mchInfoList = mchInfoService.list(MchInfo.gw()
.in(MchInfo::getAgentNo, subAgentNoList)
.eq(MchInfo::getState,1))
.stream()
.map(MchInfo::getMchNo).collect(Collectors.toList());
packageOrder.setMchInfoList(mchInfoList);
Page<PackageOrder> result = packageOrderService.getList(page, packageOrder);
return ApiRes.ok(result);
}
@RequestMapping(value = "/getPackageOderById", method = RequestMethod.GET)
@MethodLog(remark = "开通记录详情")
public ApiRes getPackageOderById() throws BizException {
//获取查询条件
PackageOrder packageOrder = getObject(PackageOrder.class);
PackageOrder serviceById = packageOrderService.getDetail(packageOrder.getId());
return ApiRes.ok(serviceById);
}
@MethodLog(remark = "更新开通记录")
@PutMapping("/{id}")
public ApiRes reSubmit(@PathVariable("id") String id) {
PackageOrder packageOrder = getObject(PackageOrder.class);
packageOrder.setId(id);//设置主键
packageOrder.setUpdatedAt(new Date());
packageOrder.setState(PackageOrder.STATE_AUDITING);
packageOrderService.updateById(packageOrder);
return ApiRes.ok();
}
@RequestMapping(value = "/getPackageTypeList", method = RequestMethod.GET)
@MethodLog(remark = "获取所有方案分类列表")
public ApiRes getPackageTypeList() throws BizException {
return ApiRes.ok(packageTypeService.list());
}
}

View File

@ -0,0 +1,140 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.MchStoreTerminalManage;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchStoreTerminal;
import com.jeequan.jeepay.service.impl.MchStoreTerminalService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/***
* 终端设备管理
*
* @author terrfly
*
* @date 2022/4/26 17:34
*/
@Slf4j
@RestController
@RequestMapping("/api/mchTerminals")
public class TerminalController extends CommonCtrl {
@Autowired private MchStoreTerminalService mchStoreTerminalService;
@Autowired private MchStoreTerminalManage mchStoreTerminalManage;
@PreAuthorize("hasAuthority('ENT_TERMINAL_LIST')")
@GetMapping
public ApiRes pages() {
// 请求参数
MchStoreTerminal queryObject = getObject(MchStoreTerminal.class);
// 可查看自己和全部下级代理的设备
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
// 自己和下级服务商
if (CollUtil.isNotEmpty(subAgentNoList)){
queryObject.setSubAgentNoList(subAgentNoList);
}
IPage<MchStoreTerminal> page = mchStoreTerminalService.getMchStoreTerminalList(getIPage(), queryObject);
return ApiRes.page(page);
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_TERMINAL_VIEW' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") String recordId) {
return ApiRes.ok(mchStoreTerminalService.getById(recordId));
}
/** add */
@PreAuthorize("hasAuthority( 'ENT_TERMINAL_ADD' )")
@MethodLog(remark = "添加商户终端信息")
@RequestMapping(value="", method = RequestMethod.POST)
public ApiRes add() {
return mchStoreTerminalManage.add(getObject(MchStoreTerminal.class));
}
/** update */
@PreAuthorize("hasAuthority( 'ENT_TERMINAL_EDIT' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.PUT)
@MethodLog(remark = "更新商户终端信息")
public ApiRes update(@PathVariable("recordId") Long recordId) {
MchStoreTerminal record = getObject(MchStoreTerminal.class);
record.setTrmId(recordId);
return mchStoreTerminalManage.update(record);
}
/** update */
@PreAuthorize("hasAuthority( 'ENT_TERMINAL_EDIT' )")
@RequestMapping(value="/trmDefaults", method = RequestMethod.PUT)
@MethodLog(remark = "更新商户终端默认状态")
public ApiRes updateDefault() {
return mchStoreTerminalManage.updateDefault(getValLongRequired("trmId"), getValByteRequired("defaultFlag"));
}
/** delete */
@PreAuthorize("hasAuthority('ENT_TERMINAL_DEL')")
@MethodLog(remark = "删除终端")
@RequestMapping(value="/{recordId}", method = RequestMethod.DELETE)
public ApiRes del(@PathVariable("recordId") String recordId) {
mchStoreTerminalService.removeById(recordId);
return ApiRes.ok();
}
/** 报备列表 */
@PreAuthorize("hasAuthority('ENT_TERMINAL_SENDUP')")
@RequestMapping(value="channelBindInfos/{recordId}", method = RequestMethod.GET)
public ApiRes channelBindInfos(@PathVariable("recordId") Long recordId) {
return mchStoreTerminalManage.getChannelBindInfos(recordId);
}
/** 终端报备 */
@PreAuthorize("hasAuthority('ENT_TERMINAL_SENDUP')")
@MethodLog(remark = "终端报备")
@RequestMapping(value="channelSendup/{recordId}", method = RequestMethod.POST)
public ApiRes channelSendup(@PathVariable("recordId") Long recordId) {
String ifCode = getValStringRequired("ifCode");
Byte state = getValByteRequired("state"); // 0 - 取消报备 1- 申请报备
return mchStoreTerminalManage.channelSendup(recordId, ifCode, state);
}
/** 修改终端报备信息 */
@PreAuthorize("hasAuthority('ENT_TERMINAL_SENDUP')")
@MethodLog(remark = "自定义终端报备信息")
@RequestMapping(value="channelBindInfos/{recordId}", method = RequestMethod.POST)
public ApiRes updChannelBindInfos(@PathVariable("recordId") Long recordId) {
String ifCode = getValStringRequired("ifCode");
String channelTrmNo = getValStringDefault("channelTrmNo", ""); // 报备信息
Byte state = getValByteRequired("state");
return mchStoreTerminalManage.updChannelBindInfos(recordId, ifCode, channelTrmNo, state);
}
}

View File

@ -0,0 +1,171 @@
package com.jeequan.jeepay.agent.ctrl.merchant;
import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.zxing.WriterException;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.agent.util.CodeImgUtil;
import com.jeequan.jeepay.components.oss.config.OssYmlConfig;
import com.jeequan.jeepay.components.oss.model.OssFileConfig;
import com.jeequan.jeepay.core.aop.MethodLog;
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.DBApplicationConfig;
import com.jeequan.jeepay.core.model.DBOSSConfig;
import com.jeequan.jeepay.core.model.DBWxMpConfig;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.MchWxmpUser;
import com.jeequan.jeepay.service.impl.MchInfoService;
import com.jeequan.jeepay.service.impl.MchWxmpUserService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.io.File;
import java.io.IOException;
/**
* 微信公众号提醒配置类
*
* @author zx
*
* @date 2021-10-15 09:15
*/
@RestController
@RequestMapping("/api/wxmp")
public class WxMpUserController extends CommonCtrl {
@Autowired private MchInfoService mchInfoService;
@Autowired private SysConfigService sysConfigService;
@Autowired private MchWxmpUserService mchWxmpUserService;
@Autowired private OssYmlConfig ossYmlConfig;
/**
* @Author: zx
* @Description: 商户创建微信公众号接收者的显示信息
* @Date: 2021-10-15 09:15
*/
@GetMapping("/getWxmpInfo")
public ApiRes getWxmpInfo() {
MchInfo mchInfo = mchInfoService.getById(getCurrentUser().getSysUser().getBelongInfoId());
DBApplicationConfig applicationConfig = sysConfigService.getDBApplicationConfig();
DBOSSConfig ossConfig = sysConfigService.getOssConfig();
DBWxMpConfig wxMpConfig = sysConfigService.getDBWxMpConfig();
if(wxMpConfig == null){
throw new BizException("未正确配置微信公众号消息配置项");
}
String mchAuthRedirectUrl = StringUtils.isBlank(wxMpConfig.getMchAuthRedirectUrl()) ? DBWxMpConfig.DEFAULT_WX_AUTH_DOMAIN : wxMpConfig.getMchAuthRedirectUrl();
JSONObject result = new JSONObject();
String authUrl = DBWxMpConfig.mchAuthUrl
.replace("{{mchAuthRedirectUrl}}", mchAuthRedirectUrl)
.replace("{{mchNo}}", mchInfo.getMchNo())
.replace("{{appId}}", wxMpConfig.getWxAppId())
.replace("{{paySiteUrl}}", applicationConfig.getPaySiteUrl());
// 文件地址 (xxx/xxx.jpg 格式)
String filePath = ossYmlConfig.getOss().getFilePublicPath() + File.separator + OssFileConfig.BIZ_TYPE.WX_FILE + File.separator;
String fileName = UUID.fastUUID() + ".png";
try {
CodeImgUtil.codeImgEncode(filePath, fileName, authUrl, 200, 200);
result.put("authQr", ossConfig.getOssPublicSiteUrl() + File.separator + OssFileConfig.BIZ_TYPE.WX_FILE + File.separator + fileName);
result.put("wxmpQr", wxMpConfig.getWxmpUrl());
return ApiRes.ok(result);
} catch (WriterException | IOException e) {
logger.error("", e);
return ApiRes.customFail("获取授权码失败");
}
}
/**
* @Author: zx
* @Description: 微信公众号取消关注
* @Date: 2021-10-15 09:15
*/
@GetMapping("/unAuth")
public ApiRes unAuth() {
LambdaUpdateWrapper<MchWxmpUser> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(MchWxmpUser::getMchNo, getCurrentAgentNo());
updateWrapper.set(MchWxmpUser::getSendStatus, MchWxmpUser.SEND_STATE_CLOSE);
boolean updateResult = mchWxmpUserService.update(updateWrapper);
if (!updateResult) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 微信公众号消息接收者列表
*/
@PreAuthorize("hasAuthority('ENT_MCH_WXMP_USER_LIST')")
@GetMapping
public ApiRes pages() {
LambdaQueryWrapper<MchWxmpUser> gw = MchWxmpUser.gw();
gw.eq(MchWxmpUser::getMchNo, getCurrentAgentNo());
if (StringUtils.isNotBlank(getValString("nickname"))) {
gw.like(MchWxmpUser::getNickname, getValString("nickname"));
}
IPage<MchWxmpUser> page = mchWxmpUserService.page(getIPage(), gw);
//返回数据
return ApiRes.page(page);
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 微信公众号消息接收者修改
*/
@PreAuthorize("hasAuthority('ENT_MCH_WXMP_USER_EDIT')")
@MethodLog(remark = "微信公众号消息接收者修改")
@PutMapping("/{userId}")
public ApiRes update(@PathVariable("userId") Long userId) {
MchWxmpUser mchWxmpUser = getObject(MchWxmpUser.class);
mchWxmpUser.setUserId(userId);
MchWxmpUser dbRecord = mchWxmpUserService.getById(userId);
if (!getCurrentAgentNo().equals(dbRecord.getMchNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
if(!mchWxmpUserService.updateById(mchWxmpUser)) {
return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "更新失败");
}
return ApiRes.ok();
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 微信公众号消息接收者删除
*/
@PreAuthorize("hasAuthority('ENT_MCH_WXMP_USER_DELETE')")
@MethodLog(remark = "微信公众号消息接收者删除")
@DeleteMapping("/{userId}")
public ApiRes delete(@PathVariable("userId") Long userId) {
if(mchWxmpUserService.remove(MchWxmpUser.gw().eq(MchWxmpUser::getUserId, userId).eq(MchWxmpUser::getMchNo, getCurrentAgentNo()))) {
return ApiRes.ok();
}
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
}
}

View File

@ -0,0 +1,261 @@
package com.jeequan.jeepay.agent.ctrl.order;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.JeepayClient;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.device.IPrinterService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBOSSConfig;
import com.jeequan.jeepay.core.model.device.PayOrderInfo4Device;
import com.jeequan.jeepay.core.model.export.PayOrderExportExcel;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.exception.JeepayException;
import com.jeequan.jeepay.model.PayOrderQueryReqModel;
import com.jeequan.jeepay.model.PayOrderQueryResModel;
import com.jeequan.jeepay.request.PayOrderQueryRequest;
import com.jeequan.jeepay.response.PayOrderQueryResponse;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.*;
/**
* 支付订单管理类
*
* @author zhuxiao
* @site https://www.jeequan.com
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("/api/payOrder")
public class PayOrderController extends CommonCtrl {
@Autowired private PayOrderService payOrderService;
@Autowired private PayWayService payWayService;
@Autowired private SysConfigService sysConfigService;
@Autowired private MchStoreDeviceService mchStoreDeviceService;
@Autowired private AgentInfoService agentInfoService;
@Autowired private OrderProfitSettRecordService orderProfitSettRecordService;
@Autowired private StatsTradeService statsTradeService;
@Autowired private MchAppService mchAppService;
/**
* @Author: ZhuXiao
* @Description: 订单信息列表
* @Date: 10:43 2021/5/13
*/
@PreAuthorize("hasAuthority('ENT_ORDER_LIST')")
@GetMapping
public ApiRes list() {
PayOrder payOrder = getObject(PayOrder.class);
JSONObject paramJSON = getReqParamJSON();
if (StringUtils.isEmpty(payOrder.getAgentNo())) {
List<String> allSubAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
payOrder.setSubAgentNoList(allSubAgentNoList);
}else {
if ("onlyOne".equals(payOrder.getAgentNo())) {
payOrder.setAgentNo(getCurrentAgentNo());
}
}
IPage<PayOrder> pages = payOrderService.listByPage(getIPage(), payOrder, paramJSON);
return ApiRes.page(pages);
}
/**
* @Author: ZhuXiao
* @Description: 支付订单信息
* @Date: 10:43 2021/5/13
*/
@PreAuthorize("hasAuthority('ENT_PAY_ORDER_VIEW')")
@GetMapping("/{payOrderId}")
public ApiRes detail(@PathVariable("payOrderId") String payOrderId) {
PayOrder payOrder = payOrderService.getDetails(payOrderId);
if (payOrder == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
List<String> allSubAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
if (!allSubAgentNoList.contains(payOrder.getAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
if (StringUtils.isNotBlank(payOrder.getChannelOrderNo())) {
DBOSSConfig ossConfig = sysConfigService.getOssConfig();
payOrder.addExt("channelOrderNoBar", ossConfig.getOssPublicSiteUrl() + "/bar/" + payOrder.getChannelOrderNo());
}
// 查询订单分润情况
List<OrderProfitSettRecord> profitList = orderProfitSettRecordService.getBaseMapper().queryOrderProfitSum(payOrderId, getCurrentAgentNo(), CS.SYS_ROLE_TYPE.AGENT);
payOrder.addExt("profitAmount", profitList.isEmpty() ? null : profitList.get(0).getCalProfitAmount());
return ApiRes.ok(payOrder);
}
/**
* @author: xiaoyu
* @date: 2022/2/10 17:00
* @describe: 订单列表统计
*/
@PreAuthorize("hasAuthority('ENT_ORDER_COUNT')")
@RequestMapping(value="/count", method = RequestMethod.GET)
public ApiRes count() {
PayOrder payOrder = getObject(PayOrder.class);
List<String> allAgentNoList = null;
if (StringUtils.isEmpty(payOrder.getAgentNo())) {
allAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
}else if ("onlyOne".equals(payOrder.getAgentNo())) {
allAgentNoList = Arrays.asList(getCurrentAgentNo());
}else {
allAgentNoList = Arrays.asList(payOrder.getAgentNo());
}
payOrder.setAgentNo(null);
JSONObject paramJSON = getReqParamJSON();
paramJSON.put("allAgentNoList", allAgentNoList);
// 查询支付退款金额 笔数
PayOrderCount orderCount = statsTradeService.selectTotalByTransaction(paramJSON, allAgentNoList);
return ApiRes.ok(orderCount);
}
/**
* @author: xiaoyu
* @date: 2022/1/14 9:45
* @describe: 订单列表数据导出
*/
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() {
try {
JSONObject paramJSON = getReqParamJSON();
PayOrder payOrder = getObject(PayOrder.class);
if (StringUtils.isEmpty(payOrder.getAgentNo())) {
List<String> allSubAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
payOrder.setSubAgentNoList(allSubAgentNoList);
}else if ("onlyOne".equals(payOrder.getAgentNo())) {
payOrder.setAgentNo(getCurrentAgentNo());
}else {
payOrder.setAgentNo(payOrder.getAgentNo());
}
payOrder.setAgentNo(null);
IPage<PayOrder> pages = payOrderService.listByPage(getIPage(true), payOrder, paramJSON);
List<JSONObject> newList = new LinkedList<>();
for (PayOrder order:pages.getRecords()) {
JSONObject object = (JSONObject) JSONObject.toJSON(order);
object.put("amount", AmountUtil.convertCent2Dollar(order.getAmount()));
object.put("refundAmount", AmountUtil.convertCent2Dollar(order.getRefundAmount()));
object.put("mchFeeAmount", AmountUtil.convertCent2Dollar(order.getMchFeeAmount()));
object.put("mchOrderFeeAmount", AmountUtil.convertCent2Dollar(order.getMchOrderFeeAmount()));
newList.add(object);
}
List<PayOrderExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), PayOrderExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "支付订单", "支付订单", PayOrderExportExcel.class, "支付订单", response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出订单失败!");
}
}
/**
* @Author: ZhuXiao
* @Description: 订单打印
* @Date: 10:43 2022/01/13
*/
@PreAuthorize("hasAuthority('ENT_PAY_ORDER_VIEW')")
@GetMapping("/print/{payOrderId}")
public ApiRes print(@PathVariable("payOrderId") String payOrderId) {
PayOrder payOrder = payOrderService.getById(payOrderId);
if (payOrder == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if (!payOrder.getAgentNo().equals(getCurrentAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
PayOrderInfo4Device printPayOrderInfo = new PayOrderInfo4Device();
BeanUtil.copyProperties(payOrder, printPayOrderInfo);
try {
// 查询打印设备
List<JSONObject> deviceList = mchStoreDeviceService.selectAvailableDeviceList(payOrder.getMchNo(), payOrder.getStoreId(), Arrays.asList(DeviceProvideConfig.DEVICE_TYPE_PRINTER));
if (CollectionUtils.isEmpty(deviceList)) {
return ApiRes.customFail("打印机未配置");
}
// 循环调用单个设备
for (JSONObject deviceParams : deviceList) {
// 设备类型
String provider = deviceParams.getString("provider");
IPrinterService printerService = SpringBeansUtil.getBean(provider + "PrinterService", IPrinterService.class);
printerService.send(deviceParams, printPayOrderInfo);
}
return ApiRes.ok();
} catch (BizException e) {
throw e;
}
}
@MethodLog(remark = "订单状态刷新")
@PreAuthorize("hasAuthority('ENT_PAY_ORDER_REFRESH')")
@PostMapping("/refresh/{payOrderId}")
public ApiRes refresh(@PathVariable("payOrderId") String payOrderId) {
PayOrder payOrder = payOrderService.getById(payOrderId);
if(payOrder == null){
throw new BizException("订单数据异常");
}
if(PayOrder.STATE_ING != payOrder.getState()){
throw new BizException("订单状态不支持该操作");
}
MchAppEntity mchAppEntity = mchAppService.getById(payOrder.getAppId());
PayOrderQueryRequest request = new PayOrderQueryRequest();
PayOrderQueryReqModel model = new PayOrderQueryReqModel();
model.setPas(SysConfigService.PLATFORM_API_SECRET); // 通信秘钥
model.setMchNo(payOrder.getMchNo()); // 商户号
model.setAppId(payOrder.getAppId());
model.setPayOrderId(payOrderId);
request.setBizModel(model);
JeepayClient jeepayClient = new JeepayClient(sysConfigService.getDBApplicationConfig().getPaySiteUrl(), mchAppEntity.getAppSecret());
try {
PayOrderQueryResponse response = jeepayClient.execute(request);
if(response.getCode() != 0){
throw new BizException(response.getMsg());
}
PayOrderQueryResModel respData = response.get();
if(respData.getState() == PayOrder.STATE_SUCCESS){
return ApiRes.ok("订单刷新成功");
}
return ApiRes.customFail("订单状态一致,无需当前操作");
} catch (JeepayException e) {
throw new BizException(e.getMessage());
}
}
}

View File

@ -0,0 +1,161 @@
package com.jeequan.jeepay.agent.ctrl.order;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.export.MchRefundOrderExportExcel;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.db.entity.RefundOrder;
import com.jeequan.jeepay.service.impl.AgentInfoService;
import com.jeequan.jeepay.service.impl.RefundOrderService;
import com.jeequan.jeepay.service.impl.StatsTradeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/***
* 退款订单管理
*
* @author terrfly
* @date 2022/3/16 20:37
*/
@RestController
@RequestMapping("/api/refundOrder")
public class RefundOrderController extends CommonCtrl {
@Autowired private RefundOrderService refundOrderService;
@Autowired private AgentInfoService agentInfoService;
@Autowired
private StatsTradeService statsTradeService;
/**
* @Author: ZhuXiao
* @Description: 退款订单信息列表
* @Date: 10:44 2021/5/13
*/
@PreAuthorize("hasAuthority('ENT_REFUND_LIST')")
@GetMapping
public ApiRes list() {
RefundOrder refundOrder = getObject(RefundOrder.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<RefundOrder> wrapper = RefundOrder.gw();
if (StringUtils.isEmpty(refundOrder.getAgentName())) {
List<String> allSubAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
wrapper.in(RefundOrder::getAgentNo, allSubAgentNoList);
}else {
if ("onlyOne".equals(refundOrder.getAgentNo())) {
//refundOrder.setAgentNo(getCurrentAgentNo());
refundOrder.setAgentName(getCurrentAgentNo());
}
}
IPage<RefundOrder> pages = refundOrderService.pageList(getIPage(), wrapper, refundOrder, paramJSON);
setIfName(pages.getRecords());
return ApiRes.page(pages);
}
/**
* @Author: ZhuXiao
* @Description: 退款订单信息
* @Date: 10:44 2021/5/13
*/
@PreAuthorize("hasAuthority('ENT_REFUND_ORDER_VIEW')")
@GetMapping("/{refundOrderId}")
public ApiRes detail(@PathVariable("refundOrderId") String refundOrderId) {
RefundOrder refundOrder = refundOrderService.getById(refundOrderId);
if (refundOrder == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
List<String> allSubAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
if (!allSubAgentNoList.contains(refundOrder.getAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
return ApiRes.ok(refundOrder);
}
/**
* @author: xiaoyu
* @date: 2022/1/14 9:45
* @describe: 退款列表数据导出
*/
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() {
try {
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<RefundOrder> wrapper = RefundOrder.gw();
RefundOrder refundOrder = getObject(RefundOrder.class);
if (StringUtils.isEmpty(refundOrder.getAgentNo())) {
List<String> allSubAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
wrapper.in(RefundOrder::getAgentNo, allSubAgentNoList);
}else if ("onlyOne".equals(refundOrder.getAgentNo())) {
wrapper.in(RefundOrder::getAgentNo, getCurrentAgentNo());
}else {
wrapper.in(RefundOrder::getAgentNo, refundOrder.getAgentNo());
}
refundOrder.setAgentNo(null);
IPage<RefundOrder> pages = refundOrderService.pageList(getIPage(true), wrapper, refundOrder, paramJSON);
List<JSONObject> newList = new LinkedList<>();
for (RefundOrder order:pages.getRecords()) {
JSONObject object = (JSONObject) JSONObject.toJSON(order);
object.put("payAmount", AmountUtil.convertCent2Dollar(order.getPayAmount()));
object.put("refundAmount", AmountUtil.convertCent2Dollar(order.getRefundAmount()));
object.put("refundFeeAmount", AmountUtil.convertCent2Dollar(order.getRefundFeeAmount()));
newList.add(object);
}
List<MchRefundOrderExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), MchRefundOrderExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "退款订单", "退款订单", MchRefundOrderExportExcel.class, "退款订单", response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出订单失败!");
}
}
/**
* @author: xiaoyu
* @date: 2022/2/10 17:00
* @describe: 退款列表统计
*/
@PreAuthorize("hasAuthority('ENT_REFUND_ORDER_COUNT')")
@RequestMapping(value = "/count", method = RequestMethod.GET)
public ApiRes count() {
RefundOrder refundOrder = getObject(RefundOrder.class);
List<String> allAgentNoList = null;
if (StringUtils.isEmpty(refundOrder.getAgentNo())) {
allAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
} else if ("onlyOne".equals(refundOrder.getAgentNo())) {
allAgentNoList = Collections.singletonList(getCurrentAgentNo());
} else {
allAgentNoList = Collections.singletonList(refundOrder.getAgentNo());
}
refundOrder.setAgentNo(null);
JSONObject paramJSON = getReqParamJSON();
paramJSON.put("allAgentNoList", allAgentNoList);
// 查询支付退款金额 笔数
PayOrderCount resMap = statsTradeService.selectTotalByTransaction(paramJSON, allAgentNoList);
return ApiRes.ok(resMap);
}
}

View File

@ -0,0 +1,125 @@
package com.jeequan.jeepay.agent.ctrl.order;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
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.export.MchTransferOrderExportExcel;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.db.entity.TransferOrderEntity;
import com.jeequan.jeepay.service.impl.TransferOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 转账订单api
*
* @author terrfly
*
* @date 2021/8/13 10:52
*/
@RestController
@RequestMapping("/api/transferOrders")
public class TransferOrderController extends CommonCtrl {
@Autowired private TransferOrderService transferOrderService;
/** list **/
@PreAuthorize("hasAuthority('ENT_TRANSFER_ORDER_LIST')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
TransferOrderEntity transferOrder = getObject(TransferOrderEntity.class);
// 可查看自己和全部下级代理数据
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
// 自己和下级服务商
if (CollUtil.isNotEmpty(subAgentNoList)){
transferOrder.setSubAgentNoList(subAgentNoList);
}
IPage<TransferOrderEntity> pages = transferOrderService.pageList(getIPage(), transferOrder);
return ApiRes.page(pages);
}
/** detail **/
/*@PreAuthorize("hasAuthority('ENT_TRANSFER_ORDER_VIEW')")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") String transferId) {
TransferOrderEntity refundOrder = transferOrderService.queryMchOrder(getCurrentMchNo(), null, transferId);
if (refundOrder == null) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(refundOrder);
}*/
/**
* @author: xiaoyu
* @date: 2022/1/14 9:45
* @describe: 转账数据导出
*/
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() {
try {
TransferOrderEntity transferOrder = getObject(TransferOrderEntity.class);
transferOrder.setAgentNo(getCurrentAgentNo());
IPage<TransferOrderEntity> pages = transferOrderService.pageList(getIPage(true), transferOrder);
List<JSONObject> newList = new LinkedList<>();
for (TransferOrderEntity order:pages.getRecords()) {
JSONObject object = (JSONObject) JSONObject.toJSON(order);
object.put("entryType", order.getEntryType().replaceAll("_",""));
object.put("amount", AmountUtil.convertCent2Dollar(order.getAmount()));
newList.add(object);
}
List<MchTransferOrderExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), MchTransferOrderExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "转账订单", "转账订单", MchTransferOrderExportExcel.class, "转账订单", response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出订单失败!");
}
}
/**
* @author: xiaoyu
* @date: 2023/4/26 14:55
* @describe: 数据统计
*/
@PreAuthorize("hasAuthority('ENT_TRANSFER_ORDER_COUNT')")
@RequestMapping(value="/count", method = RequestMethod.GET)
public ApiRes count() {
TransferOrderEntity transferOrder = getObject(TransferOrderEntity.class);
LambdaQueryWrapper<TransferOrderEntity> wrapper = TransferOrderEntity.gw();
// 可查看自己和全部下级代理数据
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
// 自己和下级服务商
if (CollUtil.isNotEmpty(subAgentNoList)){
transferOrder.setSubAgentNoList(subAgentNoList);
}
transferOrder.setState(null);
// 条件参数
transferOrderService.selectParams(wrapper, transferOrder);
Map result = transferOrderService.queryCount(wrapper);
return ApiRes.ok(result);
}
}

View File

@ -0,0 +1,145 @@
package com.jeequan.jeepay.agent.ctrl.payconfig;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.MchPayPassageConfigManage;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.applyment.ApplymentBasicInfo;
import com.jeequan.jeepay.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.core.utils.JsonKit;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.db.entity.MchPayPassage;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchPayPassageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/****
* 新版商户支付通道配置ctrl
*
* @author terrfly
*
* @date 2022/3/30 16:37
*/
@RestController
@RequestMapping("/api/mch/payPassages")
public class MchPayPassageConfigController extends CommonCtrl {
@Autowired private MchPayPassageService mchPayPassageService;
@Autowired private MchPayPassageConfigManage mchPayPassageConfigManage;
@Autowired
private MchApplymentService mchApplymentService;
@Autowired
private IMQSender mqSender;
/**
* 支付方式 <--> 通道配置
* 左侧列表支付方式
*
* **/
@GetMapping
public ApiRes list() {
String appId = getValStringRequired("appId");
String wayCode = getValString("wayCode");
String wayName = getValString("wayName");
String unionSearchId = getValString("unionSearchId");
return mchPayPassageConfigManage.queryPaywayList(appId, wayCode, wayName, null, unionSearchId, getIPage());
}
/**
* 支付方式 <--> 通道配置
* 右侧列表可用的支付接口
*
* **/
@GetMapping("/availablePayInterface/{appId}/{wayCode}")
public ApiRes availablePayInterface(@PathVariable("appId") String appId, @PathVariable("wayCode") String wayCode) {
return mchPayPassageConfigManage.availablePayInterface(appId, wayCode);
}
/**
* 更新商户使用的通道信息
*/
@PostMapping("/mchPassage")
@MethodLog(remark = "更新商户支付通道")
public ApiRes updatePassage() {
String appId = getValStringRequired("appId");
String ifCode = getValStringRequired("ifCode");
String wayCode = getValStringRequired("wayCode");
Byte state = getValByteRequired("state");
mchPayPassageService.updateMchPassageState(appId, wayCode, ifCode, state);
return ApiRes.ok();
}
/**
* 查询商户应用支付通道是否配置
* 用于进件成功一键配置到应用点击按钮时检查进件记录中包含的支付方式是否在该应用下已配置其他渠道
*/
@GetMapping("/exist/{applyId}/{appId}")
public ApiRes exist(@PathVariable("applyId") String applyId, @PathVariable("appId") String appId) {
MchApplyment tbMchApplyment = mchApplymentService.getById(applyId);
if (tbMchApplyment == null || tbMchApplyment.getState() != MchApplyment.STATE_SUCCESS) {
return ApiRes.customFail("进件记录不存在或进件状态未成功");
}
// 获取当前进件记录费率配置
ApplymentBasicInfo applymentBasicInfo = JSONObject.parseObject(tbMchApplyment.getApplyDetailInfo(), ApplymentBasicInfo.class);
// 费率
List<PaywayFee> paywayFeeList = applymentBasicInfo.getPaywayFeeList();
// 费率为空进件成功一键配置到应用将不执行配置费率和通道可直接返回
if (CollUtil.isEmpty(paywayFeeList)) {
return ApiRes.ok();
}
// 获取费率配置的支付方式
List<String> wayCodeList = new ArrayList<>();
paywayFeeList.forEach(paywayFee -> {
wayCodeList.add(paywayFee.getWayCode());
});
// 支付方式已配置其他渠道
List<MchPayPassage> payPassages = mchPayPassageService.list(MchPayPassage.gw()
.eq(MchPayPassage::getAppId, appId)
.ne(MchPayPassage::getIfCode, tbMchApplyment.getIfCode())
.in(MchPayPassage::getWayCode, wayCodeList));
if (CollUtil.isNotEmpty(payPassages)) {
return ApiRes.ok(JsonKit.newJson("existMchPayPassage", CS.YES));
}
return ApiRes.ok();
}
/**
* 进件成功一键配置到应用更新商户支付通道
*/
@MethodLog(remark = "进件成功,一键配置商户支付信息")
@PostMapping("/applyment/{applyId}/{appId}")
public ApiRes updateMchPayPassageByApplyment(@PathVariable("applyId") String applyId, @PathVariable("appId") String appId) {
// AutoConfigMchAppPayInfoResult result = mchApplymentService.autoConfigMchAppPayInfo(applyId, appId, getValByteRequired("isOverWrite") == CS.YES);
//
// if (StringUtils.isNotBlank(result.getErrMsg())) {
// return ApiRes.customFail(result.getErrMsg());
// }
return ApiRes.ok();
}
}

View File

@ -0,0 +1,282 @@
package com.jeequan.jeepay.agent.ctrl.payconfig;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.IsvUserConn;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.params.IsvParams;
import com.jeequan.jeepay.core.model.params.NormalMchParams;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.impl.IsvInfoService;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.PayInterfaceConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/***
* 支付配置
*
* @author terrfly
*
* @date 2022/3/21 0:13
*/
@RestController
@RequestMapping("/api/payConfig")
public class PayConfigController extends CommonCtrl {
@Autowired
private MchAppService mchAppService;
@Autowired
private PayInterfaceConfigService payInterfaceConfigService;
@Autowired
private IsvInfoService isvInfoService;
/**
* 查询可用的支付接口
* <p>
* 使用功能项目 参数及费率的填写
* 服务商查询全部支付接口
* 服务商查询服务商开启的支付接口
**/
@PreAuthorize("hasAnyAuthority('ENT_PC', 'ENT_AGENT_RATE_CONFIG', 'ENT_MCH_APPLYMENT')")
@GetMapping("/ifCodes")
public ApiRes ifCodes() {
// 搜索条件
String ifName = getValString("ifName");
String infoId = getValStringRequired("infoId"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
// 支付接口列表
LambdaQueryWrapper<PayInterfaceDefine> lambdaQueryWrapper = PayInterfaceDefine.gw();
lambdaQueryWrapper.eq(PayInterfaceDefine::getState, CS.YES); // 查询可用的支付接口列表
lambdaQueryWrapper.like(StringUtils.isNotEmpty(ifName), PayInterfaceDefine::getIfName, ifName);
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
Map<String, IsvUserConn> ifCodeMap = new HashMap<>();
// 服务商 配置 商户费率 | 下级服务商费率 | 自己配置信息 显示 当前服务商所有接口
if (RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode) ||
RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode) ||
RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)
) {
ifCodeMap = isvInfoService.getIsvUserConn(CS.SYS_ROLE_TYPE.AGENT, agentInfo.getAgentNo(), CS.YES);
List<String> ifCodeList = new ArrayList<>(ifCodeMap.keySet());
if (ifCodeList.isEmpty()) { // 没有可用的接口
return ApiRes.ok(ifCodeList);
}
lambdaQueryWrapper.in(PayInterfaceDefine::getIfCode, ifCodeList);
} else if (RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)) { // 服务商进件
// 查询 当前服务商 开通的
ifCodeMap = isvInfoService.getIsvUserConn(CS.SYS_ROLE_TYPE.AGENT, agentInfo.getAgentNo(), null);
if (ifCodeMap.isEmpty()) { // 没有可用的接口
return ApiRes.ok(Collections.emptyList());
}
lambdaQueryWrapper.in(PayInterfaceDefine::getIfCode, ifCodeMap.keySet());
lambdaQueryWrapper.eq(PayInterfaceDefine::getIsSupportApplyment, CS.YES); // 查询支持进件的接口
}
final List<PayInterfaceDefine> list = new ArrayList<>();
lambdaQueryWrapper.orderByAsc(PayInterfaceDefine::getCreatedAt);
final Map<String, IsvUserConn> finalMap = ifCodeMap;
payInterfaceDefineService.list(lambdaQueryWrapper).forEach(item -> {
// 如果服务商上级配置的开启进件为关闭那么最终展示的列表中显示的是否开启进件也为关闭
IsvUserConn ifCodeInfo = finalMap.get(item.getIfCode());
boolean isEnabled = ifCodeInfo.getStatus() == CS.YES && ifCodeInfo.getConfigStatus() == CS.YES;
item.addExt("configState", ifCodeInfo.getStatus());
item.setState(isEnabled ? CS.YES : CS.NO);
list.add(item);
});
return ApiRes.ok(list);
}
/**
* 查询已经配置的参数信息
**/
@PreAuthorize("hasAuthority('ENT_MCH_APP_PAY_CONFIG')")
@GetMapping(value = "/interfaceSavedConfigs")
public ApiRes interfaceSavedConfigs() {
String ifCode = getValStringRequired("ifCode"); // ifCode
String infoId = getValStringRequired("infoId"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
PayInterfaceDefine payInterfaceDefine = payInterfaceDefineService.getById(ifCode);
String infoType = null;
JSONArray ifDefineArray = null;
Byte mchType = null; // 商户类型
Byte isvIsOpenApplyment = 0; // 服务商是否开启进件
// 服务商 配置商户应用信息
if (RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.MCH_APP;
MchInfo mchInfo = mchInfoService.getById(mchAppService.getById(infoId).getMchNo());
mchType = mchInfo.getType();
if (mchType == CS.MCH_TYPE_NORMAL) {
ifDefineArray = JSON.parseArray(payInterfaceDefine.getNormalMchParams());
} else {
ifDefineArray = JSON.parseArray(payInterfaceDefine.getIsvsubMchParams());
}
}
// 服务商 配置下级服务商信息
else if (RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode) || RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.AGENT;
if ("CURRENTAGENT".equals(infoId)) {
infoId = getCurrentAgentNo();
}
AgentInfo agentInfo = agentInfoService.getById(infoId);
if (agentInfo != null && StringUtils.isNotBlank(agentInfo.getIsvNo())) {
PayInterfaceConfig isvIfConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.ISV, agentInfo.getIsvNo(), ifCode);
isvIsOpenApplyment = isvIfConfig != null ? isvIfConfig.getIsOpenApplyment() : 0;
}
}
// 查询已经配置的信息
PayInterfaceConfig payInterfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(infoType, infoId, ifCode);
if (payInterfaceConfig == null) {
payInterfaceConfig = new PayInterfaceConfig();
}
// 处理脱敏数据
if (StringUtils.isNotEmpty(payInterfaceConfig.getIfParams())) {
if (RateConfig.CONFIG_MODE_MGRISV.equals(configMode)) {
IsvParams isvParams = IsvParams.factory(ifCode, payInterfaceConfig.getIfParams());
if (isvParams != null) {
payInterfaceConfig.setIfParams(isvParams.deSenData());
}
} else if (RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)) {
if (mchType == CS.MCH_TYPE_NORMAL) {
NormalMchParams isvParams = NormalMchParams.factory(ifCode, payInterfaceConfig.getIfParams());
if (isvParams != null) {
payInterfaceConfig.setIfParams(isvParams.deSenData());
}
} else {
}
}
}
payInterfaceConfig.addExt("ifDefineArray", ifDefineArray);
payInterfaceConfig.addExt("mchType", mchType);
payInterfaceConfig.addExt("configPageType", payInterfaceDefine.getConfigPageType());
payInterfaceConfig.addExt("isSupportApplyment", payInterfaceDefine.getIsSupportApplyment()); // 支付接口是否支持进件
payInterfaceConfig.addExt("isvIsOpenApplyment", isvIsOpenApplyment); // 上级服务商是否开启进件
return ApiRes.ok(payInterfaceConfig);
}
/**
* 更新支付参数
**/
@PreAuthorize("hasAuthority('ENT_MCH_APP_PAY_CONFIG')")
@PostMapping("/interfaceParams")
@MethodLog(remark = "更新支付参数")
public ApiRes saveOrUpdate() {
PayInterfaceConfig payInterfaceConfig = getObject(PayInterfaceConfig.class);
String configMode = payInterfaceConfig.extv().getString("configMode"); // 设置类型
String infoType = null;
if (RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.MCH_APP;
}
// 服务商 配置下级服务商
else if (RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode) || RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)) {
infoType = CS.SYS_ROLE_TYPE.AGENT;
if ("CURRENTAGENT".equals(payInterfaceConfig.getInfoId())) {
payInterfaceConfig.setInfoId(getCurrentAgentNo());
}
}
payInterfaceConfig.setInfoType(infoType);
//添加更新者信息
Long userId = getCurrentUser().getSysUser().getSysUserId();
String realName = getCurrentUser().getSysUser().getRealname();
payInterfaceConfig.setUpdatedUid(userId);
payInterfaceConfig.setUpdatedBy(realName);
//根据 服务商号接口类型 获取商户参数配置
PayInterfaceConfig dbRecoed = payInterfaceConfigService.getByInfoIdAndIfCode(payInterfaceConfig.getInfoType(), payInterfaceConfig.getInfoId(), payInterfaceConfig.getIfCode());
//若配置存在为saveOrUpdate添加ID第一次配置添加创建者
if (dbRecoed != null) {
payInterfaceConfig.setId(dbRecoed.getId());
// 合并支付参数
payInterfaceConfig.setIfParams(StringKit.marge(dbRecoed.getIfParams(), payInterfaceConfig.getIfParams(), dbRecoed.getIfCode()));
} else {
payInterfaceConfig.setCreatedUid(userId);
payInterfaceConfig.setCreatedBy(realName);
}
boolean result = payInterfaceConfigService.saveOrUpdate(payInterfaceConfig);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "配置失败");
}
return ApiRes.ok();
}
/**
* 查询商户应用支付参数费率是否配置
* 用于发起进件 自动配置到应用时的提示
*/
@GetMapping("/existPayParams/{appId}/{ifCode}")
public ApiRes existPayParams(@PathVariable("appId") String appId, @PathVariable("ifCode") String ifCode) {
// Integer range = getValInteger("range");
// String mccCode = getValString("mccCode");
// String isvNo = getValString("isvNo");
//
// // 应用参数配置
// PayInterfaceConfig interfaceConfig = payInterfaceConfigService.getByInfoIdAndIfCode(CS.SYS_ROLE_TYPE.MCH_APP, appId, ifCode);
// if (interfaceConfig == null) {
// return ApiRes.ok();
// }
//
// if (StringUtils.isNotBlank(interfaceConfig.getIfParams()) && !interfaceConfig.getIfParams().equals("{}")) {
// return ApiRes.ok(JsonKit.newJson("existMchParams", CS.YES));
// }
//
// // 费率配置
// Map<String, PaywayFee> paywayFeeMap = rateConfigService.queryPaywayFeeMap(appId + "_" + RateConfig.MCHRATE, CS.SYS_ROLE_TYPE.MCH_APP, ifCode, range, mccCode, isvNo);
// if (paywayFeeMap != null && StringUtils.isNotBlank(interfaceConfig.getIfParams()) && !interfaceConfig.getIfParams().equals("{}")) {
// return ApiRes.ok(JsonKit.newJson("existMchParams", CS.YES));
// }
return ApiRes.ok();
}
}

View File

@ -0,0 +1,58 @@
package com.jeequan.jeepay.agent.ctrl.payconfig;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PayInterfaceDefine;
import com.jeequan.jeepay.service.impl.PayInterfaceDefineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 支付接口定义管理类
*
* @author zhuxiao
*
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("api/payIfDefines")
public class PayInterfaceDefineController extends CommonCtrl {
@Autowired private PayInterfaceDefineService payInterfaceDefineService;
/**
* @Author: ZhuXiao
* @Description: list
* @Date: 15:51 2021/4/27
*/
@GetMapping
public ApiRes list() {
PayInterfaceDefine queryRecord = getObject(PayInterfaceDefine.class);
LambdaQueryWrapper<PayInterfaceDefine> lambdaQueryWrapper = PayInterfaceDefine.gw();
lambdaQueryWrapper.eq(queryRecord.getState() != null , PayInterfaceDefine::getState, queryRecord.getState());
lambdaQueryWrapper.eq(queryRecord.getIsSupportApplyment() != null , PayInterfaceDefine::getIsSupportApplyment, queryRecord.getIsSupportApplyment());
lambdaQueryWrapper.orderByAsc(PayInterfaceDefine::getCreatedAt);
List<PayInterfaceDefine> list = payInterfaceDefineService.list(lambdaQueryWrapper);
return ApiRes.ok(list);
}
/**
* @Author: ZhuXiao
* @Description: detail
* @Date: 15:51 2021/4/27
*/
@GetMapping("/{ifCode}")
public ApiRes detail(@PathVariable("ifCode") String ifCode) {
return ApiRes.ok(payInterfaceDefineService.getById(ifCode));
}
}

View File

@ -0,0 +1,59 @@
package com.jeequan.jeepay.agent.ctrl.payconfig;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PayWay;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 支付方式配置类
*
* @author zhuxiao
*
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("/api/payWays")
public class PayWayController extends CommonCtrl {
@Autowired PayWayService payWayService;
@Autowired MchPayPassageService mchPayPassageService;
@Autowired PayOrderService payOrderService;
@Autowired MchInfoService mchInfoService;
@Autowired PayInterfaceConfigService payInterfaceConfigService;
/**
* @Author: ZhuXiao
* @Description: list
* @Date: 15:52 2021/4/27
*/
@PreAuthorize("hasAuthority('ENT_PAY_ORDER_SEARCH_PAY_WAY')")
@GetMapping
public ApiRes list() {
PayWay queryObject = getObject(PayWay.class);
LambdaQueryWrapper<PayWay> condition = PayWay.gw();
if(StringUtils.isNotEmpty(queryObject.getWayCode())){
condition.like(PayWay::getWayCode, queryObject.getWayCode());
}
if(StringUtils.isNotEmpty(queryObject.getWayName())){
condition.like(PayWay::getWayName, queryObject.getWayName());
}
condition.orderByAsc(PayWay::getWayCode);
IPage<PayWay> pages = payWayService.page(getIPage(true), condition);
return ApiRes.page(pages);
}
}

View File

@ -0,0 +1,46 @@
package com.jeequan.jeepay.agent.ctrl.payconfig;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.QualificationDefineEntity;
import com.jeequan.jeepay.service.impl.QualificationDefineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RequestMapping("/api/qualificationDefine")
@RestController
public class QualificationDefineController extends CommonCtrl {
@Autowired
private QualificationDefineService qualificationDefineService;
@PostMapping("/save")
public ApiRes save() {
QualificationDefineEntity entity = getObject(QualificationDefineEntity.class);
boolean save = qualificationDefineService.save(entity);
return ApiRes.ok(save);
}
@GetMapping("/page")
public ApiRes page() {
Page<QualificationDefineEntity> iPage = getIPage(false);
QualificationDefineEntity condition = getObject(QualificationDefineEntity.class);
qualificationDefineService.lambdaQuery().setEntity(condition).page(iPage);
return ApiRes.ok(iPage);
}
@GetMapping("/{code}")
public ApiRes one(@PathVariable String code) {
QualificationDefineEntity one = qualificationDefineService.lambdaQuery().eq(QualificationDefineEntity::getCode, code).one();
return ApiRes.ok(one);
}
@DeleteMapping("/{code}")
public ApiRes del(@PathVariable String code) {
qualificationDefineService.removeById(code);
return ApiRes.ok();
}
}

View File

@ -0,0 +1,657 @@
package com.jeequan.jeepay.agent.ctrl.payconfig;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.converter.BaseConverter;
import com.jeequan.jeepay.core.aop.MethodLog;
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.core.model.applyment.PaywayFee;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.model.RateConfigSimple;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/***
* 费率配置信息
*
* @author terrfly
*
* @date 2022/3/21 0:13
*/
@RestController
@RequestMapping("/api/rateConfig")
public class RateConfigController extends CommonCtrl {
@Autowired private MchAppService mchAppService;
@Autowired private RateConfigService rateConfigService;
@Autowired private PayWayService payWayService;
@Autowired private PayInterfaceConfigService payInterfaceConfigService;
@Autowired
private BaseConverter baseConverter;
@Autowired
private RateConfigV2Service rateConfigV2Service;
/** 查询可用的支付接口 **/
@GetMapping("/ifCodes")
public ApiRes ifCodes() {
// 搜索条件
String ifName = getValString("ifName");
String infoId = getValStringRequired("infoId"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
// 支付接口列表
LambdaQueryWrapper<PayInterfaceDefine> lambdaQueryWrapper = PayInterfaceDefine.gw();
lambdaQueryWrapper.eq(PayInterfaceDefine::getState, CS.YES); // 查询可用的支付接口列表
lambdaQueryWrapper.like(StringUtils.isNotEmpty(ifName), PayInterfaceDefine::getIfName, ifName);
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
// 服务商 配置 商户费率 | 下级服务商费率 | 自己配置信息 显示 当前服务商所有接口
if(RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode) ||
RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode)||
RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)
){
List<String> ifCodeList = new ArrayList<>();
payInterfaceConfigService.list(PayInterfaceConfig.gw().select(PayInterfaceConfig::getIfCode)
.eq(PayInterfaceConfig::getInfoId, agentInfo.getIsvNo())
.eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.ISV)
.eq(PayInterfaceConfig::getState, CS.YES)
).forEach(r -> ifCodeList.add(r.getIfCode()));
if(ifCodeList.isEmpty()){ // 没有可用的接口
return ApiRes.ok(ifCodeList);
}
lambdaQueryWrapper.in(PayInterfaceDefine::getIfCode, ifCodeList);
}else if( RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode) ){ // 服务商进件
// 查询服务商开通的
List<String> ifCodeList = new ArrayList<>();
List<PayInterfaceConfig> result = payInterfaceConfigService.list(PayInterfaceConfig.gw().select(PayInterfaceConfig::getIfCode)
.eq(PayInterfaceConfig::getInfoId, agentInfo.getIsvNo())
.eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.ISV)
.eq(PayInterfaceConfig::getState, CS.YES));
for (PayInterfaceConfig payInterfaceConfig : result) {
ifCodeList.add(payInterfaceConfig.getIfCode());
}
if(ifCodeList.isEmpty()){ // 没有可用的接口
return ApiRes.ok(ifCodeList);
}
// 查询服务商配置费率的支付接口
Set<String> agentIfCodes = new HashSet<>();
rateConfigService.lambdaQuery()
.select(RateConfig::getIfCode)
.eq(RateConfig::getInfoId, RateConfig.appendInfoByAgent(getCurrentAgentNo()))
.eq(RateConfig::getInfoType, CS.SYS_ROLE_TYPE.AGENT)
.in(RateConfig::getIfCode, ifCodeList)
.list().forEach(r -> agentIfCodes.add(r.getIfCode()));
//
Collection<String> ifCodeList1 = CollUtil.intersection(ifCodeList, agentIfCodes);
ifCodeList = new ArrayList<>(ifCodeList1);
if(ifCodeList.isEmpty()){ // 没有可用的接口
return ApiRes.ok(ifCodeList);
}
lambdaQueryWrapper.in(PayInterfaceDefine::getIfCode, ifCodeList);
}
lambdaQueryWrapper.orderByAsc(PayInterfaceDefine::getCreatedAt);
List<PayInterfaceDefine> list = payInterfaceDefineService.list(lambdaQueryWrapper);
return ApiRes.ok(list);
}
/** 查询所有可配置的支付方式 payways **/
@GetMapping("/payways")
public ApiRes payways() {
String ifCode = getValStringRequired("ifCode"); // ifCode
// String infoId = getValStringRequired("infoId"); // infoId
// String isvNo = getValStringRequired("isvNo"); // infoId
String isvNo = getValStringDefault("isvNo", "V1703659196"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
Integer range = getValInteger("range");
String mccCode = getValString("mccCode");
String mchAppId = getValString("appId");
if (!ObjUtil.isEmpty(mchAppId)) {
MchAppEntity mchApp = mchAppService.getById(mchAppId);
range = mchApp.getRange();
mccCode = mchApp.getMccCode();
}
// 商户服务商或者服务商的父ID (用于过滤掉关闭的支付方式)
String belongAgentNo = null;
// 是否仅显示 支持进件的支付方式用作进件使用
boolean isOnlyApplymentSupport = false;
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
belongAgentNo = agentInfo.getAgentNo();
// 进件模式
if(RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)){
isOnlyApplymentSupport = true;
}
IPage<PayWay> pages = payWayService.queryWayListByRate(ifCode, isvNo, belongAgentNo, isOnlyApplymentSupport, range, mccCode, isvNo);
return ApiRes.page(pages);
}
/** 查询当前已经配置的列表 **/
@GetMapping(value="/savedMapData")
public ApiRes savedMapData() {
String ifCode = getValStringRequired("ifCode"); // ifCode
String infoId = getValStringRequired("infoId"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
// String isvNo = getValStringRequired("isvNo"); // 设置类型
String isvNo = getValStringDefault("isvNo", "V1703659196"); // 设置类型
Integer range = getValInteger("range");
String mccCode = getValString("mccCode");
String mchAppId = getValString("appId");
if (!ObjUtil.isEmpty(mchAppId)) {
MchAppEntity mchApp = mchAppService.getById(mchAppId);
range = mchApp.getRange();
mccCode = mchApp.getMccCode();
}
// 配置商户费率 || 服务商进件模式
if(RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode) || RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)){
Map<String, Map<String, PaywayFee>> result = new HashMap<>();
String mchNo = "";
String applyId = "";
// 进件模式 : infoId = applyId_mchNo 的拼接方式
if(RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)){
applyId = infoId.split("_")[0];
mchNo = infoId.split("_")[1];
} else {
// MchAppEntity mchAppEntity = mchAppService.getById(infoId);
// mchNo = mchAppEntity.getMchNo();
mchNo = infoId;
}
Map<String, PaywayFee> mchRateMap = null;
// 查询已经配置的信息
if(RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)){ // 运营平台进件模式
// mchRateMap = rateConfigService.queryPaywayFeeMapByApplyment(applyId);
// 此处费率不从商户信息里面取了
mchRateMap = rateConfigService.queryPaywayFeeMap(mchNo, CS.SYS_ROLE_TYPE.MCH_APPLYMENT, ifCode, range, mccCode, isvNo);
}else{
mchRateMap = rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.MCHRATE, commonGetInfoType(configMode), ifCode, range, mccCode, isvNo);
}
MchInfo mchInfo = mchInfoService.getById(mchNo);
Map<String, PaywayFee> parentDefRate = null;
// 特约商户
if(mchInfo.getType() == CS.MCH_TYPE_ISVSUB){
// 我的费率商户上级服务商的费率
result.put(RateConfig.READONLYPARENTAGENT, rateConfigService.queryPaywayFeeMap(mchInfo.getAgentNo() + "_" + RateConfig.AGENTRATE, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
// 默认费率
parentDefRate = rateConfigService.queryPaywayFeeMap(mchInfo.getAgentNo() + "_" + RateConfig.MCHAPPLYDEF, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
result.put(RateConfig.READONLYPARENTDEFRATE, parentDefRate);
}
// 商户费率为空时将默认费率设置为商户费率
if (ObjUtil.isEmpty(mchRateMap)) {
mchRateMap = parentDefRate;
}
PaywayFee.resetData(mchRateMap, parentDefRate);
result.put(RateConfig.MCHRATE, mchRateMap);
// 默认商户最大费率
result.put(RateConfig.READONLYPARENTMCHMAX, rateConfigService.queryPaywayFeeMap(getCurrentAgentNo() + "_" + RateConfig.MCHAPPLYMAX, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
return ApiRes.ok(result);
}
// 配置子服务商的费率
else if(RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode) ){
Map<String, Object> result = new HashMap<>();
Map<String, PaywayFee> agentRate = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(infoId), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
// 查询已经配置的信息
result.put(RateConfig.AGENTRATE, agentRate);
AgentInfo agentInfo = agentInfoService.getById(infoId);
Map<String, PaywayFee> parentDefRate = null;
if (agentInfo.getPid() == null) {
parentDefRate = rateConfigService.queryPaywayFeeMap(infoId + "_" + RateConfig.AGENTDEF, CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
}
if (parentDefRate == null) {
parentDefRate = rateConfigService.queryPaywayFeeMap(isvNo + "_" + RateConfig.AGENTDEF, CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo);
}
Map<String, PaywayFee> mchFeeMax = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchMax(infoId), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo);
Map<String, PaywayFee> isvMchFeeMax = rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchMax(isvNo), CS.SYS_ROLE_TYPE.ISV, ifCode, range, mccCode, isvNo);
for (Map.Entry<String, PaywayFee> isvMchFeeMaxItem : isvMchFeeMax.entrySet()) {
String wayCode = isvMchFeeMaxItem.getKey();
PaywayFee item = isvMchFeeMaxItem.getValue();
if (mchFeeMax.get(wayCode) == null) {
// 为空传递空值
mchFeeMax.put(wayCode, PaywayFee.toEmptyData(item));
}
}
result.put(RateConfig.MCHAPPLYMAX, mchFeeMax);
// 我的费率商户上级服务商的费率
result.put(RateConfig.READONLYPARENTAGENT, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
// 默认费率
result.put(RateConfig.READONLYPARENTDEFRATE, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgentDef(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
// 商户最大费率
result.put(RateConfig.READONLYPARENTMCHMAX, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchMax(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
PaywayFee.resetData(agentRate, baseConverter.newPaywayFeeMap(parentDefRate));
return ApiRes.ok(result);
}// 配置服务商自己的配置
else if(RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode) ){
Map<String, Object> result = new HashMap<>();
// 当前服务商的费率配置信息
result.put(RateConfig.AGENTRATE, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgent(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
// 用于显示代理的费率信息兼容前端
result.put(RateConfig.READONLYPARENTAGENT, result.get(RateConfig.AGENTRATE));
// 商户默认费率
result.put(RateConfig.MCHAPPLYDEF, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchDef(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
// 服务商默认费率
result.put(RateConfig.AGENTDEF, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByAgentDef(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
// 商户最大费率
result.put(RateConfig.READONLYPARENTMCHMAX, rateConfigService.queryPaywayFeeMap(RateConfig.appendInfoByMchMax(getCurrentAgentNo()), CS.SYS_ROLE_TYPE.AGENT, ifCode, range, mccCode, isvNo));
return ApiRes.ok(result);
}
return ApiRes.ok();
}
/** 保存费率信息 **/
@MethodLog(remark = "配置费率")
@PostMapping(value="")
public ApiRes reset() {
// 需要删除的集合 比如 配置渠道商底价 关闭了某些渠道 那么需要将下属的配置删除掉
List<RateConfig> delList = new ArrayList<>();
String configMode = getValStringRequired("configMode");
// 主对象
RateConfig mainRateConfig = getObject(RateConfig.class);
mainRateConfig.setInfoType(commonGetInfoType(configMode)); // 必须设置infoType, 检查费率会使用
// 当前服务商的配置信息
if(RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)){
mainRateConfig.setInfoId(getCurrentAgentNo());
}
List<RateConfig> list = new ArrayList<>();
// 服务商默认费率 infoId = ISVNO_AGENTDEF infoType = 1(服务商)
if(StringUtils.isNotEmpty(mainRateConfig.extv().getString(RateConfig.AGENTDEF))){
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.AGENTDEF), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.AGENTDEF, configMode)));
}
// 商户默认费率 infoId = ISVNO_MCHAPPLYDEF infoType = 1(服务商)
if(StringUtils.isNotEmpty(mainRateConfig.extv().getString(RateConfig.MCHAPPLYDEF))){
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.MCHAPPLYDEF), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.MCHAPPLYDEF, configMode)));
}
// 商户费率
if(StringUtils.isNotEmpty(mainRateConfig.extv().getString(RateConfig.MCHRATE))){
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.MCHRATE), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.MCHRATE, configMode)));
}
// 服务商费率
if(StringUtils.isNotEmpty(mainRateConfig.extv().getString(RateConfig.AGENTRATE))){
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.AGENTRATE), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.AGENTRATE, configMode)));
// 配置 服务商 需要删除 下属配置
delList = this.genDelRateConfigList(null, mainRateConfig.getInfoId(), mainRateConfig.getIfCode());
}
// 服务商最大费率 infoId = ISVNO_AGENTMAX infoType = 1(服务商)
if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.AGENTMAX))) {
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.AGENTMAX), PaywayFee.class)
.forEach(r -> list.add( getFillInfoIdAndType(mainRateConfig, r, RateConfig.AGENTMAX, configMode)));
}
// 商户最大费率 infoId = ISVNO_MCHAPPLYMAX infoType = 1(服务商)
if (configMode.equalsIgnoreCase(RateConfig.CONFIG_MODE_AGENTSELF)
|| configMode.equalsIgnoreCase(RateConfig.CONFIG_MODE_AGENTEMCH)) {
// 配置代理费率和商户费率时删除最大费率值
mainRateConfig.getExt().remove(RateConfig.MCHAPPLYMAX);
}
if (!ObjUtil.isEmpty(mainRateConfig.extv().getString(RateConfig.MCHAPPLYMAX))) {
JSON.parseArray(mainRateConfig.extv().getString(RateConfig.MCHAPPLYMAX), PaywayFee.class)
.forEach(r -> list.add(getFillInfoIdAndType(mainRateConfig, r, RateConfig.MCHAPPLYMAX, configMode)));
}
LambdaQueryWrapper<RateConfig> delWrapper = RateConfig.gw();
delWrapper.eq(RateConfig::getIfCode, mainRateConfig.getIfCode());
delWrapper.eq(RateConfig::getInfoType, commonGetInfoType(configMode));
delWrapper.eq(mainRateConfig.getRange()!= null, RateConfig::getRange, mainRateConfig.getRange());
delWrapper.eq(!ObjUtil.isEmpty(mainRateConfig.getMccCode()), RateConfig::getMccCode, mainRateConfig.getMccCode());
delWrapper.in(RateConfig::getInfoId, commonGetInfoId(configMode, mainRateConfig.getInfoId()));
rateConfigService.resetRate(list, delWrapper, mainRateConfig, false, delList);
return ApiRes.ok();
}
private RateConfig getFillInfoIdAndType(RateConfig mainRateConfig, PaywayFee paywayFee, String infoSuffix, String configMode){
RateConfig result = new RateConfig();
result.setInfoId(mainRateConfig.getInfoId() + "_" + infoSuffix);
result.setIfCode(mainRateConfig.getIfCode());
result.setMccCode(mainRateConfig.getMccCode());
result.setRange(mainRateConfig.getRange());
result.setIsvNo(mainRateConfig.getIsvNo());
result.setWayCode(paywayFee.getWayCode());
result.setFeeType(paywayFee.getFeeType());
result.setFeeRate(paywayFee.getFeeRate());
result.setApplymentSupport(paywayFee.getApplymentSupport());
result.setPaywayFeeDetail((JSONObject) JSON.toJSON(paywayFee));
result.setInfoType(commonGetInfoType(configMode));
return result;
}
private String commonGetInfoType(String configMode){
//设置服务商信息
if(RateConfig.CONFIG_MODE_MGRISV.equals(configMode)){
return CS.SYS_ROLE_TYPE.ISV;
}else if(RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)){
return CS.SYS_ROLE_TYPE.AGENT;
}else if(RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)){
return CS.SYS_ROLE_TYPE.MCH_APP;
}else if(RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)){
return CS.SYS_ROLE_TYPE.AGENT;
}else if(RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode)){
return CS.SYS_ROLE_TYPE.AGENT;
}else if(RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode)){
return CS.SYS_ROLE_TYPE.MCH_APP;
}
return "";
}
private List<String> commonGetInfoId(String configMode, String infoId){
//设置服务商信息
if(RateConfig.CONFIG_MODE_MGRISV.equals(configMode)){
return Arrays.asList(
(infoId + "_" + RateConfig.ISVCOST),
(infoId + "_" + RateConfig.AGENTDEF),
(infoId + "_" + RateConfig.AGENTMAX),
(infoId + "_" + RateConfig.MCHAPPLYDEF),
(infoId + "_" + RateConfig.MCHAPPLYMAX)
);
}else if(RateConfig.CONFIG_MODE_MGRAGENT.equals(configMode)){
return Arrays.asList(
(infoId + "_" + RateConfig.AGENTRATE),
(infoId + "_" + RateConfig.AGENTDEF),
(infoId + "_" + RateConfig.AGENTMAX),
(infoId + "_" + RateConfig.MCHAPPLYDEF),
(infoId + "_" + RateConfig.MCHAPPLYMAX)
);
}else if(RateConfig.CONFIG_MODE_MGRMCH.equals(configMode)){
return Collections.singletonList(
(infoId + "_" + RateConfig.MCHRATE)
);
}else if(RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)){
return Arrays.asList(
(infoId + "_" + RateConfig.AGENTDEF),
(infoId + "_" + RateConfig.MCHAPPLYDEF),
(infoId + "_" + RateConfig.MCHAPPLYMAX)
);
}else if(RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode)){
return Arrays.asList(
(infoId + "_" + RateConfig.AGENTRATE),
(infoId + "_" + RateConfig.MCHAPPLYMAX)
);
}else if(RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode)){
return Collections.singletonList(
(infoId + "_" + RateConfig.MCHRATE)
);
}
return new ArrayList<>();
}
/**
获取待删除的列表集合 info_id/ info_type if_code way_code
以下三个场景需要判断
渠道商底价
运营平台 -- 设置服务商费率
服务商 配置 下级服务商费率 (服务商)
**/
private List<RateConfig> genDelRateConfigList(String isvNo, String agentNo, String ifCode){
String delPaywayCodeListStr = getValString("delPaywayCodeListStr");
if(StringUtils.isEmpty(delPaywayCodeListStr)){
return null;
}
List<String> delWayCodeList = JSON.parseArray(delPaywayCodeListStr, String.class);
// 没有待删除的列表
if(delWayCodeList.isEmpty()){
return null;
}
List<RateConfig> result = new ArrayList<>();
Set<String> allAgentNoList = new HashSet<>();
Set<String> allMchNoList = new HashSet<>();
Set<String> allAppIdList = new HashSet<>();
// 服务商不为空
if(StringUtils.isNotEmpty(isvNo)){
// 判断是否支持服务商
if(SysConfigService.IS_HAS_AGENT_ENT){
// 查询所有的服务商列表 ( 一级服务商 )
agentInfoService.list(AgentInfo.gw().select(AgentInfo::getAgentNo).eq(AgentInfo::getIsvNo, isvNo)).forEach(r -> allAgentNoList.add(r.getAgentNo()));
}
// 查询所有的商户列表 [ 无需查询服务商的所属了 已经是全部服务商下的商户了 ]
mchInfoService.lambdaQuery().select(MchInfo::getMchNo).list().forEach(r -> allMchNoList.add(r.getMchNo()));
// 查询下级服务商的 子服务商递归
for (String agentNoItem : allAgentNoList) {
allAgentNoList.addAll(agentInfoService.queryAllSubAgentNo(agentNoItem));
}
// 查询下级服务商递归的商户
}
// 服务商不为空
if(StringUtils.isNotEmpty(agentNo)){
// 查询所有的服务商列表 当前服务商的 直属 服务商
agentInfoService.lambdaQuery().select(AgentInfo::getAgentNo).eq(AgentInfo::getPid, agentNo).list().forEach(r -> allAgentNoList.add(r.getAgentNo()));
// 查询所有的商户列表 当前服务商的 直属 商户 当前服务商的所属商户
mchInfoService.lambdaQuery().select(MchInfo::getMchNo).eq(MchInfo::getAgentNo, agentNo).list().forEach(r -> allMchNoList.add(r.getMchNo()));
// 查询下级服务商的 子服务商递归
for (String agentNoItem : allAgentNoList) {
allAgentNoList.addAll(agentInfoService.queryAllSubAgentNo(agentNoItem));
}
// 查询下级服务商 所属的商户集合
for (String agentNoItem : allAgentNoList) {
mchInfoService.lambdaQuery().select(MchInfo::getMchNo).eq(MchInfo::getAgentNo, agentNoItem)
.list().forEach(r -> allMchNoList.add(r.getMchNo()));
}
}
if(!allMchNoList.isEmpty()){
// 查询所有的商户列表
mchAppService.lambdaQuery().select(MchAppEntity::getMchNo).in(MchAppEntity::getMchNo, allMchNoList)
.list().forEach(r -> allAppIdList.add(r.getAppId()));
}
// 服务商 包括 服务商配置 下级服务商默认 服务商商户默认
for (String agentNoItem : allAgentNoList) {
for (String wayCode : delWayCodeList) {
RateConfig r = new RateConfig();
r.setInfoId(RateConfig.buildInfoId(agentNoItem, RateConfig.AGENTRATE)); r.setInfoType(CS.SYS_ROLE_TYPE.AGENT); r.setIfCode(ifCode); r.setWayCode(wayCode);
result.add(r);
RateConfig r1 = new RateConfig();
r1.setInfoId(RateConfig.buildInfoId(agentNoItem, RateConfig.AGENTDEF)); r1.setInfoType(CS.SYS_ROLE_TYPE.AGENT); r1.setIfCode(ifCode); r1.setWayCode(wayCode);
result.add(r1);
RateConfig r2 = new RateConfig();
r2.setInfoId(RateConfig.buildInfoId(agentNoItem, RateConfig.MCHAPPLYDEF)); r2.setInfoType(CS.SYS_ROLE_TYPE.AGENT); r2.setIfCode(ifCode); r2.setWayCode(wayCode);
result.add(r2);
}
}
// 商户 包括 商户应用费率
for (String appIdItem : allAppIdList) {
for (String wayCode : delWayCodeList) {
RateConfig r = new RateConfig();
r.setInfoId(RateConfig.buildInfoId(appIdItem, RateConfig.MCHRATE)); r.setInfoType(CS.SYS_ROLE_TYPE.MCH_APP); r.setIfCode(ifCode); r.setWayCode(wayCode);
result.add(r);
}
}
return result;
}
@GetMapping("/rateInfoDetail")
public ApiRes rateInfoDetail() {
String isvNo = getValStringRequired("isvNo");
String ifCode = getValStringRequired("ifCode");
Integer range = getValInteger("range");
String mccCode = getValString("mccCode");
String infoType = getValStringRequired("infoType");
String infoId = getValStringRequired("infoId");
String currentAgentNo = getCurrentAgentNo();
List<RateConfigSimple> result = rateConfigV2Service.getRankFeeList(isvNo, infoType, infoId, ifCode, range, mccCode, currentAgentNo);
return ApiRes.ok(result);
}
@PostMapping("/resetV2")
public ApiRes resetV2() {
String currentAgentNo = getCurrentAgentNo();
RateConfigSimple rateConfigSimple = getObject(RateConfigSimple.class);
if (rateConfigSimple.getInfoType().equalsIgnoreCase(CS.SYS_ROLE_TYPE.AGENT)) {
AgentInfo agentInfo = agentInfoService.getById(rateConfigSimple.getInfoId());
Assert.equals(agentInfo.getPid(), currentAgentNo, "所操作的服务商与登录账号非上下级关系");
} else if (rateConfigSimple.getInfoType().equalsIgnoreCase(CS.SYS_ROLE_TYPE.MCH)) {
MchInfo mchInfo = mchInfoService.getById(rateConfigSimple.getInfoId());
Assert.equals(mchInfo.getAgentNo(), currentAgentNo, "所操作的用户与登录账号非上下级关系");
} else {
throw new BizException("未知的操作类型");
}
rateConfigV2Service.save(rateConfigSimple);
return ApiRes.ok();
}
}

View File

@ -0,0 +1,148 @@
package com.jeequan.jeepay.agent.ctrl.product;
import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PackageOrder;
import com.jeequan.jeepay.db.entity.ProductInfo;
import com.jeequan.jeepay.db.entity.ProductType;
import com.jeequan.jeepay.service.impl.PackageOrderService;
import com.jeequan.jeepay.service.impl.ProductInfoService;
import com.jeequan.jeepay.service.impl.ProductTypeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* 产品中心
*
* @author deng
* @since 2024-04-10
*/
@RestController
@RequestMapping("/api/product")
public class ProductController extends CommonCtrl {
@Autowired
private ProductInfoService productInfoService;
@Autowired
private ProductTypeService productTypeService;
@Autowired
private PackageOrderService packageOrderService;
/**
* 产品中心列表
**/
@RequestMapping(value = "/getProductList", method = RequestMethod.GET)
@MethodLog(remark = "产品中心列表")
public ApiRes getProductList() throws BizException {
ProductInfo productInfo = getObject(ProductInfo.class);
/*LambdaQueryWrapper<ProductInfo> wrapper = ProductInfo.gw();
selectParams(productInfo, wrapper);
wrapper.orderByDesc(ProductInfo::getCreatedAt);*/
Page<ProductInfo> page = new Page<>();
List<ProductInfo> productInfoList = productInfoService.getProductList(productInfo.getProductName(), productInfo.getState(), productInfo.getProductType());
page.setRecords(productInfoList);
page.setTotal(productInfoList.size());
page.setCurrent(1);
return ApiRes.ok(page);
}
@RequestMapping(value = "/getProductById", method = RequestMethod.GET)
@MethodLog(remark = "产品详情")
public ApiRes getProductById() throws BizException {
//获取查询条件
ProductInfo productInfo = getObject(ProductInfo.class);
ProductInfo info = productInfoService.getDetailById(productInfo.getProductId());
return ApiRes.ok(info);
}
@RequestMapping(value = "/getProductByUser", method = RequestMethod.GET)
@MethodLog(remark = "被选择用户绑定关系")
public ApiRes getProductByUser() throws BizException {
//获取查询条件
String productOrPackage = getValStringRequired("productOrPackage");
String userNo = getValStringRequired("userNo");
ProductInfo resut=new ProductInfo();
//查询已关联已开通的应用数量
List<PackageOrder> packageOrderList = packageOrderService.getList(productOrPackage,userNo);
List<String> bindingApp = packageOrderList.stream().map(PackageOrder::getAppId).filter(str-> !str.isEmpty()).distinct().collect(Collectors.toList());
resut.setApplyCount(packageOrderList.size());
resut.setBindingAppList(bindingApp);
//返回收费信息和剩余天数以及总剩余天数
List<PackageOrder> packageOrderListSave =new ArrayList<>();
long allRemainingDays = 0L;
for (PackageOrder packageOrder : packageOrderList) {
if (packageOrder.getCostRule() != null){
JSONArray costRule = packageOrder.getCostRule();
//目前规则只能选取一条
int validTime = costRule.getJSONObject(0).getIntValue("validTime");
if (costRule.getJSONObject(0).getDate("autoTime") != null){
LocalDate currentDate = costRule.getJSONObject(0).getDate("autoTime").toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
// 计算到期后的日期
LocalDate futureDate = currentDate.plusDays(validTime);
// 计算剩余天数
LocalDate today = new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
long remainingDays = ChronoUnit.DAYS.between(today, futureDate);
packageOrder.setRemainingDays(remainingDays);
//暂时不需要
//productAppListSave.add(productApp);
allRemainingDays += remainingDays;
}
}
}
//暂时不需要
//info.setProductAppList(productAppListSave);
resut.setAllRemainingDays(allRemainingDays);
return ApiRes.ok(resut);
}
@RequestMapping(value = "/startProduct", method = RequestMethod.POST)
@MethodLog(remark = "产品开通")
public ApiRes startProduct() throws BizException {
//获取查询条件
PackageOrder app = getObject(PackageOrder.class);
Assert.isTrue(!ObjUtil.isEmpty(getValString("userNo")), "用户号[userNo]不能为空");
app.setMchNo(getValString("userNo"));
app.setCreatedAt(new Date());
app.setUpdatedAt(new Date());
app.setCreatedUid(getCurrentUser().getSysUserId());
productInfoService.startProduct(app);
return ApiRes.ok("已提交!");
}
@RequestMapping(value = "/getProductTypeList", method = RequestMethod.GET)
@MethodLog(remark = "获取所有分类列表")
public ApiRes getProductTypeList() throws BizException {
return ApiRes.ok(productTypeService.list(ProductType.gw()));
}
/**
* @author: huay
* @describe: 查询公共条件
*/
public void selectParams(ProductInfo productInfo, LambdaQueryWrapper<ProductInfo> wrapper) {
wrapper.like(StringUtils.isNotEmpty(productInfo.getProductName()), ProductInfo::getProductName, productInfo.getProductName());
wrapper.eq(ProductInfo::getState, productInfo.getState());
}
}

View File

@ -0,0 +1,482 @@
package com.jeequan.jeepay.agent.ctrl.qrcode;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.qrshell.AbstractGenerator;
import com.jeequan.jeepay.bizcommons.manage.qrshell.ShellQRGenerator;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBApplicationConfig;
import com.jeequan.jeepay.core.model.QRCodeParams;
import com.jeequan.jeepay.core.model.export.MchQrCodesExportExcel;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 商户应用管理类
*
* @author zhuxiao
* @date 2021-06-16 09:15
*/
@RestController
@RequestMapping("/api/mchQrCodes")
public class MchQrCodeController extends CommonCtrl {
@Autowired private MchQrcodeCardService mchQrcodeCardService;
@Autowired private MchQrcShellService mchQrcShellService;
@Autowired private MchInfoService mchInfoService;
@Autowired private MchStoreService mchStoreService;
@Autowired private MchAppService mchAppService;
@Autowired private MchApplymentService mchApplymentService;
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_LIST')")
@GetMapping
public ApiRes list() {
// 构造查询条件
MchQrcodeCard mchQrCode = getObject(MchQrcodeCard.class);
// 可查看自己和全部下级代理的设备
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
// 自己和下级服务商
if (CollUtil.isNotEmpty(subAgentNoList)){
mchQrCode.setSubAgentNoList(subAgentNoList);
}
IPage<MchQrcodeCard> page = mchQrcodeCardService.selectPageRecords(getIPage(), mchQrCode);
if (page.getTotal() == 0) {
return ApiRes.page(page);
}
// 列表添加是否属于自身设备只能绑定直属商户app端展示隐藏也使用此字段
for (MchQrcodeCard qrcodeCard: page.getRecords()) {
if (currentAgentNo.equals(qrcodeCard.getAgentNo())) {
qrcodeCard.addExt("isSelf", true);
}
}
return ApiRes.page(page);
}
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_VIEW')")
@GetMapping("/{recordId}")
public ApiRes detail(@PathVariable("recordId") Long recordId) {
// 可查看自己和全部下级代理的码牌
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(recordId);
if (!subAgentNoList.contains(dbRecord.getAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
// 设备是否属于自身
if (getCurrentAgentNo().equals(dbRecord.getAgentNo())) {
dbRecord.addExt("isSelf", true);
}
// 添加服务商商户门店应用名称
AgentInfo allotAgent = agentInfoService.getById(dbRecord.getAgentNo());
if (allotAgent != null) {
dbRecord.addExt("agentName", allotAgent.getAgentName());
}
if (dbRecord.getBindState() == CS.YES) {
if (StringUtils.isNotBlank(dbRecord.getMchNo())) {
MchInfo mchInfo = mchInfoService.getById(dbRecord.getMchNo());
if (mchInfo != null) {
dbRecord.addExt("mchName", mchInfo.getMchName());
}
}
if (dbRecord.getStoreId() != null) {
MchStore mchStore = mchStoreService.getById(dbRecord.getStoreId());
if (mchStore != null) {
dbRecord.addExt("storeName", mchStore.getStoreName());
}
}
if (StringUtils.isNotBlank(dbRecord.getAppId())) {
MchAppEntity mchAppEntity = mchAppService.getById(dbRecord.getAppId());
if (mchAppEntity != null) {
dbRecord.addExt("appName", mchAppEntity.getAppName());
}
}
}
MchApplyment mchApplyment = mchApplymentService.getById(dbRecord.getMchApplyId());
// 封装URL
dbRecord.addExt("qrUrl", sysConfigService.getDBApplicationConfig().genUniJsapiPayUrl(QRCodeParams.TYPE_QRC, dbRecord.getEntryPage(), recordId + "", mchApplyment.getIsvNo()));
return ApiRes.ok(dbRecord);
}
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_EDIT')")
@MethodLog(remark = "更新二维码信息")
@PutMapping("/{recordId}")
public ApiRes update(@PathVariable("recordId") Long recordId) {
// 可查看自己和全部下级代理的码牌
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(recordId);
if (!subAgentNoList.contains(dbRecord.getAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
// 处理金额类型
handleParamAmount("fixedPayAmount");
MchQrcodeCard mchQrCode = getObject(MchQrcodeCard.class);
mchQrCode.setBatchId(null); // 批次号不允许变更
mchQrCode.setCreatedAt(null);
mchQrCode.setUpdatedAt(null);
mchQrCode.setQrcId(recordId);
// 解绑同时设置商户号为空串设置门店ID为-1
if (mchQrCode.getBindState() != null && mchQrCode.getBindState() == CS.NO) {
mchQrCode.setMchNo("");
mchQrCode.setAppId("");
mchQrCode.setStoreId("-1");
}
boolean result = mchQrcodeCardService.updateById(mchQrCode);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/** 解析二维码 && 验证二维码是否可绑定 **/
@GetMapping("/parseQrCodeUrl")
public ApiRes parseQrCodeUrl() {
String url = getValStringRequired("qrUrl");
// 不是支付平台开头的 说明不是可用二维码
if(!url.startsWith(sysConfigService.getDBApplicationConfig().getPaySiteUrl())){
throw new BizException("二维码解析失败");
}
int tokenIndex = url.indexOf(JeepayKit.TOKEN_KEY + "=");
if(tokenIndex <= 0){
throw new BizException("二维码解析失败");
}
String token = url.substring(tokenIndex + 12);
QRCodeParams qrCodeParams = JSON.parseObject(JeepayKit.aesDecode(token), QRCodeParams.class); //解析token
MchQrcodeCard mchQrcodeCard = mchQrcodeCardService.getById( qrCodeParams.getId());
// 不存在 不可用 已绑定
if(mchQrcodeCard == null || mchQrcodeCard.getQrcState() != CS.YES || mchQrcodeCard.getBindState() != CS.NO){
throw new BizException("二维码不存在");
}
return ApiRes.ok(mchQrcodeCard.getQrcId());
}
/**
* @author: xiaoyu
* @date: 2022/1/14 9:45
* @describe: 订单列表数据导出
*/
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_EXPORT')")
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() throws Exception{
String exportModel = getValStringRequired("exportModel");
MchQrcodeCard mchQrcodeCard = getObject(MchQrcodeCard.class);
LambdaQueryWrapper<MchQrcodeCard> wrapper = MchQrcodeCard.gw();
if(mchQrcodeCardService.countByWrapper(mchQrcodeCard) > 500){
throw new BizException("导出数量不可超过500");
}
// 服务商号条件不为空搜索该服务商号下
wrapper.eq(StringUtils.isNotEmpty(mchQrcodeCard.getAgentNo()), MchQrcodeCard::getAgentNo, mchQrcodeCard.getAgentNo());
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
// 自己和下级服务商
wrapper.in(CollUtil.isNotEmpty(subAgentNoList), MchQrcodeCard::getAgentNo, subAgentNoList);
IPage<MchQrcodeCard> pages = mchQrcodeCardService.listByPage(getIPage(true), mchQrcodeCard, wrapper);
// 查询当前系统配置信息
DBApplicationConfig dbApplicationConfig = sysConfigService.getDBApplicationConfig();
// Excel: 信息和url
if ("infoAndUrl".equals(exportModel)) {
try {
List<JSONObject> newList = new LinkedList<>();
for (MchQrcodeCard qrcodeCard:pages.getRecords()) {
MchApplyment mchApplyment = mchApplymentService.getById(qrcodeCard.getMchApplyId());
JSONObject object = (JSONObject) JSONObject.toJSON(qrcodeCard);
object.put("fixedPayAmount", AmountUtil.convertCent2Dollar(qrcodeCard.getFixedPayAmount()));
object.put("qrCodeUrl", dbApplicationConfig.genUniJsapiPayUrl(QRCodeParams.TYPE_QRC, qrcodeCard.getEntryPage(), qrcodeCard.getQrcId() + "", mchApplyment.getIsvNo()));
newList.add(object);
}
List<MchQrCodesExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), MchQrCodesExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "码牌", "码牌", MchQrCodesExportExcel.class, "码牌", response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出二维码失败!");
}
// 模板图片 || 纯二维码 || 二维码包含ID
}else if ("templateImg".equals(exportModel) || "qrcode".equals(exportModel) || "qrcodeAndQrcId".equals(exportModel) ) {
//文件的名称
String downloadFilename = "qrcode_" + DateUtil.today() + ".zip";
//设置格式
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(downloadFilename, "UTF-8"));
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
// 查询所有的模板数据
Map<Long, MchQrcShell> map = new HashMap<>();
pages.getRecords().stream().forEach(r -> map.put(r.getQrcShellId(), null));
if(!map.keySet().isEmpty()){
mchQrcShellService.list(MchQrcShell.gw().in(MchQrcShell::getSid, map.keySet())).stream().forEach(r -> {
map.put(r.getSid(), r);
});
}
for (MchQrcodeCard qrcodeCard:pages.getRecords()) {
String mchStoreName = "";
if(qrcodeCard.getBindState() == CS.YES && qrcodeCard.getStoreId() != null && !"-1".equals(qrcodeCard.getStoreId())){
MchStore mchStore = mchStoreService.getById(qrcodeCard.getStoreId());
mchStoreName = mchStore != null ? mchStore.getStoreName() : "";
}
BufferedImage bufferedImage = null;
MchQrcShell mchQrcShell = map.get(qrcodeCard.getQrcShellId());
AbstractGenerator abstractGenerator = SpringBeansUtil.getBean(ShellQRGenerator.class);
if(mchQrcShell != null && "templateImg".equals(exportModel)){ //存在模板 && 显式导出模板
abstractGenerator = getAbstractGenerator(mchQrcShell.getStyleCode());
}
String configStr = null;
if("templateImg".equals(exportModel)){ // 模板图片
if(mchQrcShell != null){
configStr = mchQrcShell.getConfigInfo();
}
}else if("qrcode".equals(exportModel)){ // 纯二维码不包含ID
configStr = "{showIdFlag: false}";
}else if("qrcodeAndQrcId".equals(exportModel)){ // 二维码 + ID
configStr = "{showIdFlag: true}";
}
MchApplyment applyment = mchApplymentService.getById(qrcodeCard.getMchApplyId());
bufferedImage = abstractGenerator
.genQrImgBuffer(configStr,
dbApplicationConfig.genUniJsapiPayUrl(QRCodeParams.TYPE_QRC, qrcodeCard.getEntryPage(), qrcodeCard.getQrcId() + "", applyment.getIsvNo()),
qrcodeCard.getQrcId(),
mchStoreName,
false
);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", out);
InputStream is = new ByteArrayInputStream(out.toByteArray());
zos.putNextEntry(new ZipEntry( qrcodeCard.getQrcId() + ".png"));
byte[] buffer = new byte[1024];
int r = 0;
while ((r = is.read(buffer)) != -1) {
zos.write(buffer, 0, r);
}
is.close();
is = null;
out.close();
out = null;
zos.flush();
}
zos.flush();
zos.close();
}
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 绑定码牌
*/
@MethodLog(remark = "绑定码牌")
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_EDIT')")
@PutMapping("/bind/{recordId}")
public ApiRes bind(@PathVariable("recordId") Long recordId) {
String mchNo = getValStringRequired("mchNo");
String appId = getValStringRequired("appId");
String storeId = getValStringRequired("storeId");
MchInfo mchInfo = mchInfoService.getById(mchNo);
if (mchInfo == null || StringUtils.isBlank(mchInfo.getAgentNo()) || !mchInfo.getAgentNo().equals(getCurrentAgentNo())) {
throw new BizException("商户不存在");
}
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(recordId);
if (dbRecord == null || StringUtils.isBlank(dbRecord.getAgentNo()) || !dbRecord.getAgentNo().equals(getCurrentAgentNo())) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
MchQrcodeCard updateRecord = new MchQrcodeCard();
updateRecord.setQrcId(recordId).setMchNo(mchNo).setStoreId(storeId).setAppId(appId).setBindState(CS.YES);
mchQrcodeCardService.bindEmptyQR(updateRecord);
return ApiRes.ok();
}
/**
* @Author: zx
* @Description: 解绑码牌
* @Date: 15:59 2022/5/30
*/
@MethodLog(remark = "解绑码牌")
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_RELIEVE')")
@PostMapping("/unbind/{qrcId}")
public ApiRes unbind(@PathVariable("qrcId") Long qrcId) {
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(qrcId);
if (dbRecord == null || !dbRecord.getAgentNo().equals(getCurrentAgentNo())) {
return ApiRes.customFail("解绑失败");
}
mchQrcodeCardService.unbind(dbRecord);
return ApiRes.ok();
}
/**
* @Author: zx
* @Description: 查看码牌绑定的设备列表
* @Date: 15:59 2022/5/30
*/
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_EDIT')")
@GetMapping("/bindDevice/{qrcId}")
public ApiRes bindDevice(@PathVariable("qrcId") Long qrcId) {
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(qrcId);
if (dbRecord == null || !dbRecord.getAgentNo().equals(getCurrentAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
IPage<MchStoreDevice> page = mchQrcodeCardService.getBindDevice(getIPage(), dbRecord, getCurrentAgentNo());
return ApiRes.page(page);
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 划拨码牌给服务商
*/
@MethodLog(remark = "划拨/收回码牌给服务商")
@PreAuthorize("hasAuthority('ENT_DEVICE_QRC_ALLOT')")
@PostMapping("/allotQrc")
public ApiRes allotQrc() {
// 服务商是否支持划拨码牌设备
SysConfig isSupportAgentAllot = sysConfigService.getById("isSupportAgentAllot");
if(isSupportAgentAllot == null || String.valueOf(CS.NO).equals(isSupportAgentAllot.getConfigVal())){
throw new BizException("不支持服务商划拨码牌、设备");
}
String allotType = getValStringRequired("allotType"); // 划拨类型select-勾选划拨 batch-批次划拨
String allotOrRecover = getValStringRequired("allotOrRecover"); // 分配类型allot-划拨 recover-收回
List<Long> qrcIdList = new LinkedList<>();
// 构建批量更新设备ID集合
if (allotType.equals("select")) {
String allotds = getValStringRequired("allotIds");
qrcIdList = Arrays.stream(allotds.split(",")).map(Long::parseLong).collect(Collectors.toList());
}else if (allotType.equals("batch")) {
String batchId = getValStringRequired("batchId");
List<MchQrcodeCard> list = mchQrcodeCardService.list(MchQrcodeCard.gw().eq(MchQrcodeCard::getBatchId, batchId));
if (CollUtil.isEmpty(list)) {
throw new BizException("批次号错误");
}
for (MchQrcodeCard mchQrcodeCard : list) {
qrcIdList.add(mchQrcodeCard.getQrcId());
}
}else {
throw new BizException("划拨类型错误");
}
if (CollUtil.isEmpty(qrcIdList)) {
throw new BizException("请选择码牌");
}
// 只能操作下级代理
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
// 1收回码牌
if (allotOrRecover.equals("recover")) {
mchQrcodeCardService.recoverQrc(true, qrcIdList, subAgentNoList, getCurrentAgentNo());
return ApiRes.ok();
}
// 2划拨码牌
String agentNo = getValStringRequired("agentNo");
List<String> mchNoList = getMchNoListByAgentNo(agentNo);
mchQrcodeCardService.allotQrc(true, agentNo, qrcIdList, mchNoList, subAgentNoList);
return ApiRes.ok();
}
private AbstractGenerator getAbstractGenerator(String code){
AbstractGenerator generator = SpringBeansUtil.getBean(code + "Generator", AbstractGenerator.class);
if(generator == null){
throw new BizException("选择模板[" + code + "]不存在!");
}
return generator;
}
}

View File

@ -0,0 +1,85 @@
package com.jeequan.jeepay.agent.ctrl.qrcode;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.qrshell.AbstractGenerator;
import com.jeequan.jeepay.bizcommons.manage.qrshell.ShellQRGenerator;
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.core.model.QRCodeParams;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.db.entity.MchQrcShell;
import com.jeequan.jeepay.db.entity.MchQrcodeCard;
import com.jeequan.jeepay.db.entity.MchStore;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchQrcShellService;
import com.jeequan.jeepay.service.impl.MchQrcodeCardService;
import com.jeequan.jeepay.service.impl.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.awt.image.BufferedImage;
/**
* 二维码模板管理
*
* @author terrfly
* @date 2022/1/17 14:22
*/
@RestController
@RequestMapping("/api/mchQrcShells")
public class MchQrcShellController extends CommonCtrl {
@Autowired private MchQrcodeCardService mchQrcodeCardService;
@Autowired private MchQrcShellService mchQrcShellService;
@Autowired private SysConfigService sysConfigService;
@Autowired private MchApplymentService mchApplymentService;
/** 根据qrcId获取图片base64 **/
@GetMapping("/viewByQrc/{qrcId}")
public ApiRes viewByQrc(@PathVariable("qrcId") Long qrcId) throws Exception {
MchQrcodeCard dbRecord = mchQrcodeCardService.getById(qrcId);
String mchStoreName = "";
if(dbRecord.getBindState() == CS.YES && dbRecord.getStoreId() != null && !"-1".equals(dbRecord.getStoreId())){
MchStore mchStore = mchStoreService.getById(dbRecord.getStoreId());
mchStoreName = mchStore != null ? mchStore.getStoreName() : "";
}
AbstractGenerator shellGenerator = SpringBeansUtil.getBean(ShellQRGenerator.class);
MchApplyment applyment = mchApplymentService.getById(dbRecord.getMchApplyId());
// 封装URL
String qrUrlContent = sysConfigService.getDBApplicationConfig().genUniJsapiPayUrl(QRCodeParams.TYPE_QRC, dbRecord.getEntryPage(), qrcId + "", applyment.getIsvNo());
if(dbRecord.getQrcShellId() == null || dbRecord.getQrcShellId() <= 0){
//给前端拼接上 data:image/jpg;base64
return ApiRes.ok("data:image/jpg;base64,"+ AbstractGenerator.convertImgBase64(shellGenerator.genQrImgBuffer(null, qrUrlContent, qrcId, mchStoreName, false)));
}
MchQrcShell mchQrcShell = mchQrcShellService.getById(dbRecord.getQrcShellId());
BufferedImage bufferedImage = getAbstractGenerator(mchQrcShell.getStyleCode()).genQrImgBuffer(mchQrcShell.getConfigInfo(), qrUrlContent, qrcId, mchStoreName, false);
//给前端拼接上 data:image/jpg;base64
return ApiRes.ok("data:image/jpg;base64,"+ AbstractGenerator.convertImgBase64(bufferedImage));
}
private AbstractGenerator getAbstractGenerator(String code){
AbstractGenerator generator = SpringBeansUtil.getBean(code + "Generator", AbstractGenerator.class);
if(generator == null){
throw new BizException("选择模板[" + code + "]不存在!");
}
return generator;
}
}

View File

@ -0,0 +1,130 @@
package com.jeequan.jeepay.agent.ctrl.settle;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.export.SettleInfoExportExcel;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.db.entity.PayInterfaceDefine;
import com.jeequan.jeepay.db.entity.SettleInfo;
import com.jeequan.jeepay.service.impl.PayInterfaceDefineService;
import com.jeequan.jeepay.service.impl.SettleInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* TODO
*
* @author crystal
* @date 2023/12/6 15:11
*/
@RestController
@RequestMapping("/api/settle")
public class SettleInfoController extends CommonCtrl {
@Autowired private SettleInfoService settleInfoService;
@Autowired private PayInterfaceDefineService payInterfaceDefineService;
@PreAuthorize("hasAuthority('ENT_SETTLE_LIST')")
@GetMapping
public ApiRes list() {
SettleInfo info = getObject(SettleInfo.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<SettleInfo> wrapper = SettleInfo.gw();
// 查询下级服务商
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
wrapper.in(SettleInfo::getAgentNo,subAgentNoList);
//wrapper.eq(SettleInfo::getAgentNo, getCurrentAgentNo());
Page<SettleInfo> pages = settleInfoService.pageList(getIPage(), wrapper,info,paramJSON);
Map<String, String> ifCodeMap = new HashMap<>();
List<PayInterfaceDefine> list = payInterfaceDefineService.list();
if(!list.isEmpty()){
for (PayInterfaceDefine define:list) {
ifCodeMap.put(define.getIfCode(), define.getIfName());
}
}
for (SettleInfo data:pages.getRecords()) {
if(StringUtils.isNotBlank(data.getIfCode())){
data.setIfName(ifCodeMap.get(data.getIfCode()));
}
}
return ApiRes.page(pages);
}
/**
* 结算信息导出
*/
@RequestMapping(value="/exportExcel", method = RequestMethod.GET)
public void exportExcel() {
try {
SettleInfo info = getObject(SettleInfo.class);
JSONObject paramJSON = getReqParamJSON();
LambdaQueryWrapper<SettleInfo> wrapper = SettleInfo.gw(info);
wrapper.eq(SettleInfo::getAgentNo, getCurrentAgentNo());
Page<SettleInfo> pages = settleInfoService.pageList(getIPage(), wrapper,info,paramJSON);
Map<String, String> ifCodeMap = new HashMap<>();
List<PayInterfaceDefine> list = payInterfaceDefineService.list();
if(!list.isEmpty()){
for (PayInterfaceDefine define:list) {
ifCodeMap.put(define.getIfCode(), define.getIfName());
}
}
List<JSONObject> newList = new LinkedList<>();
if (!pages.getRecords().isEmpty()){
//成功交易总笔数
List<SettleInfo> infoList = pages.getRecords().stream().filter(p -> p.getState() == 2).collect(Collectors.toList());
//成功交易总金额
BigDecimal allSuccessAmount = BigDecimal.ZERO;
for (SettleInfo settleInfo : infoList) {
allSuccessAmount=allSuccessAmount.add(BigDecimal.valueOf(settleInfo.getSettleAmt()));
}
for (SettleInfo data:pages.getRecords()) {
if(StringUtils.isNotBlank(data.getIfCode())){
data.setIfName(ifCodeMap.get(data.getIfCode()));
}
JSONObject object = (JSONObject) JSONObject.toJSON(data);
newList.add(object);
}
}
List<SettleInfoExportExcel> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), SettleInfoExportExcel.class);
// excel输出
ExcelUtil.exportExcel(linkedList, "结算信息", "结算信息", SettleInfoExportExcel.class, "结算信息", response);
}catch (Exception e){
logger.error("导出excel失败", e);
throw new BizException("导出结算信息失败!");
}
}
@GetMapping("/count")
public ApiRes getCount(){
SettleInfo info = getObject(SettleInfo.class);
LambdaQueryWrapper<SettleInfo> wrapper = SettleInfo.gw();
// 时间范围条件
Date[] dateRange = info.buildQueryDateRange();
if (dateRange[0] != null) {
wrapper.ge(SettleInfo::getUpdatedAt, dateRange[0]);
}
if (dateRange[1] != null) {
wrapper.le(SettleInfo::getUpdatedAt, dateRange[1]);
}
wrapper.eq(SettleInfo::getAgentNo, getCurrentAgentNo());
List<SettleInfo> infoList = settleInfoService.list(wrapper);
return settleInfoService.getCount(infoList);
}
}

View File

@ -0,0 +1,175 @@
package com.jeequan.jeepay.agent.ctrl.statistics;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.export.statistic.*;
import com.jeequan.jeepay.core.utils.ExcelUtil;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.service.impl.AgentInfoService;
import com.jeequan.jeepay.service.impl.StatsDeviceService;
import com.jeequan.jeepay.service.impl.StatsPayWayService;
import com.jeequan.jeepay.service.impl.StatsTradeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
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.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;
/**
* 统计列表接口
*
* @author xiaoyu
*
* @date 2022/5/23 16:52
*/
@Slf4j
@RestController
@RequestMapping("/api/statistic/export")
public class ExportExcelStatisticController extends CommonCtrl {
@Autowired private AgentInfoService agentInfoService;
@Autowired private StatsTradeService statsTradeService;
@Autowired private StatsPayWayService statsPayWayService;
@Autowired private StatsDeviceService statsDeviceService;
/**
* @author: xiaoyu
* @date: 2022/5/23 17:15
* @describe: 统计列表
*/
@PreAuthorize("hasAnyAuthority('ENT_STATISTIC_TRANSACTION', 'ENT_STATISTIC_MCH', 'ENT_STATISTIC_MCH_STORE', 'ENT_STATISTIC_MCH_WAY', 'ENT_STATISTIC_MCH_TYPE', 'ENT_STATISTIC_AGENT', 'ENT_STATISTIC_CHANNEL')")
@RequestMapping(value="", method = RequestMethod.GET)
public void list() {
JSONObject paramJSON = getReqParamJSON();
PayOrder payOrder = getObject(PayOrder.class);
List<String> agentSubList = null;
if (StringUtils.isEmpty(payOrder.getAgentNo())) {
// 查询服务商所有下级
agentSubList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
}
String method = getValStringRequired("method");
String mchNo = null;
Page<PayOrderCount> countPage = null;
switch (method) {
case CS.STATISTIC_TYPE.MCH:
// 商户
countPage = statsTradeService.selectMchStatsList(paramJSON, agentSubList);
exportExcel(countPage, StatisticMchExportExcel.class, "商户统计");
break;
case CS.STATISTIC_TYPE.AGENT:
// 服务商
countPage = statsTradeService.selectAgentStatsList(paramJSON, agentSubList);
exportExcel(countPage, StatisticAgentExportExcel.class, "服务商统计");
break;
case CS.STATISTIC_TYPE.TRANSACTION:
// 交易报表
// mapPage = payOrderService.countListByTransaction(payOrder, paramJSON, agentSubList);
countPage = statsTradeService.selectTransactionStatsList(payOrder, paramJSON, agentSubList);
exportExcel(countPage, StatisticTransactionExportExcel.class, "交易报表");
break;
case CS.STATISTIC_TYPE.STORE:
// 门店
getValStringRequired("mchNo");
countPage = statsTradeService.selectStoreStatsList(paramJSON);
exportExcel(countPage, StatisticStoreExportExcel.class, "门店统计");
break;
case CS.STATISTIC_TYPE.WAY_CODE:
// 支付方式
getValStringRequired("mchNo");
countPage = statsPayWayService.selectPayWayStatsList(paramJSON);
exportExcel(countPage, StatisticWayCodeExportExcel.class, "支付方式统计");
break;
case CS.STATISTIC_TYPE.WAY_CODE_TYPE:
// 支付类型
getValStringRequired("mchNo");
countPage = statsPayWayService.selectWayCodeTypeStatsList(paramJSON);
exportExcel(countPage, StatisticWayCodeTypeExportExcel.class, "支付类型统计");
break;
case CS.STATISTIC_TYPE.DEVICE:
// 设备统计
countPage = statsDeviceService.selectStatsList(paramJSON, agentSubList);
exportExcel(countPage, StatisticDeviceExportExcel.class, "设备统计");
break;
default:
break;
}
}
public List<String> getAgentSubList(JSONObject paramJSON, PayOrder payOrder) {
List<String> allAgentNoList = null;
if (StringUtils.isNotEmpty(payOrder.getAgentNo())) {
Boolean onlyOne = paramJSON.getBoolean("onlyOne");
// if (onlyOne) {
// // 仅查询单个服务商
// allAgentNoList = Arrays.asList(payOrder.getAgentNo());
// } else if ("onlyOne".equals(payOrder.getAgentNo())) {
// allAgentNoList = Arrays.asList(getCurrentAgentNo());
// } else {
// // 查询服务商所有下级
// allAgentNoList = agentInfoService.queryAllSubAgentNo(payOrder.getAgentNo());
// }
}
return allAgentNoList;
}
/** 通用导出类 **/
public void exportExcel(Page<PayOrderCount> countPage, Class clazz, String title) {
try {
List<JSONObject> newList = new LinkedList<>();
countPage.getRecords().stream().forEach(record -> {
JSONObject itemData = (JSONObject) JSONObject.toJSON(record);
// 交易金额转换
BigDecimal totalSuccAmt = new BigDecimal(record.getTotalSuccAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
itemData.put("allAmount", totalSuccAmt);
// 实收金额转换
BigDecimal totalFinalAmt = BigDecimal.valueOf(record.getTotalFinalAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
itemData.put("payAmount", totalFinalAmt);
// 退款金额转换
BigDecimal refundAmount = BigDecimal.valueOf(record.getTotalRefundAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
itemData.put("refundAmount", refundAmount);
//手续费
if (record.getTotalFeeAmt() != null){
BigDecimal totalfeeamt = BigDecimal.valueOf(record.getTotalFeeAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
itemData.put("totalFeeAmt", totalfeeamt);
}
//手续费回退
if (record.getTotalRefundFeeAmt() != null){
BigDecimal totalReFeeAmt= BigDecimal.valueOf(record.getTotalRefundFeeAmt()).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
itemData.put("totalRefundFeeAmt", totalReFeeAmt);
}
// 成功率
itemData.put("round", record.getSuccRate() + "%");
if (StringUtils.isNotBlank(record.getDeviceType())) {
itemData.put("deviceType", PayOrder.DEVICE_TYPE_MAP.get(record.getDeviceType()));
}
newList.add(itemData);
});
List<T> linkedList = JSONArray.parseArray(JSONArray.toJSONString(newList), clazz);
// excel输出
ExcelUtil.exportExcel(linkedList, title, title, clazz, title, response);
}catch (Exception e) {
logger.error("导出excel失败", e);
throw new BizException("导出订单失败!");
}
}
}

View File

@ -0,0 +1,98 @@
package com.jeequan.jeepay.agent.ctrl.statistics;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.service.impl.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.List;
/**
* 统计列表接口
*
* @author xiaoyu
*
* @date 2022/5/23 16:52
*/
@Slf4j
@RestController
@RequestMapping("/api/statistic")
public class StatisticController extends CommonCtrl {
@Autowired private PayOrderService payOrderService;
@Autowired private AgentInfoService agentInfoService;
@Autowired private StatsTradeService statsTradeService;
@Autowired private StatsChannelService statsChannelService;
@Autowired private StatsPayWayService statsPayWayService;
@Autowired private StatsDeviceService statsDeviceService;
/**
* @author: xiaoyu
* @date: 2022/5/23 17:15
* @describe: 统计列表
*/
@PreAuthorize("hasAnyAuthority('ENT_STATISTIC_TRANSACTION', 'ENT_STATISTIC_MCH', 'ENT_STATISTIC_MCH_STORE', 'ENT_STATISTIC_MCH_WAY', 'ENT_STATISTIC_MCH_TYPE', 'ENT_STATISTIC_AGENT', 'ENT_STATISTIC_CHANNEL')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
JSONObject paramJSON = getReqParamJSON();
PayOrder payOrder = getObject(PayOrder.class);
List<String> agentSubList = null;
// 交易报表
if (StringUtils.isEmpty(payOrder.getAgentNo())) {
// 查询服务商所有下级
agentSubList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
}
String method = getValStringRequired("method");
String mchNo = null;
Page<PayOrderCount> mapPage = new Page<>();
switch (method) {
case CS.STATISTIC_TYPE.MCH:
// 商户
mapPage = statsTradeService.selectMchStatsList(paramJSON, agentSubList);
break;
case CS.STATISTIC_TYPE.AGENT:
// 服务商
mapPage = statsTradeService.selectAgentStatsList(paramJSON, agentSubList);
break;
case CS.STATISTIC_TYPE.TRANSACTION:
mapPage = statsTradeService.selectTransactionStatsList(payOrder, paramJSON, agentSubList);
break;
case CS.STATISTIC_TYPE.STORE:
// 门店
getValStringRequired("mchNo");
mapPage = statsTradeService.selectStoreStatsList(paramJSON);
break;
case CS.STATISTIC_TYPE.WAY_CODE:
// 支付方式
getValStringRequired("mchNo");
mapPage = statsPayWayService.selectPayWayStatsList(paramJSON);
break;
case CS.STATISTIC_TYPE.WAY_CODE_TYPE:
// 支付类型
getValStringRequired("mchNo");
mapPage = statsPayWayService.selectWayCodeTypeStatsList(paramJSON);
break;
case CS.STATISTIC_TYPE.DEVICE:
// 设备
mapPage = statsDeviceService.selectStatsList(paramJSON, agentSubList);
break;
default:
break;
}
// 解决hasnext不显示的问题
mapPage.setCurrent(paramJSON.getIntValue("pageNumber"));
mapPage.setSize(paramJSON.getIntValue("pageSize"));
return ApiRes.page(mapPage);
}
}

View File

@ -0,0 +1,109 @@
package com.jeequan.jeepay.agent.ctrl.statistics;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.PayOrderCount;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.PayOrder;
import com.jeequan.jeepay.service.impl.AgentInfoService;
import com.jeequan.jeepay.service.impl.StatsDeviceService;
import com.jeequan.jeepay.service.impl.StatsPayWayService;
import com.jeequan.jeepay.service.impl.StatsTradeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.List;
/**
* 总计接口
*
* @author xiaoyu
*
* @date 2022/5/23 16:52
*/
@Slf4j
@RestController
@RequestMapping("/api/statistic/total")
public class TotalStatisticController extends CommonCtrl {
@Autowired private AgentInfoService agentInfoService;
@Autowired private StatsTradeService statsTradeService;
@Autowired private StatsPayWayService statsPayWayService;
@Autowired private StatsDeviceService statsDeviceService;
/**
* @author: xiaoyu
* @date: 2022/5/23 17:15
* @describe: 总计
*/
@PreAuthorize("hasAnyAuthority('ENT_STATISTIC_TRANSACTION', 'ENT_STATISTIC_MCH', 'ENT_STATISTIC_MCH_STORE', 'ENT_STATISTIC_MCH_WAY', 'ENT_STATISTIC_MCH_TYPE', 'ENT_STATISTIC_AGENT', 'ENT_STATISTIC_CHANNEL')")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes total() {
JSONObject paramJSON = getReqParamJSON();
PayOrder payOrder = getObject(PayOrder.class);
List<String> agentSubList = null;
if (StringUtils.isEmpty(payOrder.getAgentNo())) {
// 查询服务商所有下级
agentSubList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
}else {
}
String method = getValStringRequired("method");
String mchNo = null;
PayOrderCount orderCount = new PayOrderCount();
switch (method) {
case CS.STATISTIC_TYPE.MCH:
// 商户统计
// resMap = payOrderService.totalByMch(payOrder, paramJSON, agentSubList);
orderCount = statsTradeService.selectTotalByTransaction(paramJSON, agentSubList);
break;
case CS.STATISTIC_TYPE.AGENT:
// 服务商统计
// resMap = payOrderService.totalByAgent(payOrder, paramJSON, agentSubList);
orderCount = statsTradeService.selectTotalByAgent(paramJSON, agentSubList);
break;
case CS.STATISTIC_TYPE.TRANSACTION:
// 交易报表统计
// resMap = payOrderService.totalByTransaction(payOrder, paramJSON, agentSubList);
orderCount = statsTradeService.selectTotalByTransaction(paramJSON, agentSubList, false);
break;
case CS.STATISTIC_TYPE.STORE:
// 门店统计
getValStringRequired("mchNo");
// payOrder.setMchNo(mchNo);
// resMap = payOrderService.totalByStore(payOrder, paramJSON);
orderCount = statsTradeService.selectTotalByStore(paramJSON, null);
break;
case CS.STATISTIC_TYPE.WAY_CODE:
// 支付方式统计
getValStringRequired("mchNo");
// payOrder.setMchNo(mchNo);
// resMap = payOrderService.totalByWayCode(payOrder, paramJSON);
orderCount = statsPayWayService.selectTotalByPayWay(paramJSON);
break;
case CS.STATISTIC_TYPE.WAY_CODE_TYPE:
// 支付类型统计
getValStringRequired("mchNo");
// payOrder.setMchNo(mchNo);
// resMap = payOrderService.totalByWayCodeType(payOrder, paramJSON);
orderCount = statsPayWayService.selectTotalByWayCodeType(paramJSON);
break;
case CS.STATISTIC_TYPE.DEVICE:
// 设备统计
// resMap = payOrderService.totalByDevice(payOrder, paramJSON, agentSubList);
orderCount = statsDeviceService.selectTotalByDeviceNo(paramJSON, agentSubList);
break;
default:
break;
}
return ApiRes.ok(orderCount);
}
}

View File

@ -0,0 +1,56 @@
package com.jeequan.jeepay.agent.ctrl.store;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.DeviceProvideConfig;
import com.jeequan.jeepay.service.impl.DeviceProvideConfigService;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 设备厂商配置管理类
*
* @author zx
* @date 2021-12-28 09:15
*/
@Slf4j
@RestController
@RequestMapping("api/device/provider")
public class DeviceProvideConfigController extends CommonCtrl {
@Autowired private DeviceProvideConfigService deviceProvideConfigService;
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 厂商配置列表
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_LIST', 'ENT_DEVICE_PRINTER_LIST', 'ENT_DEVICE_SPEAKER_ADD'," +
"'ENT_DEVICE_PRINTER_ADD', 'ENT_DEVICE_SPEAKER_EDIT', 'ENT_DEVICE_PRINTER_EDIT')")
@GetMapping
public ApiRes pages() {
LambdaQueryWrapper<DeviceProvideConfig> gw = DeviceProvideConfig.gw();
gw.select(DeviceProvideConfig::getConfigId, DeviceProvideConfig::getConfigDesc, DeviceProvideConfig::getProvider);
gw.orderByDesc(DeviceProvideConfig::getCreatedAt);
gw.eq(DeviceProvideConfig::getDeviceType, getValByteRequired("deviceType"));
if (null != getValByte("state")) {
gw.eq(DeviceProvideConfig::getState, getValByte("state"));
}
gw.select(DeviceProvideConfig::getConfigId, DeviceProvideConfig::getConfigDesc, DeviceProvideConfig::getDeviceType, DeviceProvideConfig::getProvider,
DeviceProvideConfig::getCreatedAt, DeviceProvideConfig::getAppId, DeviceProvideConfig::getState);
IPage<DeviceProvideConfig> page = deviceProvideConfigService.page(getIPage(true), gw);
//返回数据
return ApiRes.page(page);
}
}

View File

@ -0,0 +1,201 @@
package com.jeequan.jeepay.agent.ctrl.store;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
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.core.model.DBApiMapConfig;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.MchStore;
import com.jeequan.jeepay.service.impl.AgentInfoService;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.service.impl.MchInfoService;
import com.jeequan.jeepay.service.impl.MchStoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
/**
* 商户门店管理
*
* @date 2021/12/29 9:52
*/
@RestController
@RequestMapping("/api/mchStore")
public class MchStoreController extends CommonCtrl {
@Autowired private MchStoreService mchStoreService;
@Autowired private AgentInfoService agentInfoService;
@Autowired private MchInfoService mchInfoService;
@Autowired
private MchApplymentService mchApplymentService;
/**
* @date: 2021/12/29 9:53
* @describe: 门店列表查询
*/
@GetMapping
@PreAuthorize("hasAuthority('ENT_MCH_STORE_LIST')")
public ApiRes list() {
MchStore mchStore = getObject(MchStore.class);
//mchStore.setAgentNo(getCurrentAgentNo());
JSONObject paramJSON = getReqParamJSON();
// 可查看自己和全部下级服务商
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
if (CollectionUtil.isNotEmpty(subAgentNoList)) {
mchStore.setSubAgentNoList(subAgentNoList);
}
IPage<MchStore> mchStoreList = mchStoreService.listByPage(getIPage(true), mchStore, paramJSON);
return ApiRes.page(mchStoreList);
}
/**
* @date: 2021/12/29 9:59
* @describe: 新建门店
*/
@MethodLog(remark = "新建门店")
@PostMapping
@PreAuthorize("hasAuthority('ENT_MCH_STORE_ADD')")
public ApiRes add() {
MchStore mchStore = getObject(MchStore.class);
Assert.hasLength(mchStore.getMchNo(), "用户号[mchNo]不能为空");
Assert.notNull(mchStore.getAreaCode(), "请选择省市区");
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
Assert.hasLength(mchStore.getMchApplyId(), "商户号[mchApplyId]不能为空");
MchApplyment tbMchApplyment = mchApplymentService.getById(mchStore.getMchApplyId());
Assert.notNull(tbMchApplyment, "商户不存在");
//关联商户信息原进件信息t_mch_applyment需要校验商户状态必须是进件成功的
if (MchApplyment.STATE_SUCCESS != tbMchApplyment.getState()) {
return ApiRes.customFail("该商户状态未进件成功!");
}
//校验指定商户号下的进件信息
String applyMchNo = tbMchApplyment.getMchNo();
String storeMchNo = mchStore.getMchNo();
if (!applyMchNo.equals(storeMchNo)) {
return ApiRes.customFail("用户信息与商户信息不匹配!");
}
mchStore.setStoreId(SeqKit.genStoreNo());
mchStore.setAgentNo(agentInfo.getAgentNo());
mchStore.setTopAgentNo(agentInfoService.queryTopAgentNo(getCurrentAgentNo()));
mchStore.setIsvNo(agentInfo.getIsvNo());
// 初始为非默认门店
mchStore.setDefaultFlag(CS.NO);
boolean result = mchStoreService.save(mchStore);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/**
* @date: 2021/12/29 9:59
* @describe: 门店详情
*/
@GetMapping("/{recordId}")
@PreAuthorize("hasAuthority('ENT_MCH_STORE_VIEW')")
public ApiRes detail(@PathVariable("recordId") String recordId) {
MchStore mchStore = mchStoreService.getById(recordId);
if (mchStore == null || !mchStore.getAgentNo().equals(getCurrentAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
MchInfo mchInfo = mchInfoService.getById(mchStore.getMchNo());
mchStore.addExt("mchName", mchInfo.getMchName());
return ApiRes.ok(mchStore);
}
/**
* @date: 2021/12/29 10:00
* @describe: 更新门店
*/
@MethodLog(remark = "更新门店")
@PutMapping("/{recordId}")
@PreAuthorize("hasAuthority('ENT_MCH_STORE_EDIT')")
public ApiRes update(@PathVariable("recordId") String recordId) {
MchStore mchStore = getObject(MchStore.class);
mchStore.setStoreId(recordId);
mchStore.setMchNo(null);
mchStore.setAgentNo(null);
mchStore.setTopAgentNo(null);
mchStore.setCreatedAt(null);
mchStore.setUpdatedAt(null);
MchStore dbRecord = mchStoreService.getById(recordId);
if (!dbRecord.getAgentNo().equals(getCurrentAgentNo())) {
throw new BizException("无权操作!");
}
// 如果修改当前为默认
if (mchStore.getDefaultFlag() == CS.YES) {
mchStoreService.updateAllDefaultFlag(dbRecord.getMchNo());
}else {
mchStore.setDefaultFlag(null);
}
boolean result = mchStoreService.updateById(mchStore);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @date: 2021/12/29 10:05
* @describe: 删除门店
*/
@MethodLog(remark = "删除门店")
@DeleteMapping("/{recordId}")
@PreAuthorize("hasAuthority('ENT_MCH_STORE_DELETE')")
public ApiRes delete(@PathVariable("recordId") String recordId) {
MchStore mchStore = mchStoreService.getById(recordId);
if (!mchStore.getAgentNo().equals(getCurrentAgentNo())) {
throw new BizException("无权操作!");
}
if (mchStore.getDefaultFlag() == CS.YES) {
throw new BizException("默认门店无法删除!");
}
mchStoreService.deleteStore(recordId, false);
return ApiRes.ok();
}
/**
* @date: 2022/2/19 10:41
* @describe: 获取地图配置参数
*/
@GetMapping("/mapConfig")
@PreAuthorize("hasAuthority('ENT_MCH_STORE_MAP')")
public ApiRes getMapConfig() {
DBApiMapConfig apiMapConfig = sysConfigService.getDBApiMapConfig();
return ApiRes.ok(apiMapConfig);
}
}

View File

@ -0,0 +1,466 @@
package com.jeequan.jeepay.agent.ctrl.store;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.device.IPrinterService;
import com.jeequan.jeepay.core.interfaces.device.ISpeakerService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.device.PayOrderInfo4Device;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.impl.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 设备厂商配置管理类
*
* @author zx
*
* @date 2021-12-28 09:15
*/
@Slf4j
@RestController
@RequestMapping("api/store/device")
public class MchStoreDeviceController extends CommonCtrl {
@Autowired private DeviceProvideConfigService deviceProvideConfigService;
@Autowired private MchStoreDeviceService mchStoreDeviceService;
@Autowired private MchStoreService mchStoreService;
@Autowired private MchAppService mchAppService;
@Autowired private MchQrcDeviceRelaService mchQrcDeviceRelaService;
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 门店设备列表
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_LIST', 'ENT_DEVICE_PRINTER_DEVICE_LIST', 'ENT_DEVICE_POS_DEVICE_LIST', " +
"'ENT_DEVICE_PLUGIN_CDKEY_LIST', 'ENT_DEVICE_FACE_APP_LIST')")
@GetMapping
public ApiRes pages() {
MchStoreDevice mchStoreDevice = getObject(MchStoreDevice.class);
// 可查看自己和全部下级代理的设备
String currentAgentNo = getCurrentAgentNo();
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(currentAgentNo);
if (CollectionUtil.isNotEmpty(subAgentNoList)) {
mchStoreDevice.setSubAgentNoList(subAgentNoList);
}
IPage<MchStoreDevice> page = mchStoreDeviceService.selectPage(getIPage(), mchStoreDevice);
if (page.getTotal() == 0) {
return ApiRes.page(page);
}
// 列表添加是否属于自身设备只能绑定直属商户app端展示隐藏也使用此字段
for (MchStoreDevice device: page.getRecords()) {
if (currentAgentNo.equals(device.getAgentNo())) {
device.addExt("isSelf", true);
}
}
//返回数据
return ApiRes.page(page);
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 门店设备修改
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_EDIT', 'ENT_DEVICE_PRINTER_DEVICE_EDIT', 'ENT_DEVICE_POS_DEVICE_EDIT', " +
"'ENT_DEVICE_PLUGIN_CDKEY_EDIT', 'ENT_DEVICE_FACE_APP_EDIT')")
@MethodLog(remark = "设备厂商配置修改")
@PutMapping("/{deviceId}")
public ApiRes update(@PathVariable("deviceId") Long deviceId) {
MchStoreDevice mchStoreDevice = getObject(MchStoreDevice.class);
mchStoreDevice.setDeviceId(deviceId);
mchStoreDevice.setBatchId(null);
mchStoreDevice.setDeviceNo(null);
mchStoreDevice.setDeviceParams(null);
mchStoreDevice.setCreatedAt(null);
mchStoreDevice.setUpdatedAt(null);
// 可查看自己和全部下级代理的设备
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
MchStoreDevice dbRecord = mchStoreDeviceService.getById(deviceId);
if (!subAgentNoList.contains(dbRecord.getAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
boolean result = mchStoreDeviceService.updateById(mchStoreDevice);
if(!result) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 根据ID获取门店设备
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_VIEW', 'ENT_DEVICE_PRINTER_DEVICE_VIEW', 'ENT_DEVICE_POS_DEVICE_VIEW', " +
"'ENT_DEVICE_PLUGIN_CDKEY_VIEW', 'ENT_DEVICE_FACE_APP_VIEW')")
@GetMapping("/{deviceId}")
public ApiRes get(@PathVariable("deviceId") Long deviceId) {
// 可查看自己和全部下级代理的设备
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
MchStoreDevice dbRecord = mchStoreDeviceService.getById(deviceId);
if (!subAgentNoList.contains(dbRecord.getAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
// 设备是否属于自身
if (getCurrentAgentNo().equals(dbRecord.getAgentNo())) {
dbRecord.addExt("isSelf", true);
}
// 添加服务商商户门店名称
AgentInfo allotAgent = agentInfoService.getById(dbRecord.getAgentNo());
if (allotAgent != null) {
dbRecord.addExt("agentName", allotAgent.getAgentName());
}
if (dbRecord.getBindState() == CS.YES) {
if (StringUtils.isNotBlank(dbRecord.getMchNo())) {
MchInfo mchInfo = mchInfoService.getById(dbRecord.getMchNo());
if (mchInfo != null) {
dbRecord.addExt("mchName", mchInfo.getMchName());
}
}
if (StringUtils.isNotBlank(dbRecord.getAppId())) {
MchAppEntity mchAppEntity = mchAppService.getById(dbRecord.getAppId());
if (mchAppEntity != null) {
dbRecord.addExt("appName", mchAppEntity.getAppName());
}
}
if (dbRecord.getStoreId() != null) {
MchStore mchStore = mchStoreService.getById(dbRecord.getStoreId());
if (mchStore != null) {
dbRecord.addExt("storeName", mchStore.getStoreName());
}
}
}
List<MchQrcDeviceRela> relaList = mchQrcDeviceRelaService.list(MchQrcDeviceRela.gw().eq(MchQrcDeviceRela::getDeviceId, deviceId));
if (!CollectionUtils.isEmpty(relaList)) {
dbRecord.addExt("qrcIdList", relaList.stream().map(MchQrcDeviceRela::getQrcId).collect(Collectors.toList()));
}
return ApiRes.ok(dbRecord);
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 播报测试
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_TEST')")
@PostMapping("/speak/{deviceId}")
public ApiRes speak(@PathVariable("deviceId") Long deviceId) {
Long amountL = getRequiredAmountL("amount");
// 可查看自己和全部下级代理的设备
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
MchStoreDevice mchStoreDevice = mchStoreDeviceService.getById(deviceId);
if (mchStoreDevice == null || mchStoreDevice.getState() != CS.YES || !subAgentNoList.contains(mchStoreDevice.getAgentNo())) {
return ApiRes.customFail("设备不存在或已禁用");
}
DeviceProvideConfig provideConfig = deviceProvideConfigService.getById(mchStoreDevice.getConfigId());
if (provideConfig == null || provideConfig.getState() != CS.YES) {
return ApiRes.customFail("设备厂商未配置或已禁用");
}
// 设备类型
String provider = mchStoreDevice.getProvider();
ISpeakerService speakerService = SpringBeansUtil.getBean(provider + "SpeakerService", ISpeakerService.class);
// 设备参数
JSONObject deviceParams = new JSONObject();
deviceParams.put("deviceParams", mchStoreDevice.getDeviceParams());
deviceParams.put("bizConfigParams", mchStoreDevice.getBizConfigParams());
deviceParams.put("providerParams", provideConfig.getProviderParams());
// 消息内容
PayOrderInfo4Device speakPayOrderInfo = new PayOrderInfo4Device();
speakPayOrderInfo.setAmount(amountL);
speakPayOrderInfo.setWayCodeType(CS.PAY_WAY_CODE_TYPE.WECHAT);
speakPayOrderInfo.setPayOrderId(String.valueOf(DateKit.currentTimeMillis()));
try {
speakerService.send(deviceParams, speakPayOrderInfo);
return ApiRes.ok();
}catch (BizException e) {
throw e;
}
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 打印测试
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_PRINTER_DEVICE_TEST')")
@PostMapping("/print/{deviceId}")
public ApiRes print(@PathVariable("deviceId") Long deviceId) {
Long amountL = getRequiredAmountL("amount");
// 可查看自己和全部下级代理的设备
List<String> subAgentNoList = agentInfoService.queryAllSubAgentNo(getCurrentAgentNo());
MchStoreDevice mchStoreDevice = mchStoreDeviceService.getById(deviceId);
if (mchStoreDevice == null || mchStoreDevice.getState() != CS.YES || !subAgentNoList.contains(mchStoreDevice.getAgentNo())) {
return ApiRes.customFail("设备不存在或已禁用");
}
DeviceProvideConfig provideConfig = deviceProvideConfigService.getById(mchStoreDevice.getConfigId());
if (provideConfig == null || provideConfig.getState() != CS.YES) {
return ApiRes.customFail("设备厂商未配置或已禁用");
}
// 设备类型
String provider = mchStoreDevice.getProvider();
IPrinterService printerService = SpringBeansUtil.getBean(provider + "PrinterService", IPrinterService.class);
// 设备参数
JSONObject deviceParams = new JSONObject();
deviceParams.put("deviceParams", mchStoreDevice.getDeviceParams());
deviceParams.put("bizConfigParams", mchStoreDevice.getBizConfigParams());
deviceParams.put("providerParams", provideConfig.getProviderParams());
// 消息内容
PayOrderInfo4Device printPayOrderInfo = new PayOrderInfo4Device();
printPayOrderInfo.setAmount(amountL);
printPayOrderInfo.setWayCodeType(CS.PAY_WAY_CODE_TYPE.WECHAT);
printPayOrderInfo.setPayOrderId(String.valueOf(DateKit.currentTimeMillis()));
printPayOrderInfo.setCreatedAt(DateUtil.date());
try {
printerService.send(deviceParams, printPayOrderInfo);
return ApiRes.ok();
}catch (BizException e) {
throw e;
}
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 清空打印队列
*/
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_PRINTER_DEVICE_CLEAR')")
@PostMapping("/clear/{deviceId}")
public ApiRes clear(@PathVariable("deviceId") Long deviceId) {
MchStoreDevice mchStoreDevice = mchStoreDeviceService.getById(deviceId);
if (mchStoreDevice == null || mchStoreDevice.getState() != CS.YES) {
return ApiRes.customFail("设备不存在");
}
DeviceProvideConfig provideConfig = deviceProvideConfigService.getById(mchStoreDevice.getConfigId());
if (provideConfig == null || provideConfig.getState() != CS.YES) {
return ApiRes.customFail("设备厂商未配置");
}
// 设备类型
String provider = mchStoreDevice.getProvider();
IPrinterService printerService = SpringBeansUtil.getBean(provider + "PrinterService", IPrinterService.class);
// 设备参数
JSONObject deviceParams = new JSONObject();
deviceParams.put("deviceParams", mchStoreDevice.getDeviceParams());
deviceParams.put("bizConfigParams", mchStoreDevice.getBizConfigParams());
deviceParams.put("providerParams", provideConfig.getProviderParams());
try {
printerService.clearPrinter(deviceParams);
return ApiRes.ok();
}catch (Exception e) {
return ApiRes.customFail(e.getMessage());
}
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 绑定设备
*/
@MethodLog(remark = "绑定设备")
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_EDIT', 'ENT_DEVICE_PRINTER_DEVICE_EDIT', 'ENT_DEVICE_POS_DEVICE_EDIT'," +
"'ENT_DEVICE_PLUGIN_CDKEY_EDIT', 'ENT_DEVICE_FACE_APP_EDIT')")
@PutMapping("/bind/{deviceId}")
public ApiRes bind(@PathVariable("deviceId") Long deviceId) {
String mchNo = getValStringRequired("mchNo");
String storeId = getValStringRequired("storeId");
Byte bindType = getValByte("bindType");
MchInfo mchInfo = mchInfoService.getById(mchNo);
if (mchInfo == null || StringUtils.isBlank(mchInfo.getAgentNo()) || !mchInfo.getAgentNo().equals(getCurrentAgentNo())) {
throw new BizException("商户不存在");
}
MchStoreDevice dbRecord = mchStoreDeviceService.getById(deviceId);
if (dbRecord == null || StringUtils.isBlank(dbRecord.getAgentNo()) || !dbRecord.getAgentNo().equals(getCurrentAgentNo())) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
// 除云喇叭和云打印外的设备 需绑定商户应用
String appId = "";
if (dbRecord.getDeviceType() != MchStoreDevice.DEVICE_TYPE_SPEAKER && dbRecord.getDeviceType() != MchStoreDevice.DEVICE_TYPE_PRINTER) {
appId = getValStringRequired("appId");
}
MchStoreDevice updateRecord = new MchStoreDevice();
updateRecord.setDeviceId(deviceId).setMchNo(mchNo).setAppId(appId).setStoreId(storeId).setBindState(CS.YES);
if (null != bindType) {
updateRecord.setBindType(bindType);
}
// 云喇叭 同步绑定码牌
if (dbRecord.getDeviceType() == MchStoreDevice.DEVICE_TYPE_SPEAKER) {
String qrcIdListStr = getValString("qrcIdList");
// 云喇叭绑定类型 为码牌时需传入绑定的码牌id
List<Long> qrcList = new LinkedList<>();
if (null != bindType && bindType == MchStoreDevice.DEVICE_BIND_TYPE_QRC && StringUtils.isNotBlank(qrcIdListStr)) {
qrcList = JSONArray.parseArray(qrcIdListStr, Long.class);
}
boolean result = mchStoreDeviceService.bindSpeakerDevice(updateRecord, dbRecord.getBindQrcId(), qrcList);
if (!result) {
return ApiRes.customFail("绑定失败");
}
return ApiRes.ok();
}
// 云打印扫码pos执行更新
if (mchStoreDeviceService.updateById(updateRecord)) {
return ApiRes.ok();
}
return ApiRes.customFail("绑定失败");
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 解绑设备
*/
@MethodLog(remark = "解绑设备")
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_EDIT', 'ENT_DEVICE_PRINTER_DEVICE_EDIT', 'ENT_DEVICE_POS_DEVICE_EDIT'," +
" 'ENT_DEVICE_PLUGIN_CDKEY_EDIT', 'ENT_DEVICE_FACE_APP_EDIT')")
@PostMapping("/unbind/{deviceId}")
public ApiRes unbind(@PathVariable("deviceId") Long deviceId) {
MchStoreDevice dbRecord = mchStoreDeviceService.getById(deviceId);
if (dbRecord == null || dbRecord.getBindState() == CS.NO || !dbRecord.getAgentNo().equals(getCurrentAgentNo())) {
return ApiRes.customFail("解绑失败");
}
MchInfo mchInfo = mchInfoService.getById(dbRecord.getMchNo());
if (mchInfo == null || StringUtils.isBlank(mchInfo.getAgentNo()) || !mchInfo.getAgentNo().equals(getCurrentAgentNo())) {
throw new BizException("当前解绑设备不属于您的直属商户,无法解绑!");
}
mchStoreDeviceService.unbind(dbRecord);
return ApiRes.ok();
}
/**
* @author: zx
* @date: 2021-12-28 09:15
* @describe: 划拨/收回设备
*/
@MethodLog(remark = "划拨/收回设备")
@PreAuthorize("hasAnyAuthority('ENT_DEVICE_SPEAKER_DEVICE_ALLOT', 'ENT_DEVICE_PRINTER_DEVICE_ALLOT', " +
"'ENT_DEVICE_POS_DEVICE_ALLOT', 'ENT_DEVICE_PLUGIN_CDKEY_ALLOT', 'ENT_DEVICE_FACE_APP_ALLOT')")
@PostMapping("/allotDevice")
public ApiRes allotDevice() {
// 服务商是否支持划拨码牌设备
SysConfig isSupportAgentAllot = sysConfigService.getById("isSupportAgentAllot");
if(isSupportAgentAllot == null || String.valueOf(CS.NO).equals(isSupportAgentAllot.getConfigVal())){
throw new BizException("不支持服务商划拨码牌、设备");
}
String allotType = getValStringRequired("allotType"); // 划拨类型select-勾选划拨 batch-批次划拨
String allotOrRecover = getValStringRequired("allotOrRecover"); // 分配类型allot-划拨 recover-收回
// 构建批量更新设备ID集合
List<MchStoreDevice> list;
if (allotType.equals("select")) {
String allotDeviceIds = getValStringRequired("allotDeviceIds");
list = mchStoreDeviceService.list(MchStoreDevice.gw().in(MchStoreDevice::getDeviceId, Arrays.asList(allotDeviceIds.split(","))));
}else if (allotType.equals("batch")) {
String batchId = getValStringRequired("batchId");
list = mchStoreDeviceService.list(MchStoreDevice.gw().eq(MchStoreDevice::getBatchId, batchId));
}else {
throw new BizException("划拨类型错误");
}
if (CollUtil.isEmpty(list)) {
throw new BizException("请选择设备");
}
// 当前代理只可划拨自己和直接下级代理的设备
List<String> subAgentNoList = agentInfoService.querySubAgentNo(getCurrentAgentNo());
for (MchStoreDevice mchStoreDevice: list) {
if (!subAgentNoList.contains(mchStoreDevice.getAgentNo())) {
throw new BizException("存在不可划拨设备【设备号:" + mchStoreDevice.getDeviceNo() + "");
}
}
List<Long> deviceIdList = list.stream().map(MchStoreDevice::getDeviceId).collect(Collectors.toList());
// 1收回设备
if (allotOrRecover.equals("recover")) {
mchStoreDeviceService.recoverDevice(true, deviceIdList, subAgentNoList, getCurrentAgentNo());
return ApiRes.ok();
}
// 2划拨设备
String agentNo = getValStringRequired("agentNo");
List<String> mchNoList = getMchNoListByAgentNo(agentNo);
mchStoreDeviceService.allotDevice(true, agentNo, deviceIdList, mchNoList, subAgentNoList);
return ApiRes.ok();
}
}

View File

@ -0,0 +1,159 @@
package com.jeequan.jeepay.agent.ctrl.subagent;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.db.entity.SysAdvertConfig;
import com.jeequan.jeepay.service.impl.SysAdvertConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 广告
*
* @author xiaoyu
*
* @date 2023/2/21 16:13
*/
@RestController
@RequestMapping("/api/advert")
public class AdvertController extends CommonCtrl {
@Autowired SysAdvertConfigService advertConfigService;
/** APP 展业宝广告 **/
@GetMapping("/appAdvert")
public ApiRes appAdvert() {
// 广告位置 1-启动页 2-首页 3-我的页
Byte appPlace = getValByteRequired("appPlace");
// 查询平台全局广告
LambdaQueryWrapper<SysAdvertConfig> wrapper = SysAdvertConfig.gw();
wrapper.eq(SysAdvertConfig::getAdvertType, SysAdvertConfig.ADVERT_TYPE_APP_AGENT);
wrapper.eq(SysAdvertConfig::getAppPlace, appPlace);
wrapper.eq(SysAdvertConfig::getReleaseState, CS.YES);
wrapper.orderByAsc(SysAdvertConfig::getAdvertSort);
wrapper.orderByDesc(SysAdvertConfig::getCreatedAt);
List<SysAdvertConfig> list = advertConfigService.list(wrapper);
return ApiRes.ok(list);
}
/**
* @author: xiaoyu
* @date: 2023/2/20 11:06
* @describe: 广告配置列表
*/
@PreAuthorize("hasAnyAuthority('ENT_ADVERT_LIST', 'ENT_ADVERT_VIEW')")
@GetMapping
public ApiRes pages() {
SysAdvertConfig record = getObject(SysAdvertConfig.class);
LambdaQueryWrapper<SysAdvertConfig> condition = SysAdvertConfig.gw();
condition.eq(record.getAdvertId() != null, SysAdvertConfig::getAdvertId, record.getAdvertId());
condition.eq(record.getAppPlaceType() != null, SysAdvertConfig::getAppPlaceType, record.getAppPlaceType());
condition.eq(record.getReleaseState() != null, SysAdvertConfig::getReleaseState, record.getReleaseState());
condition.eq(record.getAdvertType() != null, SysAdvertConfig::getAdvertType, record.getAdvertType());
condition.eq(record.getAppPlace() != null, SysAdvertConfig::getAppPlace, record.getAppPlace());
condition.like(StringUtils.isNotEmpty(record.getTitle()), SysAdvertConfig::getTitle, record.getTitle());
condition.eq(StringUtils.isNotEmpty(record.getMchNo()), SysAdvertConfig::getMchNo, record.getMchNo());
condition.eq(SysAdvertConfig::getAgentNo, getCurrentAgentNo());
condition.orderByDesc(SysAdvertConfig::getCreatedAt);
IPage<SysAdvertConfig> pages = advertConfigService.page(getIPage(), condition);
for (SysAdvertConfig config: pages.getRecords()) {
if (StringUtils.isNotEmpty(config.getMchNo())) {
MchInfo mchInfo = mchInfoService.getById(config.getMchNo());
if (mchInfo != null) {
config.addExt("infoName", mchInfo.getMchName());
}else {
config.addExt("infoName", "");
}
}
}
//返回数据
return ApiRes.ok(pages);
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_ADVERT_VIEW' )")
@RequestMapping(value="/{advertId}", method = RequestMethod.GET)
public ApiRes getConfigs(@PathVariable("advertId") Long advertId) {
SysAdvertConfig config = advertConfigService.getOne(
SysAdvertConfig.gw()
.eq(SysAdvertConfig::getAdvertId, advertId)
.eq(SysAdvertConfig::getAgentNo, getCurrentAgentNo())
);
return ApiRes.ok(config);
}
/**
* @author: xiaoyu
* @date: 2023/2/20 11:06
* @describe: 广告配置修改
*/
@PreAuthorize("hasAnyAuthority('ENT_ADVERT_EDIT')")
@MethodLog(remark = "广告配置修改")
@RequestMapping(value="/{advertId}", method = RequestMethod.PUT)
public ApiRes update(@PathVariable("advertId") Long advertId) {
// 校验权限
SysAdvertConfig config = advertConfigService.getById(advertId);
if (config != null && !getCurrentAgentNo().equals(config.getAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
SysAdvertConfig record = getObject(SysAdvertConfig.class);
record.setAdvertId(advertId);
if (getReqParamJSON().getByte("state") != null) {
record.setReleaseState(getReqParamJSON().getByte("state"));
}
advertConfigService.updateAdvert(record);
return ApiRes.ok();
}
/**
* @author: xiaoyu
* @date: 2023/2/20 11:10
* @describe: 广告配置新增
*/
@PreAuthorize("hasAuthority( 'ENT_ADVERT_ADD' )")
@MethodLog(remark = "广告配置新增")
@RequestMapping(value="", method = RequestMethod.POST)
public ApiRes add() {
JSONObject paramJSON = getReqParamJSON();
SysAdvertConfig record = getObject(SysAdvertConfig.class);
String infoIds = paramJSON.getString("infoIds");
record.setAgentNo(getCurrentAgentNo());
record.setCreatedUid(getCurrentUser().getSysUserId());
record.setCreatedBy(getCurrentUser().getSysUser().getRealname());
advertConfigService.addConfig(infoIds, record);
return ApiRes.ok();
}
/** delete */
@PreAuthorize("hasAuthority('ENT_ADVERT_DEL')")
@MethodLog(remark = "广告配置删除")
@DeleteMapping
public ApiRes del() {
String delAdvertIds = getValStringRequired("delAdvertIds");
List<String> advertIdList = Arrays.stream(delAdvertIds.split(",")).collect(Collectors.toList());
advertConfigService.removeConfig(advertIdList, getCurrentAgentNo(), CS.SYS_ROLE_TYPE.AGENT);
return ApiRes.ok();
}
}

View File

@ -0,0 +1,183 @@
package com.jeequan.jeepay.agent.ctrl.subagent;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.components.mq.model.CleanAgentLoginAuthCacheMQ;
import com.jeequan.jeepay.components.mq.model.ResetIsvMchAppInfoConfigMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
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.model.smsconfig.SmsBizDiyContentModel;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.MchInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
/***
* 服务商管理
*
* @author terrfly
*
* @date 2022/3/15 15:25
*/
@RestController
@RequestMapping("/api/subAgents")
public class SubAgentInfoController extends CommonCtrl {
@Autowired private IMQSender mqSender;
@Autowired private SmsManager smsManager;
@PreAuthorize("hasAuthority('ENT_AGENT_LIST')")
@GetMapping
public ApiRes list() {
AgentInfo agentInfo = getObject(AgentInfo.class);
LambdaQueryWrapper<AgentInfo> wrapper = AgentInfo.gw();
wrapper.eq(AgentInfo::getPid, getCurrentAgentNo());
wrapper.eq(StringUtils.isNotEmpty(agentInfo.getAgentNo()), AgentInfo::getAgentNo, agentInfo.getAgentNo());
wrapper.eq(StringUtils.isNotEmpty(agentInfo.getIsvNo()), AgentInfo::getIsvNo, agentInfo.getIsvNo());
wrapper.like(StringUtils.isNotEmpty(agentInfo.getAgentName()), AgentInfo::getAgentName, agentInfo.getAgentName());
wrapper.eq(agentInfo.getState() != null, AgentInfo::getState, agentInfo.getState());
wrapper.like(StringUtils.isNotEmpty(agentInfo.getContactTel()), AgentInfo::getContactTel, agentInfo.getContactTel());
wrapper.like(StringUtils.isNotEmpty(agentInfo.getLoginUsername()), AgentInfo::getLoginUsername, agentInfo.getLoginUsername());
wrapper.orderByDesc(AgentInfo::getCreatedAt);
// app端 联合模糊查询字段
String unionAgentInfo = getValString("unionAgentInfo");
if (StringUtils.isNotBlank(unionAgentInfo)) {
wrapper.and(i -> i.like(AgentInfo::getAgentNo, unionAgentInfo)
.or().like(AgentInfo::getAgentName, unionAgentInfo)
.or().like(AgentInfo::getContactTel, unionAgentInfo));
}
IPage<AgentInfo> pages = agentInfoService.page(getIPage(), wrapper);
for (AgentInfo info:pages.getRecords()) {
info.setContactTel(DesensitizedUtil.mobilePhone(info.getContactTel()));
long count = mchInfoService.count(MchInfo.gw().eq(MchInfo::getAgentNo, info.getAgentNo()));
info.addExt("mchCount", count);
}
return ApiRes.page(pages);
}
@PreAuthorize("hasAuthority('ENT_AGENT_INFO_ADD')")
@MethodLog(remark = "新增服务商")
@PostMapping
public ApiRes add() {
// 当前服务商是否允许发展下级代理
AgentInfo pAgentInfo = agentInfoService.getById(getCurrentAgentNo());
if (pAgentInfo.getAddAgentFlag() != CS.YES) {
throw new BizException("当前服务商不可发展下级服务商");
}
AgentInfo agentInfo = getObject(AgentInfo.class);
agentInfo.setPid(getCurrentAgentNo());
AgentInfo thisAgent = agentInfoService.getById(getCurrentAgentNo());
agentInfo.setIsvNo(thisAgent.getIsvNo());
// 获取传入的服务商登录名登录密码
String loginPassword = getValString("loginPassword");
Byte isNotify = getValByteRequired("isNotify");
if (StringUtils.isBlank(loginPassword)) {
loginPassword = null;
}
agentInfo.setAgentNo("P" + DateUtil.format(new Date(), "yyMMdd")+ RandomUtil.randomNumbers(6));
// 当前登录用户信息
SysUser sysUser = getCurrentUser().getSysUser();
agentInfo.setCreatedUid(sysUser.getSysUserId());
agentInfo.setCreatedBy(sysUser.getRealname());
agentInfoService.addAgentV2(agentInfo, loginPassword, true);
// 发送短信通知
if (isNotify == CS.YES) {
smsManager.sendDiyContentSms(SmsBizDiyContentModel.genUserOpenAccount(agentInfo.getContactTel(), agentInfo.getLoginUsername(), loginPassword));
}
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_AGENT_INFO_DEL')")
@MethodLog(remark = "删除服务商")
@DeleteMapping(value="/{agentNo}")
public ApiRes delete(@PathVariable("agentNo") String agentNo) {
List<Long> userIdList = agentInfoService.removeByAgentNo(agentNo);
// 推送mq删除redis用户缓存
mqSender.send(CleanAgentLoginAuthCacheMQ.build(userIdList));
return ApiRes.ok();
}
@PreAuthorize("hasAuthority('ENT_AGENT_INFO_EDIT')")
@MethodLog(remark = "更新服务商信息")
@PutMapping(value="/{agentNo}")
public ApiRes update(@PathVariable("agentNo") String agentNo) {
AgentInfo dbAgentInfo = agentInfoService.getById(agentNo);
if (dbAgentInfo == null) {
throw new BizException("服务商信息不存在");
}
//获取查询条件
AgentInfo agentInfo = getObject(AgentInfo.class);
agentInfo.setAgentNo(agentNo); //设置服务商号主键
agentInfo.setIsvNo(null); // 不允许更改
agentInfo.setPid(null);
agentInfo.setLoginUsername(null); // 防止修改用户登录名
boolean resetPass = getReqParamJSON().getBooleanValue("resetPass");
String confirmPwd = null;
if(resetPass){
confirmPwd = Boolean.TRUE.equals(getReqParamJSON().getBoolean("defaultPass")) ? null : Base64.decodeStr(getValStringRequired("confirmPwd"));
}
// 判断要修改的服务商信息是否需要审核 如果为审核失败/待认证->待审核
if (dbAgentInfo.getState() == AgentInfo.AUDIT_STATE_FALSE || dbAgentInfo.getState() == AgentInfo.AUDIT_STATE_UN_AUTH) {
agentInfo.setState(AgentInfo.AUDIT_STATE_ING);
}
// 更新 & 得到需要删除的用户ID的记录
Set<Long> removeCacheUserIdList = agentInfoService.updateAgent(agentInfo, getReqParamJSON(), resetPass, confirmPwd);
// 推送mq删除redis用户认证信息
if (!removeCacheUserIdList.isEmpty()) {
mqSender.send(CleanAgentLoginAuthCacheMQ.build(new ArrayList<>(removeCacheUserIdList)));
}
// 推送mq到目前节点进行更新数据
mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_MCH_INFO, null, agentNo, null));
return ApiRes.ok();
}
@PreAuthorize("hasAnyAuthority('ENT_AGENT_INFO_EDIT', 'ENT_AGENT_INFO_VIEW')")
@GetMapping(value="/{agentNo}")
public ApiRes detail(@PathVariable("agentNo") String agentNo) {
AgentInfo agentInfo = agentInfoService.getById(agentNo);
if (agentInfo == null || !agentInfo.getPid().equals(getCurrentAgentNo())) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(agentInfo);
}
}

View File

@ -0,0 +1,51 @@
package com.jeequan.jeepay.agent.ctrl.sysuser;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.TreeDataBuilder;
import com.jeequan.jeepay.db.entity.SysEntitlement;
import com.jeequan.jeepay.service.impl.SysEntitlementService;
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.List;
/**
* 权限菜单管理类
*
* @author terrfly
* @modify zhuxiao
*
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("api/sysEnts")
public class SysEntController extends CommonCtrl {
@Autowired SysEntitlementService sysEntitlementService;
/** 查询权限集合 */
@PreAuthorize("hasAnyAuthority( 'ENT_UR_ROLE_ENT_LIST', 'ENT_UR_ROLE_DIST' )")
@RequestMapping(value="/showTree", method = RequestMethod.GET)
public ApiRes showTree() {
//查询全部数据
List<SysEntitlement> list = sysEntitlementService.list(SysEntitlement.gw().eq(SysEntitlement::getSysType, CS.SYS_ROLE_TYPE.AGENT));
//4. 转换为json树状结构
JSONArray jsonArray = (JSONArray) JSONArray.toJSON(list);
List<JSONObject> leftMenuTree = new TreeDataBuilder(jsonArray,
"entId", "pid", "children", "entSort", true)
.buildTreeObject();
return ApiRes.ok(leftMenuTree);
}
}

View File

@ -0,0 +1,159 @@
package com.jeequan.jeepay.agent.ctrl.sysuser;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.agent.service.AuthService;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
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.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.SysRole;
import com.jeequan.jeepay.db.entity.SysUserRoleRela;
import com.jeequan.jeepay.service.impl.SysRoleEntRelaService;
import com.jeequan.jeepay.service.impl.SysRoleService;
import com.jeequan.jeepay.service.impl.SysUserRoleRelaService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.web.bind.annotation.PathVariable;
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;
/**
* 角色管理类
*
* @author terrfly
* @modify zhuxiao
*
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("api/sysRoles")
public class SysRoleController extends CommonCtrl {
@Autowired SysRoleService sysRoleService;
@Autowired SysUserRoleRelaService sysUserRoleRelaService;
@Autowired private AuthService authService;
@Autowired private SysRoleEntRelaService sysRoleEntRelaService;
/** list */
@PreAuthorize("hasAnyAuthority( 'ENT_UR_ROLE_LIST', 'ENT_UR_USER_UPD_ROLE' )")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
SysRole queryObject = getObject(SysRole.class);
LambdaQueryWrapper<SysRole> condition = SysRole.gw();
condition.eq(SysRole::getSysType, CS.SYS_ROLE_TYPE.AGENT);
condition.eq(SysRole::getBelongInfoId, getCurrentAgentNo());
if(StringUtils.isNotEmpty(queryObject.getRoleName())){
condition.like(SysRole::getRoleName, queryObject.getRoleName());
}
if(StringUtils.isNotEmpty(queryObject.getRoleId())){
condition.like(SysRole::getRoleId, queryObject.getRoleId());
}
condition.orderByDesc(SysRole::getUpdatedAt); //时间倒序
IPage<SysRole> pages = sysRoleService.page(getIPage(true), condition);
return ApiRes.page(pages);
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_UR_ROLE_EDIT' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") String recordId) {
SysRole sysRole = sysRoleService.getOne(SysRole.gw().eq(SysRole::getRoleId, recordId).eq(SysRole::getBelongInfoId, getCurrentAgentNo()));
if (sysRole == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
return ApiRes.ok(sysRole);
}
/** add */
@PreAuthorize("hasAuthority( 'ENT_UR_ROLE_ADD' )")
@RequestMapping(value="", method = RequestMethod.POST)
public ApiRes add() {
SysRole SysRole = getObject(SysRole.class);
String roleId = "ROLE_" + StringKit.getUUID(6);
SysRole.setRoleId(roleId);
SysRole.setSysType(CS.SYS_ROLE_TYPE.AGENT); //后台系统
SysRole.setBelongInfoId(getCurrentUser().getSysUser().getBelongInfoId());
sysRoleService.save(SysRole);
//权限信息集合
String entIdListStr = getValString("entIdListStr");
//如果包含 可分配权限的权限 && entIdListStr 不为空
if(getCurrentUser().getAuthorities().contains(new SimpleGrantedAuthority("ENT_UR_ROLE_DIST"))
&& StringUtils.isNotEmpty(entIdListStr)){
List<String> entIdList = JSONArray.parseArray(entIdListStr, String.class);
sysRoleEntRelaService.resetRela(roleId, entIdList);
}
return ApiRes.ok();
}
/** update */
@PreAuthorize("hasAuthority( 'ENT_UR_ROLE_EDIT' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.PUT)
public ApiRes update(@PathVariable("recordId") String recordId) {
SysRole sysRole = getObject(SysRole.class);
LambdaUpdateWrapper<SysRole> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(SysRole::getRoleId, recordId);
updateWrapper.eq(SysRole::getBelongInfoId, getCurrentAgentNo());
sysRoleService.update(sysRole, updateWrapper);
//权限信息集合
String entIdListStr = getValString("entIdListStr");
//如果包含 可分配权限的权限 && entIdListStr 不为空
if(getCurrentUser().getAuthorities().contains(new SimpleGrantedAuthority("ENT_UR_ROLE_DIST"))
&& StringUtils.isNotEmpty(entIdListStr)){
List<String> entIdList = JSONArray.parseArray(entIdListStr, String.class);
sysRoleEntRelaService.resetRela(recordId, entIdList);
List<Long> sysUserIdList = new ArrayList<>();
sysUserRoleRelaService.list(SysUserRoleRela.gw().eq(SysUserRoleRela::getRoleId, recordId)).stream().forEach(item -> sysUserIdList.add(item.getUserId()));
//查询到该角色的人员 将redis更新
authService.refAuthentication(sysUserIdList);
}
return ApiRes.ok();
}
/** delete */
@PreAuthorize("hasAuthority('ENT_UR_ROLE_DEL')")
@RequestMapping(value="/{recordId}", method = RequestMethod.DELETE)
public ApiRes del(@PathVariable("recordId") String recordId) {
SysRole sysRole = sysRoleService.getOne(SysRole.gw().eq(SysRole::getRoleId, recordId).eq(SysRole::getBelongInfoId, getCurrentAgentNo()));
if (sysRole == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if(sysUserRoleRelaService.count(SysUserRoleRela.gw().eq(SysUserRoleRela::getRoleId, recordId)) > 0){
throw new BizException("当前角色已分配到用户, 不可删除!");
}
sysRoleService.removeRole(recordId);
return ApiRes.ok();
}
}

View File

@ -0,0 +1,85 @@
package com.jeequan.jeepay.agent.ctrl.sysuser;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.agent.service.AuthService;
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.db.entity.SysRole;
import com.jeequan.jeepay.db.entity.SysRoleEntRela;
import com.jeequan.jeepay.db.entity.SysUserRoleRela;
import com.jeequan.jeepay.service.impl.SysRoleEntRelaService;
import com.jeequan.jeepay.service.impl.SysRoleService;
import com.jeequan.jeepay.service.impl.SysUserRoleRelaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
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;
/**
* 角色权限管理类
*
* @author terrfly
* @modify zhuxiao
*
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("api/sysRoleEntRelas")
public class SysRoleEntRelaController extends CommonCtrl {
@Autowired private SysRoleEntRelaService sysRoleEntRelaService;
@Autowired private SysUserRoleRelaService sysUserRoleRelaService;
@Autowired private SysRoleService sysRoleService;
@Autowired private AuthService authService;
/** list */
@PreAuthorize("hasAuthority( 'ENT_UR_ROLE_DIST' )")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
SysRoleEntRela queryObject = getObject(SysRoleEntRela.class);
LambdaQueryWrapper<SysRoleEntRela> condition = SysRoleEntRela.gw();
if(queryObject.getRoleId() != null){
condition.eq(SysRoleEntRela::getRoleId, queryObject.getRoleId());
}
IPage<SysRoleEntRela> pages = sysRoleEntRelaService.page(getIPage(true), condition);
return ApiRes.page(pages);
}
/** 重置角色权限关联信息 */
@PreAuthorize("hasAuthority( 'ENT_UR_ROLE_DIST' )")
@RequestMapping(value="relas/{roleId}", method = RequestMethod.POST)
public ApiRes relas(@PathVariable("roleId") String roleId) {
SysRole sysRole = sysRoleService.getOne(SysRole.gw().eq(SysRole::getRoleId, roleId).eq(SysRole::getBelongInfoId, getCurrentAgentNo()));
if (sysRole == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
List<String> entIdList = JSONArray.parseArray(getValStringRequired("entIdListStr"), String.class);
sysRoleEntRelaService.resetRela(roleId, entIdList);
List<Long> sysUserIdList = new ArrayList<>();
sysUserRoleRelaService.list(SysUserRoleRela.gw().eq(SysUserRoleRela::getRoleId, roleId)).stream().forEach(item -> sysUserIdList.add(item.getUserId()));
//查询到该角色的人员 将redis更新
authService.refAuthentication(sysUserIdList);
return ApiRes.ok();
}
}

View File

@ -0,0 +1,327 @@
package com.jeequan.jeepay.agent.ctrl.sysuser;
import cn.hutool.core.util.DesensitizedUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.agent.service.AuthService;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.cache.RedisUtil;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.jwt.JWTPayload;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.smsconfig.SmsBizDiyContentModel;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.SysUserAuth;
import com.jeequan.jeepay.db.entity.SysUserEntity;
import com.jeequan.jeepay.db.entity.SysUserTeam;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
/**
* 用户管理类
*
* @author terrfly
* @modify zhuxiao
*
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("api/sysUsers")
public class SysUserController extends CommonCtrl {
@Autowired SysUserService sysUserService;
@Autowired SysUserAuthService sysUserAuthService;
@Autowired SysConfigService sysConfigService;
@Autowired private AuthService authService;
@Autowired private SysUserTeamService sysUserTeamService;
@Autowired private AgentInfoService agentInfoService;
@Autowired private SmsManager smsManager;
/** list */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_LIST' )")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
SysUserEntity queryObject = getObject(SysUserEntity.class);
queryObject.setSysType(CS.SYS_ROLE_TYPE.AGENT);
queryObject.setBelongInfoId(getCurrentAgentNo());
// 是否app登录
String loginType = getCurrentUser().getLoginType();
boolean isApp = StringUtils.isNotBlank(loginType) && (loginType.equals(JWTPayload.LOGIN_PAGE_TYPE.APP) || loginType.equals(JWTPayload.LOGIN_PAGE_TYPE.LITE));
// true表示是APP端
if (isApp) {
String queryNameOrPhone = getValString("queryNameOrPhone"); // 名字或手机号模糊查询
LambdaQueryWrapper<SysUserEntity> queryWrapper = SysUserEntity.gw();
queryWrapper.eq(SysUserEntity::getSysType, queryObject.getSysType());
queryWrapper.eq(SysUserEntity::getBelongInfoId, queryObject.getBelongInfoId());
queryWrapper.eq(null != queryObject.getUserType(), SysUserEntity::getUserType, queryObject.getUserType());
if (StringUtils.isNotBlank(queryNameOrPhone)) {
queryWrapper.and(wr -> {
wr.like(SysUserEntity::getRealname, queryNameOrPhone)
.or().like(SysUserEntity::getTelphone, queryNameOrPhone);
});
}
IPage<SysUserEntity> iPage = sysUserService.page(getIPage(), queryWrapper);
// 数据脱敏
iPage.getRecords().stream().forEach(i -> i.setTelphone(DesensitizedUtil.mobilePhone(i.getTelphone())));
return ApiRes.page(iPage);
}
long count = sysUserService.queryCount(queryObject);
if (count <=0 ) {
return ApiRes.page(new Page());
}
List<JSONObject> list = sysUserService.selectList(getIPage(), queryObject);
// 邀请码二维码地址
String mchRegisterUrl = String.format("%s/register", sysConfigService.getDBApplicationConfig().getMchSiteUrl());
String agentRegisterUrl = String.format("%s/register", sysConfigService.getDBApplicationConfig().getAgentSiteUrl());
list.forEach(item -> {
item.put("inviteCodeUrl", String.format("%s?c=%s", mchRegisterUrl, item.getString("inviteCode")));
item.put("agentInviteCodeUrl", String.format("%s?c=%s", agentRegisterUrl, item.getString("inviteCode")));
// 数据脱敏
item.put("telphone", DesensitizedUtil.mobilePhone(item.getString("telphone")));
// 是否初始用户
boolean ifInitUser = agentInfoService.count(AgentInfo.gw().eq(AgentInfo::getInitUserId, item.getLong("sysUserId")).eq(AgentInfo::getAgentNo, item.getString("belongInfoId"))) >0;
item.put("initUser", ifInitUser);
});
return ApiRes.page(getIPage(), list, count);
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_VIEW' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") Integer recordId) {
SysUserEntity sysUserEntity = sysUserService.getById(recordId);
if (sysUserEntity == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
if (!sysUserEntity.getBelongInfoId().equals(getCurrentUser().getSysUser().getBelongInfoId())) {
throw new BizException(ApiCodeEnum.SYS_PERMISSION_ERROR);
}
if (sysUserEntity.getTeamId() != null) {
SysUserTeam sysUserTeam = sysUserTeamService.getById(sysUserEntity.getTeamId());
if (sysUserTeam != null) {
sysUserEntity.addExt("teamName", sysUserTeam.getTeamName());
}
}
return ApiRes.ok(sysUserEntity);
}
/** add */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_ADD' )")
@RequestMapping(value="", method = RequestMethod.POST)
@MethodLog(remark = "添加管理员")
public ApiRes add() {
String loginPassword = getValString("loginPassword");
Byte isNotify = getValByteRequired("isNotify");
if (StringUtils.isBlank(loginPassword)) {
loginPassword = null;
}
SysUserEntity sysUserEntity = getObject(SysUserEntity.class);
sysUserEntity.setBelongInfoId(getCurrentUser().getSysUser().getBelongInfoId());
sysUserService.addSysUser(sysUserEntity, CS.SYS_ROLE_TYPE.AGENT, loginPassword);
// 发送短信通知
if (isNotify == CS.YES) {
smsManager.sendDiyContentSms(SmsBizDiyContentModel.genUserOpenAccount(sysUserEntity.getTelphone(), sysUserEntity.getLoginUsername(), loginPassword ));
}
return ApiRes.ok();
}
/** 修改操作员 登录认证信息 */
// @RequestMapping(value="/modifyPwd", method = RequestMethod.PUT)
public ApiRes authInfo() {
Long opSysUserId = getValLongRequired("recordId"); //操作员ID
//更改密码 验证当前用户信息
String currentUserPwd = getValStringRequired("originalPwd"); //当前用户登录密码
//验证当前密码是否正确
if(!sysUserAuthService.validateCurrentUserPwd(currentUserPwd)){
throw new BizException("原密码验证失败!");
}
String opUserPwd = getValStringRequired("confirmPwd");
// 验证原密码与新密码是否相同
if (opUserPwd.equals(currentUserPwd)) {
throw new BizException("新密码与原密码相同!");
}
sysUserAuthService.resetAuthInfo(opSysUserId, null, null, true, opUserPwd, CS.SYS_ROLE_TYPE.AGENT);
return ApiRes.ok();
}
/** update */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_EDIT' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.PUT)
@MethodLog(remark = "修改操作员信息")
public ApiRes update(@PathVariable("recordId") Long recordId) {
SysUserEntity sysUserEntity = getObject(SysUserEntity.class);
sysUserEntity.setSysUserId(recordId);
// 避免越权操作
SysUserEntity dbRecord = sysUserService.getOne(SysUserEntity.gw().eq(SysUserEntity::getSysUserId, recordId)
.eq(SysUserEntity::getSysType, CS.SYS_ROLE_TYPE.AGENT).eq(SysUserEntity::getBelongInfoId, getCurrentAgentNo()));
if (dbRecord == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
boolean delAuthenticationFlag = sysUserService.updateUserOnTx(sysUserEntity, recordId, getCurrentUser().getSysUserId());
// 删除用户redis缓存信息
if(delAuthenticationFlag){
authService.delAuthentication(Arrays.asList(recordId));
}
// 返回最新用户信息
SysUserEntity latestRecord = sysUserService.getById(recordId);
// 邀请码二维码地址
String mchRegisterUrl = String.format("%s/register", sysConfigService.getDBApplicationConfig().getMchSiteUrl());
latestRecord.addExt("inviteCodeUrl", String.format("%s?c=%s", mchRegisterUrl, latestRecord.getInviteCode()));
return ApiRes.ok(latestRecord);
}
/** delete */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_DELETE' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.DELETE)
@MethodLog(remark = "删除操作员信息")
public ApiRes delete(@PathVariable("recordId") Long recordId) {
//查询该操作员信息
SysUserEntity sysUserEntity = sysUserService.getById(recordId);
if (sysUserEntity == null) {
throw new BizException("该操作员不存在!");
}
//判断是否自己删除自己
if(recordId.equals(getCurrentUser().getSysUser().getSysUserId())){
throw new BizException("系统不允许删除当前登陆用户!");
}
//判断是否删除商户默认超管
if(agentInfoService.count(AgentInfo.gw().eq(AgentInfo::getInitUserId, recordId).eq(AgentInfo::getAgentNo, sysUserEntity.getBelongInfoId())) > 0 ){
throw new BizException("系统不允许删除服务商默认用户!");
}
// 删除用户
sysUserService.removeUser(sysUserEntity, CS.SYS_ROLE_TYPE.AGENT);
//如果用户被删除需要更新redis数据
authService.refAuthentication(Arrays.asList(recordId));
return ApiRes.ok();
}
/** MFA验证 解绑 */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_MFA_DELETE' )")
@RequestMapping(value="/mfaRelieve", method = RequestMethod.PUT)
@MethodLog(remark = "MFA验证解除")
public ApiRes mfaRelieve() throws BizException{
Long recordId = getValLongRequired("recordId");
// 当前登录账户是否为超管
Long currentUserId = getCurrentUser().getSysUser().getSysUserId();
// 解除操作员MFA验证
sysUserService.relieveOperatorMFA(currentUserId, recordId);
return ApiRes.ok();
}
/** 解除登录失败次数限制 */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_LOGIN_LIMIT_DELETE' )")
@RequestMapping(value="/loginLimit/{recordId}", method = RequestMethod.DELETE)
@MethodLog(remark = "解除登录限制")
public ApiRes deleteLoginLimit(@PathVariable("recordId") Long recordId) throws BizException{
List<SysUserAuth> authList = sysUserAuthService.list(SysUserAuth.gw().eq(SysUserAuth::getUserId, recordId));
if (authList.isEmpty()) {
return ApiRes.ok();
}
for (SysUserAuth sysUserAuth : authList) {
RedisUtil.del(CS.getCacheKeyLoginErr(CS.SYS_ROLE_TYPE.AGENT, sysUserAuth.getIdentifier()));
}
return ApiRes.ok();
}
/** 提交审核 */
@RequestMapping(value="/audit", method = RequestMethod.PUT)
@MethodLog(remark = "提交审核")
public ApiRes audit() throws BizException{
// 提交的资料
AgentInfo agentInfo = getObject(AgentInfo.class);
// 查询数据库中的服务商信息
AgentInfo dbAgentInfo = agentInfoService.getById(getCurrentAgentNo());
if (dbAgentInfo == null) {
throw new BizException("服务商信息不存在!");
}
if (dbAgentInfo.getState() == CS.YES) {
throw new BizException("当前服务商已通过审核,不可修改信息!");
}
// 更新服务商资料
AgentInfo updateInfo = new AgentInfo();
updateInfo.setAgentNo(dbAgentInfo.getAgentNo());
updateInfo.setState(AgentInfo.AUDIT_STATE_ING);
updateInfo.setAgentName(agentInfo.getAgentName()); // 服务商名称
updateInfo.setAgentShortName(agentInfo.getAgentShortName()); // 服务商简称
updateInfo.setContactName(agentInfo.getContactName()); // 联系人姓名
updateInfo.setContactEmail(agentInfo.getContactEmail()); // 联系人邮箱
updateInfo.setLicenseImg(agentInfo.getLicenseImg()); // 营业执照
updateInfo.setIdcard1Img(agentInfo.getIdcard1Img()); // 身份证人像面
updateInfo.setIdcard2Img(agentInfo.getIdcard2Img()); // 身份证国徽面
updateInfo.setIdcardInHandImg(agentInfo.getIdcardInHandImg()); // 手持身份证照
updateInfo.setBankCardImg(agentInfo.getBankCardImg()); // 银行卡照片
updateInfo.setPermitImg(agentInfo.getPermitImg()); // 许可证照片
updateInfo.setAgentType(agentInfo.getAgentType()); // 服务商类型
updateInfo.setSettAccountType(agentInfo.getSettAccountType()); // 账户类型
updateInfo.setSettAccountNo(agentInfo.getSettAccountNo()); // 账户账号
updateInfo.setSettAccountName(agentInfo.getSettAccountName()); // 账户姓名
updateInfo.setSettAccountBank(agentInfo.getSettAccountBank()); // 银行名称
updateInfo.setSettAccountSubBank(agentInfo.getSettAccountSubBank()); // 开户行支行名称
agentInfoService.updateById(updateInfo);
return ApiRes.ok();
}
}

View File

@ -0,0 +1,78 @@
package com.jeequan.jeepay.agent.ctrl.sysuser;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.agent.service.AuthService;
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.db.entity.SysUserEntity;
import com.jeequan.jeepay.db.entity.SysUserRoleRela;
import com.jeequan.jeepay.service.impl.SysUserRoleRelaService;
import com.jeequan.jeepay.service.impl.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
/**
* 用户角色管理类
*
* @author terrfly
* @modify zhuxiao
*
* @date 2021-04-27 15:50
*/
@RestController
@RequestMapping("api/sysUserRoleRelas")
public class SysUserRoleRelaController extends CommonCtrl {
@Autowired private SysUserRoleRelaService sysUserRoleRelaService;
@Autowired private SysUserService sysUserService;
@Autowired private AuthService authService;
/** list */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_UPD_ROLE' )")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
SysUserRoleRela queryObject = getObject(SysUserRoleRela.class);
LambdaQueryWrapper<SysUserRoleRela> condition = SysUserRoleRela.gw();
if(queryObject.getUserId() != null){
condition.eq(SysUserRoleRela::getUserId, queryObject.getUserId());
}
IPage<SysUserRoleRela> pages = sysUserRoleRelaService.page(getIPage(true), condition);
return ApiRes.page(pages);
}
/** 重置用户角色关联信息 */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_UPD_ROLE' )")
@RequestMapping(value="relas/{sysUserId}", method = RequestMethod.POST)
public ApiRes relas(@PathVariable("sysUserId") Long sysUserId) {
SysUserEntity dbRecord = sysUserService.getOne(SysUserEntity.gw().eq(SysUserEntity::getSysUserId, sysUserId).eq(SysUserEntity::getBelongInfoId, getCurrentAgentNo()));
if (dbRecord == null) {
throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
}
List<String> roleIdList = JSONArray.parseArray(getValStringRequired("roleIdListStr"), String.class);
sysUserService.saveUserRole(sysUserId, roleIdList);
authService.refAuthentication(Arrays.asList(sysUserId));
return ApiRes.ok();
}
}

View File

@ -0,0 +1,232 @@
package com.jeequan.jeepay.agent.ctrl.sysuser;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.jwt.JWTPayload;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.utils.DateKit;
import com.jeequan.jeepay.db.entity.SysUserEntity;
import com.jeequan.jeepay.db.entity.SysUserTeam;
import com.jeequan.jeepay.service.impl.SysUserService;
import com.jeequan.jeepay.service.impl.SysUserTeamService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
* 操作员列表
*
* @author zx
*
* @date 2022/3/17 17:13
*/
@RestController
@RequestMapping("/api/userTeams")
public class SysUserTeamController extends CommonCtrl {
@Autowired private SysUserTeamService sysUserTeamService;
@Autowired private SysUserService sysUserService;
/** list */
@PreAuthorize("hasAuthority( 'ENT_UR_TEAM_LIST' )")
@RequestMapping(value="", method = RequestMethod.GET)
public ApiRes list() {
// 是否app登录
String loginType = getCurrentUser().getLoginType();
boolean isApp = StringUtils.isNotBlank(loginType) && (loginType.equals(JWTPayload.LOGIN_PAGE_TYPE.APP) || loginType.equals(JWTPayload.LOGIN_PAGE_TYPE.LITE));
SysUserTeam queryObject = getObject(SysUserTeam.class);
queryObject.setSysType(CS.SYS_ROLE_TYPE.AGENT);
queryObject.setBelongInfoId(getCurrentAgentNo());
// 团队列表
IPage<SysUserTeam> iPage = sysUserTeamService.selectPage(getIPage(true), queryObject);
// 1查询全部团队列表直接返回
int pageSize = getValIntegerRequired("pageSize");
if (pageSize == -1) {
return ApiRes.page(iPage);
}
// 2web端仅返回团队列表
if (!isApp) {
return ApiRes.page(iPage);
}
if (iPage.getTotal() <= 0) {
return ApiRes.page(new Page());
}
// 3app端返回团队列表 包含团队成员信息
// 当前分页团队ID集合
List<Long> teamIdList = new LinkedList<>();
iPage.getRecords().forEach(record -> teamIdList.add(record.getTeamId()));
// 查询团队id下的用户
List<JSONObject> list = sysUserTeamService.selectList(teamIdList, null, null);
if (CollUtil.isEmpty(list)) {
return ApiRes.page(iPage);
}
// 外层循环团队 内层团队成员数据
for (SysUserTeam sysUserTeam : iPage.getRecords()) {
// 用户列表
List<JSONObject> userList = new LinkedList<>();
// 团队总商户数
Long totalMchCount = 0L;
// 团队总交易额
Long totalOrderAmount = 0L;
for (JSONObject json : list) {
if (sysUserTeam.getTeamId().equals(json.getLong("teamId"))) {
userList.add(json);
if (json.getLong("mchCount") != null) {
totalMchCount += json.getLong("mchCount");
}
if (json.getLong("orderAmount") != null) {
totalOrderAmount += json.getLong("orderAmount");
}
}
}
sysUserTeam.addExt("userList", userList);
sysUserTeam.addExt("totalMchCount", totalMchCount);
sysUserTeam.addExt("totalOrderAmount", totalOrderAmount);
}
return ApiRes.page(iPage);
}
/** web端 团队详情下的拓展员信息 */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_VIEW' )")
@RequestMapping(value="/userList/{recordId}", method = RequestMethod.GET)
public ApiRes userList(@PathVariable("recordId") Long recordId) {
IPage<SysUserEntity> iPage = sysUserService.page(getIPage(), SysUserEntity.gw().eq(SysUserEntity::getTeamId, recordId));
if (iPage.getTotal() <= 0) {
return ApiRes.page(new Page());
}
// 查询团队id下的用户
String dateRange = getValStringRequired("queryDateRange");
// 获取查询时间请求参数 [开始时间, 结束时间]
Date[] queryDateRangeArray = DateKit.getQueryDateRange(dateRange);
String createdStart = DateUtil.formatDateTime(queryDateRangeArray[0]);
String createdEnd = DateUtil.formatDateTime(queryDateRangeArray[1]);
List<JSONObject> list = sysUserTeamService.selectList(Arrays.asList(recordId), createdStart, createdEnd);
if (CollUtil.isEmpty(list)) {
return ApiRes.page(iPage);
}
// 用户列表
List<JSONObject> userList = new LinkedList<>();
for (SysUserEntity sysUserEntity : iPage.getRecords()) {
for (JSONObject json : list) {
if (sysUserEntity.getSysUserId().equals(json.getLong("sysUserId"))) {
userList.add(json);
}
}
}
return ApiRes.page(getIPage(), userList, iPage.getTotal());
}
/** detail */
@PreAuthorize("hasAuthority( 'ENT_UR_USER_EDIT' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.GET)
public ApiRes detail(@PathVariable("recordId") Integer recordId) {
return ApiRes.ok(sysUserTeamService.getById(recordId));
}
/** add */
@PreAuthorize("hasAuthority( 'ENT_UR_TEAM_ADD' )")
@MethodLog(remark = "添加团队")
@RequestMapping(value="", method = RequestMethod.POST)
public ApiRes add() {
SysUserTeam sysUserTeam = getObject(SysUserTeam.class);
sysUserTeam.setSysType(CS.SYS_ROLE_TYPE.AGENT);
sysUserTeam.setBelongInfoId(getCurrentAgentNo());
long count = sysUserTeamService.count(SysUserTeam.gw().eq(SysUserTeam::getTeamName, sysUserTeam.getTeamName()));
if (count > 0) {
throw new BizException("团队名已存在");
}
boolean result = sysUserTeamService.save(sysUserTeam);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
}
return ApiRes.ok();
}
/** update */
@PreAuthorize("hasAuthority( 'ENT_UR_TEAM_EDIT' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.PUT)
@MethodLog(remark = "修改团队信息")
public ApiRes update(@PathVariable("recordId") Long recordId) {
SysUserTeam sysUserTeam = getObject(SysUserTeam.class);
sysUserTeam.setTeamId(recordId);
long count = sysUserTeamService.count(SysUserTeam.gw()
.eq(SysUserTeam::getTeamName, sysUserTeam.getTeamName())
.ne(SysUserTeam::getTeamId, recordId)
);
if (count > 0) {
throw new BizException("团队名已存在");
}
boolean result = sysUserTeamService.updateById(sysUserTeam);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
}
return ApiRes.ok();
}
/** delete */
@PreAuthorize("hasAuthority( 'ENT_UR_TEAM_DELETE' )")
@RequestMapping(value="/{recordId}", method = RequestMethod.DELETE)
@MethodLog(remark = "删除团队")
public ApiRes delete(@PathVariable("recordId") Long recordId) {
// 删除团队
boolean result = sysUserTeamService.removeById(recordId);
if (!result) {
return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_DELETE);
}
return ApiRes.ok();
}
}

View File

@ -0,0 +1,40 @@
package com.jeequan.jeepay.agent.ctrl.transfer;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.agent.websocket.server.WsChannelUserIdServer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 获取用户ID - 回调函数
*
* @author terrfly
*
* @date 2021/8/13 17:54
*/
@Controller
@RequestMapping("/api/anon/channelUserIdCallback")
public class ChannelUserIdNotifyController extends CommonCtrl {
@RequestMapping("")
public String channelUserIdCallback() {
try {
//请求参数
JSONObject params = getReqParamJSON();
String extParam = params.getString("extParam");
String channelUserId = params.getString("channelUserId");
String appId = params.getString("appId");
//推送到前端
WsChannelUserIdServer.sendMsgByAppAndCid(appId, extParam, channelUserId);
} catch (Exception e) {
request.setAttribute("errMsg", e.getMessage());
}
return "channelUser/getChannelUserIdPage";
}
}

View File

@ -0,0 +1,105 @@
package com.jeequan.jeepay.agent.ctrl.transfer;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.IsvUserConn;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.RateConfig;
import com.jeequan.jeepay.db.entity.TransferInterfaceDefineEntity;
import com.jeequan.jeepay.service.impl.IsvInfoService;
import com.jeequan.jeepay.service.impl.TransferInterfaceDefineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* TODO
*
* @author deng
* @since 2024/4/25
*/
@RestController
@RequestMapping("api/transferConfig")
public class TransferConfigController extends CommonCtrl {
@Autowired
private TransferInterfaceDefineService transferInterfaceDefineService;
@Autowired
private IsvInfoService isvInfoService;
/**
* 查询可用的支付接口
* <p>
* 使用功能项目 参数及费率的填写
* 服务商查询全部支付接口
* 服务商查询服务商开启的支付接口
**/
@GetMapping("/ifCodes")
public ApiRes ifCodes() {
// 搜索条件
String ifName = getValString("ifName");
String infoId = getValStringRequired("infoId"); // infoId
String configMode = getValStringRequired("configMode"); // 设置类型
// 支付接口列表
LambdaQueryWrapper<TransferInterfaceDefineEntity> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(TransferInterfaceDefineEntity::getState, CS.YES); // 查询可用的支付接口列表
lambdaQueryWrapper.like(ObjUtil.isNotEmpty(ifName), TransferInterfaceDefineEntity::getTransIfName, ifName);
AgentInfo agentInfo = agentInfoService.getById(getCurrentAgentNo());
Map<String, IsvUserConn> ifCodeMap = new HashMap<>();
// 服务商 配置 商户费率 | 下级服务商费率 | 自己配置信息 显示 当前服务商所有接口
if (RateConfig.CONFIG_MODE_AGENTEMCH.equals(configMode) ||
RateConfig.CONFIG_MODE_AGENTSUBAGENT.equals(configMode) ||
RateConfig.CONFIG_MODE_AGENTSELF.equals(configMode)
) {
ifCodeMap = isvInfoService.getTransIsvUserConn(CS.SYS_ROLE_TYPE.AGENT, agentInfo.getAgentNo(), CS.YES);
List<String> ifCodeList = new ArrayList<>(ifCodeMap.keySet());
if (ifCodeList.isEmpty()) { // 没有可用的接口
return ApiRes.ok(ifCodeList);
}
lambdaQueryWrapper.in(TransferInterfaceDefineEntity::getTransIfCode, ifCodeList);
} else if (RateConfig.CONFIG_MODE_AGENTAPPLYMENT.equals(configMode)) { // 服务商进件
// 查询 当前服务商 开通的
ifCodeMap = isvInfoService.getTransIsvUserConn(CS.SYS_ROLE_TYPE.AGENT, agentInfo.getAgentNo(), null);
if (ifCodeMap.isEmpty()) { // 没有可用的接口
return ApiRes.ok(Collections.emptyList());
}
lambdaQueryWrapper.in(TransferInterfaceDefineEntity::getTransIfCode, ifCodeMap.keySet());
}
final List<TransferInterfaceDefineEntity> list = new ArrayList<>();
lambdaQueryWrapper.orderByAsc(TransferInterfaceDefineEntity::getId);
final Map<String, IsvUserConn> finalMap = ifCodeMap;
transferInterfaceDefineService.list(lambdaQueryWrapper).forEach(item -> {
// 如果服务商上级配置的开启进件为关闭那么最终展示的列表中显示的是否开启进件也为关闭
IsvUserConn ifCodeInfo = finalMap.get(item.getTransIfCode());
boolean isEnabled = ifCodeInfo.getStatus() == CS.YES && ifCodeInfo.getConfigStatus() == CS.YES;
item.addExt("configState", ifCodeInfo.getStatus());
item.setState(isEnabled ? CS.YES : CS.NO);
list.add(item);
});
return ApiRes.ok(list);
}
}

Some files were not shown because too many files have changed in this diff Show More