Browse Source

first commit

main
简小朤 4 months ago
commit
a0486f0cf2
  1. BIN
      .DS_Store
  2. 18
      .editorconfig
  3. 52
      .gitignore
  4. 12
      .run/ruoyi-monitor-admin.run.xml
  5. 12
      .run/ruoyi-server.run.xml
  6. 12
      .run/ruoyi-xxl-job-admin.run.xml
  7. BIN
      LFH支付系统初期_申请牌照__Feature_List.xlsx
  8. 20
      LICENSE
  9. 171
      README.md
  10. 23
      coin-admin/Dockerfile
  11. 136
      coin-admin/pom.xml
  12. 24
      coin-admin/src/main/java/com/coin/CoinApplication.java
  13. 18
      coin-admin/src/main/java/com/coin/CoinServletInitializer.java
  14. 119
      coin-admin/src/main/java/com/coin/business/controller/AgentVerificationController.java
  15. 106
      coin-admin/src/main/java/com/coin/business/controller/AppVersionController.java
  16. 106
      coin-admin/src/main/java/com/coin/business/controller/BehaviorModelInfoController.java
  17. 106
      coin-admin/src/main/java/com/coin/business/controller/CommonFeedbackController.java
  18. 106
      coin-admin/src/main/java/com/coin/business/controller/CommonInfoController.java
  19. 106
      coin-admin/src/main/java/com/coin/business/controller/CommonLimitSettingController.java
  20. 106
      coin-admin/src/main/java/com/coin/business/controller/CommonNotifyController.java
  21. 106
      coin-admin/src/main/java/com/coin/business/controller/CreditRuleController.java
  22. 106
      coin-admin/src/main/java/com/coin/business/controller/CustomerServiceChatController.java
  23. 106
      coin-admin/src/main/java/com/coin/business/controller/DealPaymentController.java
  24. 106
      coin-admin/src/main/java/com/coin/business/controller/DealProxyController.java
  25. 106
      coin-admin/src/main/java/com/coin/business/controller/DealReceiptController.java
  26. 106
      coin-admin/src/main/java/com/coin/business/controller/DealRechargeController.java
  27. 106
      coin-admin/src/main/java/com/coin/business/controller/DealTransferController.java
  28. 106
      coin-admin/src/main/java/com/coin/business/controller/DealWithdrawalController.java
  29. 106
      coin-admin/src/main/java/com/coin/business/controller/FaqController.java
  30. 106
      coin-admin/src/main/java/com/coin/business/controller/FeeRecordController.java
  31. 106
      coin-admin/src/main/java/com/coin/business/controller/FeeStandardController.java
  32. 106
      coin-admin/src/main/java/com/coin/business/controller/FinancialRecordController.java
  33. 121
      coin-admin/src/main/java/com/coin/business/controller/MerchantVerificationController.java
  34. 106
      coin-admin/src/main/java/com/coin/business/controller/RecordPayCallbackController.java
  35. 106
      coin-admin/src/main/java/com/coin/business/controller/RecordTransactionController.java
  36. 106
      coin-admin/src/main/java/com/coin/business/controller/TradingChannelController.java
  37. 106
      coin-admin/src/main/java/com/coin/business/controller/TradingChannelRecordController.java
  38. 105
      coin-admin/src/main/java/com/coin/business/controller/UserAccountController.java
  39. 106
      coin-admin/src/main/java/com/coin/business/controller/UserBehaviorLogController.java
  40. 106
      coin-admin/src/main/java/com/coin/business/controller/UserBehaviorRuleActionController.java
  41. 106
      coin-admin/src/main/java/com/coin/business/controller/UserBehaviorRuleRiskController.java
  42. 106
      coin-admin/src/main/java/com/coin/business/controller/UserBehaviorStatsController.java
  43. 106
      coin-admin/src/main/java/com/coin/business/controller/UserCardController.java
  44. 106
      coin-admin/src/main/java/com/coin/business/controller/UserCreditController.java
  45. 106
      coin-admin/src/main/java/com/coin/business/controller/UserCreditRecordController.java
  46. 106
      coin-admin/src/main/java/com/coin/business/controller/UserFriendController.java
  47. 106
      coin-admin/src/main/java/com/coin/business/controller/UserInfoAgentController.java
  48. 106
      coin-admin/src/main/java/com/coin/business/controller/UserInfoBusController.java
  49. 106
      coin-admin/src/main/java/com/coin/business/controller/UserInfoController.java
  50. 106
      coin-admin/src/main/java/com/coin/business/controller/UserPasswdController.java
  51. 164
      coin-admin/src/main/java/com/coin/business/controller/UserRegisterController.java
  52. 119
      coin-admin/src/main/java/com/coin/business/controller/UserVerificationController.java
  53. 106
      coin-admin/src/main/java/com/coin/business/controller/WalletLimitConfigController.java
  54. 134
      coin-admin/src/main/java/com/coin/web/controller/common/CaptchaController.java
  55. 168
      coin-admin/src/main/java/com/coin/web/controller/monitor/CacheController.java
  56. 88
      coin-admin/src/main/java/com/coin/web/controller/monitor/SysLogininforController.java
  57. 74
      coin-admin/src/main/java/com/coin/web/controller/monitor/SysOperlogController.java
  58. 90
      coin-admin/src/main/java/com/coin/web/controller/monitor/SysUserOnlineController.java
  59. 137
      coin-admin/src/main/java/com/coin/web/controller/system/SysConfigController.java
  60. 122
      coin-admin/src/main/java/com/coin/web/controller/system/SysDeptController.java
  61. 116
      coin-admin/src/main/java/com/coin/web/controller/system/SysDictDataController.java
  62. 125
      coin-admin/src/main/java/com/coin/web/controller/system/SysDictTypeController.java
  63. 32
      coin-admin/src/main/java/com/coin/web/controller/system/SysIndexController.java
  64. 144
      coin-admin/src/main/java/com/coin/web/controller/system/SysLoginController.java
  65. 127
      coin-admin/src/main/java/com/coin/web/controller/system/SysMenuController.java
  66. 80
      coin-admin/src/main/java/com/coin/web/controller/system/SysNoticeController.java
  67. 105
      coin-admin/src/main/java/com/coin/web/controller/system/SysOssConfigController.java
  68. 109
      coin-admin/src/main/java/com/coin/web/controller/system/SysOssController.java
  69. 120
      coin-admin/src/main/java/com/coin/web/controller/system/SysPostController.java
  70. 126
      coin-admin/src/main/java/com/coin/web/controller/system/SysProfileController.java
  71. 40
      coin-admin/src/main/java/com/coin/web/controller/system/SysRegisterController.java
  72. 228
      coin-admin/src/main/java/com/coin/web/controller/system/SysRoleController.java
  73. 256
      coin-admin/src/main/java/com/coin/web/controller/system/SysUserController.java
  74. 186
      coin-admin/src/main/resources/application-dev.yml
  75. 185
      coin-admin/src/main/resources/application-prod.yml
  76. 287
      coin-admin/src/main/resources/application.yml
  77. 8
      coin-admin/src/main/resources/banner.txt
  78. 49
      coin-admin/src/main/resources/i18n/messages.properties
  79. 49
      coin-admin/src/main/resources/i18n/messages_en_US.properties
  80. 49
      coin-admin/src/main/resources/i18n/messages_zh_CN.properties
  81. BIN
      coin-admin/src/main/resources/ip2region.xdb
  82. 129
      coin-admin/src/main/resources/logback-plus.xml
  83. 28
      coin-admin/src/main/resources/spy.properties
  84. 45
      coin-admin/src/test/java/com/coin/test/AssertUnitTest.java
  85. 70
      coin-admin/src/test/java/com/coin/test/DemoUnitTest.java
  86. 72
      coin-admin/src/test/java/com/coin/test/ParamUnitTest.java
  87. 54
      coin-admin/src/test/java/com/coin/test/TagUnitTest.java
  88. BIN
      coin-app/.DS_Store
  89. 23
      coin-app/Dockerfile
  90. 136
      coin-app/pom.xml
  91. BIN
      coin-app/src/.DS_Store
  92. BIN
      coin-app/src/main/.DS_Store
  93. BIN
      coin-app/src/main/java/.DS_Store
  94. BIN
      coin-app/src/main/java/com/.DS_Store
  95. 21
      coin-app/src/main/java/com/coin/CoinAppApplication.java
  96. 18
      coin-app/src/main/java/com/coin/CoinAppServletInitializer.java
  97. 197
      coin-app/src/main/java/com/coin/app/controller/common/CaptchaController.java
  98. 74
      coin-app/src/main/java/com/coin/app/controller/common/QRCodeController.java
  99. 121
      coin-app/src/main/java/com/coin/app/controller/common/UserFriendController.java
  100. 86
      coin-app/src/main/java/com/coin/app/controller/deal/DealController.java

BIN
.DS_Store

Binary file not shown.

18
.editorconfig

@ -0,0 +1,18 @@
# http://editorconfig.org
root = true
# 空格替代Tab缩进在各种编辑工具下效果一致
[*]
indent_style = space
indent_size = 4
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
[*.{json,yml,yaml}]
indent_size = 2
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

52
.gitignore

@ -0,0 +1,52 @@
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
# log
/logs/
# upload file
/file/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml

12
.run/ruoyi-monitor-admin.run.xml

@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile">
<settings>
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:4.8.2" />
<option name="buildOnly" value="true" />
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>

12
.run/ruoyi-server.run.xml

@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile">
<settings>
<option name="imageTag" value="ruoyi/ruoyi-server:4.8.2" />
<option name="buildOnly" value="true" />
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>

12
.run/ruoyi-xxl-job-admin.run.xml

@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ruoyi-xxl-job-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile">
<settings>
<option name="imageTag" value="ruoyi/ruoyi-xxl-job-admin:4.8.2" />
<option name="buildOnly" value="true" />
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>

BIN
LFH支付系统初期_申请牌照__Feature_List.xlsx

Binary file not shown.

20
LICENSE

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2019 RuoYi-Vue-Plus
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

171
README.md

@ -0,0 +1,171 @@
<img src="https://foruda.gitee.com/images/1679673773341074847/178e8451_1766278.png" width="50%" height="50%">
<div style="height: 10px; clear: both;"></div>
- - -
## 版本状态说明
由于 springboot 2.X 与 vue 2.X 官方均宣布停止维护, 故而 框架 4.X 版本 进入维护状态(只处理问题不更新功能)
停止维护时间预计: 2024年6-10月具体根据使用人数动态决定, 此版本已经相当稳定 即便不更新功能也不影响使用
如果依旧选择使用 jdk8 或者 jdk11 可以放心使用此版本, 如果希望使用 jdk17 或者 jdk21 可以选择使用 5.X 分支
## 平台简介
[![码云Gitee](https://gitee.com/dromara/RuoYi-Vue-Plus/badge/star.svg?theme=blue)](https://gitee.com/dromara/RuoYi-Vue-Plus)
[![GitHub](https://img.shields.io/github/stars/JavaLionLi/RuoYi-Vue-Plus.svg?style=social&label=Stars)](https://github.com/dromara/RuoYi-Vue-Plus)
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE)
[![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
<br>
[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-4.8.2-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus)
[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.7-blue.svg)]()
[![JDK-8+](https://img.shields.io/badge/JDK-8-green.svg)]()
[![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]()
> RuoYi-Vue-Plus 是重写 RuoYi-Vue 针对 `分布式集群` 场景全方位升级(不兼容原框架)
> 项目代码、文档 均开源免费可商用 遵循开源协议在项目中保留开源协议文件即可<br>
活到老写到老 为兴趣而开源 为学习而开源 为让大家真正可以学到技术而开源
> 系统演示: [传送门](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=4836388&doc_id=1469725)
# 本框架与RuoYi的功能差异
| 功能 | 本框架 | RuoYi |
|-------------|-------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|
| 前端项目 | 基于vue3-element-admin开源项目重写<br/>Vue3 + TS + ElementPlus | 基于Vue2/Vue3 + JS |
| 后端项目结构 | 采用插件化 + 扩展包形式 结构解耦 易于扩展 | 模块相互注入耦合严重难以扩展 |
| 后端代码风格 | 严格遵守Alibaba规范与项目统一配置的代码格式化 | 代码书写与常规结构不同阅读障碍大 |
| Web容器 | 采用 Undertow 基于 XNIO 的高性能容器 | 采用 Tomcat |
| 权限认证 | 采用 Sa-Token、Jwt 静态使用功能齐全 低耦合 高扩展 | Spring Security 配置繁琐扩展性极差 |
| 权限注解 | 采用 Sa-Token 支持注解 登录校验、角色校验、权限校验、二级认证校验、HttpBasic校验、忽略校验<br/>角色与权限校验支持多种条件 如 `AND` `OR``权限 OR 角色` 等复杂表达式 | 只支持是否存在匹配 |
| 关系数据库支持 | 原生支持 MySQL、Oracle、PostgreSQL、SQLServer<br/>可同时使用异构切换 | 支持 Mysql、Oracle 不支持同时使用、不支持异构切换 |
| 缓存数据库 | 支持 Redis 5-7 支持大部分新功能特性 如 分布式限流、分布式队列 | Redis 简单 get set 支持 |
| Redis客户端 | 采用 Redisson Redis官方推荐 基于Netty的客户端工具<br/>支持Redis 90%以上的命令 底层优化规避很多不正确的用法 例如: keys被转换为scan<br/>支持单机、哨兵、单主集群、多主集群等模式 | Lettuce + RedisTemplate 支持模式少 工具使用繁琐<br/>连接池采用 common-pool Bug多经常性出问题 |
| 缓存注解 | 采用 Spring-Cache 注解 对其扩展了实现支持了更多功能<br/>例如 过期时间 最大空闲时间 组最大长度等 只需一个注解即可完成数据自动缓存 | 需手动编写Redis代码逻辑 |
| ORM框架 | 采用 Mybatis-Plus 基于对象几乎不用写SQL全java操作 功能强大插件众多<br/>例如多租户插件 分页插件 乐观锁插件等等 | 采用 Mybatis 基于XML需要手写SQL |
| SQL监控 | 采用 p6spy 可输出完整SQL与执行时间监控 | log输出 需手动拼接sql与参数无法快速查看调试问题 |
| 数据分页 | 采用 Mybatis-Plus 分页插件<br/>框架对其进行了扩展 对象化分页对象 支持多种方式传参 支持前端多排序 复杂排序 | 采用 PageHelper 仅支持单查询分页 参数只能从param传 只能单排序 功能扩展性差 体验不好 |
| 数据权限 | 采用 Mybatis-Plus 插件 自行分析拼接SQL 无感式过滤<br/>只需为Mapper设置好注解条件 支持多种自定义 不限于部门角色 | 采用 注解+aop 实现 基于部门角色 生成的sql兼容性差 不支持其他业务扩展<br/>生成sql后需手动拼接到具体业务sql上 对于多个Mapper查询不起作用 |
| 数据脱敏 | 采用 注解 + jackson 序列化期间脱敏 支持不同模块不同的脱敏条件<br/>支持多种策略 如身份证、手机号、地址、邮箱、银行卡等 可自行扩展 | 无 |
| 数据加解密 | 采用 注解 + mybatis 拦截器 对存取数据期间自动加解密<br/>支持多种策略 如BASE64、AES、RSA、SM2、SM4等 | 无 |
| 数据翻译 | 采用 注解 + jackson 序列化期间动态修改数据 数据进行翻译<br/>支持多种模式: `映射翻译` `直接翻译` `其他扩展条件翻译` 接口化两步即可完成自定义扩展 内置多种翻译实现 | 无 |
| 多数据源框架 | 采用 dynamic-datasource 支持世面大部分数据库<br/>通过yml配置即可动态管理异构不同种类的数据库 也可通过前端页面添加数据源<br/>支持spel表达式从请求头参数等条件切换数据源 | 基于 druid 手动编写代码配置数据源 配置繁琐 支持性差 |
| 多数据源事务 | 采用 dynamic-datasource 支持多数据源不同种类的数据库事务回滚 | 不支持 |
| 数据库连接池 | 采用 HikariCP Spring官方内置连接池 配置简单 以性能与稳定性闻名天下 | 采用 druid bug众多 社区维护差 活跃度低 配置众多繁琐性能一般 |
| 数据库主键 | 采用 雪花ID 基于时间戳的 有序增长 唯一ID 再也不用为分库分表 数据合并主键冲突重复而发愁 | 采用 数据库自增ID 支持数据量有限 不支持多数据源主键唯一 |
| WebSocket协议 | 基于 Spring 封装的 WebSocket 协议 扩展了Token鉴权与分布式会话同步 不再只是基于单机的废物 | 无 |
| 序列化 | 采用 Jackson Spring官方内置序列化 靠谱!!! | 采用 fastjson bugjson 远近闻名 |
| 分布式幂等 | 参考美团GTIS防重系统简化实现(细节可看文档) | 手动编写注解基于aop实现 |
| 分布式任务调度 | 采用 Xxl-Job 天生支持分布式 统一的管理中心 | 采用 Quartz 基于数据库锁性能差 集群需要做很多配置与改造 |
| 文件存储 | 采用 Minio 分布式文件存储 天生支持多机、多硬盘、多分片、多副本存储<br/>支持权限管理 安全可靠 文件可加密存储 | 采用 本机文件存储 文件裸漏 易丢失泄漏 不支持集群有单点效应 |
| 云存储 | 采用 AWS S3 协议客户端 支持 七牛、阿里、腾讯 等一切支持S3协议的厂家 | 不支持 |
| 短信 | 采用 sms4j 短信融合包 支持数十种短信厂家 只需在yml配置好厂家密钥即可使用 可多厂家共用 | 不支持 |
| 邮件 | 采用 mail-api 通用协议支持大部分邮件厂商 | 不支持 |
| 接口文档 | 采用 SpringDoc、javadoc 无注解零入侵基于java注释<br/>只需把注释写好 无需再写一大堆的文档注解了 | 采用 Springfox 已停止维护 需要编写大量的注解来支持文档生成 |
| 校验框架 | 采用 Validation 支持注解与工具类校验 注解支持国际化 | 仅支持注解 且注解不支持国际化 |
| Excel框架 | 采用 Alibaba EasyExcel 基于插件化<br/>框架对其增加了很多功能 例如 自动合并相同内容 自动排列布局 字典翻译等 | 基于 POI 手写实现 功能有限 复杂 扩展性差 |
| 工具类框架 | 采用 Hutool、Lombok 上百种工具覆盖90%的使用需求 基于注解自动生成 get set 等简化框架大量代码 | 手写工具稳定性差易出问题 工具数量有限 代码臃肿需自己手写 get set 等 |
| 监控框架 | 采用 SpringBoot-Admin 基于SpringBoot官方 actuator 探针机制<br/>实时监控服务状态 框架还为其扩展了在线日志查看监控 | 无 |
| 链路追踪 | 采用 Apache SkyWalking 还在为请求不知道去哪了 到哪出了问题而烦恼吗<br/>用了它即可实时查看请求经过的每一处每一个节点 | 无 |
| 代码生成器 | 只需设计好表结构 一键生成所有crud代码与页面<br/>降低80%的开发量 把精力都投入到业务设计上<br/>框架为其适配MP、SpringDoc规范化代码 同时支持动态多数据源代码生成 | 代码生成原生结构 只支持单数据源生成 |
| 部署方式 | 支持 Docker 编排 一键搭建所有环境 让开发人员从此不再为搭建环境而烦恼 | 原生jar部署 其他环境需手动下载安装 自行搭建 |
| 项目路径修改 | 提供详细的修改方案文档 并为其做了一些改动 非常简单即可修改成自己想要的 | 需要做很多改造 文档说明有限 |
| 国际化 | 基于请求头动态返回不同语种的文本内容 开发难度低 有对应的工具类 支持大部分注解内容国际化 | 只提供基础功能 其他需自行编写扩展 |
| 代码单例测试 | 提供单例测试 使用方式编写方法与maven多环境单测插件 | 只提供基础功能 其他需自行编写扩展 |
| Demo案例 | 提供框架功能的实际使用案例 单独一个模块提供了很多很全 | 无 |
## 本框架与RuoYi的业务差异
| 业务 | 功能说明 | 本框架 | RuoYi |
|--------|-----------------------------------------|-----|------------------|
| 用户管理 | 用户的管理配置 如:新增用户、分配用户所属部门、角色、岗位等 | 支持 | 支持 |
| 部门管理 | 配置系统组织机构(公司、部门、小组) 树结构展现支持数据权限 | 支持 | 支持 |
| 岗位管理 | 配置系统用户所属担任职务 | 支持 | 支持 |
| 菜单管理 | 配置系统菜单、操作权限、按钮权限标识等 | 支持 | 支持 |
| 角色管理 | 角色菜单权限分配、设置角色按机构进行数据范围权限划分 | 支持 | 支持 |
| 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 | 支持 | 支持 |
| 参数管理 | 对系统动态配置常用参数 | 支持 | 支持 |
| 通知公告 | 系统通知公告信息发布维护 | 支持 | 支持 |
| 操作日志 | 系统正常操作日志记录和查询 系统异常信息日志记录和查询 | 支持 | 支持 |
| 登录日志 | 系统登录日志记录查询包含登录异常 | 支持 | 支持 |
| 文件管理 | 系统文件展示、上传、下载、删除等管理 | 支持 | 无 |
| 文件配置管理 | 系统文件上传、下载所需要的配置信息动态添加、修改、删除等管理 | 支持 | 无 |
| 在线用户管理 | 已登录系统的在线用户信息监控与强制踢出操作 | 支持 | 支持 |
| 定时任务 | 运行报表、任务管理(添加、修改、删除)、日志管理、执行器管理等 | 支持 | 仅支持任务与日志管理 |
| 代码生成 | 多数据源前后端代码的生成(java、html、xml、sql)支持CRUD下载 | 支持 | 仅支持单数据源 |
| 系统接口 | 根据业务代码自动生成相关的api接口文档 | 支持 | 支持 |
| 服务监控 | 监视集群系统CPU、内存、磁盘、堆栈、在线日志、Spring相关配置等 | 支持 | 仅支持单机CPU、内存、磁盘监控 |
| 缓存监控 | 对系统的缓存信息查询,命令统计等。 | 支持 | 支持 |
| 在线构建器 | 拖动表单元素生成相应的HTML代码。 | 支持 | 支持 |
| 使用案例 | 系统的一些功能案例 | 支持 | 不支持 |
## 参考文档
使用框架前请仔细阅读文档重点注意事项
<br>
>[初始化项目 必看](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=4164117&doc_id=1469725)
>>[https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=4164117&doc_id=1469725](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=4164117&doc_id=1469725)
>
>[专栏与视频 入门必看](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=5473272&doc_id=1469725)
>>[https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=5473272&doc_id=1469725](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=5473272&doc_id=1469725)
>
>[部署项目 必看](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=4219382&doc_id=1469725)
>>[https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=4219382&doc_id=1469725](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=4219382&doc_id=1469725)
>
>[参考文档 Wiki](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages)
>>[https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages)
## 软件架构图
![Plus部署架构图](https://images.gitee.com/uploads/images/2021/1112/202137_673ac5d2_1766278.png "Plus部署架构图.png")
## 贡献代码
欢迎各路英雄豪杰 `PR` 代码 请提交到 `dev` 开发分支 统一测试发版
框架定位为 `通用后台管理系统(分布式集群强化)` 原则上不接受业务 `PR`
### 其他
* 同步升级 RuoYi-Vue
* GitHub 地址 [RuoYi-Vue-Plus-github](https://github.com/dromara/RuoYi-Vue-Plus)
* 单模块 分支 [RuoYi-Vue-Plus-fast](https://gitee.com/dromara/RuoYi-Vue-Plus/tree/fast/)
* 微服务 分支 [RuoYi-Cloud-Plus](https://gitee.com/JavaLionLi/RuoYi-Cloud-Plus)
* 用户扩展项目 [扩展项目列表](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/pages?sort_id=4478302&doc_id=1469725)
## 加群与捐献
>[加群与捐献](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/加群与捐献?sort_id=4104598)
>>[https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/加群与捐献?sort_id=4104598](https://gitee.com/dromara/RuoYi-Vue-Plus/wikis/加群与捐献?sort_id=4104598)
## 捐献作者
作者为兼职做开源,平时还需要工作,如果帮到了您可以请作者吃个盒饭
<img src="https://images.gitee.com/uploads/images/2022/0218/213734_b1b8197f_1766278.jpeg" width="300px" height="450px" />
<img src="https://images.gitee.com/uploads/images/2021/0525/101713_3d18b119_1766278.jpeg" width="300px" height="450px" />
## 演示图例
| | |
|--------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
| ![输入图片说明](https://foruda.gitee.com/images/1680077524361362822/270bb429_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680077619939771291/989bf9b6_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680077681751513929/1c27c5bd_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680077721559267315/74d63e23_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680077765638904515/1b75d4a6_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078026375951297/eded7a4b_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078237104531207/0eb1b6a7_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078254306078709/5931e22f_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078287971528493/0b9af60a_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078308138770249/8d3b6696_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078352553634393/db5ef880_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078378238393374/601e4357_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078414983206024/2aae27c1_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078446738419874/ecce7d59_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078475971341775/149e8634_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078491666717143/3fadece7_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078558863188826/fb8ced2a_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078574561685461/ae68a0b2_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078594932772013/9d8bfec6_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078626493093532/fcfe4ff6_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078643608812515/0295bd4f_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078685196286463/d7612c81_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078703877318597/56fce0bc_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078716586545643/b6dbd68f_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078734103217688/eb1e6aa6_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078759131415480/73c525d8_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078779416197879/75e3ed02_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078802329118061/77e10915_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078893627848351/34a1c342_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078928175016986/f126ec4a_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078941718318363/b68a0f72_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680078963175518631/3bb769a1_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680078982294090567/b31c343d_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680079000642440444/77ca82a9_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680079020995074177/03b7d52e_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680079039367822173/76811806_1766278.png "屏幕截图") |
| ![输入图片说明](https://foruda.gitee.com/images/1680079274333484664/4dfdc7c0_1766278.png "屏幕截图") | ![输入图片说明](https://foruda.gitee.com/images/1680079290467458224/d6715fcf_1766278.png "屏幕截图") |

23
coin-admin/Dockerfile

@ -0,0 +1,23 @@
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER Lion Li
RUN mkdir -p /ruoyi/server/logs \
/ruoyi/server/temp \
/ruoyi/skywalking/agent
WORKDIR /ruoyi/server
ENV SERVER_PORT=8080
EXPOSE ${SERVER_PORT}
ADD ./target/ruoyi-admin.jar ./app.jar
ENTRYPOINT ["java", \
"-Djava.security.egd=file:/dev/./urandom", \
"-Dserver.port=${SERVER_PORT}", \
# 应用名称 如果想区分集群节点监控 改成不同的名称即可
# "-Dskywalking.agent.service_name=ruoyi-server", \
# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \
"-jar", "app.jar"]

136
coin-admin/pom.xml

@ -0,0 +1,136 @@
<?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">
<parent>
<groupId>com.coin</groupId>
<artifactId>coin-vue-plus</artifactId>
<version>4.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>coin-admin</artifactId>
<description>
web服务入口
</description>
<dependencies>
<!-- spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- Oracle -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
</dependency>
<!-- PostgreSql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- SqlServer -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-framework</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-system</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-job</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-oss</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-generator</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<!-- demo模块 -->
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-demo</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- skywalking 整合 logback -->
<!-- <dependency>-->
<!-- <groupId>org.apache.skywalking</groupId>-->
<!-- <artifactId>apm-toolkit-logback-1.x</artifactId>-->
<!-- <version>${与你的agent探针版本保持一致}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.skywalking</groupId>-->
<!-- <artifactId>apm-toolkit-trace</artifactId>-->
<!-- <version>${与你的agent探针版本保持一致}</version>-->
<!-- </dependency>-->
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>

24
coin-admin/src/main/java/com/coin/CoinApplication.java

@ -0,0 +1,24 @@
package com.coin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
/**
* 启动程序
*
* @author coin
*/
@SpringBootApplication
public class CoinApplication {
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication application = new SpringApplication(com.coin.CoinApplication.class);
application.setApplicationStartup(new BufferingApplicationStartup(2048));
application.run(args);
System.out.println("(♥◠‿◠)ノ゙ Coin启动成功 ლ(´ڡ`ლ)゙");
}
}

18
coin-admin/src/main/java/com/coin/CoinServletInitializer.java

@ -0,0 +1,18 @@
package com.coin;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* web容器中进行部署
*
* @author coin
*/
public class CoinServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(CoinApplication.class);
}
}

119
coin-admin/src/main/java/com/coin/business/controller/AgentVerificationController.java

@ -0,0 +1,119 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.domain.bo.MerchantVerificationBo;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.AgentVerificationVo;
import com.coin.business.domain.bo.AgentVerificationBo;
import com.coin.business.service.IAgentVerificationService;
import com.coin.common.core.page.TableDataInfo;
/**
* 代理商认证
*
* @author coin
* @date 2025-05-24
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/agentVerification")
public class AgentVerificationController extends BaseController {
private final IAgentVerificationService iAgentVerificationService;
/**
* 查询代理商认证列表
*/
@SaCheckPermission("business:agentVerification:list")
@GetMapping("/list")
public TableDataInfo<AgentVerificationVo> list(AgentVerificationBo bo, PageQuery pageQuery) {
return iAgentVerificationService.queryPageList(bo, pageQuery);
}
/**
* 导出代理商认证列表
*/
@SaCheckPermission("business:agentVerification:export")
@Log(title = "代理商认证", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(AgentVerificationBo bo, HttpServletResponse response) {
List<AgentVerificationVo> list = iAgentVerificationService.queryList(bo);
ExcelUtil.exportExcel(list, "代理商认证", AgentVerificationVo.class, response);
}
/**
* 获取代理商认证详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:agentVerification:query")
@GetMapping("/{id}")
public R<AgentVerificationVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iAgentVerificationService.queryById(id));
}
/**
* 新增代理商认证
*/
@SaCheckPermission("business:agentVerification:add")
@Log(title = "代理商认证", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody AgentVerificationBo bo) {
return toAjax(iAgentVerificationService.insertByBo(bo));
}
/**
* 修改代理商认证
*/
@SaCheckPermission("business:agentVerification:edit")
@Log(title = "代理商认证", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody AgentVerificationBo bo) {
return toAjax(iAgentVerificationService.updateByBo(bo));
}
/**
* 删除代理商认证
*
* @param ids 主键串
*/
@SaCheckPermission("business:agentVerification:remove")
@Log(title = "代理商认证", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iAgentVerificationService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 实名认证审核
* @param bo
* @return
*/
@SaCheckPermission("business:agentVerification:audit")
@Log(title = "认证审核", businessType = BusinessType.UPDATE)
@PostMapping("/agentVerificationAudit")
public R<Void> agentVerificationAudit(@RequestBody AgentVerificationBo bo) {
return toAjax(iAgentVerificationService.agentVerificationAudit(bo));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/AppVersionController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.AppVersionVo;
import com.coin.business.domain.bo.AppVersionBo;
import com.coin.business.service.IAppVersionService;
import com.coin.common.core.page.TableDataInfo;
/**
* 应用程序版本控制
*
* @author coin
* @date 2025-05-19
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/appVersion")
public class AppVersionController extends BaseController {
private final IAppVersionService iAppVersionService;
/**
* 查询应用程序版本控制列表
*/
@SaCheckPermission("business:appVersion:list")
@GetMapping("/list")
public TableDataInfo<AppVersionVo> list(AppVersionBo bo, PageQuery pageQuery) {
return iAppVersionService.queryPageList(bo, pageQuery);
}
/**
* 导出应用程序版本控制列表
*/
@SaCheckPermission("business:appVersion:export")
@Log(title = "应用程序版本控制", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(AppVersionBo bo, HttpServletResponse response) {
List<AppVersionVo> list = iAppVersionService.queryList(bo);
ExcelUtil.exportExcel(list, "应用程序版本控制", AppVersionVo.class, response);
}
/**
* 获取应用程序版本控制详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:appVersion:query")
@GetMapping("/{id}")
public R<AppVersionVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iAppVersionService.queryById(id));
}
/**
* 新增应用程序版本控制
*/
@SaCheckPermission("business:appVersion:add")
@Log(title = "应用程序版本控制", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody AppVersionBo bo) {
return toAjax(iAppVersionService.insertByBo(bo));
}
/**
* 修改应用程序版本控制
*/
@SaCheckPermission("business:appVersion:edit")
@Log(title = "应用程序版本控制", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody AppVersionBo bo) {
return toAjax(iAppVersionService.updateByBo(bo));
}
/**
* 删除应用程序版本控制
*
* @param ids 主键串
*/
@SaCheckPermission("business:appVersion:remove")
@Log(title = "应用程序版本控制", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iAppVersionService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/BehaviorModelInfoController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.BehaviorModelInfoVo;
import com.coin.business.domain.bo.BehaviorModelInfoBo;
import com.coin.business.service.IBehaviorModelInfoService;
import com.coin.common.core.page.TableDataInfo;
/**
* 模型管理信息
*
* @author coin
* @date 2025-05-19
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/behaviorModelInfo")
public class BehaviorModelInfoController extends BaseController {
private final IBehaviorModelInfoService iBehaviorModelInfoService;
/**
* 查询模型管理信息列表
*/
@SaCheckPermission("business:behaviorModelInfo:list")
@GetMapping("/list")
public TableDataInfo<BehaviorModelInfoVo> list(BehaviorModelInfoBo bo, PageQuery pageQuery) {
return iBehaviorModelInfoService.queryPageList(bo, pageQuery);
}
/**
* 导出模型管理信息列表
*/
@SaCheckPermission("business:behaviorModelInfo:export")
@Log(title = "模型管理信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BehaviorModelInfoBo bo, HttpServletResponse response) {
List<BehaviorModelInfoVo> list = iBehaviorModelInfoService.queryList(bo);
ExcelUtil.exportExcel(list, "模型管理信息", BehaviorModelInfoVo.class, response);
}
/**
* 获取模型管理信息详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:behaviorModelInfo:query")
@GetMapping("/{id}")
public R<BehaviorModelInfoVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iBehaviorModelInfoService.queryById(id));
}
/**
* 新增模型管理信息
*/
@SaCheckPermission("business:behaviorModelInfo:add")
@Log(title = "模型管理信息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BehaviorModelInfoBo bo) {
return toAjax(iBehaviorModelInfoService.insertByBo(bo));
}
/**
* 修改模型管理信息
*/
@SaCheckPermission("business:behaviorModelInfo:edit")
@Log(title = "模型管理信息", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BehaviorModelInfoBo bo) {
return toAjax(iBehaviorModelInfoService.updateByBo(bo));
}
/**
* 删除模型管理信息
*
* @param ids 主键串
*/
@SaCheckPermission("business:behaviorModelInfo:remove")
@Log(title = "模型管理信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iBehaviorModelInfoService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/CommonFeedbackController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.CommonFeedbackVo;
import com.coin.business.domain.bo.CommonFeedbackBo;
import com.coin.business.service.ICommonFeedbackService;
import com.coin.common.core.page.TableDataInfo;
/**
* 反馈信息
*
* @author coin
* @date 2025-02-21
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/commonFeedback")
public class CommonFeedbackController extends BaseController {
private final ICommonFeedbackService iCommonFeedbackService;
/**
* 查询反馈信息列表
*/
@SaCheckPermission("business:commonFeedback:list")
@GetMapping("/list")
public TableDataInfo<CommonFeedbackVo> list(CommonFeedbackBo bo, PageQuery pageQuery) {
return iCommonFeedbackService.queryPageList(bo, pageQuery);
}
/**
* 导出反馈信息列表
*/
@SaCheckPermission("business:commonFeedback:export")
@Log(title = "反馈信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(CommonFeedbackBo bo, HttpServletResponse response) {
List<CommonFeedbackVo> list = iCommonFeedbackService.queryList(bo);
ExcelUtil.exportExcel(list, "反馈信息", CommonFeedbackVo.class, response);
}
/**
* 获取反馈信息详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:commonFeedback:query")
@GetMapping("/{id}")
public R<CommonFeedbackVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iCommonFeedbackService.queryById(id));
}
/**
* 新增反馈信息
*/
@SaCheckPermission("business:commonFeedback:add")
@Log(title = "反馈信息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody CommonFeedbackBo bo) {
return toAjax(iCommonFeedbackService.insertByBo(bo));
}
/**
* 修改反馈信息
*/
@SaCheckPermission("business:commonFeedback:edit")
@Log(title = "反馈信息", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody CommonFeedbackBo bo) {
return toAjax(iCommonFeedbackService.updateByBo(bo));
}
/**
* 删除反馈信息
*
* @param ids 主键串
*/
@SaCheckPermission("business:commonFeedback:remove")
@Log(title = "反馈信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iCommonFeedbackService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/CommonInfoController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.CommonInfoVo;
import com.coin.business.domain.bo.CommonInfoBo;
import com.coin.business.service.ICommonInfoService;
import com.coin.common.core.page.TableDataInfo;
/**
* 关于信息
*
* @author coin
* @date 2025-02-21
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/commonInfo")
public class CommonInfoController extends BaseController {
private final ICommonInfoService iCommonInfoService;
/**
* 查询关于信息列表
*/
@SaCheckPermission("business:commonInfo:list")
@GetMapping("/list")
public TableDataInfo<CommonInfoVo> list(CommonInfoBo bo, PageQuery pageQuery) {
return iCommonInfoService.queryPageList(bo, pageQuery);
}
/**
* 导出关于信息列表
*/
@SaCheckPermission("business:commonInfo:export")
@Log(title = "关于信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(CommonInfoBo bo, HttpServletResponse response) {
List<CommonInfoVo> list = iCommonInfoService.queryList(bo);
ExcelUtil.exportExcel(list, "关于信息", CommonInfoVo.class, response);
}
/**
* 获取关于信息详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:commonInfo:query")
@GetMapping("/{id}")
public R<CommonInfoVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iCommonInfoService.queryById(id));
}
/**
* 新增关于信息
*/
@SaCheckPermission("business:commonInfo:add")
@Log(title = "关于信息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody CommonInfoBo bo) {
return toAjax(iCommonInfoService.insertByBo(bo));
}
/**
* 修改关于信息
*/
@SaCheckPermission("business:commonInfo:edit")
@Log(title = "关于信息", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody CommonInfoBo bo) {
return toAjax(iCommonInfoService.updateByBo(bo));
}
/**
* 删除关于信息
*
* @param ids 主键串
*/
@SaCheckPermission("business:commonInfo:remove")
@Log(title = "关于信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iCommonInfoService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/CommonLimitSettingController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.CommonLimitSettingVo;
import com.coin.business.domain.bo.CommonLimitSettingBo;
import com.coin.business.service.ICommonLimitSettingService;
import com.coin.common.core.page.TableDataInfo;
/**
* 阈值设置
*
* @author coin
* @date 2025-02-26
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/commonLimitSetting")
public class CommonLimitSettingController extends BaseController {
private final ICommonLimitSettingService iCommonLimitSettingService;
/**
* 查询阈值设置列表
*/
@SaCheckPermission("business:commonLimitSetting:list")
@GetMapping("/list")
public TableDataInfo<CommonLimitSettingVo> list(CommonLimitSettingBo bo, PageQuery pageQuery) {
return iCommonLimitSettingService.queryPageList(bo, pageQuery);
}
/**
* 导出阈值设置列表
*/
@SaCheckPermission("business:commonLimitSetting:export")
@Log(title = "阈值设置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(CommonLimitSettingBo bo, HttpServletResponse response) {
List<CommonLimitSettingVo> list = iCommonLimitSettingService.queryList(bo);
ExcelUtil.exportExcel(list, "阈值设置", CommonLimitSettingVo.class, response);
}
/**
* 获取阈值设置详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:commonLimitSetting:query")
@GetMapping("/{id}")
public R<CommonLimitSettingVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iCommonLimitSettingService.queryById(id));
}
/**
* 新增阈值设置
*/
@SaCheckPermission("business:commonLimitSetting:add")
@Log(title = "阈值设置", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody CommonLimitSettingBo bo) {
return toAjax(iCommonLimitSettingService.insertByBo(bo));
}
/**
* 修改阈值设置
*/
@SaCheckPermission("business:commonLimitSetting:edit")
@Log(title = "阈值设置", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody CommonLimitSettingBo bo) {
return toAjax(iCommonLimitSettingService.updateByBo(bo));
}
/**
* 删除阈值设置
*
* @param ids 主键串
*/
@SaCheckPermission("business:commonLimitSetting:remove")
@Log(title = "阈值设置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iCommonLimitSettingService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/CommonNotifyController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.CommonNotifyVo;
import com.coin.business.domain.bo.CommonNotifyBo;
import com.coin.business.service.ICommonNotifyService;
import com.coin.common.core.page.TableDataInfo;
/**
* 消息通知
*
* @author coin
* @date 2025-02-21
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/commonNotify")
public class CommonNotifyController extends BaseController {
private final ICommonNotifyService iCommonNotifyService;
/**
* 查询消息通知列表
*/
@SaCheckPermission("business:commonNotify:list")
@GetMapping("/list")
public TableDataInfo<CommonNotifyVo> list(CommonNotifyBo bo, PageQuery pageQuery) {
return iCommonNotifyService.queryPageList(bo, pageQuery);
}
/**
* 导出消息通知列表
*/
@SaCheckPermission("business:commonNotify:export")
@Log(title = "消息通知", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(CommonNotifyBo bo, HttpServletResponse response) {
List<CommonNotifyVo> list = iCommonNotifyService.queryList(bo);
ExcelUtil.exportExcel(list, "消息通知", CommonNotifyVo.class, response);
}
/**
* 获取消息通知详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:commonNotify:query")
@GetMapping("/{id}")
public R<CommonNotifyVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iCommonNotifyService.queryById(id));
}
/**
* 新增消息通知
*/
@SaCheckPermission("business:commonNotify:add")
@Log(title = "消息通知", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody CommonNotifyBo bo) {
return toAjax(iCommonNotifyService.insertByBo(bo));
}
/**
* 修改消息通知
*/
@SaCheckPermission("business:commonNotify:edit")
@Log(title = "消息通知", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody CommonNotifyBo bo) {
return toAjax(iCommonNotifyService.updateByBo(bo));
}
/**
* 删除消息通知
*
* @param ids 主键串
*/
@SaCheckPermission("business:commonNotify:remove")
@Log(title = "消息通知", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iCommonNotifyService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/CreditRuleController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.CreditRuleVo;
import com.coin.business.domain.bo.CreditRuleBo;
import com.coin.business.service.ICreditRuleService;
import com.coin.common.core.page.TableDataInfo;
/**
* 信用规则
*
* @author coin
* @date 2025-05-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/creditRule")
public class CreditRuleController extends BaseController {
private final ICreditRuleService iCreditRuleService;
/**
* 查询信用规则列表
*/
@SaCheckPermission("business:creditRule:list")
@GetMapping("/list")
public TableDataInfo<CreditRuleVo> list(CreditRuleBo bo, PageQuery pageQuery) {
return iCreditRuleService.queryPageList(bo, pageQuery);
}
/**
* 导出信用规则列表
*/
@SaCheckPermission("business:creditRule:export")
@Log(title = "信用规则", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(CreditRuleBo bo, HttpServletResponse response) {
List<CreditRuleVo> list = iCreditRuleService.queryList(bo);
ExcelUtil.exportExcel(list, "信用规则", CreditRuleVo.class, response);
}
/**
* 获取信用规则详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:creditRule:query")
@GetMapping("/{id}")
public R<CreditRuleVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iCreditRuleService.queryById(id));
}
/**
* 新增信用规则
*/
@SaCheckPermission("business:creditRule:add")
@Log(title = "信用规则", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody CreditRuleBo bo) {
return toAjax(iCreditRuleService.insertByBo(bo));
}
/**
* 修改信用规则
*/
@SaCheckPermission("business:creditRule:edit")
@Log(title = "信用规则", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody CreditRuleBo bo) {
return toAjax(iCreditRuleService.updateByBo(bo));
}
/**
* 删除信用规则
*
* @param ids 主键串
*/
@SaCheckPermission("business:creditRule:remove")
@Log(title = "信用规则", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iCreditRuleService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/CustomerServiceChatController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.CustomerServiceChatVo;
import com.coin.business.domain.bo.CustomerServiceChatBo;
import com.coin.business.service.ICustomerServiceChatService;
import com.coin.common.core.page.TableDataInfo;
/**
* 客服与用户的聊天记录
*
* @author coin
* @date 2025-05-19
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/customerServiceChat")
public class CustomerServiceChatController extends BaseController {
private final ICustomerServiceChatService iCustomerServiceChatService;
/**
* 查询客服与用户的聊天记录列表
*/
@SaCheckPermission("business:customerServiceChat:list")
@GetMapping("/list")
public TableDataInfo<CustomerServiceChatVo> list(CustomerServiceChatBo bo, PageQuery pageQuery) {
return iCustomerServiceChatService.queryPageList(bo, pageQuery);
}
/**
* 导出客服与用户的聊天记录列表
*/
@SaCheckPermission("business:customerServiceChat:export")
@Log(title = "客服与用户的聊天记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(CustomerServiceChatBo bo, HttpServletResponse response) {
List<CustomerServiceChatVo> list = iCustomerServiceChatService.queryList(bo);
ExcelUtil.exportExcel(list, "客服与用户的聊天记录", CustomerServiceChatVo.class, response);
}
/**
* 获取客服与用户的聊天记录详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:customerServiceChat:query")
@GetMapping("/{id}")
public R<CustomerServiceChatVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iCustomerServiceChatService.queryById(id));
}
/**
* 新增客服与用户的聊天记录
*/
@SaCheckPermission("business:customerServiceChat:add")
@Log(title = "客服与用户的聊天记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody CustomerServiceChatBo bo) {
return toAjax(iCustomerServiceChatService.insertByBo(bo));
}
/**
* 修改客服与用户的聊天记录
*/
@SaCheckPermission("business:customerServiceChat:edit")
@Log(title = "客服与用户的聊天记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody CustomerServiceChatBo bo) {
return toAjax(iCustomerServiceChatService.updateByBo(bo));
}
/**
* 删除客服与用户的聊天记录
*
* @param ids 主键串
*/
@SaCheckPermission("business:customerServiceChat:remove")
@Log(title = "客服与用户的聊天记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iCustomerServiceChatService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/DealPaymentController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.service.IDealPaymentService;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.DealPaymentVo;
import com.coin.business.domain.bo.DealPaymentBo;
import com.coin.common.core.page.TableDataInfo;
/**
* 付款订单
*
* @author coin
* @date 2025-05-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/dealPayment")
public class DealPaymentController extends BaseController {
private final IDealPaymentService iDealPaymentService;
/**
* 查询付款订单列表
*/
@SaCheckPermission("business:dealPayment:list")
@GetMapping("/list")
public TableDataInfo<DealPaymentVo> list(DealPaymentBo bo, PageQuery pageQuery) {
return iDealPaymentService.queryPageList(bo, pageQuery);
}
/**
* 导出付款订单列表
*/
@SaCheckPermission("business:dealPayment:export")
@Log(title = "付款订单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(DealPaymentBo bo, HttpServletResponse response) {
List<DealPaymentVo> list = iDealPaymentService.queryList(bo);
ExcelUtil.exportExcel(list, "付款订单", DealPaymentVo.class, response);
}
/**
* 获取付款订单详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:dealPayment:query")
@GetMapping("/{id}")
public R<DealPaymentVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iDealPaymentService.queryById(id));
}
/**
* 新增付款订单
*/
@SaCheckPermission("business:dealPayment:add")
@Log(title = "付款订单", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody DealPaymentBo bo) {
return toAjax(iDealPaymentService.insertByBo(bo));
}
/**
* 修改付款订单
*/
@SaCheckPermission("business:dealPayment:edit")
@Log(title = "付款订单", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody DealPaymentBo bo) {
return toAjax(iDealPaymentService.updateByBo(bo));
}
/**
* 删除付款订单
*
* @param ids 主键串
*/
@SaCheckPermission("business:dealPayment:remove")
@Log(title = "付款订单", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iDealPaymentService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/DealProxyController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.service.IDealProxyService;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.DealProxyVo;
import com.coin.business.domain.bo.DealProxyBo;
import com.coin.common.core.page.TableDataInfo;
/**
* 代缴订单
*
* @author coin
* @date 2025-05-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/dealProxy")
public class DealProxyController extends BaseController {
private final IDealProxyService iDealProxyService;
/**
* 查询代缴订单列表
*/
@SaCheckPermission("business:dealProxy:list")
@GetMapping("/list")
public TableDataInfo<DealProxyVo> list(DealProxyBo bo, PageQuery pageQuery) {
return iDealProxyService.queryPageList(bo, pageQuery);
}
/**
* 导出代缴订单列表
*/
@SaCheckPermission("business:dealProxy:export")
@Log(title = "代缴订单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(DealProxyBo bo, HttpServletResponse response) {
List<DealProxyVo> list = iDealProxyService.queryList(bo);
ExcelUtil.exportExcel(list, "代缴订单", DealProxyVo.class, response);
}
/**
* 获取代缴订单详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:dealProxy:query")
@GetMapping("/{id}")
public R<DealProxyVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iDealProxyService.queryById(id));
}
/**
* 新增代缴订单
*/
@SaCheckPermission("business:dealProxy:add")
@Log(title = "代缴订单", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody DealProxyBo bo) {
return toAjax(iDealProxyService.insertByBo(bo));
}
/**
* 修改代缴订单
*/
@SaCheckPermission("business:dealProxy:edit")
@Log(title = "代缴订单", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody DealProxyBo bo) {
return toAjax(iDealProxyService.updateByBo(bo));
}
/**
* 删除代缴订单
*
* @param ids 主键串
*/
@SaCheckPermission("business:dealProxy:remove")
@Log(title = "代缴订单", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iDealProxyService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/DealReceiptController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.service.IDealReceiptService;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.DealReceiptVo;
import com.coin.business.domain.bo.DealReceiptBo;
import com.coin.common.core.page.TableDataInfo;
/**
* 收款订单
*
* @author coin
* @date 2025-05-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/dealReceipt")
public class DealReceiptController extends BaseController {
private final IDealReceiptService iDealReceiptService;
/**
* 查询收款订单列表
*/
@SaCheckPermission("business:dealReceipt:list")
@GetMapping("/list")
public TableDataInfo<DealReceiptVo> list(DealReceiptBo bo, PageQuery pageQuery) {
return iDealReceiptService.queryPageList(bo, pageQuery);
}
/**
* 导出收款订单列表
*/
@SaCheckPermission("business:dealReceipt:export")
@Log(title = "收款订单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(DealReceiptBo bo, HttpServletResponse response) {
List<DealReceiptVo> list = iDealReceiptService.queryList(bo);
ExcelUtil.exportExcel(list, "收款订单", DealReceiptVo.class, response);
}
/**
* 获取收款订单详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:dealReceipt:query")
@GetMapping("/{id}")
public R<DealReceiptVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iDealReceiptService.queryById(id));
}
/**
* 新增收款订单
*/
@SaCheckPermission("business:dealReceipt:add")
@Log(title = "收款订单", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody DealReceiptBo bo) {
return toAjax(iDealReceiptService.insertByBo(bo));
}
/**
* 修改收款订单
*/
@SaCheckPermission("business:dealReceipt:edit")
@Log(title = "收款订单", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody DealReceiptBo bo) {
return toAjax(iDealReceiptService.updateByBo(bo));
}
/**
* 删除收款订单
*
* @param ids 主键串
*/
@SaCheckPermission("business:dealReceipt:remove")
@Log(title = "收款订单", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iDealReceiptService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/DealRechargeController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.service.IDealRechargeService;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.DealRechargeVo;
import com.coin.business.domain.bo.DealRechargeBo;
import com.coin.common.core.page.TableDataInfo;
/**
* 充值订单
*
* @author coin
* @date 2025-05-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/dealRecharge")
public class DealRechargeController extends BaseController {
private final IDealRechargeService iDealRechargeService;
/**
* 查询充值订单列表
*/
@SaCheckPermission("business:dealRecharge:list")
@GetMapping("/list")
public TableDataInfo<DealRechargeVo> list(DealRechargeBo bo, PageQuery pageQuery) {
return iDealRechargeService.queryPageList(bo, pageQuery);
}
/**
* 导出充值订单列表
*/
@SaCheckPermission("business:dealRecharge:export")
@Log(title = "充值订单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(DealRechargeBo bo, HttpServletResponse response) {
List<DealRechargeVo> list = iDealRechargeService.queryList(bo);
ExcelUtil.exportExcel(list, "充值订单", DealRechargeVo.class, response);
}
/**
* 获取充值订单详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:dealRecharge:query")
@GetMapping("/{id}")
public R<DealRechargeVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iDealRechargeService.queryById(id));
}
/**
* 新增充值订单
*/
@SaCheckPermission("business:dealRecharge:add")
@Log(title = "充值订单", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody DealRechargeBo bo) {
return toAjax(iDealRechargeService.insertByBo(bo));
}
/**
* 修改充值订单
*/
@SaCheckPermission("business:dealRecharge:edit")
@Log(title = "充值订单", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody DealRechargeBo bo) {
return toAjax(iDealRechargeService.updateByBo(bo));
}
/**
* 删除充值订单
*
* @param ids 主键串
*/
@SaCheckPermission("business:dealRecharge:remove")
@Log(title = "充值订单", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iDealRechargeService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/DealTransferController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.service.IDealTransferService;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.DealTransferVo;
import com.coin.business.domain.bo.DealTransferBo;
import com.coin.common.core.page.TableDataInfo;
/**
* 转账订单
*
* @author coin
* @date 2025-05-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/dealTransfer")
public class DealTransferController extends BaseController {
private final IDealTransferService iDealTransferService;
/**
* 查询转账订单列表
*/
@SaCheckPermission("business:dealTransfer:list")
@GetMapping("/list")
public TableDataInfo<DealTransferVo> list(DealTransferBo bo, PageQuery pageQuery) {
return iDealTransferService.queryPageList(bo, pageQuery);
}
/**
* 导出转账订单列表
*/
@SaCheckPermission("business:dealTransfer:export")
@Log(title = "转账订单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(DealTransferBo bo, HttpServletResponse response) {
List<DealTransferVo> list = iDealTransferService.queryList(bo);
ExcelUtil.exportExcel(list, "转账订单", DealTransferVo.class, response);
}
/**
* 获取转账订单详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:dealTransfer:query")
@GetMapping("/{id}")
public R<DealTransferVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iDealTransferService.queryById(id));
}
/**
* 新增转账订单
*/
@SaCheckPermission("business:dealTransfer:add")
@Log(title = "转账订单", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody DealTransferBo bo) {
return toAjax(iDealTransferService.insertByBo(bo));
}
/**
* 修改转账订单
*/
@SaCheckPermission("business:dealTransfer:edit")
@Log(title = "转账订单", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody DealTransferBo bo) {
return toAjax(iDealTransferService.updateByBo(bo));
}
/**
* 删除转账订单
*
* @param ids 主键串
*/
@SaCheckPermission("business:dealTransfer:remove")
@Log(title = "转账订单", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iDealTransferService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/DealWithdrawalController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.service.IDealWithdrawalService;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.DealWithdrawalVo;
import com.coin.business.domain.bo.DealWithdrawalBo;
import com.coin.common.core.page.TableDataInfo;
/**
* 提现订单
*
* @author coin
* @date 2025-05-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/dealWithdrawal")
public class DealWithdrawalController extends BaseController {
private final IDealWithdrawalService iDealWithdrawalService;
/**
* 查询提现订单列表
*/
@SaCheckPermission("business:dealWithdrawal:list")
@GetMapping("/list")
public TableDataInfo<DealWithdrawalVo> list(DealWithdrawalBo bo, PageQuery pageQuery) {
return iDealWithdrawalService.queryPageList(bo, pageQuery);
}
/**
* 导出提现订单列表
*/
@SaCheckPermission("business:dealWithdrawal:export")
@Log(title = "提现订单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(DealWithdrawalBo bo, HttpServletResponse response) {
List<DealWithdrawalVo> list = iDealWithdrawalService.queryList(bo);
ExcelUtil.exportExcel(list, "提现订单", DealWithdrawalVo.class, response);
}
/**
* 获取提现订单详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:dealWithdrawal:query")
@GetMapping("/{id}")
public R<DealWithdrawalVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iDealWithdrawalService.queryById(id));
}
/**
* 新增提现订单
*/
@SaCheckPermission("business:dealWithdrawal:add")
@Log(title = "提现订单", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody DealWithdrawalBo bo) {
return toAjax(iDealWithdrawalService.insertByBo(bo));
}
/**
* 修改提现订单
*/
@SaCheckPermission("business:dealWithdrawal:edit")
@Log(title = "提现订单", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody DealWithdrawalBo bo) {
return toAjax(iDealWithdrawalService.updateByBo(bo));
}
/**
* 删除提现订单
*
* @param ids 主键串
*/
@SaCheckPermission("business:dealWithdrawal:remove")
@Log(title = "提现订单", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iDealWithdrawalService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/FaqController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.FaqVo;
import com.coin.business.domain.bo.FaqBo;
import com.coin.business.service.IFaqService;
import com.coin.common.core.page.TableDataInfo;
/**
* 常见问题及答案
*
* @author coin
* @date 2025-05-19
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/faq")
public class FaqController extends BaseController {
private final IFaqService iFaqService;
/**
* 查询常见问题及答案列表
*/
@SaCheckPermission("business:faq:list")
@GetMapping("/list")
public TableDataInfo<FaqVo> list(FaqBo bo, PageQuery pageQuery) {
return iFaqService.queryPageList(bo, pageQuery);
}
/**
* 导出常见问题及答案列表
*/
@SaCheckPermission("business:faq:export")
@Log(title = "常见问题及答案", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(FaqBo bo, HttpServletResponse response) {
List<FaqVo> list = iFaqService.queryList(bo);
ExcelUtil.exportExcel(list, "常见问题及答案", FaqVo.class, response);
}
/**
* 获取常见问题及答案详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:faq:query")
@GetMapping("/{id}")
public R<FaqVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iFaqService.queryById(id));
}
/**
* 新增常见问题及答案
*/
@SaCheckPermission("business:faq:add")
@Log(title = "常见问题及答案", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody FaqBo bo) {
return toAjax(iFaqService.insertByBo(bo));
}
/**
* 修改常见问题及答案
*/
@SaCheckPermission("business:faq:edit")
@Log(title = "常见问题及答案", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody FaqBo bo) {
return toAjax(iFaqService.updateByBo(bo));
}
/**
* 删除常见问题及答案
*
* @param ids 主键串
*/
@SaCheckPermission("business:faq:remove")
@Log(title = "常见问题及答案", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iFaqService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/FeeRecordController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.service.IFeeRecordService;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.FeeRecordVo;
import com.coin.business.domain.bo.FeeRecordBo;
import com.coin.common.core.page.TableDataInfo;
/**
* 手续费记录
*
* @author coin
* @date 2025-05-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/feeRecord")
public class FeeRecordController extends BaseController {
private final IFeeRecordService iFeeRecordService;
/**
* 查询手续费记录列表
*/
@SaCheckPermission("business:feeRecord:list")
@GetMapping("/list")
public TableDataInfo<FeeRecordVo> list(FeeRecordBo bo, PageQuery pageQuery) {
return iFeeRecordService.queryPageList(bo, pageQuery);
}
/**
* 导出手续费记录列表
*/
@SaCheckPermission("business:feeRecord:export")
@Log(title = "手续费记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(FeeRecordBo bo, HttpServletResponse response) {
List<FeeRecordVo> list = iFeeRecordService.queryList(bo);
ExcelUtil.exportExcel(list, "手续费记录", FeeRecordVo.class, response);
}
/**
* 获取手续费记录详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:feeRecord:query")
@GetMapping("/{id}")
public R<FeeRecordVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iFeeRecordService.queryById(id));
}
/**
* 新增手续费记录
*/
@SaCheckPermission("business:feeRecord:add")
@Log(title = "手续费记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody FeeRecordBo bo) {
return toAjax(iFeeRecordService.insertByBo(bo));
}
/**
* 修改手续费记录
*/
@SaCheckPermission("business:feeRecord:edit")
@Log(title = "手续费记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody FeeRecordBo bo) {
return toAjax(iFeeRecordService.updateByBo(bo));
}
/**
* 删除手续费记录
*
* @param ids 主键串
*/
@SaCheckPermission("business:feeRecord:remove")
@Log(title = "手续费记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iFeeRecordService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/FeeStandardController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.service.IFeeStandardService;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.FeeStandardVo;
import com.coin.business.domain.bo.FeeStandardBo;
import com.coin.common.core.page.TableDataInfo;
/**
* 手续费规则
*
* @author coin
* @date 2025-05-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/feeStandard")
public class FeeStandardController extends BaseController {
private final IFeeStandardService iFeeStandardService;
/**
* 查询手续费规则列表
*/
@SaCheckPermission("business:feeStandard:list")
@GetMapping("/list")
public TableDataInfo<FeeStandardVo> list(FeeStandardBo bo, PageQuery pageQuery) {
return iFeeStandardService.queryPageList(bo, pageQuery);
}
/**
* 导出手续费规则列表
*/
@SaCheckPermission("business:feeStandard:export")
@Log(title = "手续费规则", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(FeeStandardBo bo, HttpServletResponse response) {
List<FeeStandardVo> list = iFeeStandardService.queryList(bo);
ExcelUtil.exportExcel(list, "手续费规则", FeeStandardVo.class, response);
}
/**
* 获取手续费规则详细信息
*
* @param feeStandardId 主键
*/
@SaCheckPermission("business:feeStandard:query")
@GetMapping("/{feeStandardId}")
public R<FeeStandardVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable String feeStandardId) {
return R.ok(iFeeStandardService.queryById(feeStandardId));
}
/**
* 新增手续费规则
*/
@SaCheckPermission("business:feeStandard:add")
@Log(title = "手续费规则", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody FeeStandardBo bo) {
return toAjax(iFeeStandardService.insertByBo(bo));
}
/**
* 修改手续费规则
*/
@SaCheckPermission("business:feeStandard:edit")
@Log(title = "手续费规则", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody FeeStandardBo bo) {
return toAjax(iFeeStandardService.updateByBo(bo));
}
/**
* 删除手续费规则
*
* @param feeStandardIds 主键串
*/
@SaCheckPermission("business:feeStandard:remove")
@Log(title = "手续费规则", businessType = BusinessType.DELETE)
@DeleteMapping("/{feeStandardIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable String[] feeStandardIds) {
return toAjax(iFeeStandardService.deleteWithValidByIds(Arrays.asList(feeStandardIds), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/FinancialRecordController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.FinancialRecordVo;
import com.coin.business.domain.bo.FinancialRecordBo;
import com.coin.business.service.IFinancialRecordService;
import com.coin.common.core.page.TableDataInfo;
/**
* 财务记录
*
* @author coin
* @date 2025-05-19
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/financialRecord")
public class FinancialRecordController extends BaseController {
private final IFinancialRecordService iFinancialRecordService;
/**
* 查询财务记录列表
*/
@SaCheckPermission("business:financialRecord:list")
@GetMapping("/list")
public TableDataInfo<FinancialRecordVo> list(FinancialRecordBo bo, PageQuery pageQuery) {
return iFinancialRecordService.queryPageList(bo, pageQuery);
}
/**
* 导出财务记录列表
*/
@SaCheckPermission("business:financialRecord:export")
@Log(title = "财务记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(FinancialRecordBo bo, HttpServletResponse response) {
List<FinancialRecordVo> list = iFinancialRecordService.queryList(bo);
ExcelUtil.exportExcel(list, "财务记录", FinancialRecordVo.class, response);
}
/**
* 获取财务记录详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:financialRecord:query")
@GetMapping("/{id}")
public R<FinancialRecordVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iFinancialRecordService.queryById(id));
}
/**
* 新增财务记录
*/
@SaCheckPermission("business:financialRecord:add")
@Log(title = "财务记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody FinancialRecordBo bo) {
return toAjax(iFinancialRecordService.insertByBo(bo));
}
/**
* 修改财务记录
*/
@SaCheckPermission("business:financialRecord:edit")
@Log(title = "财务记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody FinancialRecordBo bo) {
return toAjax(iFinancialRecordService.updateByBo(bo));
}
/**
* 删除财务记录
*
* @param ids 主键串
*/
@SaCheckPermission("business:financialRecord:remove")
@Log(title = "财务记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iFinancialRecordService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

121
coin-admin/src/main/java/com/coin/business/controller/MerchantVerificationController.java

@ -0,0 +1,121 @@
package com.coin.business.controller;
import java.util.Date;
import java.util.List;
import java.util.Arrays;
import com.coin.business.domain.bo.UserVerificationBo;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.MerchantVerificationVo;
import com.coin.business.domain.bo.MerchantVerificationBo;
import com.coin.business.service.IMerchantVerificationService;
import com.coin.common.core.page.TableDataInfo;
/**
* 商户认证信息
*
* @author coin
* @date 2025-05-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/merchantVerification")
public class MerchantVerificationController extends BaseController {
private final IMerchantVerificationService iMerchantVerificationService;
/**
* 查询商户认证信息列表
*/
@SaCheckPermission("business:merchantVerification:list")
@GetMapping("/list")
public TableDataInfo<MerchantVerificationVo> list(MerchantVerificationBo bo, PageQuery pageQuery) {
return iMerchantVerificationService.queryPageList(bo, pageQuery);
}
/**
* 导出商户认证信息列表
*/
@SaCheckPermission("business:merchantVerification:export")
@Log(title = "商户认证信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(MerchantVerificationBo bo, HttpServletResponse response) {
List<MerchantVerificationVo> list = iMerchantVerificationService.queryList(bo);
ExcelUtil.exportExcel(list, "商户认证信息", MerchantVerificationVo.class, response);
}
/**
* 获取商户认证信息详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:merchantVerification:query")
@GetMapping("/{id}")
public R<MerchantVerificationVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iMerchantVerificationService.queryById(id));
}
/**
* 新增商户认证信息
*/
@SaCheckPermission("business:merchantVerification:add")
@Log(title = "商户认证信息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody MerchantVerificationBo bo) {
return toAjax(iMerchantVerificationService.insertByBo(bo));
}
/**
* 修改商户认证信息
*/
@SaCheckPermission("business:merchantVerification:edit")
@Log(title = "商户认证信息", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody MerchantVerificationBo bo) {
return toAjax(iMerchantVerificationService.updateByBo(bo));
}
/**
* 删除商户认证信息
*
* @param ids 主键串
*/
@SaCheckPermission("business:merchantVerification:remove")
@Log(title = "商户认证信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iMerchantVerificationService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 实名认证审核
* @param bo
* @return
*/
@SaCheckPermission("business:merchantVerification:audit")
@Log(title = "认证审核", businessType = BusinessType.UPDATE)
@PostMapping("/merchantVerificationAudit")
public R<Void> merchantVerificationAudit(@RequestBody MerchantVerificationBo bo) {
return toAjax(iMerchantVerificationService.merchantVerificationAudit(bo));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/RecordPayCallbackController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.RecordPayCallbackVo;
import com.coin.business.domain.bo.RecordPayCallbackBo;
import com.coin.business.service.IRecordPayCallbackService;
import com.coin.common.core.page.TableDataInfo;
/**
* 支付回执
*
* @author coin
* @date 2025-05-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/recordPayCallback")
public class RecordPayCallbackController extends BaseController {
private final IRecordPayCallbackService iRecordPayCallbackService;
/**
* 查询支付回执列表
*/
@SaCheckPermission("business:recordPayCallback:list")
@GetMapping("/list")
public TableDataInfo<RecordPayCallbackVo> list(RecordPayCallbackBo bo, PageQuery pageQuery) {
return iRecordPayCallbackService.queryPageList(bo, pageQuery);
}
/**
* 导出支付回执列表
*/
@SaCheckPermission("business:recordPayCallback:export")
@Log(title = "支付回执", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(RecordPayCallbackBo bo, HttpServletResponse response) {
List<RecordPayCallbackVo> list = iRecordPayCallbackService.queryList(bo);
ExcelUtil.exportExcel(list, "支付回执", RecordPayCallbackVo.class, response);
}
/**
* 获取支付回执详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:recordPayCallback:query")
@GetMapping("/{id}")
public R<RecordPayCallbackVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iRecordPayCallbackService.queryById(id));
}
/**
* 新增支付回执
*/
@SaCheckPermission("business:recordPayCallback:add")
@Log(title = "支付回执", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody RecordPayCallbackBo bo) {
return toAjax(iRecordPayCallbackService.insertByBo(bo));
}
/**
* 修改支付回执
*/
@SaCheckPermission("business:recordPayCallback:edit")
@Log(title = "支付回执", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody RecordPayCallbackBo bo) {
return toAjax(iRecordPayCallbackService.updateByBo(bo));
}
/**
* 删除支付回执
*
* @param ids 主键串
*/
@SaCheckPermission("business:recordPayCallback:remove")
@Log(title = "支付回执", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iRecordPayCallbackService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/RecordTransactionController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.service.IRecordTransactionService;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.RecordTransactionVo;
import com.coin.business.domain.bo.RecordTransactionBo;
import com.coin.common.core.page.TableDataInfo;
/**
* 交易动账记录
*
* @author coin
* @date 2025-05-15
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/recordTransaction")
public class RecordTransactionController extends BaseController {
private final IRecordTransactionService iRecordTransactionService;
/**
* 查询交易动账记录列表
*/
@SaCheckPermission("business:recordTransaction:list")
@GetMapping("/list")
public TableDataInfo<RecordTransactionVo> list(RecordTransactionBo bo, PageQuery pageQuery) {
return iRecordTransactionService.queryPageList(bo, pageQuery);
}
/**
* 导出交易动账记录列表
*/
@SaCheckPermission("business:recordTransaction:export")
@Log(title = "交易动账记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(RecordTransactionBo bo, HttpServletResponse response) {
List<RecordTransactionVo> list = iRecordTransactionService.queryList(bo);
ExcelUtil.exportExcel(list, "交易动账记录", RecordTransactionVo.class, response);
}
/**
* 获取交易动账记录详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:recordTransaction:query")
@GetMapping("/{id}")
public R<RecordTransactionVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iRecordTransactionService.queryById(id));
}
/**
* 新增交易动账记录
*/
@SaCheckPermission("business:recordTransaction:add")
@Log(title = "交易动账记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody RecordTransactionBo bo) {
return toAjax(iRecordTransactionService.insertByBo(bo));
}
/**
* 修改交易动账记录
*/
@SaCheckPermission("business:recordTransaction:edit")
@Log(title = "交易动账记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody RecordTransactionBo bo) {
return toAjax(iRecordTransactionService.updateByBo(bo));
}
/**
* 删除交易动账记录
*
* @param ids 主键串
*/
@SaCheckPermission("business:recordTransaction:remove")
@Log(title = "交易动账记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iRecordTransactionService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/TradingChannelController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.TradingChannelVo;
import com.coin.business.domain.bo.TradingChannelBo;
import com.coin.business.service.ITradingChannelService;
import com.coin.common.core.page.TableDataInfo;
/**
* 交易通道/渠道
*
* @author coin
* @date 2025-05-19
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/tradingChannel")
public class TradingChannelController extends BaseController {
private final ITradingChannelService iTradingChannelService;
/**
* 查询交易通道/渠道列表
*/
@SaCheckPermission("business:tradingChannel:list")
@GetMapping("/list")
public TableDataInfo<TradingChannelVo> list(TradingChannelBo bo, PageQuery pageQuery) {
return iTradingChannelService.queryPageList(bo, pageQuery);
}
/**
* 导出交易通道/渠道列表
*/
@SaCheckPermission("business:tradingChannel:export")
@Log(title = "交易通道/渠道", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(TradingChannelBo bo, HttpServletResponse response) {
List<TradingChannelVo> list = iTradingChannelService.queryList(bo);
ExcelUtil.exportExcel(list, "交易通道/渠道", TradingChannelVo.class, response);
}
/**
* 获取交易通道/渠道详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:tradingChannel:query")
@GetMapping("/{id}")
public R<TradingChannelVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iTradingChannelService.queryById(id));
}
/**
* 新增交易通道/渠道
*/
@SaCheckPermission("business:tradingChannel:add")
@Log(title = "交易通道/渠道", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody TradingChannelBo bo) {
return toAjax(iTradingChannelService.insertByBo(bo));
}
/**
* 修改交易通道/渠道
*/
@SaCheckPermission("business:tradingChannel:edit")
@Log(title = "交易通道/渠道", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TradingChannelBo bo) {
return toAjax(iTradingChannelService.updateByBo(bo));
}
/**
* 删除交易通道/渠道
*
* @param ids 主键串
*/
@SaCheckPermission("business:tradingChannel:remove")
@Log(title = "交易通道/渠道", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iTradingChannelService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/TradingChannelRecordController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.TradingChannelRecordVo;
import com.coin.business.domain.bo.TradingChannelRecordBo;
import com.coin.business.service.ITradingChannelRecordService;
import com.coin.common.core.page.TableDataInfo;
/**
* 交易通道记录
*
* @author coin
* @date 2025-05-19
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/tradingChannelRecord")
public class TradingChannelRecordController extends BaseController {
private final ITradingChannelRecordService iTradingChannelRecordService;
/**
* 查询交易通道记录列表
*/
@SaCheckPermission("business:tradingChannelRecord:list")
@GetMapping("/list")
public TableDataInfo<TradingChannelRecordVo> list(TradingChannelRecordBo bo, PageQuery pageQuery) {
return iTradingChannelRecordService.queryPageList(bo, pageQuery);
}
/**
* 导出交易通道记录列表
*/
@SaCheckPermission("business:tradingChannelRecord:export")
@Log(title = "交易通道记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(TradingChannelRecordBo bo, HttpServletResponse response) {
List<TradingChannelRecordVo> list = iTradingChannelRecordService.queryList(bo);
ExcelUtil.exportExcel(list, "交易通道记录", TradingChannelRecordVo.class, response);
}
/**
* 获取交易通道记录详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:tradingChannelRecord:query")
@GetMapping("/{id}")
public R<TradingChannelRecordVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iTradingChannelRecordService.queryById(id));
}
/**
* 新增交易通道记录
*/
@SaCheckPermission("business:tradingChannelRecord:add")
@Log(title = "交易通道记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody TradingChannelRecordBo bo) {
return toAjax(iTradingChannelRecordService.insertByBo(bo));
}
/**
* 修改交易通道记录
*/
@SaCheckPermission("business:tradingChannelRecord:edit")
@Log(title = "交易通道记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TradingChannelRecordBo bo) {
return toAjax(iTradingChannelRecordService.updateByBo(bo));
}
/**
* 删除交易通道记录
*
* @param ids 主键串
*/
@SaCheckPermission("business:tradingChannelRecord:remove")
@Log(title = "交易通道记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iTradingChannelRecordService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

105
coin-admin/src/main/java/com/coin/business/controller/UserAccountController.java

@ -0,0 +1,105 @@
package com.coin.business.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.coin.business.domain.bo.UserAccountBo;
import com.coin.business.domain.vo.UserAccountVo;
import com.coin.business.service.IUserAccountService;
import com.coin.common.annotation.Log;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 用户账户
*
* @author coin
* @date 2025-05-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userAccount")
public class UserAccountController extends BaseController {
private final IUserAccountService iUserAccountService;
/**
* 查询用户账户列表
*/
@SaCheckPermission("business:userAccount:list")
@GetMapping("/list")
public TableDataInfo<UserAccountVo> list(UserAccountBo bo, PageQuery pageQuery) {
return iUserAccountService.queryPageList(bo, pageQuery);
}
/**
* 导出用户账户列表
*/
@SaCheckPermission("business:userAccount:export")
@Log(title = "用户账户", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserAccountBo bo, HttpServletResponse response) {
List<UserAccountVo> list = iUserAccountService.queryList(bo);
ExcelUtil.exportExcel(list, "用户账户", UserAccountVo.class, response);
}
/**
* 获取用户账户详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userAccount:query")
@GetMapping("/{id}")
public R<UserAccountVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserAccountService.queryById(id));
}
/**
* 新增用户账户
*/
@SaCheckPermission("business:userAccount:add")
@Log(title = "用户账户", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserAccountBo bo) {
return toAjax(iUserAccountService.insertByBo(bo));
}
/**
* 修改用户账户
*/
@SaCheckPermission("business:userAccount:edit")
@Log(title = "用户账户", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserAccountBo bo) {
return toAjax(iUserAccountService.updateByBo(bo));
}
/**
* 冻结用户账户
* 解冻用户账户
*
* @param bo
*/
@SaCheckPermission("business:userAccount:remove")
@Log(title = "用户账户冻结或解冻", businessType = BusinessType.DELETE)
@DeleteMapping("/lockAccount")
public R<Void> lockAccount(@RequestBody UserAccountBo bo) {
return toAjax(iUserAccountService.accountLockOrUnlock(bo));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserBehaviorLogController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserBehaviorLogVo;
import com.coin.business.domain.bo.UserBehaviorLogBo;
import com.coin.business.service.IUserBehaviorLogService;
import com.coin.common.core.page.TableDataInfo;
/**
* 用户行为日志
*
* @author coin
* @date 2025-05-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userBehaviorLog")
public class UserBehaviorLogController extends BaseController {
private final IUserBehaviorLogService iUserBehaviorLogService;
/**
* 查询用户行为日志列表
*/
@SaCheckPermission("business:userBehaviorLog:list")
@GetMapping("/list")
public TableDataInfo<UserBehaviorLogVo> list(UserBehaviorLogBo bo, PageQuery pageQuery) {
return iUserBehaviorLogService.queryPageList(bo, pageQuery);
}
/**
* 导出用户行为日志列表
*/
@SaCheckPermission("business:userBehaviorLog:export")
@Log(title = "用户行为日志", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserBehaviorLogBo bo, HttpServletResponse response) {
List<UserBehaviorLogVo> list = iUserBehaviorLogService.queryList(bo);
ExcelUtil.exportExcel(list, "用户行为日志", UserBehaviorLogVo.class, response);
}
/**
* 获取用户行为日志详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userBehaviorLog:query")
@GetMapping("/{id}")
public R<UserBehaviorLogVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserBehaviorLogService.queryById(id));
}
/**
* 新增用户行为日志
*/
@SaCheckPermission("business:userBehaviorLog:add")
@Log(title = "用户行为日志", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserBehaviorLogBo bo) {
return toAjax(iUserBehaviorLogService.insertByBo(bo));
}
/**
* 修改用户行为日志
*/
@SaCheckPermission("business:userBehaviorLog:edit")
@Log(title = "用户行为日志", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserBehaviorLogBo bo) {
return toAjax(iUserBehaviorLogService.updateByBo(bo));
}
/**
* 删除用户行为日志
*
* @param ids 主键串
*/
@SaCheckPermission("business:userBehaviorLog:remove")
@Log(title = "用户行为日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserBehaviorLogService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserBehaviorRuleActionController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserBehaviorRuleActionVo;
import com.coin.business.domain.bo.UserBehaviorRuleActionBo;
import com.coin.business.service.IUserBehaviorRuleActionService;
import com.coin.common.core.page.TableDataInfo;
/**
* 处置规则
*
* @author coin
* @date 2025-05-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userBehaviorRuleAction")
public class UserBehaviorRuleActionController extends BaseController {
private final IUserBehaviorRuleActionService iUserBehaviorRuleActionService;
/**
* 查询处置规则列表
*/
@SaCheckPermission("business:userBehaviorRuleAction:list")
@GetMapping("/list")
public TableDataInfo<UserBehaviorRuleActionVo> list(UserBehaviorRuleActionBo bo, PageQuery pageQuery) {
return iUserBehaviorRuleActionService.queryPageList(bo, pageQuery);
}
/**
* 导出处置规则列表
*/
@SaCheckPermission("business:userBehaviorRuleAction:export")
@Log(title = "处置规则", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserBehaviorRuleActionBo bo, HttpServletResponse response) {
List<UserBehaviorRuleActionVo> list = iUserBehaviorRuleActionService.queryList(bo);
ExcelUtil.exportExcel(list, "处置规则", UserBehaviorRuleActionVo.class, response);
}
/**
* 获取处置规则详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userBehaviorRuleAction:query")
@GetMapping("/{id}")
public R<UserBehaviorRuleActionVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserBehaviorRuleActionService.queryById(id));
}
/**
* 新增处置规则
*/
@SaCheckPermission("business:userBehaviorRuleAction:add")
@Log(title = "处置规则", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserBehaviorRuleActionBo bo) {
return toAjax(iUserBehaviorRuleActionService.insertByBo(bo));
}
/**
* 修改处置规则
*/
@SaCheckPermission("business:userBehaviorRuleAction:edit")
@Log(title = "处置规则", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserBehaviorRuleActionBo bo) {
return toAjax(iUserBehaviorRuleActionService.updateByBo(bo));
}
/**
* 删除处置规则
*
* @param ids 主键串
*/
@SaCheckPermission("business:userBehaviorRuleAction:remove")
@Log(title = "处置规则", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserBehaviorRuleActionService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserBehaviorRuleRiskController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserBehaviorRuleRiskVo;
import com.coin.business.domain.bo.UserBehaviorRuleRiskBo;
import com.coin.business.service.IUserBehaviorRuleRiskService;
import com.coin.common.core.page.TableDataInfo;
/**
* 风险识别规则
*
* @author coin
* @date 2025-05-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userBehaviorRuleRisk")
public class UserBehaviorRuleRiskController extends BaseController {
private final IUserBehaviorRuleRiskService iUserBehaviorRuleRiskService;
/**
* 查询风险识别规则列表
*/
@SaCheckPermission("business:userBehaviorRuleRisk:list")
@GetMapping("/list")
public TableDataInfo<UserBehaviorRuleRiskVo> list(UserBehaviorRuleRiskBo bo, PageQuery pageQuery) {
return iUserBehaviorRuleRiskService.queryPageList(bo, pageQuery);
}
/**
* 导出风险识别规则列表
*/
@SaCheckPermission("business:userBehaviorRuleRisk:export")
@Log(title = "风险识别规则", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserBehaviorRuleRiskBo bo, HttpServletResponse response) {
List<UserBehaviorRuleRiskVo> list = iUserBehaviorRuleRiskService.queryList(bo);
ExcelUtil.exportExcel(list, "风险识别规则", UserBehaviorRuleRiskVo.class, response);
}
/**
* 获取风险识别规则详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userBehaviorRuleRisk:query")
@GetMapping("/{id}")
public R<UserBehaviorRuleRiskVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserBehaviorRuleRiskService.queryById(id));
}
/**
* 新增风险识别规则
*/
@SaCheckPermission("business:userBehaviorRuleRisk:add")
@Log(title = "风险识别规则", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserBehaviorRuleRiskBo bo) {
return toAjax(iUserBehaviorRuleRiskService.insertByBo(bo));
}
/**
* 修改风险识别规则
*/
@SaCheckPermission("business:userBehaviorRuleRisk:edit")
@Log(title = "风险识别规则", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserBehaviorRuleRiskBo bo) {
return toAjax(iUserBehaviorRuleRiskService.updateByBo(bo));
}
/**
* 删除风险识别规则
*
* @param ids 主键串
*/
@SaCheckPermission("business:userBehaviorRuleRisk:remove")
@Log(title = "风险识别规则", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserBehaviorRuleRiskService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserBehaviorStatsController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserBehaviorStatsVo;
import com.coin.business.domain.bo.UserBehaviorStatsBo;
import com.coin.business.service.IUserBehaviorStatsService;
import com.coin.common.core.page.TableDataInfo;
/**
* 用户行为统计聚合
*
* @author coin
* @date 2025-05-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userBehaviorStats")
public class UserBehaviorStatsController extends BaseController {
private final IUserBehaviorStatsService iUserBehaviorStatsService;
/**
* 查询用户行为统计聚合列表
*/
@SaCheckPermission("business:userBehaviorStats:list")
@GetMapping("/list")
public TableDataInfo<UserBehaviorStatsVo> list(UserBehaviorStatsBo bo, PageQuery pageQuery) {
return iUserBehaviorStatsService.queryPageList(bo, pageQuery);
}
/**
* 导出用户行为统计聚合列表
*/
@SaCheckPermission("business:userBehaviorStats:export")
@Log(title = "用户行为统计聚合", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserBehaviorStatsBo bo, HttpServletResponse response) {
List<UserBehaviorStatsVo> list = iUserBehaviorStatsService.queryList(bo);
ExcelUtil.exportExcel(list, "用户行为统计聚合", UserBehaviorStatsVo.class, response);
}
/**
* 获取用户行为统计聚合详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userBehaviorStats:query")
@GetMapping("/{id}")
public R<UserBehaviorStatsVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserBehaviorStatsService.queryById(id));
}
/**
* 新增用户行为统计聚合
*/
@SaCheckPermission("business:userBehaviorStats:add")
@Log(title = "用户行为统计聚合", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserBehaviorStatsBo bo) {
return toAjax(iUserBehaviorStatsService.insertByBo(bo));
}
/**
* 修改用户行为统计聚合
*/
@SaCheckPermission("business:userBehaviorStats:edit")
@Log(title = "用户行为统计聚合", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserBehaviorStatsBo bo) {
return toAjax(iUserBehaviorStatsService.updateByBo(bo));
}
/**
* 删除用户行为统计聚合
*
* @param ids 主键串
*/
@SaCheckPermission("business:userBehaviorStats:remove")
@Log(title = "用户行为统计聚合", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserBehaviorStatsService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserCardController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserCardVo;
import com.coin.business.domain.bo.UserCardBo;
import com.coin.business.service.IUserCardService;
import com.coin.common.core.page.TableDataInfo;
/**
* 用户银行卡
*
* @author coin
* @date 2025-05-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userCard")
public class UserCardController extends BaseController {
private final IUserCardService iUserCardService;
/**
* 查询用户银行卡列表
*/
@SaCheckPermission("business:userCard:list")
@GetMapping("/list")
public TableDataInfo<UserCardVo> list(UserCardBo bo, PageQuery pageQuery) {
return iUserCardService.queryPageList(bo, pageQuery);
}
/**
* 导出用户银行卡列表
*/
@SaCheckPermission("business:userCard:export")
@Log(title = "用户银行卡", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserCardBo bo, HttpServletResponse response) {
List<UserCardVo> list = iUserCardService.queryList(bo);
ExcelUtil.exportExcel(list, "用户银行卡", UserCardVo.class, response);
}
/**
* 获取用户银行卡详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userCard:query")
@GetMapping("/{id}")
public R<UserCardVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserCardService.queryById(id));
}
/**
* 新增用户银行卡
*/
@SaCheckPermission("business:userCard:add")
@Log(title = "用户银行卡", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserCardBo bo) {
return iUserCardService.insertByBo(bo);
}
/**
* 修改用户银行卡
*/
@SaCheckPermission("business:userCard:edit")
@Log(title = "用户银行卡", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserCardBo bo) {
return toAjax(iUserCardService.updateByBo(bo));
}
/**
* 删除用户银行卡
*
* @param ids 主键串
*/
@SaCheckPermission("business:userCard:remove")
@Log(title = "用户银行卡", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserCardService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserCreditController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserCreditVo;
import com.coin.business.domain.bo.UserCreditBo;
import com.coin.business.service.IUserCreditService;
import com.coin.common.core.page.TableDataInfo;
/**
* 信用
*
* @author coin
* @date 2025-05-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userCredit")
public class UserCreditController extends BaseController {
private final IUserCreditService iUserCreditService;
/**
* 查询信用列表
*/
@SaCheckPermission("business:userCredit:list")
@GetMapping("/list")
public TableDataInfo<UserCreditVo> list(UserCreditBo bo, PageQuery pageQuery) {
return iUserCreditService.queryPageList(bo, pageQuery);
}
/**
* 导出信用列表
*/
@SaCheckPermission("business:userCredit:export")
@Log(title = "信用", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserCreditBo bo, HttpServletResponse response) {
List<UserCreditVo> list = iUserCreditService.queryList(bo);
ExcelUtil.exportExcel(list, "信用", UserCreditVo.class, response);
}
/**
* 获取信用详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userCredit:query")
@GetMapping("/{id}")
public R<UserCreditVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserCreditService.queryById(id));
}
/**
* 新增信用
*/
@SaCheckPermission("business:userCredit:add")
@Log(title = "信用", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserCreditBo bo) {
return toAjax(iUserCreditService.insertByBo(bo));
}
/**
* 修改信用
*/
@SaCheckPermission("business:userCredit:edit")
@Log(title = "信用", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserCreditBo bo) {
return toAjax(iUserCreditService.updateByBo(bo));
}
/**
* 删除信用
*
* @param ids 主键串
*/
@SaCheckPermission("business:userCredit:remove")
@Log(title = "信用", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserCreditService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserCreditRecordController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserCreditRecordVo;
import com.coin.business.domain.bo.UserCreditRecordBo;
import com.coin.business.service.IUserCreditRecordService;
import com.coin.common.core.page.TableDataInfo;
/**
* 信用记录
*
* @author coin
* @date 2025-05-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userCreditRecord")
public class UserCreditRecordController extends BaseController {
private final IUserCreditRecordService iUserCreditRecordService;
/**
* 查询信用记录列表
*/
@SaCheckPermission("business:userCreditRecord:list")
@GetMapping("/list")
public TableDataInfo<UserCreditRecordVo> list(UserCreditRecordBo bo, PageQuery pageQuery) {
return iUserCreditRecordService.queryPageList(bo, pageQuery);
}
/**
* 导出信用记录列表
*/
@SaCheckPermission("business:userCreditRecord:export")
@Log(title = "信用记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserCreditRecordBo bo, HttpServletResponse response) {
List<UserCreditRecordVo> list = iUserCreditRecordService.queryList(bo);
ExcelUtil.exportExcel(list, "信用记录", UserCreditRecordVo.class, response);
}
/**
* 获取信用记录详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userCreditRecord:query")
@GetMapping("/{id}")
public R<UserCreditRecordVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserCreditRecordService.queryById(id));
}
/**
* 新增信用记录
*/
@SaCheckPermission("business:userCreditRecord:add")
@Log(title = "信用记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserCreditRecordBo bo) {
return toAjax(iUserCreditRecordService.insertByBo(bo));
}
/**
* 修改信用记录
*/
@SaCheckPermission("business:userCreditRecord:edit")
@Log(title = "信用记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserCreditRecordBo bo) {
return toAjax(iUserCreditRecordService.updateByBo(bo));
}
/**
* 删除信用记录
*
* @param ids 主键串
*/
@SaCheckPermission("business:userCreditRecord:remove")
@Log(title = "信用记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserCreditRecordService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserFriendController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserFriendVo;
import com.coin.business.domain.bo.UserFriendBo;
import com.coin.business.service.IUserFriendService;
import com.coin.common.core.page.TableDataInfo;
/**
* 用户好友
*
* @author coin
* @date 2025-05-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userFriend")
public class UserFriendController extends BaseController {
private final IUserFriendService iUserFriendService;
/**
* 查询用户好友列表
*/
@SaCheckPermission("business:userFriend:list")
@GetMapping("/list")
public TableDataInfo<UserFriendVo> list(UserFriendBo bo, PageQuery pageQuery) {
return iUserFriendService.queryPageList(bo, pageQuery);
}
/**
* 导出用户好友列表
*/
@SaCheckPermission("business:userFriend:export")
@Log(title = "用户好友", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserFriendBo bo, HttpServletResponse response) {
List<UserFriendVo> list = iUserFriendService.queryList(bo);
ExcelUtil.exportExcel(list, "用户好友", UserFriendVo.class, response);
}
/**
* 获取用户好友详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userFriend:query")
@GetMapping("/{id}")
public R<UserFriendVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserFriendService.queryById(id));
}
/**
* 新增用户好友
*/
@SaCheckPermission("business:userFriend:add")
@Log(title = "用户好友", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserFriendBo bo) {
return toAjax(iUserFriendService.insertByBo(bo));
}
/**
* 修改用户好友
*/
@SaCheckPermission("business:userFriend:edit")
@Log(title = "用户好友", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserFriendBo bo) {
return toAjax(iUserFriendService.updateByBo(bo));
}
/**
* 删除用户好友
*
* @param ids 主键串
*/
@SaCheckPermission("business:userFriend:remove")
@Log(title = "用户好友", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserFriendService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserInfoAgentController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserInfoAgentVo;
import com.coin.business.domain.bo.UserInfoAgentBo;
import com.coin.business.service.IUserInfoAgentService;
import com.coin.common.core.page.TableDataInfo;
/**
* 代理商信息
*
* @author coin
* @date 2025-05-24
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userInfoAgent")
public class UserInfoAgentController extends BaseController {
private final IUserInfoAgentService iUserInfoAgentService;
/**
* 查询代理商信息列表
*/
@SaCheckPermission("business:userInfoAgent:list")
@GetMapping("/list")
public TableDataInfo<UserInfoAgentVo> list(UserInfoAgentBo bo, PageQuery pageQuery) {
return iUserInfoAgentService.queryPageList(bo, pageQuery);
}
/**
* 导出代理商信息列表
*/
@SaCheckPermission("business:userInfoAgent:export")
@Log(title = "代理商信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserInfoAgentBo bo, HttpServletResponse response) {
List<UserInfoAgentVo> list = iUserInfoAgentService.queryList(bo);
ExcelUtil.exportExcel(list, "代理商信息", UserInfoAgentVo.class, response);
}
/**
* 获取代理商信息详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userInfoAgent:query")
@GetMapping("/{id}")
public R<UserInfoAgentVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserInfoAgentService.queryById(id));
}
/**
* 新增代理商信息
*/
@SaCheckPermission("business:userInfoAgent:add")
@Log(title = "代理商信息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserInfoAgentBo bo) {
return toAjax(iUserInfoAgentService.insertByBo(bo));
}
/**
* 修改代理商信息
*/
@SaCheckPermission("business:userInfoAgent:edit")
@Log(title = "代理商信息", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserInfoAgentBo bo) {
return toAjax(iUserInfoAgentService.updateByBo(bo));
}
/**
* 删除代理商信息
*
* @param ids 主键串
*/
@SaCheckPermission("business:userInfoAgent:remove")
@Log(title = "代理商信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserInfoAgentService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserInfoBusController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserInfoBusVo;
import com.coin.business.domain.bo.UserInfoBusBo;
import com.coin.business.service.IUserInfoBusService;
import com.coin.common.core.page.TableDataInfo;
/**
* 用户信息-商户扩展
*
* @author coin
* @date 2025-05-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userInfoBus")
public class UserInfoBusController extends BaseController {
private final IUserInfoBusService iUserInfoBusService;
/**
* 查询用户信息-商户扩展列表
*/
@SaCheckPermission("business:userInfoBus:list")
@GetMapping("/list")
public TableDataInfo<UserInfoBusVo> list(UserInfoBusBo bo, PageQuery pageQuery) {
return iUserInfoBusService.queryPageList(bo, pageQuery);
}
/**
* 导出用户信息-商户扩展列表
*/
@SaCheckPermission("business:userInfoBus:export")
@Log(title = "用户信息-商户扩展", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserInfoBusBo bo, HttpServletResponse response) {
List<UserInfoBusVo> list = iUserInfoBusService.queryList(bo);
ExcelUtil.exportExcel(list, "用户信息-商户扩展", UserInfoBusVo.class, response);
}
/**
* 获取用户信息-商户扩展详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userInfoBus:query")
@GetMapping("/{id}")
public R<UserInfoBusVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserInfoBusService.queryById(id));
}
/**
* 新增用户信息-商户扩展
*/
@SaCheckPermission("business:userInfoBus:add")
@Log(title = "用户信息-商户扩展", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserInfoBusBo bo) {
return toAjax(iUserInfoBusService.insertByBo(bo));
}
/**
* 修改用户信息-商户扩展
*/
@SaCheckPermission("business:userInfoBus:edit")
@Log(title = "用户信息-商户扩展", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserInfoBusBo bo) {
return toAjax(iUserInfoBusService.updateByBo(bo));
}
/**
* 删除用户信息-商户扩展
*
* @param ids 主键串
*/
@SaCheckPermission("business:userInfoBus:remove")
@Log(title = "用户信息-商户扩展", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserInfoBusService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserInfoController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserInfoVo;
import com.coin.business.domain.bo.UserInfoBo;
import com.coin.business.service.IUserInfoService;
import com.coin.common.core.page.TableDataInfo;
/**
* 用户信息
*
* @author coin
* @date 2025-05-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userInfo")
public class UserInfoController extends BaseController {
private final IUserInfoService iUserInfoService;
/**
* 查询用户信息列表
*/
@SaCheckPermission("business:userInfo:list")
@GetMapping("/list")
public TableDataInfo<UserInfoVo> list(UserInfoBo bo, PageQuery pageQuery) {
return iUserInfoService.queryPageList(bo, pageQuery);
}
/**
* 导出用户信息列表
*/
@SaCheckPermission("business:userInfo:export")
@Log(title = "用户信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserInfoBo bo, HttpServletResponse response) {
List<UserInfoVo> list = iUserInfoService.queryList(bo);
ExcelUtil.exportExcel(list, "用户信息", UserInfoVo.class, response);
}
/**
* 获取用户信息详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userInfo:query")
@GetMapping("/{id}")
public R<UserInfoVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserInfoService.queryById(id));
}
/**
* 新增用户信息
*/
@SaCheckPermission("business:userInfo:add")
@Log(title = "用户信息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserInfoBo bo) {
return toAjax(iUserInfoService.insertByBo(bo));
}
/**
* 修改用户信息
*/
@SaCheckPermission("business:userInfo:edit")
@Log(title = "用户信息", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserInfoBo bo) {
return toAjax(iUserInfoService.updateByBo(bo));
}
/**
* 删除用户信息
*
* @param ids 主键串
*/
@SaCheckPermission("business:userInfo:remove")
@Log(title = "用户信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserInfoService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/UserPasswdController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserPasswdVo;
import com.coin.business.domain.bo.UserPasswdBo;
import com.coin.business.service.IUserPasswdService;
import com.coin.common.core.page.TableDataInfo;
/**
* 用户密码
*
* @author coin
* @date 2025-05-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userPasswd")
public class UserPasswdController extends BaseController {
private final IUserPasswdService iUserPasswdService;
/**
* 查询用户密码列表
*/
@SaCheckPermission("business:userPasswd:list")
@GetMapping("/list")
public TableDataInfo<UserPasswdVo> list(UserPasswdBo bo, PageQuery pageQuery) {
return iUserPasswdService.queryPageList(bo, pageQuery);
}
/**
* 导出用户密码列表
*/
@SaCheckPermission("business:userPasswd:export")
@Log(title = "用户密码", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserPasswdBo bo, HttpServletResponse response) {
List<UserPasswdVo> list = iUserPasswdService.queryList(bo);
ExcelUtil.exportExcel(list, "用户密码", UserPasswdVo.class, response);
}
/**
* 获取用户密码详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userPasswd:query")
@GetMapping("/{id}")
public R<UserPasswdVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserPasswdService.queryById(id));
}
/**
* 新增用户密码
*/
@SaCheckPermission("business:userPasswd:add")
@Log(title = "用户密码", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserPasswdBo bo) {
return toAjax(iUserPasswdService.insertByBo(bo));
}
/**
* 修改用户密码
*/
@SaCheckPermission("business:userPasswd:edit")
@Log(title = "用户密码", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserPasswdBo bo) {
return toAjax(iUserPasswdService.updateByBo(bo));
}
/**
* 删除用户密码
*
* @param ids 主键串
*/
@SaCheckPermission("business:userPasswd:remove")
@Log(title = "用户密码", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserPasswdService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

164
coin-admin/src/main/java/com/coin/business/controller/UserRegisterController.java

@ -0,0 +1,164 @@
package com.coin.business.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.secure.BCrypt;
import com.coin.business.domain.bo.UserRegisterBo;
import com.coin.business.domain.vo.UserRegisterAgentVo;
import com.coin.business.domain.vo.UserRegisterVo;
import com.coin.business.service.IUserRegisterService;
import com.coin.common.annotation.Log;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.PasswordUtils;
import com.coin.common.utils.poi.ExcelUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
/**
* 用户注册
*
* @author coin
* @date 2025-05-09
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userRegister")
public class UserRegisterController extends BaseController {
private final IUserRegisterService iUserRegisterService;
/**
* 查询用户注册列表-个人用户
*/
@SaCheckPermission("business:userRegister:list")
@GetMapping("/list")
public TableDataInfo<UserRegisterVo> list(UserRegisterBo bo, PageQuery pageQuery) {
//个人用户
bo.setUserType("0");
return iUserRegisterService.queryPageListRegister(bo, pageQuery);
}
/**
* 查询用户注册列表-商企用户
*/
@SaCheckPermission("business:userRegister:listBus")
@GetMapping("/listBus")
public TableDataInfo<UserRegisterVo> listBus(UserRegisterBo bo, PageQuery pageQuery) {
//商企用户
bo.setUserType("1");
return iUserRegisterService.queryPageListRegister(bo, pageQuery);
}
/**
* 查询用户注册列表-代理商
*/
@SaCheckPermission("business:userRegister:listAgent")
@GetMapping("/listAgent")
public TableDataInfo<UserRegisterAgentVo> listAgent(UserRegisterBo bo, PageQuery pageQuery) {
//商企用户
bo.setUserType("2");
return iUserRegisterService.queryPageListRegisterAgent(bo, pageQuery);
}
/**
* 导出用户注册列表
*/
@SaCheckPermission("business:userRegister:export")
@Log(title = "用户注册", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserRegisterBo bo, HttpServletResponse response) {
List<UserRegisterVo> list = iUserRegisterService.queryList(bo);
ExcelUtil.exportExcel(list, "用户注册", UserRegisterVo.class, response);
}
/**
* 获取用户注册详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userRegister:query")
@GetMapping("/{id}")
public R<UserRegisterVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserRegisterService.queryById(id));
}
/**
* 新增用户注册
*/
@SaCheckPermission("business:userRegister:add")
@Log(title = "用户注册", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserRegisterBo bo) {
//随机生成8位高安全度密码,开发阶段,密码先定死为Coin123654
String pw = PasswordUtils.getSecurePassword();
bo.setPasswd(BCrypt.hashpw("Coin123654"));
return toAjax(iUserRegisterService.insertByBo(bo));
}
/**
* 修改用户注册
*/
@SaCheckPermission("business:userRegister:edit")
@Log(title = "修改用户", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserRegisterBo bo) {
bo.setPasswd(BCrypt.hashpw(bo.getPasswd()));
return toAjax(iUserRegisterService.updateByBo(bo));
}
/**
* 删除用户注册
*
* @param ids 主键串
*/
@SaCheckPermission("business:userRegister:remove")
@Log(title = "用户注册", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserRegisterService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 密码重置
* @param id
* @return
*/
@SaCheckPermission("business:userRegister:edit")
@Log(title = "重置密码", businessType = BusinessType.UPDATE)
@PostMapping("/passwordReset")
public R<Void> passwordReset(@RequestBody Long id) {
//随机生成8位高安全度密码,开发阶段,密码先定死为Coin123654
String pw = PasswordUtils.getSecurePassword();
return toAjax(iUserRegisterService.passwordReset(id, BCrypt.hashpw("Coin123654")));
}
/**
* 账号冻结
* @param bo
* @return
*/
@SaCheckPermission("business:userRegister:edit")
@Log(title = "账号冻结", businessType = BusinessType.UPDATE)
@PostMapping("/accountLock")
public R<Void> accountLock(@RequestBody UserRegisterBo bo) {
return toAjax(iUserRegisterService.accountLock(bo.getId(),bo.getStatus()));
}
}

119
coin-admin/src/main/java/com/coin/business/controller/UserVerificationController.java

@ -0,0 +1,119 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import com.coin.business.domain.bo.UserRegisterBo;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.UserVerificationVo;
import com.coin.business.domain.bo.UserVerificationBo;
import com.coin.business.service.IUserVerificationService;
import com.coin.common.core.page.TableDataInfo;
/**
* 实名认证
*
* @author coin
* @date 2025-05-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/userVerification")
public class UserVerificationController extends BaseController {
private final IUserVerificationService iUserVerificationService;
/**
* 查询实名认证列表
*/
@SaCheckPermission("business:userVerification:list")
@GetMapping("/list")
public TableDataInfo<UserVerificationVo> list(UserVerificationBo bo, PageQuery pageQuery) {
return iUserVerificationService.queryPageList(bo, pageQuery);
}
/**
* 导出实名认证列表
*/
@SaCheckPermission("business:userVerification:export")
@Log(title = "实名认证", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserVerificationBo bo, HttpServletResponse response) {
List<UserVerificationVo> list = iUserVerificationService.queryList(bo);
ExcelUtil.exportExcel(list, "实名认证", UserVerificationVo.class, response);
}
/**
* 获取实名认证详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:userVerification:query")
@GetMapping("/{id}")
public R<UserVerificationVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserVerificationService.queryById(id));
}
/**
* 新增实名认证
*/
@SaCheckPermission("business:userVerification:add")
@Log(title = "实名认证", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserVerificationBo bo) {
return toAjax(iUserVerificationService.insertByBo(bo));
}
/**
* 修改实名认证
*/
@SaCheckPermission("business:userVerification:edit")
@Log(title = "实名认证", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserVerificationBo bo) {
return toAjax(iUserVerificationService.updateByBo(bo));
}
/**
* 删除实名认证
*
* @param ids 主键串
*/
@SaCheckPermission("business:userVerification:remove")
@Log(title = "实名认证", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserVerificationService.deleteWithValidByIds(Arrays.asList(ids), true));
}
/**
* 实名认证审核
* @param bo
* @return
*/
@SaCheckPermission("business:userVerification:audit")
@Log(title = "认证审核", businessType = BusinessType.UPDATE)
@PostMapping("/userVerificationAudit")
public R<Void> userVerificationAudit(@RequestBody UserVerificationBo bo) {
return toAjax(iUserVerificationService.userVerificationAudit(bo));
}
}

106
coin-admin/src/main/java/com/coin/business/controller/WalletLimitConfigController.java

@ -0,0 +1,106 @@
package com.coin.business.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.business.domain.vo.WalletLimitConfigVo;
import com.coin.business.domain.bo.WalletLimitConfigBo;
import com.coin.business.service.IWalletLimitConfigService;
import com.coin.common.core.page.TableDataInfo;
/**
* 钱包限制配置
*
* @author coin
* @date 2025-05-30
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/walletLimitConfig")
public class WalletLimitConfigController extends BaseController {
private final IWalletLimitConfigService iWalletLimitConfigService;
/**
* 查询钱包限制配置列表
*/
@SaCheckPermission("business:walletLimitConfig:list")
@GetMapping("/list")
public TableDataInfo<WalletLimitConfigVo> list(WalletLimitConfigBo bo, PageQuery pageQuery) {
return iWalletLimitConfigService.queryPageList(bo, pageQuery);
}
/**
* 导出钱包限制配置列表
*/
@SaCheckPermission("business:walletLimitConfig:export")
@Log(title = "钱包限制配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(WalletLimitConfigBo bo, HttpServletResponse response) {
List<WalletLimitConfigVo> list = iWalletLimitConfigService.queryList(bo);
ExcelUtil.exportExcel(list, "钱包限制配置", WalletLimitConfigVo.class, response);
}
/**
* 获取钱包限制配置详细信息
*
* @param id 主键
*/
@SaCheckPermission("business:walletLimitConfig:query")
@GetMapping("/{id}")
public R<WalletLimitConfigVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iWalletLimitConfigService.queryById(id));
}
/**
* 新增钱包限制配置
*/
@SaCheckPermission("business:walletLimitConfig:add")
@Log(title = "钱包限制配置", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody WalletLimitConfigBo bo) {
return toAjax(iWalletLimitConfigService.insertByBo(bo));
}
/**
* 修改钱包限制配置
*/
@SaCheckPermission("business:walletLimitConfig:edit")
@Log(title = "钱包限制配置", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WalletLimitConfigBo bo) {
return toAjax(iWalletLimitConfigService.updateByBo(bo));
}
/**
* 删除钱包限制配置
*
* @param ids 主键串
*/
@SaCheckPermission("business:walletLimitConfig:remove")
@Log(title = "钱包限制配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iWalletLimitConfigService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

134
coin-admin/src/main/java/com/coin/web/controller/common/CaptchaController.java

@ -0,0 +1,134 @@
package com.coin.web.controller.common;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.coin.common.constant.CacheConstants;
import com.coin.common.constant.Constants;
import com.coin.common.core.domain.R;
import com.coin.common.enums.CaptchaType;
import com.coin.common.utils.StringUtils;
import com.coin.common.utils.email.MailUtils;
import com.coin.common.utils.redis.RedisUtils;
import com.coin.common.utils.reflect.ReflectUtils;
import com.coin.common.utils.spring.SpringUtils;
import com.coin.framework.config.properties.CaptchaProperties;
import com.coin.framework.config.properties.MailProperties;
import com.coin.system.service.ISysConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.dromara.sms4j.provider.enumerate.SupplierType;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.NotBlank;
import java.time.Duration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 验证码操作处理
*
* @author Lion Li
*/
@SaIgnore
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
public class CaptchaController {
private final CaptchaProperties captchaProperties;
private final ISysConfigService configService;
private final MailProperties mailProperties;
/**
* 短信验证码
*
* @param phonenumber 用户手机号
*/
@GetMapping("/captchaSms")
public R<Void> smsCaptcha(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) {
String key = CacheConstants.CAPTCHA_CODE_KEY + phonenumber;
String code = RandomUtil.randomNumbers(4);
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
// 验证码模板id 自行处理 (查数据库或写死均可)
String templateId = "";
LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
map.put("code", code);
SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA);
SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, templateId, map);
if (!"OK".equals(smsResponse.getCode())) {
log.error("验证码短信发送异常 => {}", smsResponse);
return R.fail(smsResponse.getMessage());
}
return R.ok();
}
/**
* 邮箱验证码
*
* @param email 邮箱
*/
@GetMapping("/captchaEmail")
public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) {
if (!mailProperties.getEnabled()) {
return R.fail("当前系统没有开启邮箱功能!");
}
String key = CacheConstants.CAPTCHA_CODE_KEY + email;
String code = RandomUtil.randomNumbers(4);
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
try {
MailUtils.sendText(email, "登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。");
} catch (Exception e) {
log.error("验证码短信发送异常 => {}", e.getMessage());
return R.fail(e.getMessage());
}
return R.ok();
}
/**
* 生成验证码
*/
@GetMapping("/captchaImage")
public R<Map<String, Object>> getCode() {
Map<String, Object> ajax = new HashMap<>();
boolean captchaEnabled = configService.selectCaptchaEnabled();
ajax.put("captchaEnabled", captchaEnabled);
if (!captchaEnabled) {
return R.ok(ajax);
}
// 保存验证码信息
String uuid = IdUtil.simpleUUID();
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
// 生成验证码
CaptchaType captchaType = captchaProperties.getType();
boolean isMath = CaptchaType.MATH == captchaType;
Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
captcha.setGenerator(codeGenerator);
captcha.createCode();
String code = captcha.getCode();
if (isMath) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
code = exp.getValue(String.class);
}
RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
ajax.put("uuid", uuid);
ajax.put("img", captcha.getImageBase64());
return R.ok(ajax);
}
}

168
coin-admin/src/main/java/com/coin/web/controller/monitor/CacheController.java

@ -0,0 +1,168 @@
package com.coin.web.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import com.coin.common.constant.CacheConstants;
import com.coin.common.constant.CacheNames;
import com.coin.common.core.domain.R;
import com.coin.common.utils.JsonUtils;
import com.coin.common.utils.StringUtils;
import com.coin.common.utils.redis.CacheUtils;
import com.coin.common.utils.redis.RedisUtils;
import com.coin.system.domain.SysCache;
import lombok.RequiredArgsConstructor;
import org.redisson.spring.data.connection.RedissonConnectionFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.stream.Collectors;
/**
* 缓存监控
*
* @author Lion Li
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/monitor/cache")
public class CacheController {
private final RedissonConnectionFactory connectionFactory;
private final static List<SysCache> CACHES = new ArrayList<>();
static {
CACHES.add(new SysCache(CacheConstants.ONLINE_TOKEN_KEY, "在线用户"));
CACHES.add(new SysCache(CacheNames.SYS_CONFIG, "配置信息"));
CACHES.add(new SysCache(CacheNames.SYS_DICT, "数据字典"));
CACHES.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));
CACHES.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交"));
CACHES.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理"));
CACHES.add(new SysCache(CacheNames.SYS_OSS_CONFIG, "OSS配置"));
CACHES.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
}
/**
* 获取缓存监控列表
*/
@SaCheckPermission("monitor:cache:list")
@GetMapping()
public R<Map<String, Object>> getInfo() throws Exception {
RedisConnection connection = connectionFactory.getConnection();
Properties info = connection.info();
Properties commandStats = connection.info("commandstats");
Long dbSize = connection.dbSize();
Map<String, Object> result = new HashMap<>(3);
result.put("info", info);
result.put("dbSize", dbSize);
List<Map<String, String>> pieList = new ArrayList<>();
if (commandStats != null) {
commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(2);
String property = commandStats.getProperty(key);
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
pieList.add(data);
});
}
result.put("commandStats", pieList);
return R.ok(result);
}
/**
* 获取缓存监控缓存名列表
*/
@SaCheckPermission("monitor:cache:list")
@GetMapping("/getNames")
public R<List<SysCache>> cache() {
return R.ok(CACHES);
}
/**
* 获取缓存监控Key列表
*
* @param cacheName 缓存名
*/
@SaCheckPermission("monitor:cache:list")
@GetMapping("/getKeys/{cacheName}")
public R<Collection<String>> getCacheKeys(@PathVariable String cacheName) {
Collection<String> cacheKeys = new HashSet<>(0);
if (isCacheNames(cacheName)) {
Set<Object> keys = CacheUtils.keys(cacheName);
if (CollUtil.isNotEmpty(keys)) {
cacheKeys = keys.stream().map(Object::toString).collect(Collectors.toList());
}
} else {
cacheKeys = RedisUtils.keys(cacheName + "*");
}
return R.ok(cacheKeys);
}
/**
* 获取缓存监控缓存值详情
*
* @param cacheName 缓存名
* @param cacheKey 缓存key
*/
@SaCheckPermission("monitor:cache:list")
@GetMapping("/getValue/{cacheName}/{cacheKey}")
public R<SysCache> getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) {
Object cacheValue;
if (isCacheNames(cacheName)) {
cacheValue = CacheUtils.get(cacheName, cacheKey);
} else {
cacheValue = RedisUtils.getCacheObject(cacheKey);
}
SysCache sysCache = new SysCache(cacheName, cacheKey, JsonUtils.toJsonString(cacheValue));
return R.ok(sysCache);
}
/**
* 清理缓存监控缓存名
*
* @param cacheName 缓存名
*/
@SaCheckPermission("monitor:cache:list")
@DeleteMapping("/clearCacheName/{cacheName}")
public R<Void> clearCacheName(@PathVariable String cacheName) {
if (isCacheNames(cacheName)) {
CacheUtils.clear(cacheName);
} else {
RedisUtils.deleteKeys(cacheName + "*");
}
return R.ok();
}
/**
* 清理缓存监控Key
*
* @param cacheKey key名
*/
@SaCheckPermission("monitor:cache:list")
@DeleteMapping("/clearCacheKey/{cacheName}/{cacheKey}")
public R<Void> clearCacheKey(@PathVariable String cacheName, @PathVariable String cacheKey) {
if (isCacheNames(cacheName)) {
CacheUtils.evict(cacheName, cacheKey);
} else {
RedisUtils.deleteObject(cacheKey);
}
return R.ok();
}
/**
* 清理全部缓存监控
*/
@SaCheckPermission("monitor:cache:list")
@DeleteMapping("/clearCacheAll")
public R<Void> clearCacheAll() {
RedisUtils.deleteKeys("*");
return R.ok();
}
private boolean isCacheNames(String cacheName) {
return !StringUtils.contains(cacheName, ":");
}
}

88
coin-admin/src/main/java/com/coin/web/controller/monitor/SysLogininforController.java

@ -0,0 +1,88 @@
package com.coin.web.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.coin.common.annotation.Log;
import com.coin.common.constant.CacheConstants;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.common.utils.redis.RedisUtils;
import com.coin.system.domain.SysLogininfor;
import com.coin.system.service.ISysLogininforService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 系统访问记录
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController {
private final ISysLogininforService logininforService;
/**
* 获取系统访问记录列表
*/
@SaCheckPermission("monitor:logininfor:list")
@GetMapping("/list")
public TableDataInfo<SysLogininfor> list(SysLogininfor logininfor, PageQuery pageQuery) {
return logininforService.selectPageLogininforList(logininfor, pageQuery);
}
/**
* 导出系统访问记录列表
*/
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
@SaCheckPermission("monitor:logininfor:export")
@PostMapping("/export")
public void export(SysLogininfor logininfor, HttpServletResponse response) {
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
ExcelUtil.exportExcel(list, "登录日志", SysLogininfor.class, response);
}
/**
* 批量删除登录日志
* @param infoIds 日志ids
*/
@SaCheckPermission("monitor:logininfor:remove")
@Log(title = "登录日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{infoIds}")
public R<Void> remove(@PathVariable Long[] infoIds) {
return toAjax(logininforService.deleteLogininforByIds(infoIds));
}
/**
* 清理系统访问记录
*/
@SaCheckPermission("monitor:logininfor:remove")
@Log(title = "登录日志", businessType = BusinessType.CLEAN)
@DeleteMapping("/clean")
public R<Void> clean() {
logininforService.cleanLogininfor();
return R.ok();
}
@SaCheckPermission("monitor:logininfor:unlock")
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
@GetMapping("/unlock/{userName}")
public R<Void> unlock(@PathVariable("userName") String userName) {
String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName;
if (RedisUtils.hasKey(loginName)) {
RedisUtils.deleteObject(loginName);
}
return R.ok();
}
}

74
coin-admin/src/main/java/com/coin/web/controller/monitor/SysOperlogController.java

@ -0,0 +1,74 @@
package com.coin.web.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.system.domain.SysOperLog;
import com.coin.system.service.ISysOperLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 操作日志记录
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController {
private final ISysOperLogService operLogService;
/**
* 获取操作日志记录列表
*/
@SaCheckPermission("monitor:operlog:list")
@GetMapping("/list")
public TableDataInfo<SysOperLog> list(SysOperLog operLog, PageQuery pageQuery) {
return operLogService.selectPageOperLogList(operLog, pageQuery);
}
/**
* 导出操作日志记录列表
*/
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
@SaCheckPermission("monitor:operlog:export")
@PostMapping("/export")
public void export(SysOperLog operLog, HttpServletResponse response) {
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
ExcelUtil.exportExcel(list, "操作日志", SysOperLog.class, response);
}
/**
* 批量删除操作日志记录
* @param operIds 日志ids
*/
@Log(title = "操作日志", businessType = BusinessType.DELETE)
@SaCheckPermission("monitor:operlog:remove")
@DeleteMapping("/{operIds}")
public R<Void> remove(@PathVariable Long[] operIds) {
return toAjax(operLogService.deleteOperLogByIds(operIds));
}
/**
* 清理操作日志记录
*/
@Log(title = "操作日志", businessType = BusinessType.CLEAN)
@SaCheckPermission("monitor:operlog:remove")
@DeleteMapping("/clean")
public R<Void> clean() {
operLogService.cleanOperLog();
return R.ok();
}
}

90
coin-admin/src/main/java/com/coin/web/controller/monitor/SysUserOnlineController.java

@ -0,0 +1,90 @@
package com.coin.web.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.coin.common.annotation.Log;
import com.coin.common.constant.CacheConstants;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.dto.UserOnlineDTO;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.StreamUtils;
import com.coin.common.utils.StringUtils;
import com.coin.common.utils.redis.RedisUtils;
import com.coin.system.domain.SysUserOnline;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 在线用户监控
*
* @author Lion Li
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/monitor/online")
public class SysUserOnlineController extends BaseController {
/**
* 获取在线用户监控列表
*
* @param ipaddr IP地址
* @param userName 用户名
*/
@SaCheckPermission("monitor:online:list")
@GetMapping("/list")
public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) {
// 获取所有未过期的 token
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>();
for (String key : keys) {
String token = StringUtils.substringAfterLast(key, ":");
// 如果已经过期则跳过
if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) {
continue;
}
userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token));
}
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
StringUtils.equals(ipaddr, userOnline.getIpaddr()) &&
StringUtils.equals(userName, userOnline.getUserName())
);
} else if (StringUtils.isNotEmpty(ipaddr)) {
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
StringUtils.equals(ipaddr, userOnline.getIpaddr())
);
} else if (StringUtils.isNotEmpty(userName)) {
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
StringUtils.equals(userName, userOnline.getUserName())
);
}
Collections.reverse(userOnlineDTOList);
userOnlineDTOList.removeAll(Collections.singleton(null));
List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class);
return TableDataInfo.build(userOnlineList);
}
/**
* 强退用户
*
* @param tokenId token值
*/
@SaCheckPermission("monitor:online:forceLogout")
@Log(title = "在线用户", businessType = BusinessType.FORCE)
@DeleteMapping("/{tokenId}")
public R<Void> forceLogout(@PathVariable String tokenId) {
try {
StpUtil.kickoutByTokenValue(tokenId);
} catch (NotLoginException ignored) {
}
return R.ok();
}
}

137
coin-admin/src/main/java/com/coin/web/controller/system/SysConfigController.java

@ -0,0 +1,137 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.coin.common.annotation.Log;
import com.coin.common.constant.UserConstants;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.system.domain.SysConfig;
import com.coin.system.service.ISysConfigService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 参数配置 信息操作处理
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/config")
public class SysConfigController extends BaseController {
private final ISysConfigService configService;
/**
* 获取参数配置列表
*/
@SaCheckPermission("system:config:list")
@GetMapping("/list")
public TableDataInfo<SysConfig> list(SysConfig config, PageQuery pageQuery) {
return configService.selectPageConfigList(config, pageQuery);
}
/**
* 导出参数配置列表
*/
@Log(title = "参数管理", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:config:export")
@PostMapping("/export")
public void export(SysConfig config, HttpServletResponse response) {
List<SysConfig> list = configService.selectConfigList(config);
ExcelUtil.exportExcel(list, "参数数据", SysConfig.class, response);
}
/**
* 根据参数编号获取详细信息
*
* @param configId 参数ID
*/
@SaCheckPermission("system:config:query")
@GetMapping(value = "/{configId}")
public R<SysConfig> getInfo(@PathVariable Long configId) {
return R.ok(configService.selectConfigById(configId));
}
/**
* 根据参数键名查询参数值
*
* @param configKey 参数Key
*/
@GetMapping(value = "/configKey/{configKey}")
public R<Void> getConfigKey(@PathVariable String configKey) {
return R.ok(configService.selectConfigByKey(configKey));
}
/**
* 新增参数配置
*/
@SaCheckPermission("system:config:add")
@Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysConfig config) {
if (!configService.checkConfigKeyUnique(config)) {
return R.fail("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
configService.insertConfig(config);
return R.ok();
}
/**
* 修改参数配置
*/
@SaCheckPermission("system:config:edit")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysConfig config) {
if (!configService.checkConfigKeyUnique(config)) {
return R.fail("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
configService.updateConfig(config);
return R.ok();
}
/**
* 根据参数键名修改参数配置
*/
@SaCheckPermission("system:config:edit")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PutMapping("/updateByKey")
public R<Void> updateByKey(@RequestBody SysConfig config) {
configService.updateConfig(config);
return R.ok();
}
/**
* 删除参数配置
*
* @param configIds 参数ID串
*/
@SaCheckPermission("system:config:remove")
@Log(title = "参数管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{configIds}")
public R<Void> remove(@PathVariable Long[] configIds) {
configService.deleteConfigByIds(configIds);
return R.ok();
}
/**
* 刷新参数缓存
*/
@SaCheckPermission("system:config:remove")
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
@DeleteMapping("/refreshCache")
public R<Void> refreshCache() {
configService.resetConfigCache();
return R.ok();
}
}

122
coin-admin/src/main/java/com/coin/web/controller/system/SysDeptController.java

@ -0,0 +1,122 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.convert.Convert;
import com.coin.common.annotation.Log;
import com.coin.common.constant.UserConstants;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.entity.SysDept;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.StringUtils;
import com.coin.system.service.ISysDeptService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 部门信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/dept")
public class SysDeptController extends BaseController {
private final ISysDeptService deptService;
/**
* 获取部门列表
*/
@SaCheckPermission("system:dept:list")
@GetMapping("/list")
public R<List<SysDept>> list(SysDept dept) {
List<SysDept> depts = deptService.selectDeptList(dept);
return R.ok(depts);
}
/**
* 查询部门列表排除节点
*
* @param deptId 部门ID
*/
@SaCheckPermission("system:dept:list")
@GetMapping("/list/exclude/{deptId}")
public R<List<SysDept>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) {
List<SysDept> depts = deptService.selectDeptList(new SysDept());
depts.removeIf(d -> d.getDeptId().equals(deptId)
|| StringUtils.splitList(d.getAncestors()).contains(Convert.toStr(deptId)));
return R.ok(depts);
}
/**
* 根据部门编号获取详细信息
*
* @param deptId 部门ID
*/
@SaCheckPermission("system:dept:query")
@GetMapping(value = "/{deptId}")
public R<SysDept> getInfo(@PathVariable Long deptId) {
deptService.checkDeptDataScope(deptId);
return R.ok(deptService.selectDeptById(deptId));
}
/**
* 新增部门
*/
@SaCheckPermission("system:dept:add")
@Log(title = "部门管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysDept dept) {
if (!deptService.checkDeptNameUnique(dept)) {
return R.fail("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
return toAjax(deptService.insertDept(dept));
}
/**
* 修改部门
*/
@SaCheckPermission("system:dept:edit")
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysDept dept) {
Long deptId = dept.getDeptId();
deptService.checkDeptDataScope(deptId);
if (!deptService.checkDeptNameUnique(dept)) {
return R.fail("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
} else if (dept.getParentId().equals(deptId)) {
return R.fail("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
} else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus())) {
if (deptService.selectNormalChildrenDeptById(deptId) > 0) {
return R.fail("该部门包含未停用的子部门!");
} else if (deptService.checkDeptExistUser(deptId)) {
return R.fail("该部门下存在已分配用户,不能禁用!");
}
}
return toAjax(deptService.updateDept(dept));
}
/**
* 删除部门
*
* @param deptId 部门ID
*/
@SaCheckPermission("system:dept:remove")
@Log(title = "部门管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{deptId}")
public R<Void> remove(@PathVariable Long deptId) {
if (deptService.hasChildByDeptId(deptId)) {
return R.warn("存在下级部门,不允许删除");
}
if (deptService.checkDeptExistUser(deptId)) {
return R.warn("部门存在用户,不允许删除");
}
deptService.checkDeptDataScope(deptId);
return toAjax(deptService.deleteDeptById(deptId));
}
}

116
coin-admin/src/main/java/com/coin/web/controller/system/SysDictDataController.java

@ -0,0 +1,116 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.entity.SysDictData;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.system.service.ISysDictDataService;
import com.coin.system.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* 数据字典信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/dict/data")
public class SysDictDataController extends BaseController {
private final ISysDictDataService dictDataService;
private final ISysDictTypeService dictTypeService;
/**
* 查询字典数据列表
*/
@SaCheckPermission("system:dict:list")
@GetMapping("/list")
public TableDataInfo<SysDictData> list(SysDictData dictData, PageQuery pageQuery) {
return dictDataService.selectPageDictDataList(dictData, pageQuery);
}
/**
* 导出字典数据列表
*/
@Log(title = "字典数据", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:dict:export")
@PostMapping("/export")
public void export(SysDictData dictData, HttpServletResponse response) {
List<SysDictData> list = dictDataService.selectDictDataList(dictData);
ExcelUtil.exportExcel(list, "字典数据", SysDictData.class, response);
}
/**
* 查询字典数据详细
*
* @param dictCode 字典code
*/
@SaCheckPermission("system:dict:query")
@GetMapping(value = "/{dictCode}")
public R<SysDictData> getInfo(@PathVariable Long dictCode) {
return R.ok(dictDataService.selectDictDataById(dictCode));
}
/**
* 根据字典类型查询字典数据信息
*
* @param dictType 字典类型
*/
@GetMapping(value = "/type/{dictType}")
public R<List<SysDictData>> dictType(@PathVariable String dictType) {
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
if (ObjectUtil.isNull(data)) {
data = new ArrayList<>();
}
return R.ok(data);
}
/**
* 新增字典类型
*/
@SaCheckPermission("system:dict:add")
@Log(title = "字典数据", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysDictData dict) {
dictDataService.insertDictData(dict);
return R.ok();
}
/**
* 修改保存字典类型
*/
@SaCheckPermission("system:dict:edit")
@Log(title = "字典数据", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysDictData dict) {
dictDataService.updateDictData(dict);
return R.ok();
}
/**
* 删除字典类型
*
* @param dictCodes 字典code串
*/
@SaCheckPermission("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictCodes}")
public R<Void> remove(@PathVariable Long[] dictCodes) {
dictDataService.deleteDictDataByIds(dictCodes);
return R.ok();
}
}

125
coin-admin/src/main/java/com/coin/web/controller/system/SysDictTypeController.java

@ -0,0 +1,125 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.coin.common.annotation.Log;
import com.coin.common.constant.UserConstants;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.entity.SysDictType;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.system.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 数据字典信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/dict/type")
public class SysDictTypeController extends BaseController {
private final ISysDictTypeService dictTypeService;
/**
* 查询字典类型列表
*/
@SaCheckPermission("system:dict:list")
@GetMapping("/list")
public TableDataInfo<SysDictType> list(SysDictType dictType, PageQuery pageQuery) {
return dictTypeService.selectPageDictTypeList(dictType, pageQuery);
}
/**
* 导出字典类型列表
*/
@Log(title = "字典类型", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:dict:export")
@PostMapping("/export")
public void export(SysDictType dictType, HttpServletResponse response) {
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
ExcelUtil.exportExcel(list, "字典类型", SysDictType.class, response);
}
/**
* 查询字典类型详细
*
* @param dictId 字典ID
*/
@SaCheckPermission("system:dict:query")
@GetMapping(value = "/{dictId}")
public R<SysDictType> getInfo(@PathVariable Long dictId) {
return R.ok(dictTypeService.selectDictTypeById(dictId));
}
/**
* 新增字典类型
*/
@SaCheckPermission("system:dict:add")
@Log(title = "字典类型", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysDictType dict) {
if (!dictTypeService.checkDictTypeUnique(dict)) {
return R.fail("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dictTypeService.insertDictType(dict);
return R.ok();
}
/**
* 修改字典类型
*/
@SaCheckPermission("system:dict:edit")
@Log(title = "字典类型", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysDictType dict) {
if (!dictTypeService.checkDictTypeUnique(dict)) {
return R.fail("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dictTypeService.updateDictType(dict);
return R.ok();
}
/**
* 删除字典类型
*
* @param dictIds 字典ID串
*/
@SaCheckPermission("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictIds}")
public R<Void> remove(@PathVariable Long[] dictIds) {
dictTypeService.deleteDictTypeByIds(dictIds);
return R.ok();
}
/**
* 刷新字典缓存
*/
@SaCheckPermission("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
@DeleteMapping("/refreshCache")
public R<Void> refreshCache() {
dictTypeService.resetDictCache();
return R.ok();
}
/**
* 获取字典选择框列表
*/
@GetMapping("/optionselect")
public R<List<SysDictType>> optionselect() {
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
return R.ok(dictTypes);
}
}

32
coin-admin/src/main/java/com/coin/web/controller/system/SysIndexController.java

@ -0,0 +1,32 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaIgnore;
import com.coin.common.config.RuoYiConfig;
import com.coin.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 首页
*
* @author Lion Li
*/
@RequiredArgsConstructor
@RestController
public class SysIndexController {
/**
* 系统基础配置
*/
private final RuoYiConfig ruoyiConfig;
/**
* 访问首页提示语
*/
@SaIgnore
@GetMapping("/")
public String index() {
return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion());
}
}

144
coin-admin/src/main/java/com/coin/web/controller/system/SysLoginController.java

@ -0,0 +1,144 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaIgnore;
import com.coin.common.constant.Constants;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.entity.SysMenu;
import com.coin.common.core.domain.entity.SysUser;
import com.coin.common.core.domain.model.EmailLoginBody;
import com.coin.common.core.domain.model.LoginBody;
import com.coin.common.core.domain.model.LoginUser;
import com.coin.common.core.domain.model.SmsLoginBody;
import com.coin.common.helper.LoginHelper;
import com.coin.system.domain.vo.RouterVo;
import com.coin.system.service.ISysMenuService;
import com.coin.system.service.ISysUserService;
import com.coin.system.service.SysLoginService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.NotBlank;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 登录验证
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
public class SysLoginController {
private final SysLoginService loginService;
private final ISysMenuService menuService;
private final ISysUserService userService;
/**
* 登录方法
*
* @param loginBody 登录信息
* @return 结果
*/
@SaIgnore
@PostMapping("/login")
public R<Map<String, Object>> login(@Validated @RequestBody LoginBody loginBody) {
Map<String, Object> ajax = new HashMap<>();
// 生成令牌
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
loginBody.getUuid());
ajax.put(Constants.TOKEN, token);
return R.ok(ajax);
}
/**
* 短信登录
*
* @param smsLoginBody 登录信息
* @return 结果
*/
@SaIgnore
@PostMapping("/smsLogin")
public R<Map<String, Object>> smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) {
Map<String, Object> ajax = new HashMap<>();
// 生成令牌
String token = loginService.smsLogin(smsLoginBody.getPhonenumber(), smsLoginBody.getSmsCode());
ajax.put(Constants.TOKEN, token);
return R.ok(ajax);
}
/**
* 邮件登录
*
* @param body 登录信息
* @return 结果
*/
@PostMapping("/emailLogin")
public R<Map<String, Object>> emailLogin(@Validated @RequestBody EmailLoginBody body) {
Map<String, Object> ajax = new HashMap<>();
// 生成令牌
String token = loginService.emailLogin(body.getEmail(), body.getEmailCode());
ajax.put(Constants.TOKEN, token);
return R.ok(ajax);
}
/**
* 小程序登录(示例)
*
* @param xcxCode 小程序code
* @return 结果
*/
@SaIgnore
@PostMapping("/xcxLogin")
public R<Map<String, Object>> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) {
Map<String, Object> ajax = new HashMap<>();
// 生成令牌
String token = loginService.xcxLogin(xcxCode);
ajax.put(Constants.TOKEN, token);
return R.ok(ajax);
}
/**
* 退出登录
*/
@SaIgnore
@PostMapping("/logout")
public R<Void> logout() {
loginService.logout();
return R.ok("退出成功");
}
/**
* 获取用户信息
*
* @return 用户信息
*/
@GetMapping("getInfo")
public R<Map<String, Object>> getInfo() {
LoginUser loginUser = LoginHelper.getLoginUser();
SysUser user = userService.selectUserById(loginUser.getUserId());
Map<String, Object> ajax = new HashMap<>();
ajax.put("user", user);
ajax.put("roles", loginUser.getRolePermission());
ajax.put("permissions", loginUser.getMenuPermission());
return R.ok(ajax);
}
/**
* 获取路由信息
*
* @return 路由信息
*/
@GetMapping("getRouters")
public R<List<RouterVo>> getRouters() {
Long userId = LoginHelper.getUserId();
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return R.ok(menuService.buildMenus(menus));
}
}

127
coin-admin/src/main/java/com/coin/web/controller/system/SysMenuController.java

@ -0,0 +1,127 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.tree.Tree;
import com.coin.common.annotation.Log;
import com.coin.common.constant.UserConstants;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.entity.SysMenu;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.StringUtils;
import com.coin.system.service.ISysMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 菜单信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/menu")
public class SysMenuController extends BaseController {
private final ISysMenuService menuService;
/**
* 获取菜单列表
*/
@SaCheckPermission("system:menu:list")
@GetMapping("/list")
public R<List<SysMenu>> list(SysMenu menu) {
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return R.ok(menus);
}
/**
* 根据菜单编号获取详细信息
*
* @param menuId 菜单ID
*/
@SaCheckPermission("system:menu:query")
@GetMapping(value = "/{menuId}")
public R<SysMenu> getInfo(@PathVariable Long menuId) {
return R.ok(menuService.selectMenuById(menuId));
}
/**
* 获取菜单下拉树列表
*/
@GetMapping("/treeselect")
public R<List<Tree<Long>>> treeselect(SysMenu menu) {
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return R.ok(menuService.buildMenuTreeSelect(menus));
}
/**
* 加载对应角色菜单列表树
*
* @param roleId 角色ID
*/
@GetMapping(value = "/roleMenuTreeselect/{roleId}")
public R<Map<String, Object>> roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
List<SysMenu> menus = menuService.selectMenuList(getUserId());
Map<String, Object> ajax = new HashMap<>();
ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
ajax.put("menus", menuService.buildMenuTreeSelect(menus));
return R.ok(ajax);
}
/**
* 新增菜单
*/
@SaCheckPermission("system:menu:add")
@Log(title = "菜单管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysMenu menu) {
if (!menuService.checkMenuNameUnique(menu)) {
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
}
return toAjax(menuService.insertMenu(menu));
}
/**
* 修改菜单
*/
@SaCheckPermission("system:menu:edit")
@Log(title = "菜单管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysMenu menu) {
if (!menuService.checkMenuNameUnique(menu)) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
} else if (menu.getMenuId().equals(menu.getParentId())) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
}
return toAjax(menuService.updateMenu(menu));
}
/**
* 删除菜单
*
* @param menuId 菜单ID
*/
@SaCheckPermission("system:menu:remove")
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{menuId}")
public R<Void> remove(@PathVariable("menuId") Long menuId) {
if (menuService.hasChildByMenuId(menuId)) {
return R.warn("存在子菜单,不允许删除");
}
if (menuService.checkMenuExistRole(menuId)) {
return R.warn("菜单已分配,不允许删除");
}
return toAjax(menuService.deleteMenuById(menuId));
}
}

80
coin-admin/src/main/java/com/coin/web/controller/system/SysNoticeController.java

@ -0,0 +1,80 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.enums.BusinessType;
import com.coin.system.domain.SysNotice;
import com.coin.system.service.ISysNoticeService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* 公告 信息操作处理
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/notice")
public class SysNoticeController extends BaseController {
private final ISysNoticeService noticeService;
/**
* 获取通知公告列表
*/
@SaCheckPermission("system:notice:list")
@GetMapping("/list")
public TableDataInfo<SysNotice> list(SysNotice notice, PageQuery pageQuery) {
return noticeService.selectPageNoticeList(notice, pageQuery);
}
/**
* 根据通知公告编号获取详细信息
*
* @param noticeId 公告ID
*/
@SaCheckPermission("system:notice:query")
@GetMapping(value = "/{noticeId}")
public R<SysNotice> getInfo(@PathVariable Long noticeId) {
return R.ok(noticeService.selectNoticeById(noticeId));
}
/**
* 新增通知公告
*/
@SaCheckPermission("system:notice:add")
@Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysNotice notice) {
return toAjax(noticeService.insertNotice(notice));
}
/**
* 修改通知公告
*/
@SaCheckPermission("system:notice:edit")
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysNotice notice) {
return toAjax(noticeService.updateNotice(notice));
}
/**
* 删除通知公告
*
* @param noticeIds 公告ID串
*/
@SaCheckPermission("system:notice:remove")
@Log(title = "通知公告", businessType = BusinessType.DELETE)
@DeleteMapping("/{noticeIds}")
public R<Void> remove(@PathVariable Long[] noticeIds) {
return toAjax(noticeService.deleteNoticeByIds(noticeIds));
}
}

105
coin-admin/src/main/java/com/coin/web/controller/system/SysOssConfigController.java

@ -0,0 +1,105 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.coin.common.annotation.Log;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.core.validate.QueryGroup;
import com.coin.common.enums.BusinessType;
import com.coin.system.domain.bo.SysOssConfigBo;
import com.coin.system.domain.vo.SysOssConfigVo;
import com.coin.system.service.ISysOssConfigService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
/**
* 对象存储配置
*
* @author Lion Li
* @author 孤舟烟雨
* @date 2021-08-13
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/oss/config")
public class SysOssConfigController extends BaseController {
private final ISysOssConfigService iSysOssConfigService;
/**
* 查询对象存储配置列表
*/
@SaCheckPermission("system:oss:list")
@GetMapping("/list")
public TableDataInfo<SysOssConfigVo> list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) {
return iSysOssConfigService.queryPageList(bo, pageQuery);
}
/**
* 获取对象存储配置详细信息
*
* @param ossConfigId OSS配置ID
*/
@SaCheckPermission("system:oss:query")
@GetMapping("/{ossConfigId}")
public R<SysOssConfigVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long ossConfigId) {
return R.ok(iSysOssConfigService.queryById(ossConfigId));
}
/**
* 新增对象存储配置
*/
@SaCheckPermission("system:oss:add")
@Log(title = "对象存储配置", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysOssConfigBo bo) {
return toAjax(iSysOssConfigService.insertByBo(bo));
}
/**
* 修改对象存储配置
*/
@SaCheckPermission("system:oss:edit")
@Log(title = "对象存储配置", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysOssConfigBo bo) {
return toAjax(iSysOssConfigService.updateByBo(bo));
}
/**
* 删除对象存储配置
*
* @param ossConfigIds OSS配置ID串
*/
@SaCheckPermission("system:oss:remove")
@Log(title = "对象存储配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ossConfigIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ossConfigIds) {
return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true));
}
/**
* 状态修改
*/
@SaCheckPermission("system:oss:edit")
@Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) {
return toAjax(iSysOssConfigService.updateOssConfigStatus(bo));
}
}

109
coin-admin/src/main/java/com/coin/web/controller/system/SysOssController.java

@ -0,0 +1,109 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.core.validate.QueryGroup;
import com.coin.common.enums.BusinessType;
import com.coin.system.domain.bo.SysOssBo;
import com.coin.system.domain.vo.SysOssVo;
import com.coin.system.service.ISysOssService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 文件上传 控制层
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/oss")
public class SysOssController extends BaseController {
private final ISysOssService iSysOssService;
/**
* 查询OSS对象存储列表
*/
@SaCheckPermission("system:oss:list")
@GetMapping("/list")
public TableDataInfo<SysOssVo> list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) {
return iSysOssService.queryPageList(bo, pageQuery);
}
/**
* 查询OSS对象基于id串
*
* @param ossIds OSS对象ID串
*/
@SaCheckPermission("system:oss:list")
@GetMapping("/listByIds/{ossIds}")
public R<List<SysOssVo>> listByIds(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ossIds) {
List<SysOssVo> list = iSysOssService.listByIds(Arrays.asList(ossIds));
return R.ok(list);
}
/**
* 上传OSS对象存储
*
* @param file 文件
*/
@SaCheckPermission("system:oss:upload")
@Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Map<String, String>> upload(@RequestPart("file") MultipartFile file) {
if (ObjectUtil.isNull(file)) {
return R.fail("上传文件不能为空");
}
SysOssVo oss = iSysOssService.upload(file);
Map<String, String> map = new HashMap<>(2);
map.put("url", oss.getUrl());
map.put("fileName", oss.getOriginalName());
map.put("ossId", oss.getOssId().toString());
return R.ok(map);
}
/**
* 下载OSS对象
*
* @param ossId OSS对象ID
*/
@SaCheckPermission("system:oss:download")
@GetMapping("/download/{ossId}")
public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException {
iSysOssService.download(ossId,response);
}
/**
* 删除OSS对象存储
*
* @param ossIds OSS对象ID串
*/
@SaCheckPermission("system:oss:remove")
@Log(title = "OSS对象存储", businessType = BusinessType.DELETE)
@DeleteMapping("/{ossIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ossIds) {
return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true));
}
}

120
coin-admin/src/main/java/com/coin/web/controller/system/SysPostController.java

@ -0,0 +1,120 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.coin.common.annotation.Log;
import com.coin.common.constant.UserConstants;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.system.domain.SysPost;
import com.coin.system.service.ISysPostService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 岗位信息操作处理
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/post")
public class SysPostController extends BaseController {
private final ISysPostService postService;
/**
* 获取岗位列表
*/
@SaCheckPermission("system:post:list")
@GetMapping("/list")
public TableDataInfo<SysPost> list(SysPost post, PageQuery pageQuery) {
return postService.selectPagePostList(post, pageQuery);
}
/**
* 导出岗位列表
*/
@Log(title = "岗位管理", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:post:export")
@PostMapping("/export")
public void export(SysPost post, HttpServletResponse response) {
List<SysPost> list = postService.selectPostList(post);
ExcelUtil.exportExcel(list, "岗位数据", SysPost.class, response);
}
/**
* 根据岗位编号获取详细信息
*
* @param postId 岗位ID
*/
@SaCheckPermission("system:post:query")
@GetMapping(value = "/{postId}")
public R<SysPost> getInfo(@PathVariable Long postId) {
return R.ok(postService.selectPostById(postId));
}
/**
* 新增岗位
*/
@SaCheckPermission("system:post:add")
@Log(title = "岗位管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysPost post) {
if (!postService.checkPostNameUnique(post)) {
return R.fail("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
} else if (!postService.checkPostCodeUnique(post)) {
return R.fail("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
return toAjax(postService.insertPost(post));
}
/**
* 修改岗位
*/
@SaCheckPermission("system:post:edit")
@Log(title = "岗位管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysPost post) {
if (!postService.checkPostNameUnique(post)) {
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
} else if (!postService.checkPostCodeUnique(post)) {
return R.fail("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
} else if (UserConstants.POST_DISABLE.equals(post.getStatus())
&& postService.countUserPostById(post.getPostId()) > 0) {
return R.fail("该岗位下存在已分配用户,不能禁用!");
}
return toAjax(postService.updatePost(post));
}
/**
* 删除岗位
*
* @param postIds 岗位ID串
*/
@SaCheckPermission("system:post:remove")
@Log(title = "岗位管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{postIds}")
public R<Void> remove(@PathVariable Long[] postIds) {
return toAjax(postService.deletePostByIds(postIds));
}
/**
* 获取岗位选择框列表
*/
@GetMapping("/optionselect")
public R<List<SysPost>> optionselect() {
SysPost post = new SysPost();
post.setStatus(UserConstants.POST_NORMAL);
List<SysPost> posts = postService.selectPostList(post);
return R.ok(posts);
}
}

126
coin-admin/src/main/java/com/coin/web/controller/system/SysProfileController.java

@ -0,0 +1,126 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.io.FileUtil;
import com.coin.common.annotation.Log;
import com.coin.common.constant.UserConstants;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.entity.SysUser;
import com.coin.common.enums.BusinessType;
import com.coin.common.helper.LoginHelper;
import com.coin.common.utils.StringUtils;
import com.coin.common.utils.file.MimeTypeUtils;
import com.coin.system.domain.SysOss;
import com.coin.system.domain.vo.SysOssVo;
import com.coin.system.service.ISysOssService;
import com.coin.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* 个人信息 业务处理
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController {
private final ISysUserService userService;
private final ISysOssService iSysOssService;
/**
* 个人信息
*/
@GetMapping
public R<Map<String, Object>> profile() {
SysUser user = userService.selectUserById(getUserId());
Map<String, Object> ajax = new HashMap<>();
ajax.put("user", user);
ajax.put("roleGroup", userService.selectUserRoleGroup(user.getUserName()));
ajax.put("postGroup", userService.selectUserPostGroup(user.getUserName()));
return R.ok(ajax);
}
/**
* 修改用户
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> updateProfile(@RequestBody SysUser user) {
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
}
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setUserId(getUserId());
user.setUserName(null);
user.setPassword(null);
user.setAvatar(null);
user.setDeptId(null);
if (userService.updateUserProfile(user) > 0) {
return R.ok();
}
return R.fail("修改个人信息异常,请联系管理员");
}
/**
* 重置密码
*
* @param newPassword 新密码
* @param oldPassword 旧密码
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd")
public R<Void> updatePwd(String oldPassword, String newPassword) {
SysUser user = userService.selectUserById(LoginHelper.getUserId());
String userName = user.getUserName();
String password = user.getPassword();
if (!BCrypt.checkpw(oldPassword, password)) {
return R.fail("修改密码失败,旧密码错误");
}
if (BCrypt.checkpw(newPassword, password)) {
return R.fail("新密码不能与旧密码相同");
}
if (userService.resetUserPwd(userName, BCrypt.hashpw(newPassword)) > 0) {
return R.ok();
}
return R.fail("修改密码异常,请联系管理员");
}
/**
* 头像上传
*
* @param avatarfile 用户头像
*/
@Log(title = "用户头像", businessType = BusinessType.UPDATE)
@PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Map<String, Object>> avatar(@RequestPart("avatarfile") MultipartFile avatarfile) {
Map<String, Object> ajax = new HashMap<>();
if (!avatarfile.isEmpty()) {
String extension = FileUtil.extName(avatarfile.getOriginalFilename());
if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
return R.fail("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式");
}
SysOssVo oss = iSysOssService.upload(avatarfile);
String avatar = oss.getUrl();
if (userService.updateUserAvatar(getUsername(), avatar)) {
ajax.put("imgUrl", avatar);
return R.ok(ajax);
}
}
return R.fail("上传图片异常,请联系管理员");
}
}

40
coin-admin/src/main/java/com/coin/web/controller/system/SysRegisterController.java

@ -0,0 +1,40 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaIgnore;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.model.RegisterBody;
import com.coin.system.service.ISysConfigService;
import com.coin.system.service.SysRegisterService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
* 注册验证
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
public class SysRegisterController extends BaseController {
private final SysRegisterService registerService;
private final ISysConfigService configService;
/**
* 用户注册
*/
@SaIgnore
@PostMapping("/register")
public R<Void> register(@Validated @RequestBody RegisterBody user) {
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) {
return R.fail("当前系统没有开启注册功能!");
}
registerService.register(user);
return R.ok();
}
}

228
coin-admin/src/main/java/com/coin/web/controller/system/SysRoleController.java

@ -0,0 +1,228 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.coin.common.annotation.Log;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.entity.SysDept;
import com.coin.common.core.domain.entity.SysRole;
import com.coin.common.core.domain.entity.SysUser;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.system.domain.SysUserRole;
import com.coin.system.service.ISysDeptService;
import com.coin.system.service.ISysRoleService;
import com.coin.system.service.ISysUserService;
import com.coin.system.service.SysPermissionService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 角色信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/role")
public class SysRoleController extends BaseController {
private final ISysRoleService roleService;
private final ISysUserService userService;
private final ISysDeptService deptService;
private final SysPermissionService permissionService;
/**
* 获取角色信息列表
*/
@SaCheckPermission("system:role:list")
@GetMapping("/list")
public TableDataInfo<SysRole> list(SysRole role, PageQuery pageQuery) {
return roleService.selectPageRoleList(role, pageQuery);
}
/**
* 导出角色信息列表
*/
@Log(title = "角色管理", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:role:export")
@PostMapping("/export")
public void export(SysRole role, HttpServletResponse response) {
List<SysRole> list = roleService.selectRoleList(role);
ExcelUtil.exportExcel(list, "角色数据", SysRole.class, response);
}
/**
* 根据角色编号获取详细信息
*
* @param roleId 角色ID
*/
@SaCheckPermission("system:role:query")
@GetMapping(value = "/{roleId}")
public R<SysRole> getInfo(@PathVariable Long roleId) {
roleService.checkRoleDataScope(roleId);
return R.ok(roleService.selectRoleById(roleId));
}
/**
* 新增角色
*/
@SaCheckPermission("system:role:add")
@Log(title = "角色管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysRole role) {
roleService.checkRoleAllowed(role);
if (!roleService.checkRoleNameUnique(role)) {
return R.fail("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
} else if (!roleService.checkRoleKeyUnique(role)) {
return R.fail("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
return toAjax(roleService.insertRole(role));
}
/**
* 修改保存角色
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysRole role) {
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
if (!roleService.checkRoleNameUnique(role)) {
return R.fail("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
} else if (!roleService.checkRoleKeyUnique(role)) {
return R.fail("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
if (roleService.updateRole(role) > 0) {
roleService.cleanOnlineUserByRole(role.getRoleId());
return R.ok();
}
return R.fail("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
}
/**
* 修改保存数据权限
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/dataScope")
public R<Void> dataScope(@RequestBody SysRole role) {
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.authDataScope(role));
}
/**
* 状态修改
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysRole role) {
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.updateRoleStatus(role));
}
/**
* 删除角色
*
* @param roleIds 角色ID串
*/
@SaCheckPermission("system:role:remove")
@Log(title = "角色管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{roleIds}")
public R<Void> remove(@PathVariable Long[] roleIds) {
return toAjax(roleService.deleteRoleByIds(roleIds));
}
/**
* 获取角色选择框列表
*/
@SaCheckPermission("system:role:query")
@GetMapping("/optionselect")
public R<List<SysRole>> optionselect() {
return R.ok(roleService.selectRoleAll());
}
/**
* 查询已分配用户角色列表
*/
@SaCheckPermission("system:role:list")
@GetMapping("/authUser/allocatedList")
public TableDataInfo<SysUser> allocatedList(SysUser user, PageQuery pageQuery) {
return userService.selectAllocatedList(user, pageQuery);
}
/**
* 查询未分配用户角色列表
*/
@SaCheckPermission("system:role:list")
@GetMapping("/authUser/unallocatedList")
public TableDataInfo<SysUser> unallocatedList(SysUser user, PageQuery pageQuery) {
return userService.selectUnallocatedList(user, pageQuery);
}
/**
* 取消授权用户
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/cancel")
public R<Void> cancelAuthUser(@RequestBody SysUserRole userRole) {
return toAjax(roleService.deleteAuthUser(userRole));
}
/**
* 批量取消授权用户
*
* @param roleId 角色ID
* @param userIds 用户ID串
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/cancelAll")
public R<Void> cancelAuthUserAll(Long roleId, Long[] userIds) {
return toAjax(roleService.deleteAuthUsers(roleId, userIds));
}
/**
* 批量选择用户授权
*
* @param roleId 角色ID
* @param userIds 用户ID串
*/
@SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/selectAll")
public R<Void> selectAuthUserAll(Long roleId, Long[] userIds) {
roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds));
}
/**
* 获取对应角色部门树列表
*
* @param roleId 角色ID
*/
@SaCheckPermission("system:role:list")
@GetMapping(value = "/deptTree/{roleId}")
public R<Map<String, Object>> roleDeptTreeselect(@PathVariable("roleId") Long roleId) {
Map<String, Object> ajax = new HashMap<>();
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
return R.ok(ajax);
}
}

256
coin-admin/src/main/java/com/coin/web/controller/system/SysUserController.java

@ -0,0 +1,256 @@
package com.coin.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.coin.common.annotation.Log;
import com.coin.common.constant.UserConstants;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.entity.SysDept;
import com.coin.common.core.domain.entity.SysRole;
import com.coin.common.core.domain.entity.SysUser;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.enums.BusinessType;
import com.coin.common.excel.ExcelResult;
import com.coin.common.helper.LoginHelper;
import com.coin.common.utils.StreamUtils;
import com.coin.common.utils.StringUtils;
import com.coin.common.utils.poi.ExcelUtil;
import com.coin.system.domain.SysPost;
import com.coin.system.domain.vo.SysUserExportVo;
import com.coin.system.domain.vo.SysUserImportVo;
import com.coin.system.listener.SysUserImportListener;
import com.coin.system.service.ISysDeptService;
import com.coin.system.service.ISysPostService;
import com.coin.system.service.ISysRoleService;
import com.coin.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 用户信息
*
* @author Lion Li
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController {
private final ISysUserService userService;
private final ISysRoleService roleService;
private final ISysPostService postService;
private final ISysDeptService deptService;
/**
* 获取用户列表
*/
@SaCheckPermission("system:user:list")
@GetMapping("/list")
public TableDataInfo<SysUser> list(SysUser user, PageQuery pageQuery) {
return userService.selectPageUserList(user, pageQuery);
}
/**
* 导出用户列表
*/
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
@SaCheckPermission("system:user:export")
@PostMapping("/export")
public void export(SysUser user, HttpServletResponse response) {
List<SysUser> list = userService.selectUserList(user);
List<SysUserExportVo> listVo = BeanUtil.copyToList(list, SysUserExportVo.class);
for (int i = 0; i < list.size(); i++) {
SysDept dept = list.get(i).getDept();
SysUserExportVo vo = listVo.get(i);
if (ObjectUtil.isNotEmpty(dept)) {
vo.setDeptName(dept.getDeptName());
vo.setLeader(dept.getLeader());
}
}
ExcelUtil.exportExcel(listVo, "用户数据", SysUserExportVo.class, response);
}
/**
* 导入数据
*
* @param file 导入文件
* @param updateSupport 是否更新已存在数据
*/
@Log(title = "用户管理", businessType = BusinessType.IMPORT)
@SaCheckPermission("system:user:import")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport));
return R.ok(result.getAnalysis());
}
/**
* 获取导入模板
*/
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) {
ExcelUtil.exportExcel(new ArrayList<>(), "用户数据", SysUserImportVo.class, response);
}
/**
* 根据用户编号获取详细信息
*
* @param userId 用户ID
*/
@SaCheckPermission("system:user:query")
@GetMapping(value = {"/", "/{userId}"})
public R<Map<String, Object>> getInfo(@PathVariable(value = "userId", required = false) Long userId) {
userService.checkUserDataScope(userId);
Map<String, Object> ajax = new HashMap<>();
SysRole role = new SysRole();
role.setStatus(UserConstants.ROLE_NORMAL);
SysPost post = new SysPost();
post.setStatus(UserConstants.POST_NORMAL);
List<SysRole> roles = roleService.selectRoleList(role);
ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin()));
ajax.put("posts", postService.selectPostList(post));
if (ObjectUtil.isNotNull(userId)) {
SysUser sysUser = userService.selectUserById(userId);
ajax.put("user", sysUser);
ajax.put("postIds", postService.selectPostListByUserId(userId));
ajax.put("roleIds", StreamUtils.toList(sysUser.getRoles(), SysRole::getRoleId));
}
return R.ok(ajax);
}
/**
* 新增用户
*/
@SaCheckPermission("system:user:add")
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping
public R<Void> add(@Validated @RequestBody SysUser user) {
deptService.checkDeptDataScope(user.getDeptId());
if (!userService.checkUserNameUnique(user)) {
return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return R.fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
return R.fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setPassword(BCrypt.hashpw(user.getPassword()));
return toAjax(userService.insertUser(user));
}
/**
* 修改用户
*/
@SaCheckPermission("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping
public R<Void> edit(@Validated @RequestBody SysUser user) {
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId());
if (!userService.checkUserNameUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
} else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
} else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
return toAjax(userService.updateUser(user));
}
/**
* 删除用户
*
* @param userIds 角色ID串
*/
@SaCheckPermission("system:user:remove")
@Log(title = "用户管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{userIds}")
public R<Void> remove(@PathVariable Long[] userIds) {
if (ArrayUtil.contains(userIds, getUserId())) {
return R.fail("当前用户不能删除");
}
return toAjax(userService.deleteUserByIds(userIds));
}
/**
* 重置密码
*/
@SaCheckPermission("system:user:resetPwd")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/resetPwd")
public R<Void> resetPwd(@RequestBody SysUser user) {
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setPassword(BCrypt.hashpw(user.getPassword()));
return toAjax(userService.resetPwd(user));
}
/**
* 状态修改
*/
@SaCheckPermission("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysUser user) {
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
return toAjax(userService.updateUserStatus(user));
}
/**
* 根据用户编号获取授权角色
*
* @param userId 用户ID
*/
@SaCheckPermission("system:user:query")
@GetMapping("/authRole/{userId}")
public R<Map<String, Object>> authRole(@PathVariable Long userId) {
SysUser user = userService.selectUserById(userId);
List<SysRole> roles = roleService.selectRolesByUserId(userId);
Map<String, Object> ajax = new HashMap<>();
ajax.put("user", user);
ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin()));
return R.ok(ajax);
}
/**
* 用户授权角色
*
* @param userId 用户Id
* @param roleIds 角色ID串
*/
@SaCheckPermission("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.GRANT)
@PutMapping("/authRole")
public R<Void> insertAuthRole(Long userId, Long[] roleIds) {
userService.checkUserDataScope(userId);
userService.insertUserAuth(userId, roleIds);
return R.ok();
}
/**
* 获取部门树列表
*/
@SaCheckPermission("system:user:list")
@GetMapping("/deptTree")
public R<List<Tree<Long>>> deptTree(SysDept dept) {
return R.ok(deptService.selectDeptTreeList(dept));
}
}

186
coin-admin/src/main/resources/application-dev.yml

@ -0,0 +1,186 @@
--- # 监控中心配置
spring.boot.admin.client:
# 增加客户端开关
enabled: true
url: http://localhost:9090/admin
instance:
service-host-type: IP
username: ruoyi
password: 123456
--- # xxl-job 配置
xxl.job:
# 执行器开关
enabled: true
# 调度中心地址:如调度中心集群部署存在多个地址则用逗号分隔。
admin-addresses: http://localhost:9100/xxl-job-admin
# 执行器通讯TOKEN:非空时启用
access-token: xxl-job
executor:
# 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册
appname: xxl-job-executor
# 28080 端口 随着主应用端口飘逸 避免集群冲突
port: 2${server.port}
# 执行器注册:默认IP:PORT
address:
# 执行器IP:默认自动获取IP
ip:
# 执行器运行日志文件存储磁盘路径
logpath: ./logs/xxl-job
# 执行器日志文件保存天数:大于3生效
logretentiondays: 30
--- # 数据源配置
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
# 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
dynamic:
# 性能分析插件(有性能损耗 不建议生产环境使用)
p6spy: true
# 设置默认的数据源或者数据源组,默认值即为 master
primary: master
# 严格模式 匹配不到数据源则报错
strict: true
datasource:
# 主库数据源
master:
type: ${spring.datasource.type}
driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://192.168.0.60:3306/fundhold?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
# url: jdbc:mysql://8.137.52.68:3308/foundhold?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
username: fundhold
password: Coin123654
# admin@Passw0rd
# 从库数据源
slave:
lazy: true
type: ${spring.datasource.type}
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.0.60:3306/fundhold?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
# url: jdbc:mysql://8.137.52.68:3308/foundhold?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
username: fundhold
password: Coin123654
# admin@Passw0rd
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
# postgres:
# type: ${spring.datasource.type}
# driverClassName: org.postgresql.Driver
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
# username: root
# password: root
# sqlserver:
# type: ${spring.datasource.type}
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
# username: SA
# password: root
hikari:
# 最大连接池数量
maxPoolSize: 20
# 最小空闲线程数量
minIdle: 10
# 配置获取连接等待超时的时间
connectionTimeout: 30000
# 校验超时时间
validationTimeout: 5000
# 空闲连接存活最大时间,默认10分钟
idleTimeout: 600000
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
maxLifetime: 1800000
# 多久检查一次连接的活性
keepaliveTime: 30000
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
spring:
redis:
# 地址
host: 192.168.0.60
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码(如没有密码请注释掉)
password: Coin123654
# 连接超时时间
timeout: 10s
# 是否开启ssl
ssl: false
redisson:
# redis key前缀
keyPrefix:
# 线程池数量
threads: 4
# Netty线程池数量
nettyThreads: 8
# 单节点配置
singleServerConfig:
# 客户端名称
clientName: ${ruoyi.name}
# 最小空闲连接数
connectionMinimumIdleSize: 8
# 连接池大小
connectionPoolSize: 32
# 连接空闲超时,单位:毫秒
idleConnectionTimeout: 10000
# 命令等待超时,单位:毫秒
timeout: 3000
# 发布和订阅连接池大小
subscriptionConnectionPoolSize: 50
--- # mail 邮件发送
mail:
enabled: false
host: smtp.163.com
port: 465
# 是否需要用户名密码验证
auth: true
# 发送方,遵循RFC-822标准
from: xxx@163.com
# 用户名(注意:如果使用foxmail邮箱,此处user为qq号)
user: xxx@163.com
# 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助)
pass: xxxxxxxxxx
# 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。
starttlsEnable: true
# 使用SSL安全连接
sslEnable: true
# SMTP超时时长,单位毫秒,缺省值不超时
timeout: 0
# Socket连接超时值,单位毫秒,缺省值不超时
connectionTimeout: 0
--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商
# https://wind.kim/doc/start 文档地址 各个厂商可同时使用
sms:
# 阿里云 dysmsapi.aliyuncs.com
alibaba:
#请求地址 默认为 dysmsapi.aliyuncs.com 如无特殊改变可以不用设置
requestUrl: dysmsapi.aliyuncs.com
#阿里云的accessKey
accessKeyId: xxxxxxx
#阿里云的accessKeySecret
accessKeySecret: xxxxxxx
#短信签名
signature: 测试
tencent:
#请求地址默认为 sms.tencentcloudapi.com 如无特殊改变可不用设置
requestUrl: sms.tencentcloudapi.com
#腾讯云的accessKey
accessKeyId: xxxxxxx
#腾讯云的accessKeySecret
accessKeySecret: xxxxxxx
#短信签名
signature: 测试
#短信sdkAppId
sdkAppId: appid
#地域信息默认为 ap-guangzhou 如无特殊改变可不用设置
territory: ap-guangzhou

185
coin-admin/src/main/resources/application-prod.yml

@ -0,0 +1,185 @@
--- # 临时文件存储位置 避免临时文件被系统清理报错
spring.servlet.multipart.location: /ruoyi/server/temp
--- # 监控中心配置
spring.boot.admin.client:
# 增加客户端开关
enabled: true
url: http://localhost:9090/admin
instance:
service-host-type: IP
username: ruoyi
password: 123456
--- # xxl-job 配置
xxl.job:
# 执行器开关
enabled: true
# 调度中心地址:如调度中心集群部署存在多个地址则用逗号分隔。
admin-addresses: http://localhost:9100/xxl-job-admin
# 执行器通讯TOKEN:非空时启用
access-token: xxl-job
executor:
# 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册
appname: xxl-job-executor
# 28080 端口 随着主应用端口飘逸 避免集群冲突
port: 2${server.port}
# 执行器注册:默认IP:PORT
address:
# 执行器IP:默认自动获取IP
ip:
# 执行器运行日志文件存储磁盘路径
logpath: ./logs/xxl-job
# 执行器日志文件保存天数:大于3生效
logretentiondays: 30
--- # 数据源配置
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
# 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
dynamic:
# 性能分析插件(有性能损耗 不建议生产环境使用)
p6spy: false
# 设置默认的数据源或者数据源组,默认值即为 master
primary: master
# 严格模式 匹配不到数据源则报错
strict: true
datasource:
# 主库数据源
master:
type: ${spring.datasource.type}
driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
username: root
password: root
# 从库数据源
slave:
lazy: true
type: ${spring.datasource.type}
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
username:
password:
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
# postgres:
# type: ${spring.datasource.type}
# driverClassName: org.postgresql.Driver
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
# username: root
# password: root
# sqlserver:
# type: ${spring.datasource.type}
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
# username: SA
# password: root
hikari:
# 最大连接池数量
maxPoolSize: 20
# 最小空闲线程数量
minIdle: 10
# 配置获取连接等待超时的时间
connectionTimeout: 30000
# 校验超时时间
validationTimeout: 5000
# 空闲连接存活最大时间,默认10分钟
idleTimeout: 600000
# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
maxLifetime: 1800000
# 多久检查一次连接的活性
keepaliveTime: 30000
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
spring:
redis:
# 地址
host: localhost
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码(如没有密码请注释掉)
# password:
# 连接超时时间
timeout: 10s
# 是否开启ssl
ssl: false
redisson:
# redis key前缀
keyPrefix:
# 线程池数量
threads: 16
# Netty线程池数量
nettyThreads: 32
# 单节点配置
singleServerConfig:
# 客户端名称
clientName: ${ruoyi.name}
# 最小空闲连接数
connectionMinimumIdleSize: 32
# 连接池大小
connectionPoolSize: 64
# 连接空闲超时,单位:毫秒
idleConnectionTimeout: 10000
# 命令等待超时,单位:毫秒
timeout: 3000
# 发布和订阅连接池大小
subscriptionConnectionPoolSize: 50
--- # mail 邮件发送
mail:
enabled: false
host: smtp.163.com
port: 465
# 是否需要用户名密码验证
auth: true
# 发送方,遵循RFC-822标准
from: xxx@163.com
# 用户名(注意:如果使用foxmail邮箱,此处user为qq号)
user: xxx@163.com
# 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助)
pass: xxxxxxxxxx
# 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。
starttlsEnable: true
# 使用SSL安全连接
sslEnable: true
# SMTP超时时长,单位毫秒,缺省值不超时
timeout: 0
# Socket连接超时值,单位毫秒,缺省值不超时
connectionTimeout: 0
--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商
# https://wind.kim/doc/start 文档地址 各个厂商可同时使用
sms:
# 阿里云 dysmsapi.aliyuncs.com
alibaba:
#请求地址 默认为 dysmsapi.aliyuncs.com 如无特殊改变可以不用设置
requestUrl: dysmsapi.aliyuncs.com
#阿里云的accessKey
accessKeyId: xxxxxxx
#阿里云的accessKeySecret
accessKeySecret: xxxxxxx
#短信签名
signature: 测试
tencent:
#请求地址默认为 sms.tencentcloudapi.com 如无特殊改变可不用设置
requestUrl: sms.tencentcloudapi.com
#腾讯云的accessKey
accessKeyId: xxxxxxx
#腾讯云的accessKeySecret
accessKeySecret: xxxxxxx
#短信签名
signature: 测试
#短信sdkAppId
sdkAppId: appid
#地域信息默认为 ap-guangzhou 如无特殊改变可不用设置
territory: ap-guangzhou

287
coin-admin/src/main/resources/application.yml

@ -0,0 +1,287 @@
# 项目相关配置
ruoyi:
# 名称
name: Coin
# 版本
version: ${ruoyi-vue-plus.version}
# 版权年份
copyrightYear: 2023
# 缓存懒加载
cacheLazy: false
captcha:
# 页面 <参数设置> 可开启关闭 验证码校验
# 验证码类型 math 数组计算 char 字符验证
type: CHAR
# line 线段干扰 circle 圆圈干扰 shear 扭曲干扰
category: CIRCLE
# 数字验证码位数
numberLength: 1
# 字符验证码长度
charLength: 4
# 开发环境配置
server:
# 服务器的HTTP端口,默认为8080
port: 8081
servlet:
# 应用的访问路径
context-path: /
# undertow 配置
undertow:
# HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的
max-http-post-size: -1
# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
# 每块buffer的空间大小,越小的空间被利用越充分
buffer-size: 512
# 是否分配的直接内存
direct-buffers: true
threads:
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
io: 8
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
worker: 256
# 日志配置
logging:
level:
com.coin: @logging.level@
org.springframework: warn
config: classpath:logback-plus.xml
# 用户配置
user:
password:
# 密码最大错误次数
maxRetryCount: 5
# 密码锁定时间(默认10分钟)
lockTime: 10
# Spring配置
spring:
application:
name: ${ruoyi.name}
# 资源信息
messages:
# 国际化资源文件路径
basename: i18n/messages
profiles:
active: @profiles.active@
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
mvc:
format:
date-time: yyyy-MM-dd HH:mm:ss
jackson:
# 日期格式化
date-format: yyyy-MM-dd HH:mm:ss
serialization:
# 格式化输出
indent_output: false
# 忽略无法转换的对象
fail_on_empty_beans: false
deserialization:
# 允许对象忽略json中不存在的属性
fail_on_unknown_properties: false
# Sa-Token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: Authorization
# token有效期 设为一天 (必定过期) 单位: 秒
timeout: 86400
# 多端不同 token 有效期 可查看 LoginHelper.loginByDevice 方法自定义
# token最低活跃时间 (指定时间无操作就过期) 单位: 秒
active-timeout: 1800
# 允许动态设置 token 有效期
dynamic-active-timeout: true
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# 是否尝试从header里读取token
is-read-header: true
# 是否尝试从cookie里读取token
is-read-cookie: false
# token前缀
token-prefix: "Bearer"
# jwt秘钥
jwt-secret-key: abcdefghijklmnopqrstuvwxyz
# security配置
security:
# 排除路径
excludes:
# 静态资源
- /*.html
- /**/*.html
- /**/*.css
- /**/*.js
# 公共路径
- /favicon.ico
- /error
# swagger 文档配置
- /*/api-docs
- /*/api-docs/**
# actuator 监控配置
- /actuator
- /actuator/**
# app端口
- /commonFile/**
# MyBatisPlus配置
# https://baomidou.com/config/
mybatis-plus:
# 不支持多包, 如有需要可在注解配置 或 提升扫包等级
# 例如 com.**.**.mapper
mapperPackage: com.coin.**.mapper
# 对应的 XML 文件位置
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.coin.**.domain
# 启动时是否检查 MyBatis XML 文件的存在,默认不检查
checkConfigLocation: false
configuration:
# 自动驼峰命名规则(camel case)映射
mapUnderscoreToCamelCase: true
# MyBatis 自动映射策略
# NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射
autoMappingBehavior: PARTIAL
# MyBatis 自动映射时未知列或未知属性处理策
# NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息
autoMappingUnknownColumnBehavior: NONE
# 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl
# 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl
# 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl
# logImpl: org.apache.ibatis.logging.slf4j.Slf4jImpl
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
# 是否打印 Logo banner
banner: true
dbConfig:
# 主键类型
# AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
idType: ASSIGN_ID
# 逻辑已删除值
logicDeleteValue: 2
# 逻辑未删除值
logicNotDeleteValue: 0
# 字段验证策略之 insert,在 insert 的时候的字段验证策略
# IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 默认 NEVER 不加入 SQL
insertStrategy: NOT_NULL
# 字段验证策略之 update,在 update 的时候的字段验证策略
updateStrategy: NOT_NULL
# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件
where-strategy: NOT_NULL
# 数据加密
mybatis-encryptor:
# 是否开启加密
enable: false
# 默认加密算法
algorithm: BASE64
# 编码方式 BASE64/HEX。默认BASE64
encode: BASE64
# 安全秘钥 对称算法的秘钥 如:AES,SM4
password:
# 公私钥 非对称算法的公私钥 如:SM2,RSA
publicKey:
privateKey:
springdoc:
api-docs:
# 是否开启接口文档
enabled: true
# swagger-ui:
# # 持久化认证数据
# persistAuthorization: true
info:
# 标题
title: '标题:${ruoyi.name}后台管理系统_接口文档'
# 描述
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
# 版本
version: '版本号: ${ruoyi-vue-plus.version}'
# 作者信息
contact:
name: Lion Li
email: crazylionli@163.com
url: https://gitee.com/dromara/RuoYi-Vue-Plus
components:
# 鉴权方式配置
security-schemes:
apiKey:
type: APIKEY
in: HEADER
name: ${sa-token.token-name}
#这里定义了两个分组,可定义多个,也可以不定义
group-configs:
- group: 1.演示模块
packages-to-scan: com.coin.demo
- group: 2.系统模块
packages-to-scan: com.coin.web
- group: 3.代码生成模块
packages-to-scan: com.coin.generator
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
# 全局线程池相关配置
thread-pool:
# 是否开启线程池
enabled: false
# 队列最大长度
queueCapacity: 128
# 线程池维护线程所允许的空闲时间
keepAliveSeconds: 300
--- # 分布式锁 lock4j 全局配置
lock4j:
# 获取分布式锁超时时间,默认为 3000 毫秒
acquire-timeout: 3000
# 分布式锁的超时时间,默认为 30 秒
expire: 30000
--- # Actuator 监控端点的配置项
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: ALWAYS
logfile:
external-file: ./logs/sys-console.log
#<<<<<<< HEAD
# 文件上传配置
file:
upload:
path: ./img
maxSize: 10
sourcePath: ./img/preview
#=======
#
## 文件上传配置
#file:
# upload:
# path: /Users/jian/coin/fundHold/coin/file
# maxSize: 10
# sourcePath: /file/preview
#>>>>>>> 695ba6d7b9b173c36cd0da900de9afd83d32d219

8
coin-admin/src/main/resources/banner.txt

@ -0,0 +1,8 @@
Application Version: ${ruoyi-vue-plus.version}
Spring Boot Version: ${spring-boot.version}
__________ _____.___.__ ____ ____ __________.__
\______ \__ __ ____\__ | |__| \ \ / /_ __ ____ \______ \ | __ __ ______
| _/ | \/ _ \/ | | | ______ \ Y / | \_/ __ \ ______ | ___/ | | | \/ ___/
| | \ | ( <_> )____ | | /_____/ \ /| | /\ ___/ /_____/ | | | |_| | /\___ \
|____|_ /____/ \____// ______|__| \___/ |____/ \___ > |____| |____/____//____ >
\/ \/ \/ \/

49
coin-admin/src/main/resources/i18n/messages.properties

@ -0,0 +1,49 @@
#错误消息
not.null=* 必须填写
user.jcaptcha.error=验证码错误
user.jcaptcha.expire=验证码已失效
user.not.exists=对不起, 您的账号:{0} 不存在.
user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete=对不起,您的账号:{0} 已被删除
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
role.blocked=角色已封禁,请联系管理员
user.logout.success=退出成功
length.not.valid=长度必须在{min}到{max}个字符之间
user.username.not.blank=用户名不能为空
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
user.username.length.valid=账户长度必须在{min}到{max}个字符之间
user.password.not.blank=用户密码不能为空
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
user.password.not.valid=* 5-50个字符
user.email.not.valid=邮箱格式错误
user.email.not.blank=邮箱不能为空
user.phonenumber.not.blank=用户手机号不能为空
user.mobile.phone.number.not.valid=手机号格式错误
user.login.success=登录成功
user.register.success=注册成功
user.register.save.error=保存用户 {0} 失败,注册账号已存在
user.register.error=注册失败,请联系系统管理人员
user.notfound=请重新登录
user.forcelogout=管理员强制退出,请重新登录
user.unknown.error=未知错误,请重新登录
##文件上传消息
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
upload.filename.exceed.length=上传的文件名最长{0}个字符
##权限
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
repeat.submit.message=不允许重复提交,请稍候再试
rate.limiter.message=访问过于频繁,请稍候再试
sms.code.not.blank=短信验证码不能为空
sms.code.retry.limit.count=短信验证码输入错误{0}次
sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟
email.code.not.blank=邮箱验证码不能为空
email.code.retry.limit.count=邮箱验证码输入错误{0}次
email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟
xcx.code.not.blank=小程序code不能为空

49
coin-admin/src/main/resources/i18n/messages_en_US.properties

@ -0,0 +1,49 @@
#错误消息
not.null=* Required fill in
user.jcaptcha.error=Captcha error
user.jcaptcha.expire=Captcha invalid
user.not.exists=Sorry, your account: {0} does not exist
user.password.not.match=User does not exist/Password error
user.password.retry.limit.count=Password input error {0} times
user.password.retry.limit.exceed=Password input error {0} times, account locked for {1} minutes
user.password.delete=Sorry, your account:{0} has been deleted
user.blocked=Sorry, your account: {0} has been disabled. Please contact the administrator
role.blocked=Role disabled,please contact administrators
user.logout.success=Exit successful
length.not.valid=The length must be between {min} and {max} characters
user.username.not.blank=Username cannot be blank
user.username.not.valid=* 2 to 20 chinese characters, letters, numbers or underscores, and must start with a non number
user.username.length.valid=Account length must be between {min} and {max} characters
user.password.not.blank=Password cannot be empty
user.password.length.valid=Password length must be between {min} and {max} characters
user.password.not.valid=* 5-50 characters
user.email.not.valid=Mailbox format error
user.email.not.blank=Mailbox cannot be blank
user.phonenumber.not.blank=Phone number cannot be blank
user.mobile.phone.number.not.valid=Phone number format error
user.login.success=Login successful
user.register.success=Register successful
user.register.save.error=Failed to save user {0}, The registered account already exists
user.register.error=Register failed, please contact system administrator
user.notfound=Please login again
user.forcelogout=The administrator is forced to exit,please login again
user.unknown.error=Unknown error, please login again
##文件上传消息
upload.exceed.maxSize=The uploaded file size exceeds the limit file size!<br/>the maximum allowed file size is:{0}MB!
upload.filename.exceed.length=The maximum length of uploaded file name is {0} characters
##权限
no.permission=You do not have permission to the data,please contact your administrator to add permissions [{0}]
no.create.permission=You do not have permission to create data,please contact your administrator to add permissions [{0}]
no.update.permission=You do not have permission to modify data,please contact your administrator to add permissions [{0}]
no.delete.permission=You do not have permission to delete data,please contact your administrator to add permissions [{0}]
no.export.permission=You do not have permission to export data,please contact your administrator to add permissions [{0}]
no.view.permission=You do not have permission to view data,please contact your administrator to add permissions [{0}]
repeat.submit.message=Repeat submit is not allowed, please try again later
rate.limiter.message=Visit too frequently, please try again later
sms.code.not.blank=Sms code cannot be blank
sms.code.retry.limit.count=Sms code input error {0} times
sms.code.retry.limit.exceed=Sms code input error {0} times, account locked for {1} minutes
email.code.not.blank=Email code cannot be blank
email.code.retry.limit.count=Email code input error {0} times
email.code.retry.limit.exceed=Email code input error {0} times, account locked for {1} minutes
xcx.code.not.blank=Mini program code cannot be blank

49
coin-admin/src/main/resources/i18n/messages_zh_CN.properties

@ -0,0 +1,49 @@
#错误消息
not.null=* 必须填写
user.jcaptcha.error=验证码错误
user.jcaptcha.expire=验证码已失效
user.not.exists=对不起, 您的账号:{0} 不存在.
user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete=对不起,您的账号:{0} 已被删除
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
role.blocked=角色已封禁,请联系管理员
user.logout.success=退出成功
length.not.valid=长度必须在{min}到{max}个字符之间
user.username.not.blank=用户名不能为空
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
user.username.length.valid=账户长度必须在{min}到{max}个字符之间
user.password.not.blank=用户密码不能为空
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
user.password.not.valid=* 5-50个字符
user.email.not.valid=邮箱格式错误
user.email.not.blank=邮箱不能为空
user.phonenumber.not.blank=用户手机号不能为空
user.mobile.phone.number.not.valid=手机号格式错误
user.login.success=登录成功
user.register.success=注册成功
user.register.save.error=保存用户 {0} 失败,注册账号已存在
user.register.error=注册失败,请联系系统管理人员
user.notfound=请重新登录
user.forcelogout=管理员强制退出,请重新登录
user.unknown.error=未知错误,请重新登录
##文件上传消息
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
upload.filename.exceed.length=上传的文件名最长{0}个字符
##权限
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
repeat.submit.message=不允许重复提交,请稍候再试
rate.limiter.message=访问过于频繁,请稍候再试
sms.code.not.blank=短信验证码不能为空
sms.code.retry.limit.count=短信验证码输入错误{0}次
sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟
email.code.not.blank=邮箱验证码不能为空
email.code.retry.limit.count=邮箱验证码输入错误{0}次
email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟
xcx.code.not.blank=小程序code不能为空

BIN
coin-admin/src/main/resources/ip2region.xdb

Binary file not shown.

129
coin-admin/src/main/resources/logback-plus.xml

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="log.path" value="./logs"/>
<property name="console.log.pattern"
value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${console.log.pattern}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<!-- 控制台输出 -->
<appender name="file_console" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-console.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-console.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大 1天 -->
<maxHistory>1</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
</filter>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- info异步输出 -->
<appender name="async_info" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="file_info"/>
</appender>
<!-- error异步输出 -->
<appender name="async_error" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="file_error"/>
</appender>
<!-- 整合 skywalking 控制台输出 tid -->
<!-- <appender name="console" class="ch.qos.logback.core.ConsoleAppender">-->
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>-->
<!-- </layout>-->
<!-- <charset>utf-8</charset>-->
<!-- </encoder>-->
<!-- </appender>-->
<!-- 整合 skywalking 推送采集日志 -->
<!-- <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">-->
<!-- <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
<!-- <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
<!-- <pattern>[%tid] ${console.log.pattern}</pattern>-->
<!-- </layout>-->
<!-- <charset>utf-8</charset>-->
<!-- </encoder>-->
<!-- </appender>-->
<!--系统操作日志-->
<root level="info">
<appender-ref ref="console" />
<appender-ref ref="async_info" />
<appender-ref ref="async_error" />
<appender-ref ref="file_console" />
<!-- <appender-ref ref="sky_log"/>-->
</root>
</configuration>

28
coin-admin/src/main/resources/spy.properties

@ -0,0 +1,28 @@
# p6spy 性能分析插件配置文件
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
#deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# SQL语句打印时间格式
databaseDialectTimestampFormat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
# 是否过滤 Log
filter=true
# 过滤 Log 时所排除的 sql 关键字,以逗号分隔
exclude=SELECT 1

45
coin-admin/src/test/java/com/coin/test/AssertUnitTest.java

@ -0,0 +1,45 @@
package com.coin.test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
/**
* 断言单元测试案例
*
* @author Lion Li
*/
@DisplayName("断言单元测试案例")
public class AssertUnitTest {
@DisplayName("测试 assertEquals 方法")
@Test
public void testAssertEquals() {
Assertions.assertEquals("666", new String("666"));
Assertions.assertNotEquals("666", new String("666"));
}
@DisplayName("测试 assertSame 方法")
@Test
public void testAssertSame() {
Object obj = new Object();
Object obj1 = obj;
Assertions.assertSame(obj, obj1);
Assertions.assertNotSame(obj, obj1);
}
@DisplayName("测试 assertTrue 方法")
@Test
public void testAssertTrue() {
Assertions.assertTrue(true);
Assertions.assertFalse(true);
}
@DisplayName("测试 assertNull 方法")
@Test
public void testAssertNull() {
Assertions.assertNull(null);
Assertions.assertNotNull(null);
}
}

70
coin-admin/src/test/java/com/coin/test/DemoUnitTest.java

@ -0,0 +1,70 @@
package com.coin.test;
import com.coin.common.config.RuoYiConfig;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.TimeUnit;
/**
* 单元测试案例
*
* @author Lion Li
*/
@SpringBootTest // 此注解只能在 springboot 主包下使用 需包含 main 方法与 yml 配置文件
@DisplayName("单元测试案例")
public class DemoUnitTest {
@Autowired
private RuoYiConfig ruoYiConfig;
@DisplayName("测试 @SpringBootTest @Test @DisplayName 注解")
@Test
public void testTest() {
System.out.println(ruoYiConfig);
}
@Disabled
@DisplayName("测试 @Disabled 注解")
@Test
public void testDisabled() {
System.out.println(ruoYiConfig);
}
@Timeout(value = 2L, unit = TimeUnit.SECONDS)
@DisplayName("测试 @Timeout 注解")
@Test
public void testTimeout() throws InterruptedException {
Thread.sleep(3000);
System.out.println(ruoYiConfig);
}
@DisplayName("测试 @RepeatedTest 注解")
@RepeatedTest(3)
public void testRepeatedTest() {
System.out.println(666);
}
@BeforeAll
public static void testBeforeAll() {
System.out.println("@BeforeAll ==================");
}
@BeforeEach
public void testBeforeEach() {
System.out.println("@BeforeEach ==================");
}
@AfterEach
public void testAfterEach() {
System.out.println("@AfterEach ==================");
}
@AfterAll
public static void testAfterAll() {
System.out.println("@AfterAll ==================");
}
}

72
coin-admin/src/test/java/com/coin/test/ParamUnitTest.java

@ -0,0 +1,72 @@
package com.coin.test;
import com.coin.common.enums.UserType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.params.provider.ValueSource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/**
* 带参数单元测试案例
*
* @author Lion Li
*/
@DisplayName("带参数单元测试案例")
public class ParamUnitTest {
@DisplayName("测试 @ValueSource 注解")
@ParameterizedTest
@ValueSource(strings = {"t1", "t2", "t3"})
public void testValueSource(String str) {
System.out.println(str);
}
@DisplayName("测试 @NullSource 注解")
@ParameterizedTest
@NullSource
public void testNullSource(String str) {
System.out.println(str);
}
@DisplayName("测试 @EnumSource 注解")
@ParameterizedTest
@EnumSource(UserType.class)
public void testEnumSource(UserType type) {
System.out.println(type.getUserType());
}
@DisplayName("测试 @MethodSource 注解")
@ParameterizedTest
@MethodSource("getParam")
public void testMethodSource(String str) {
System.out.println(str);
}
public static Stream<String> getParam() {
List<String> list = new ArrayList<>();
list.add("t1");
list.add("t2");
list.add("t3");
return list.stream();
}
@BeforeEach
public void testBeforeEach() {
System.out.println("@BeforeEach ==================");
}
@AfterEach
public void testAfterEach() {
System.out.println("@AfterEach ==================");
}
}

54
coin-admin/src/test/java/com/coin/test/TagUnitTest.java

@ -0,0 +1,54 @@
package com.coin.test;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.context.SpringBootTest;
/**
* 标签单元测试案例
*
* @author Lion Li
*/
@SpringBootTest
@DisplayName("标签单元测试案例")
public class TagUnitTest {
@Tag("dev")
@DisplayName("测试 @Tag dev")
@Test
public void testTagDev() {
System.out.println("dev");
}
@Tag("prod")
@DisplayName("测试 @Tag prod")
@Test
public void testTagProd() {
System.out.println("prod");
}
@Tag("local")
@DisplayName("测试 @Tag local")
@Test
public void testTagLocal() {
System.out.println("local");
}
@Tag("exclude")
@DisplayName("测试 @Tag exclude")
@Test
public void testTagExclude() {
System.out.println("exclude");
}
@BeforeEach
public void testBeforeEach() {
System.out.println("@BeforeEach ==================");
}
@AfterEach
public void testAfterEach() {
System.out.println("@AfterEach ==================");
}
}

BIN
coin-app/.DS_Store

Binary file not shown.

23
coin-app/Dockerfile

@ -0,0 +1,23 @@
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER Lion Li
RUN mkdir -p /ruoyi/server/logs \
/ruoyi/server/temp \
/ruoyi/skywalking/agent
WORKDIR /ruoyi/server
ENV SERVER_PORT=8080
EXPOSE ${SERVER_PORT}
ADD ./target/ruoyi-admin.jar ./app.jar
ENTRYPOINT ["java", \
"-Djava.security.egd=file:/dev/./urandom", \
"-Dserver.port=${SERVER_PORT}", \
# 应用名称 如果想区分集群节点监控 改成不同的名称即可
# "-Dskywalking.agent.service_name=ruoyi-server", \
# "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \
"-jar", "app.jar"]

136
coin-app/pom.xml

@ -0,0 +1,136 @@
<?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">
<parent>
<groupId>com.coin</groupId>
<artifactId>coin-vue-plus</artifactId>
<version>4.8.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>coin-app</artifactId>
<description>
app服务入口
</description>
<dependencies>
<!-- spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- Oracle -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
</dependency>
<!-- PostgreSql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- SqlServer -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-framework</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-system</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-job</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-oss</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-generator</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<!-- demo模块 -->
<dependency>
<groupId>com.coin</groupId>
<artifactId>coin-demo</artifactId>
<version>${coin-vue-plus.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- skywalking 整合 logback -->
<!-- <dependency>-->
<!-- <groupId>org.apache.skywalking</groupId>-->
<!-- <artifactId>apm-toolkit-logback-1.x</artifactId>-->
<!-- <version>${与你的agent探针版本保持一致}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.skywalking</groupId>-->
<!-- <artifactId>apm-toolkit-trace</artifactId>-->
<!-- <version>${与你的agent探针版本保持一致}</version>-->
<!-- </dependency>-->
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>

BIN
coin-app/src/.DS_Store

Binary file not shown.

BIN
coin-app/src/main/.DS_Store

Binary file not shown.

BIN
coin-app/src/main/java/.DS_Store

Binary file not shown.

BIN
coin-app/src/main/java/com/.DS_Store

Binary file not shown.

21
coin-app/src/main/java/com/coin/CoinAppApplication.java

@ -0,0 +1,21 @@
package com.coin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
/**
* 启动程序
*
* @author coin
*/
@SpringBootApplication(scanBasePackages = {"com.coin"})
public class CoinAppApplication {
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication application = new SpringApplication(CoinAppApplication.class);
application.setApplicationStartup(new BufferingApplicationStartup(2048));
application.run(args);
System.out.println("(♥◠‿◠)ノ゙ Coin app 启动成功 ლ(´ڡ`ლ)゙");
}
}

18
coin-app/src/main/java/com/coin/CoinAppServletInitializer.java

@ -0,0 +1,18 @@
package com.coin;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* web容器中进行部署
*
* @author coin
*/
public class CoinAppServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(CoinAppApplication.class);
}
}

197
coin-app/src/main/java/com/coin/app/controller/common/CaptchaController.java

@ -0,0 +1,197 @@
package com.coin.app.controller.common;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.coin.business.domain.bo.UserAccountBo;
import com.coin.business.domain.bo.UserRegisterBo;
import com.coin.business.domain.vo.UserAccountVo;
import com.coin.business.service.IUserAccountService;
import com.coin.business.service.IUserRegisterService;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.constant.CacheConstants;
import com.coin.common.constant.Constants;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.entity.SysUser;
import com.coin.common.core.domain.model.RegisterBody;
import com.coin.common.enums.CaptchaType;
import com.coin.common.exception.ServiceException;
import com.coin.common.utils.BeanCopyUtils;
import com.coin.common.utils.StringUtils;
import com.coin.common.utils.code.BusinessCodeUtils;
import com.coin.common.utils.email.MailUtils;
import com.coin.common.utils.redis.RedisUtils;
import com.coin.common.utils.reflect.ReflectUtils;
import com.coin.common.utils.spring.SpringUtils;
import com.coin.framework.config.properties.CaptchaProperties;
import com.coin.framework.config.properties.MailProperties;
import com.coin.system.service.ISysConfigService;
import com.coin.system.service.SysRegisterService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.groovy.util.BeanUtils;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.dromara.sms4j.provider.enumerate.SupplierType;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 验证码操作处理
*
* @author Lion Li
*/
@SaIgnore
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/appCommon")
public class CaptchaController {
private final CaptchaProperties captchaProperties;
private final ISysConfigService configService;
private final MailProperties mailProperties;
private final SysRegisterService registerService;
private final IUserAccountService userAccountService;
private final IUserRegisterService userRegisterService;
/**
* 用户注册
*/
@SaIgnore
@RepeatSubmit()
@PostMapping("/register")
public R<Void> register(@Validated @RequestBody RegisterBody user) {
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) {
return R.fail("当前系统没有开启注册功能!");
}
try {
// 先校验手机号是否存在
String phone = user.getPhone();
if (userRegisterService.checkByPhone(phone)) {
return R.fail("手机号已存在!");
}
// 1. 处理用户信息
UserRegisterBo userRegisterBo = BeanUtil.copyProperties(user, UserRegisterBo.class);
userRegisterBo.setUserId(BusinessCodeUtils.generateSnowFlakeStr()); // 生成 id
userRegisterBo.setPasswd(BCrypt.hashpw(user.getPassword())); // 加密密码
userRegisterBo.setAccount(user.getPhone()); // 初始用户名
userRegisterBo.setStatus(0L); // 设置状态
userRegisterBo.setUserLevel("0"); // 默认普通用户
if (userRegisterService.insertByBo(userRegisterBo)) {
// 2. 创建账户
// UserAccountBo userAccount = new UserAccountBo();
// userAccount.setAccountId(BusinessCodeUtils.generateUserAccountId())
// .setUserId(userRegisterBo.getUserId()) // 用户id
// .setUserType("0") // 用户类型
// .setAccountType(0) // 0: 普通账户
// .setStatus(0) // 状态 0: 正常
// .setAccountAmount(new BigDecimal(0)); // 初始余额为 0
// userAccountService.insertByBo(userAccount); // 创建账户
return R.ok("注册成功!");
} else {
throw new ServiceException("注册失败,请稍后再试~");
}
} catch (Exception e) {
log.error("用户注册失败", e);
return R.fail("注册异常:" + e.getMessage());
}
}
/**
* 短信验证码
*
* @param phonenumber 用户手机号
*/
@GetMapping("/captchaSms")
public R<Void> smsCaptcha(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) {
String key = CacheConstants.CAPTCHA_CODE_KEY + phonenumber;
String code = RandomUtil.randomNumbers(4);
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
// 验证码模板id 自行处理 (查数据库或写死均可)
String templateId = "";
LinkedHashMap<String, String> map = new LinkedHashMap<>(1);
map.put("code", code);
SmsBlend smsBlend = SmsFactory.createSmsBlend(SupplierType.ALIBABA);
SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, templateId, map);
if (!"OK".equals(smsResponse.getCode())) {
log.error("验证码短信发送异常 => {}", smsResponse);
return R.fail(smsResponse.getMessage());
}
return R.ok();
}
/**
* 邮箱验证码
*
* @param email 邮箱
*/
@GetMapping("/captchaEmail")
public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) {
if (!mailProperties.getEnabled()) {
return R.fail("当前系统没有开启邮箱功能!");
}
String key = CacheConstants.CAPTCHA_CODE_KEY + email;
String code = RandomUtil.randomNumbers(4);
RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
try {
MailUtils.sendText(email, "登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。");
} catch (Exception e) {
log.error("验证码短信发送异常 => {}", e.getMessage());
return R.fail(e.getMessage());
}
return R.ok();
}
/**
* 生成验证码
*/
@GetMapping("/captchaImage")
public R<Map<String, Object>> getCode() {
Map<String, Object> ajax = new HashMap<>();
boolean captchaEnabled = configService.selectCaptchaEnabled();
ajax.put("captchaEnabled", captchaEnabled);
if (!captchaEnabled) {
return R.ok(ajax);
}
// 保存验证码信息
String uuid = IdUtil.simpleUUID();
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
// 生成验证码
CaptchaType captchaType = captchaProperties.getType();
boolean isMath = CaptchaType.MATH == captchaType;
Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
captcha.setGenerator(codeGenerator);
captcha.createCode();
String code = captcha.getCode();
if (isMath) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
code = exp.getValue(String.class);
}
RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
ajax.put("uuid", uuid);
ajax.put("img", captcha.getImageBase64());
return R.ok(ajax);
}
}

74
coin-app/src/main/java/com/coin/app/controller/common/QRCodeController.java

@ -0,0 +1,74 @@
package com.coin.app.controller.common;
import com.coin.system.vo.DealItemVO;
import com.coin.app.service.QRCodeService;
import com.coin.common.core.domain.R;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
* 二维码处理接口
*
* @CreateTime 2025年02月25日 14:09:00
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/appQRCode")
public class QRCodeController {
private final QRCodeService qrCodeService;
/**
* 二维码合规校验
*
* @param code 二维码字符串
* @return 校验结果
*/
@GetMapping("/verifyCode/{code}")
public R<Boolean> verifyCode(@PathVariable("code") String code) {
return R.ok("ok", qrCodeService.verifyCode(code));
}
/**
* 收款码生成
*
* @param dealItem 交易信息
* @return 生成结果
*/
@PostMapping("/genReceiveCode")
public R<String> genReceiveCode(@RequestBody DealItemVO dealItem) {
return R.ok("ok", qrCodeService.genReceiveCode(dealItem));
}
/**
* 付款码生成
*
* @param dealItem 交易信息
* @return 生成结果
*/
@PostMapping("/genPayCode")
public R<String> genPayCode(@RequestBody DealItemVO dealItem) {
return R.ok("ok", qrCodeService.genPayCode(dealItem));
}
/**
* 收款码解析
*
* @param code 收款码信息
* @return 解析结果
*/
@GetMapping("/parseReceiveCode/{code}")
public R<Object> parseReceiveCode(@PathVariable("code") String code) {
return R.ok("ok", qrCodeService.parseReceiveCode(code));
}
/**
* 付款码解析
*
* @param code 付款码信息
* @return 解析结果
*/
@GetMapping("/parsePayCode/{code}")
public R<Object> parsePayCode(@PathVariable("code") String code) {
return R.ok(qrCodeService.parsePayCode(code));
}
}

121
coin-app/src/main/java/com/coin/app/controller/common/UserFriendController.java

@ -0,0 +1,121 @@
package com.coin.app.controller.common;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.coin.business.domain.UserInfo;
import com.coin.business.domain.bo.UserFriendBo;
import com.coin.business.domain.bo.UserInfoBo;
import com.coin.business.domain.vo.UserFriendVo;
import com.coin.business.service.IUserFriendService;
import com.coin.common.annotation.Log;
import com.coin.common.annotation.RepeatSubmit;
import com.coin.common.core.controller.BaseController;
import com.coin.common.core.domain.PageQuery;
import com.coin.common.core.domain.R;
import com.coin.common.core.domain.entity.SysUser;
import com.coin.common.core.page.TableDataInfo;
import com.coin.common.core.validate.AddGroup;
import com.coin.common.core.validate.EditGroup;
import com.coin.common.enums.BusinessType;
import com.coin.common.utils.poi.ExcelUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
/**
* 用户好友
*
* @author coin
* @date 2025-02-21
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/appUserFriend")
public class UserFriendController extends BaseController {
private final IUserFriendService iUserFriendService;
/**
* 查询登录用户的好友列表
*/
// @SaCheckPermission("business:userFriend:list")
@GetMapping("/listByUser")
public TableDataInfo<SysUser> listByUser(UserFriendBo bo, PageQuery pageQuery) {
return iUserFriendService.queryPageListByUser(bo, pageQuery);
}
/**
* 查询用户好友列表
*/
// @SaCheckPermission("business:userFriend:list")
@GetMapping("/list")
public TableDataInfo<UserFriendVo> list(UserFriendBo bo, PageQuery pageQuery) {
return iUserFriendService.queryPageList(bo, pageQuery);
}
/**
* 导出用户好友列表
*/
// @SaCheckPermission("business:userFriend:export")
@Log(title = "用户好友", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(UserFriendBo bo, HttpServletResponse response) {
List<UserFriendVo> list = iUserFriendService.queryList(bo);
ExcelUtil.exportExcel(list, "用户好友", UserFriendVo.class, response);
}
/**
* 获取用户好友详细信息
*
* @param id 主键
*/
// @SaCheckPermission("business:userFriend:query")
@GetMapping("/{id}")
public R<UserFriendVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(iUserFriendService.queryById(id));
}
/**
* 新增用户好友
*/
// @SaCheckPermission("business:userFriend:add")
@Log(title = "用户好友", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserFriendBo bo) {
return toAjax(iUserFriendService.insertByBo(bo));
}
/**
* 修改用户好友
*/
// @SaCheckPermission("business:userFriend:edit")
@Log(title = "用户好友", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserFriendBo bo) {
return toAjax(iUserFriendService.updateByBo(bo));
}
/**
* 删除用户好友
*
* @param ids 主键串
*/
// @SaCheckPermission("business:userFriend:remove")
@Log(title = "用户好友", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(iUserFriendService.deleteWithValidByIds(Arrays.asList(ids), true));
}
}

86
coin-app/src/main/java/com/coin/app/controller/deal/DealController.java

@ -0,0 +1,86 @@
package com.coin.app.controller.deal;
import com.coin.business.domain.*;
import com.coin.common.core.domain.entity.SysUser;
import com.coin.common.core.domain.model.LoginUser;
import com.coin.common.helper.LoginHelper;
import com.coin.system.service.ISysUserService;
import com.coin.system.vo.DealItemVO;
import com.coin.app.service.IAppDealService;
import com.coin.common.core.domain.R;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
* APP端交易接口
*
* @CreateTime 2025年02月25日 08:19:00
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/appDeal")
public class DealController {
private final IAppDealService appDealService;
private final ISysUserService userService;
/**
* 创建转账订单
*
* @return 创建结果
*/
@PostMapping("/createTransfer")
public R<DealTransfer> createTransfer(@RequestBody DealItemVO itemVO) {
return R.ok(appDealService.createTransfer(itemVO));
}
/**
* 创建代缴订单
*
* @param itemVO
* @return
*/
@PostMapping("/createPayProxy")
public R<DealProxy> createPayProxy(@RequestBody DealItemVO itemVO) {
return R.ok(appDealService.createProxy(itemVO));
}
/**
* 创建提现订单
*
* @return 创建结果
*/
@PostMapping("/createCashOut")
public R<DealWithdrawal> createDealWithdrawal(@RequestBody DealItemVO itemVO) {
return R.ok(appDealService.createDealWithdrawal(itemVO));
}
/**
* 创建充值订单
*
* @return 创建结果
*/
@PostMapping("/createTopUp")
public R<DealRecharge> createTopUp(@RequestBody DealItemVO itemVO) {
return R.ok(appDealService.createDealRecharge(itemVO));
}
/**
* 创建扫码支付订单
*
* @return 创建结果
*/
@PostMapping("/createPay")
public R<DealPayment> createPay(@RequestBody DealItemVO itemVO) {
return R.ok("ok", appDealService.createPay(itemVO));
}
/**
* 创建扫码收款订单
*
* @return 创建结果
*/
@PostMapping("/createReceive")
public R<DealReceipt> createReceive(@RequestBody DealItemVO itemVO) {
return R.ok("ok", appDealService.createReceive(itemVO));
}
}

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

Loading…
Cancel
Save