在上一章我们创建了基础服务模块,为其他模块提供基础支撑,包括日志、标签、租户、系统设置、数据字典等基础服务。
这一章我们将创建用户服务模块,主要提供客户、平台管理账户、商户等服务。
创建saasdemo-user模块
创建saasdemo-user模块
修改user模块pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>SaasDemo</artifactId><version>1.0-SNAPSHOT</version></parent>
<artifactId>saasdemo-user</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>saasdemo-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
创建namespace
创建user模块namespace
创建应用入口
package org.example.saas.user;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@EnableDiscoveryClient
@ComponentScan(value = {
"com.chia.multienty.core",
"org.example.saas.core",
"org.example.saas.user",
})
@EnableDubbo
@MapperScan(value={"com.chia.multienty.core.mapper","org.example.saas.core.mapper"})
public class UserApplication {
public static void main(String[] args) {
System.setProperty("dubbo.application.logger","slf4j");
ConfigurableApplicationContext context = SpringApplication.run(UserApplication.class, args);
}
}
创建dubbo配置
首先在saasdemo-core中增加如下空接口,后面再填充
创建DubboReferenceConfiguration
package org.example.saas.user.config;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.example.saas.core.dubbo.service.DubboMasterService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnProperty(prefix = "dubbo", name = "enabled", havingValue = "true")
public class DubboReferenceConfiguration {
@Bean
@DubboReference(timeout = 5000)
public ReferenceBean<DubboMasterService> dubboMasterServiceReferenceBean() {
return new ReferenceBean<>();
}
@Bean
public DubboMasterService dubboMasterService(ReferenceBean<DubboMasterService> dubboMasterServiceReferenceBean) {
DubboMasterService dubboMasterService = dubboMasterServiceReferenceBean.getObject();
return dubboMasterService;
}
}
在saasdemo-master模块中实现dubboMasterService接口
实现DubboMasterServiceImpl
package org.example.saas.master.dubbo.service.impl;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboService;
import org.example.saas.core.dubbo.service.DubboMasterService;
@DubboService
@RequiredArgsConstructor
public class DubboMasterServiceImpl implements DubboMasterService {
}
Ok, 现在用户模块构造完成,开始添加配置
切换到nacos后台
创建saasdemo-user-dev.yml
spring:
shardingSphere:
# 开启分片
enabled: true
rabbitmq:
# 禁用rabbitmq, 后面章节需要用到的时候再开放
enabled: false
datasource:
type: com.alibaba.druid.pool.DruidDataSource
dynamic:
enabled: true
# 设置默认数据源为分片数据源
primary: ds_master
datasource:
ds_master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxx.cn:3301/saas_master?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: saas_master
password: xxxxx
# root帐号主要用于flyway进行数据迁移时自动授权,也可以不配置,但是需要先手动授权,否则会报错
ds_root:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxxx.com:3333/mysql?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: root
password: xxxxxxx
kuta:
multi-tenant:
user-module-enabled: true
domain: user.xxx.com
security:
auth:
header: X-TOKEN
token-prefix: USER
base64-secret: 5LmQ6IGa5oOg5piv5LiA5Liq5aW9563667uf5ZWK5aW957O757uf6K+35rOf7zSP5LiN6KaB5Zyo5LiK6Z2i5Y+R5biD6L+d5rOV5L+h5oGv6L+Z5qC3566h55CG5ZGY5Lmf5LiN5aW95aSE55CG55qE
# 令牌持有时间(秒)
token-holding-time: 86400
# 客户持有令牌时间,-1永久
customer-token-time: 86400
# 续期时长
renew-time: 86400
# 是否支持多点登陆
multipoint-login-enabled: true
ignore-paths:
- /file/upload
rsa:
# 请根据自身情况设置
private-key: xxxxxx
public-key: xxxx==
file:
# 大写
storage-mode: LOCAL
custom:
custom-file-upload-service-impl-class: org.example.saas.core.strategy.file.impl.QNYFileUploadServiceImpl
local:
path-prefix: C:\projects\multienty\store
url-prefix: https://${spring.kuta.multi-tenant.domain}/local/
code-generator:
author: "Multi Tenant Auto Generator"
root-package: org.example.saas
common-module-name: saasdemo-core
table-prefix: saas_
# 设置controller类放置模块名称
controller-module-name: saasdemo-user
# controller save path=project-path(user.dir) + "/" + controller-module-name + controller-file-path-suffix
controller-file-path-suffix: /src/main/java/org/example/saas/user/controller
dto-file-path-suffix: /src/main/java/org/example/saas
# AUTO, NONE, INPUT, ASSIGN_ID, ASSIGN_UUID
id-type: INPUT
logic-delete-column-name: deleted
dto-full-package-name: org.example.saas.core.domain.dto
table-fills:
version: INSERT
create_time: INSERT
update_time: UPDATE
deleted: INSERT
status: INSERT
packages:
controller: user.controller
entity: core.pojo
service: core.service.user
mapper: core.mapper
service-impl: core.service.user.impl
dto: core.domain.dto
parameter: core.parameter
formatter:
controller: "%sController"
entity: "%s"
service: "%sService"
service-impl: "%sServiceImpl"
mapper: "%sMapper"
xml: "%sMapper"
database:
host: xxxx.com
port: 3333
db-name: saas_user_1
username: saas_user_1
password: xxxxx
package-merge-mapping:
Customer: user
CustomerWx: user
CustomerAddress: user
CustomerBalance: user
BalanceBill: user
tables:
- saas_customer
- saas_customer_wx
- saas_customer_address
- saas_customer_balance
- saas_balance_bill
创建shardingsphere-saasdemo-user.yml
spring:
shardingsphere:
enabled: true
dataSource:
common:
type: com.alibaba.druid.pool.DruidDataSource
validationQuery: SELECT 1 FROM DUAL
names:
ds_user_1, ds_user_2
ds_user_1:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxxx:3333/saas_user_1?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: saas_user_1
password: xxxxx
ds_user_2:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxxx:3333/saas_user_2?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: saas_user_2
password: xxxxx
rules:
sharding:
tables:
saas_customer:
actualDataNodes: ds_user_${1..2}.saas_customer
saas_balance_bill:
actualDataNodes: ds_user_${1..2}.saas_balance_bill
saas_customer_address:
actualDataNodes: ds_user_${1..2}.saas_customer_address
saas_customer_balance:
actualDataNodes: ds_user_${1..2}.saas_customer_balance
saas_customer_wx:
actualDataNodes: ds_user_${1..2}.saas_customer_wx
shardingAlgorithms:
user-db-inline:
type: INLINE
props:
algorithm-expression: ds_user_${tenant_id % 2 + 1 }
defaultDatabaseStrategy:
standard:
shardingColumn: tenant_id
shardingAlgorithmName: user-db-inline
bindingTables:
- saas_customer, saas_customer_address, saas_customer_balance, saas_customer_wx
props:
sql-show: true
在前期我们并未开启调试,所以有一些公用配置并未配置,现在我们将这些公用配置都配置一下
sms.yml
spring:
sms:
enabled: true
active: aliyun
#阿里云短信
aliyun:
#区域id,参考 https://help.aliyun.com/document_detail/40654.html?spm=a2c6h.13066369.0.0.c85c7eecnh6fH6
region-id: cn-chengdu
#产品名称:云通信短信API产品,开发者无需替换
name: Dysmsapi
#产品域名,开发者无需替换
domain: dysmsapi.aliyuncs.com
#产品keyid
key-id: XXXXX
#产品keysecret
key-secret: XXXXX
#短信签名
sign-name: 百灵鸟
#读取超时时间
read-timeout: 10000
#连接超时时间
connect-timeout: 10000
#运行模式 debug:调试模式(返回9999),release:发布模式,将实际发送短信
running-mode: release
#短信模板编号
templates:
#登陆验证码
verification-code: SMS_26700XXXX
rabbitmq.yml
spring:
rabbitmq:
host: xxx.xxx.xxx.xxx
port: 10086
username: xxxx
password: xxxxx
virtual-host: /
publisher-confirm-type: correlated
publisher-returns: true
retry-execute-cron: "0 0/1 * * * ? "
# 每三分钟从数据库加载需要发送的Rabbit消息
reload-from-db-interval: 180000
retry-running: true
# 每超过1分钟重发一次
resubmit-threshold: 60000
# 重试的时候从缓存中删除阈值,超过(N * retry-threshold)则从缓存中删除
retry-remove-threshold: 5
#虚拟主机,使用server默认host
#virtual-host: JCcccHost
listener:
simple:
# 并行消费数量 格式:N/M-N
concurrency: 1
#手动确认模式
acknowledge-mode: manual
retry:
enabled: true
#最大重试次数
max-attempts: 10
# 重试最大间隔时间
max-interval: 10000
# 重试初始间隔时间
initial-interval: 2000
# 间隔时间乘子,间隔时间*乘子=下一次的间隔时间,最大不能超过设置的最大间隔时间
multiplier: 2
redis.yml
spring:
redis:
enabled: true
host: xxx.xxx.xxx.xxx
port: 8165
password: xxxxx
database: 0
timeout: 10000
runningRedisInitialize: false
pingConnectionInterval: 1000
globalPrefix: KS-
jedis:
pool:
max-active: 6000
max-wait: 1000
max-idle: 400
min-idle: 0
以上公用配置的host、port、username 、password等均替换成您自己的配置即可
现在回到idea,创建以下文件和目录
saasdemo-user配置文件
application.yml
spring:
profiles:
active: dev
dubbo.application.logger: slf4j
bootstrap.yml
server:
port: 8881
spring:
application:
name: saasdemo-user
cloud:
nacos:
discovery:
server-addr: nacos.xxx.com:xxxx
namespace: xxxxx
username: xxxx
password: xxxx
config:
server-addr: nacos.xxxx.cn:xxxx
namespace: xxxxx
username: xxxx
password: xxxx
file-extension: yml
extension-configs[0]:
data-id: shardingsphere-saasdemo-user.yml
group: DEFAULT_GROUP
refresh: true
extension-configs[1]:
data-id: kuta-multi-tenant.yml
group: DEFAULT_GROUP
refresh: true
extension-configs[2]:
data-id: redis.yml
group: DEFAULT_GROUP
refresh: true
extension-configs[3]:
data-id: rabbitmq.yml
group: DEFAULT_GROUP
refresh: true
seata:
enabled: true
application-id: seata-server
# 客户端和服务端在同一个事务组; Seata 事务组编号,用于 TC 集群名, 一定要和 config.tx(nacos) 中配置的相同
tx-service-group: tx_user_group
# 自动数据源代理
enable-auto-data-source-proxy: false
# 数据源代理模式(分布式事务方案)
data-source-proxy-mode: AT
service:
vgroup-mapping:
tx_user_group: default
config:
# support: nacos, consul, apollo, zk, etcd3, file
type: nacos
nacos:
server-addr: xxxx
namespace: xxxx
group: SEATA_GROUP
username: xxxx
password: xxxxx
data-id: seata-server.properties
cluster: default
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: nacos
nacos:
server-addr: nacos.xxxx.cn:xxxx
namespace: xxxx
group: SEATA_GROUP
username: xxxx
password: xxxxx
# 默认TC集群名
cluster: default
# 服务名,与服务端中registry.conf配置要一致
application: seata-server
context-path:
dubbo:
enabled: true
metadata-report:
address: nacos://xxxx.cn:xxxx?username=${dubbo.metadata-report.username}&password=${dubbo.metadata-report.password}
username: xxxx
password: xxxx
parameters:
namespace: xxxxx
retry-times: 30 #重试次数,默认100
cycle-report: false #关闭定时刷新
application:
name: user-provider
# 禁用QOS同一台机器可能会有端口冲突现象
qos-enable: false
qos-accept-foreign-ip: false
service-discovery:
migration: FORCE_APPLICATION # FORCE_APPLICATION,只消费应用级地址,如无地址则报错,单订阅 3.x 地址
protocol:
name: dubbo
port: -1
scan:
base-packages: org.example.saas.user.dubbo.service.impl
cloud:
subscribed-services: saasdemo-master
registry:
address: nacos://xxxx.cn:xxxx?username=${dubbo.metadata-report.username}&password=${dubbo.metadata-report.password}
parameters:
namespace: xxxxxx
consumer:
check: false
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志文件存放路径 -->
<property name="log.path" value="./logs"/>
<!-- 日志文件输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger - [%method,%line] - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 30天 -->
<maxHistory>30</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>
<!-- 日志最大的历史 30天 -->
<maxHistory>30</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>
<!-- 用户访问日志输出 -->
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-user.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 30天 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.chia.multienty.core" level="debug"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<!-- mybatis-plus控制日志级别 -->
<logger name="com.baomidou.mybatisplus" level="error" />
<root level="info">
<appender-ref ref="console"/>
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
</root>
<!--系统用户操作日志-->
<logger name="sys-user" level="info">
<appender-ref ref="sys-user"/>
</logger>
</configuration>
V1.0.0__init_ddl.sql
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `saas_customer`
--
DROP TABLE IF EXISTS `saas_customer`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `saas_customer` (
`customer_id` bigint NOT NULL COMMENT '客户编号',
`tenant_id` bigint NOT NULL COMMENT '租户编号',
`nick_name` varchar(32) NOT NULL COMMENT '昵称',
`sex` tinyint(4) DEFAULT NULL COMMENT '性别',
`birthday` DATETIME DEFAULT NULL COMMENT '生日',
`phone_number` varchar(11) DEFAULT NULL COMMENT '电话号码',
`avatar_url` varchar(256) DEFAULT NULL COMMENT '头像地址',
`in_black_list` bit(1) NOT NULL COMMENT '是否已被拉黑',
`is_member` bit(1) NOT NULL COMMENT '是否会员',
`member_source_type` tinyint(4) NOT NULL COMMENT '会员来源类型',
`member_id` bigint DEFAULT NULL COMMENT '会员编号',
`growth` int NOT NULL COMMENT '成长值',
`credit` int NOT NULL COMMENT '积分',
`status` varchar(32) DEFAULT NULL COMMENT '状态',
`version` bigint NOT NULL COMMENT '乐观锁版本号',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='客户';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_customer_wx`
--
DROP TABLE IF EXISTS `saas_customer_wx`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `saas_customer_wx` (
`customer_id` bigint NOT NULL COMMENT '客户编号',
`tenant_id` bigint NOT NULL COMMENT '租户编号',
`wx_open_id` varchar(64) DEFAULT NULL COMMENT '微信openid',
`wx_union_id` varchar(64) DEFAULT NULL COMMENT '微信unionid',
`wx_nick_name` varchar(32) DEFAULT NULL COMMENT '微信昵称',
`wx_id` varchar(48) DEFAULT NULL COMMENT '微信id',
`access_token` varchar(128) DEFAULT NULL COMMENT '执行令牌',
`refresh_token` varchar(128) DEFAULT NULL COMMENT '刷新令牌',
`status` varchar(32) NOT NULL COMMENT '状态',
`version` bigint NOT NULL COMMENT '乐观锁版本号',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='客户微信';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_customer_address`
--
DROP TABLE IF EXISTS `saas_customer_address`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `saas_customer_address` (
`address_id` bigint NOT NULL COMMENT '客户地址编号',
`customer_id` bigint NOT NULL COMMENT '客户编号',
`tenant_id` bigint NOT NULL COMMENT '租户编号',
`name` varchar(32) NOT NULL COMMENT '收货人姓名',
`phone_number` varchar(11) NOT NULL COMMENT '收货人电话',
`region` varchar(64) NOT NULL COMMENT '地域',
`province` varchar(64) NOT NULL COMMENT '省份',
`city` varchar(64) NOT NULL COMMENT '城市',
`district` varchar(64) NOT NULL COMMENT '区县',
`street` varchar(64) DEFAULT NULL COMMENT '街道',
`house_number` varchar(64) NOT NULL COMMENT '门牌号',
`status` varchar(32) NOT NULL COMMENT '状态',
`version` bigint NOT NULL COMMENT '乐观锁版本号',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='客户地址';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_customer_balance`
--
DROP TABLE IF EXISTS `saas_customer_balance`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `saas_customer_balance` (
`customer_id` bigint NOT NULL COMMENT '客户编号',
`tenant_id` bigint NOT NULL COMMENT '租户编号',
`total` decimal(12,2) NOT NULL COMMENT '总余额',
`usable` decimal(12,2) NOT NULL COMMENT '可用的余额',
`frozen` decimal(12,2) NOT NULL COMMENT '冻结的余额',
`hidden` bit(1) NOT NULL COMMENT '是否隐藏余额',
`status` varchar(32) NOT NULL COMMENT '状态',
`version` bigint NOT NULL COMMENT '乐观锁版本号',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='客户余额';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `saas_balance_bill`
--
DROP TABLE IF EXISTS `saas_balance_bill`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `saas_balance_bill` (
`bill_id` bigint NOT NULL COMMENT '余额变更记录编号',
`customer_id` bigint NOT NULL COMMENT '客户编号',
`tenant_id` bigint DEFAULT NULL COMMENT '租户编号',
`amount` decimal(12,2) DEFAULT NULL COMMENT '变动金额',
`operator` bigint DEFAULT NULL COMMENT '操作者',
`reason` varchar(50) DEFAULT NULL COMMENT '原因',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`trigger` tinyint(4) DEFAULT NULL COMMENT '触发应用编号',
`trade_id` bigint DEFAULT NULL COMMENT '交易编号',
`before` decimal(12,2) DEFAULT NULL COMMENT '变动前余额',
`after` decimal(12,2) DEFAULT NULL COMMENT '变动后余额',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`bill_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='余额账单';
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
OK, 用户模块配置完成, 由于篇幅原因,这一章就不再加入调试部分章节,可能会有部分错误,下一章我们将开始自动生成用户模块的表,自动生成代码,使用postman调试接口, 敬请关注!