This commit is contained in:
2025-12-13 17:44:18 +08:00
commit c7a30fb094
599 changed files with 65988 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
# 设置输出编码为UTF-8
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
chcp.com 65001 | Out-Null
# 目录配置
$OUTPUT_DIR = "./model"
$TARGET_DIR = "../../app/main/model"
$HOME_DIR = Join-Path $PSScriptRoot "..\template"
# 表名列表
$tables = @(
# ============================================
# 新代理系统表
# ============================================
# "admin_api",
# "admin_dict_data",
# "admin_dict_type",
# "admin_menu",
# "admin_promotion_link",
# "admin_promotion_link_stats_history",
# "admin_promotion_link_stats_total",
# "admin_promotion_order",
# "admin_role",
# "admin_role_api",
# "admin_role_menu",
# "admin_user",
# "admin_user_role",
# "agent",
# "agent_commission",
"agent_config"
# "agent_freeze_task",
# "agent_invite_code",
# "agent_invite_code_usage",
# "agent_link",
# "agent_order",
# "agent_product_config",
# "agent_real_name",
# "agent_rebate",
# "agent_relation",
# "agent_short_link",
# "agent_upgrade",
# "agent_wallet",
# "agent_withdrawal",
# "agent_withdrawal_tax",
# "authorization_document",
# "example",
# "feature",
# "global_notifications",
# "order",
# "order_refund",
# "product",
# "product_feature",
# "query",
# "query_cleanup_config",
# "query_cleanup_detail",
# "query_cleanup_log",
# "user",
# "user_auth"
)
# 为每个表生成模型
foreach ($table in $tables) {
Write-Host "正在生成表: $table" -ForegroundColor Green
goctl model mysql datasource -url="qnc:5vg67b3UNHu8@tcp(127.0.0.1:21001)/qnc" -table="$table" -dir="./model" --home="$HOME_DIR" -cache=true --style=goZero
# 移动生成的文件到目标目录
if (Test-Path $OUTPUT_DIR) {
$sourceFiles = Get-ChildItem -Path $OUTPUT_DIR -File
foreach ($file in $sourceFiles) {
$fileName = $file.Name
$targetPath = Join-Path $TARGET_DIR $fileName
$sourcePath = $file.FullName
# 检查文件类型并决定是否移动
$shouldMove = $false
$shouldOverwrite = $false
if ($fileName -eq "vars.go") {
# vars.go: 如果目标目录不存在才移动
if (-not (Test-Path $targetPath)) {
$shouldMove = $true
Write-Host " 移动 $fileName (vars.go 不存在于目标目录)" -ForegroundColor Yellow
}
else {
Write-Host " 跳过 $fileName (vars.go 已存在于目标目录,防止覆盖)" -ForegroundColor Cyan
}
}
elseif ($fileName -match "_gen\.go$") {
# 带 _gen 后缀的文件: 直接覆盖
$shouldMove = $true
$shouldOverwrite = $true
Write-Host " 移动 $fileName (覆盖 _gen 文件)" -ForegroundColor Yellow
}
else {
# 不带 _gen 后缀的文件: 如果目标目录不存在才移动
if (-not (Test-Path $targetPath)) {
$shouldMove = $true
Write-Host " 移动 $fileName (非 _gen 文件不存在于目标目录)" -ForegroundColor Yellow
}
else {
Write-Host " 跳过 $fileName (非 _gen 文件已存在于目标目录,防止覆盖)" -ForegroundColor Cyan
}
}
# 执行移动操作
if ($shouldMove) {
# 确保目标目录存在
if (-not (Test-Path $TARGET_DIR)) {
New-Item -ItemType Directory -Path $TARGET_DIR -Force | Out-Null
}
# 如果目标文件存在且需要覆盖,先删除
if ($shouldOverwrite -and (Test-Path $targetPath)) {
Remove-Item -Path $targetPath -Force
}
# 移动文件
Move-Item -Path $sourcePath -Destination $targetPath -Force
Write-Host " ✓ 已移动到: $targetPath" -ForegroundColor Green
}
}
}
}
Write-Host ""
Write-Host '所有模型文件生成并移动完成!' -ForegroundColor Green
if (Test-Path $OUTPUT_DIR) {
Get-ChildItem -Path $OUTPUT_DIR -File | Remove-Item -Force
}

View File

@@ -0,0 +1,320 @@
# 表结构修改说明
本文档说明系统重构需要的所有表结构修改,包括:
1. UUID迁移将所有bigint类型的ID改为CHAR(36)类型的UUID
2. 用户系统重构删除UserTemp表优化UserAuth表
## 一、UUID迁移
### 1.1 概述
将所有表的主键ID从`bigint`类型改为`CHAR(36)`类型的UUID同时将所有外键关联字段也改为UUID类型。
**注意**:开发环境使用简化版脚本(`uuid_migration_simple.sql`),直接修改表结构,不保留旧数据。
### 1.2 涉及的表
**核心业务表**
- `user` - 用户表
- `agent` - 代理表
- `product` - 产品表
- `order` - 订单表
- `query` - 查询报告表
- `user_auth` - 用户认证表
**代理相关表**
- `agent_commission` - 代理佣金表
- `agent_invite_code` - 代理邀请码表
- `agent_link` - 代理链接表
- `agent_order` - 代理订单表
- `agent_wallet` - 代理钱包表
- `agent_withdrawal` - 代理提现表
- `agent_withdrawal_tax` - 代理提现税费表
- `agent_rebate` - 代理返利表
- `agent_relation` - 代理关系表
- `agent_upgrade` - 代理升级表
- `agent_real_name` - 代理实名表
- `agent_config` - 代理配置表
- `agent_product_config` - 代理产品配置表
- `agent_short_link` - 代理短链表
- `agent_invite_code_usage` - 邀请码使用记录表
- `agent_freeze_task` - 代理冻结任务表
**订单相关表**
- `order_refund` - 订单退款表
**查询相关表**
- `query_cleanup_log` - 查询清理日志表
- `query_cleanup_detail` - 查询清理详情表
- `query_cleanup_config` - 查询清理配置表
**产品相关表**
- `product_feature` - 产品功能表
- `feature` - 功能表
**其他表**
- `authorization_document` - 授权书表
- `global_notifications` - 全局通知表
**管理后台表**
- `admin_user` - 管理员用户表
- `admin_role` - 管理员角色表
- `admin_menu` - 管理员菜单表
- `admin_api` - 管理员API表
- `admin_dict_type` - 字典类型表
- `admin_dict_data` - 字典数据表
- `admin_user_role` - 管理员用户角色关联表
- `admin_role_menu` - 管理员角色菜单关联表
- `admin_role_api` - 管理员角色API关联表
### 1.3 修改内容
**主键字段**
- 所有表的`id`字段:`bigint``CHAR(36)`
- 移除`AUTO_INCREMENT`属性
- 插入时使用`UUID()`函数或应用层生成UUID
**外键字段**(软关联):
- `user_id``bigint``CHAR(36)`
- `agent_id``bigint``CHAR(36)`
- `order_id``bigint``CHAR(36)`
- `product_id``bigint``CHAR(36)`
- `invite_code_id``bigint``CHAR(36)`
- `link_id``bigint``CHAR(36)`
- `commission_id``bigint``CHAR(36)`
- `wallet_id``bigint``CHAR(36)`
- `withdrawal_id``bigint``CHAR(36)`
- `parent_agent_id``bigint``CHAR(36)`
- `team_leader_id``bigint``CHAR(36)`
- `cleanup_log_id``bigint``CHAR(36)`
- `query_id``bigint``CHAR(36)`
- `feature_id``bigint``CHAR(36)`
- `parent_id`(菜单):`bigint``CHAR(36)`
- `dict_type_id``bigint``CHAR(36)`
- `role_id``bigint``CHAR(36)`
- `menu_id``bigint``CHAR(36)`
- `api_id``bigint``CHAR(36)`
- `used_user_id``bigint``CHAR(36)`
- `used_agent_id``bigint``CHAR(36)`
### 1.4 执行脚本
**开发环境**:执行文件 `uuid_migration_simple.sql`
- 直接修改表结构,不保留旧数据
- 适用于开发环境,没有重要数据
**生产环境**:执行文件 `uuid_migration.sql`
- 完整的迁移流程,保留旧数据以便回滚
- 需要分阶段执行,包含数据迁移和验证
**开发环境执行步骤**
1. 直接执行 `uuid_migration_simple.sql`
2. 所有表的主键和外键字段直接改为CHAR(36)
3. 插入新记录时在应用层生成UUID
**注意事项**
- 开发环境脚本直接修改表结构,不保留旧数据
- 如果表中有数据需要先清空数据或手动填充UUID
- 代码层面需要同步修改所有ID字段类型int64 → string
## 二、用户系统重构
### 2.1 概述
删除`UserTemp`表,统一使用`User`表(通过`mobile`字段是否为空区分临时用户和正式用户),优化`UserAuth`表结构。
### 2.2 涉及的表
**需要修改的表**
- `user` - 用户表无需修改结构只需确保mobile可为空
- `user_auth` - 用户认证表(添加唯一索引)
- `user_temp` - 临时用户表(**删除**
**需要迁移数据的表**
- `order` - 订单表更新user_id
- `query` - 查询报告表更新user_id
### 2.3 修改内容
#### 2.3.1 UserAuth表
**添加唯一索引**
```sql
ALTER TABLE `user_auth`
ADD UNIQUE INDEX `uk_auth_type_key` (`auth_type`, `auth_key`);
```
**作用**
- 确保同一个认证方式auth_type + auth_key只能绑定一个用户
- 防止重复绑定
#### 2.3.2 UserTemp表
**删除原因**
- 临时用户可以直接创建User表记录mobile为空
- 临时用户的认证信息存储在UserAuth表
- 通过User.mobile是否为空来区分临时用户和正式用户
- 统一使用User表逻辑更清晰
**删除步骤**
1. 迁移UserTemp数据到User和UserAuth表
2. 更新关联的订单和报告的user_id
3. 验证数据完整性
4. 删除UserTemp表
### 2.4 执行脚本
**开发环境**:执行文件 `user_system_refactor.sql`(已简化)
- 直接删除UserTemp表
- 添加UserAuth唯一索引
**生产环境**:如需数据迁移,请参考完整版脚本
**开发环境执行步骤**
1. 添加UserAuth唯一索引
2. 直接删除UserTemp表
**注意事项**
- 开发环境脚本直接删除UserTemp表不进行数据迁移
- 删除UserTemp表前确保代码中已移除所有对UserTemp表的引用
## 三、执行顺序
### 3.1 推荐执行顺序
**开发环境**
1. **先执行用户系统重构**`user_system_refactor.sql`
- 添加UserAuth唯一索引
- 删除UserTemp表
2. **再执行UUID迁移**`uuid_migration_simple.sql`
- 直接修改所有表结构
- 需要同步修改代码
**生产环境**
1. 先执行用户系统重构(完整版,包含数据迁移)
2. 再执行UUID迁移完整版包含数据迁移和验证
### 3.2 如果先执行UUID迁移
如果先执行UUID迁移需要注意
- UserTemp表的ID也会改为UUID
- 迁移UserTemp数据时需要使用UUID映射
- 用户系统重构脚本需要相应调整
## 四、代码修改清单
### 4.1 UUID迁移需要的代码修改
**Model层**
- 所有Model的ID字段类型`int64``string`
- 所有外键字段类型:`int64``string`
- 移除`AUTO_INCREMENT`相关逻辑
- 插入时生成UUID使用`uuid.NewString()`
**Service层**
- 所有使用ID的地方改为UUID
- 查询条件改为UUID
- 关联查询改为UUID
**API层**
- 请求参数中的ID改为UUID
- 响应数据中的ID改为UUID
**数据库操作**
- 插入操作:使用`uuid.NewString()`生成UUID
- 查询操作使用UUID字符串查询
- 更新操作使用UUID字符串更新
### 4.2 用户系统重构需要的代码修改
**删除UserTemp相关代码**
- 删除`UserTempModel`
- 删除所有使用`UserTemp`的代码
- 删除临时用户创建逻辑中的UserTemp相关代码
**修改用户创建逻辑**
- 临时用户直接创建User记录mobile为空
- 创建UserAuth记录auth_type + auth_key
**修改用户查询逻辑**
- 通过UserAuth表查询用户
- 通过User.mobile是否为空判断用户类型
**修改账号合并逻辑**
- 绑定手机号时,检查手机号是否已存在
- 如果存在,合并账号(迁移数据)
- 如果不存在更新User.mobile
## 五、验证清单
### 5.1 UUID迁移验证
- [ ] 所有表的主键已改为CHAR(36)
- [ ] 所有外键字段已改为CHAR(36)
- [ ] 插入新记录时自动生成UUID
- [ ] 查询操作使用UUID正常
- [ ] 关联查询使用UUID正常
- [ ] 索引和约束已更新
- [ ] 数据完整性验证通过
### 5.2 用户系统重构验证
- [ ] UserAuth表有唯一索引`uk_auth_type_key`
- [ ] UserTemp表数据已迁移如果存在
- [ ] 订单和报告的user_id已更新
- [ ] UserTemp表已删除如果存在
- [ ] 临时用户创建逻辑使用User表
- [ ] 账号合并逻辑正常工作
- [ ] 数据完整性验证通过
## 六、回滚方案
### 6.1 UUID迁移回滚
如果UUID迁移出现问题可以
1. 保留原ID字段迁移脚本中已保留
2. 恢复主键为原ID字段
3. 删除UUID字段
4. 恢复代码使用int64类型
### 6.2 用户系统重构回滚
如果用户系统重构出现问题,可以:
1. 恢复UserTemp表从备份
2. 恢复订单和报告的user_id
3. 恢复代码使用UserTemp表
## 七、常见问题
### 7.1 UUID性能问题
**问题**UUID作为主键可能影响性能
**解答**
- UUID是字符串类型索引效率略低于bigint
- 但UUID的优势是全局唯一适合分布式系统
- 如果性能问题严重可以考虑使用BINARY(16)存储UUID需要转换
### 7.2 UUID长度问题
**问题**CHAR(36)占用空间较大
**解答**
- UUID标准格式是36字符包含连字符
- 如果空间敏感可以使用BINARY(16)存储(需要转换函数)
- 当前使用CHAR(36)便于调试和查看
### 7.3 UserTemp数据迁移问题
**问题**如何确保UserTemp数据正确迁移
**解答**
- 通过auth_type和auth_key匹配UserAuth记录
- 建立UserTemp.id到User.id的映射关系
- 迁移后验证数据完整性
- 保留UserTemp表一段时间确认无误后再删除
## 八、联系信息
如有问题,请联系开发团队。

View File

@@ -0,0 +1,47 @@
-- ============================================
-- 代理短链表
-- 说明:存储推广链接和邀请链接的短链映射关系
--
-- 功能说明:
-- 1. 支持两种类型promotion推广报告和 invite邀请好友
-- 2. 为每个链接生成一个短链标识6位随机字符串
-- 3. 短链格式https://推广域名/s/{short_code}
-- 4. 短链重定向到前端传入的target_path
--
-- 执行步骤:
-- 1. 执行此 SQL 创建表
-- 2. 使用 goctl 生成 Modelagent_short_link -> AgentShortLinkModel
-- 3. 在 servicecontext.go 中添加 AgentShortLinkModel
-- ============================================
CREATE TABLE `agent_short_link` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`type` tinyint NOT NULL COMMENT '类型1=推广报告(promotion)2=邀请好友(invite)',
`link_id` bigint DEFAULT NULL COMMENT '推广链接ID关联agent_link表仅推广报告类型使用',
`invite_code_id` bigint DEFAULT NULL COMMENT '邀请码ID关联agent_invite_code表仅邀请好友类型使用',
`link_identifier` varchar(200) DEFAULT NULL COMMENT '推广链接标识(加密,仅推广报告类型使用)',
`invite_code` varchar(50) DEFAULT NULL COMMENT '邀请码(仅邀请好友类型使用)',
`short_code` varchar(20) NOT NULL COMMENT '短链标识6位随机字符串',
`target_path` varchar(500) NOT NULL COMMENT '目标地址(前端传入,如:/agent/promotionInquire/xxx 或 /register?invite_code=xxx',
`promotion_domain` varchar(200) NOT NULL COMMENT '推广域名(生成短链时使用的域名)',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_short_code` (`short_code`, `del_state`) COMMENT '短链标识唯一索引',
UNIQUE KEY `uk_link_id_type` (
`link_id`,
`type`,
`del_state`
) COMMENT '同一推广链接同一类型只能有一个有效短链',
UNIQUE KEY `uk_invite_code_id_type` (
`invite_code_id`,
`type`,
`del_state`
) COMMENT '同一邀请码同一类型只能有一个有效短链',
KEY `idx_link_identifier` (`link_identifier`) COMMENT '推广链接标识索引',
KEY `idx_invite_code` (`invite_code`) COMMENT '邀请码索引',
KEY `idx_type` (`type`) COMMENT '类型索引',
KEY `idx_create_time` (`create_time`) COMMENT '创建时间索引'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '代理短链表';

View File

@@ -0,0 +1,46 @@
-- ============================================
-- 邀请码使用历史表
-- 说明:记录每次邀请码的使用情况,支持统计和查询
--
-- 功能说明:
-- 1. 记录每个邀请码每次使用的详细信息
-- 2. 支持统计每个邀请码邀请了多少代理
-- 3. 支持查询某个代理是通过哪个邀请码成为代理的
-- 4. 保留完整的使用历史记录
--
-- 执行步骤:
-- 1. 执行此 SQL 创建表和添加字段
-- 2. 使用 goctl 生成 Modelagent_invite_code_usage -> AgentInviteCodeUsageModel
-- 3. 在 servicecontext.go 中添加 AgentInviteCodeUsageModel
-- ============================================
CREATE TABLE `agent_invite_code_usage` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`invite_code_id` bigint NOT NULL COMMENT '邀请码ID关联agent_invite_code表',
`code` varchar(50) NOT NULL COMMENT '邀请码(冗余字段,便于查询)',
`user_id` bigint NOT NULL COMMENT '使用用户ID',
`agent_id` bigint NOT NULL COMMENT '成为的代理ID',
`agent_level` tinyint NOT NULL COMMENT '代理等级1=普通2=黄金3=钻石',
`used_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '使用时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
KEY `idx_invite_code_id` (`invite_code_id`) COMMENT '关联邀请码ID',
KEY `idx_code` (`code`) COMMENT '邀请码索引',
KEY `idx_user_id` (`user_id`) COMMENT '用户ID索引',
KEY `idx_agent_id` (`agent_id`) COMMENT '代理ID索引',
KEY `idx_used_time` (`used_time`) COMMENT '使用时间索引',
KEY `idx_create_time` (`create_time`) COMMENT '创建时间索引',
KEY `idx_code_time` (`code`, `used_time`) COMMENT '邀请码和使用时间复合索引'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '邀请码使用历史表';
-- ============================================
-- 在agent表中添加invite_code_id字段可选便于直接查询代理是通过哪个邀请码成为的
-- ============================================
ALTER TABLE `agent`
ADD COLUMN `invite_code_id` bigint DEFAULT NULL COMMENT '通过哪个邀请码成为代理关联agent_invite_code表' AFTER `team_leader_id`;
ALTER TABLE `agent`
ADD KEY `idx_invite_code_id` (`invite_code_id`) COMMENT '邀请码ID索引';

View File

@@ -0,0 +1,56 @@
-- ============================================
-- 代理配置表重构 SQL 脚本
-- 执行顺序:按照下面的顺序依次执行
-- ============================================
-- ============================================
-- 步骤1删除价格相关配置项
-- 说明价格配置已改为在产品配置表agent_product_config中按产品配置
-- ============================================
DELETE FROM `agent_config` WHERE `config_key` IN (
'base_price',
'system_max_price',
'price_threshold',
'price_fee_rate'
);
-- ============================================
-- 步骤2统一配置键命名
-- 说明:修改配置键名称,使其与代码逻辑一致
-- ============================================
-- 修改等级加成配置键
UPDATE `agent_config` SET `config_key` = 'level_1_bonus' WHERE `config_key` = 'level_bonus_normal';
UPDATE `agent_config` SET `config_key` = 'level_2_bonus' WHERE `config_key` = 'level_bonus_gold';
UPDATE `agent_config` SET `config_key` = 'level_3_bonus' WHERE `config_key` = 'level_bonus_diamond';
-- 修改升级费用配置键
UPDATE `agent_config` SET `config_key` = 'upgrade_to_gold_fee' WHERE `config_key` = 'upgrade_fee_normal_to_gold';
UPDATE `agent_config` SET `config_key` = 'upgrade_to_diamond_fee' WHERE `config_key` = 'upgrade_fee_to_diamond';
-- 修改升级返佣配置键
UPDATE `agent_config` SET `config_key` = 'upgrade_to_gold_rebate' WHERE `config_key` = 'upgrade_rebate_normal_to_gold';
UPDATE `agent_config` SET `config_key` = 'upgrade_to_diamond_rebate' WHERE `config_key` = 'upgrade_rebate_to_diamond';
-- ============================================
-- 步骤3添加缺失的配置项
-- 说明:添加免税额度配置项(如果不存在)
-- ============================================
INSERT INTO `agent_config` (`config_key`, `config_value`, `config_type`, `description`)
SELECT 'tax_exemption_amount', '0.00', 'tax', '提现免税额度默认0'
WHERE NOT EXISTS (
SELECT 1 FROM `agent_config` WHERE `config_key` = 'tax_exemption_amount'
);
-- ============================================
-- 验证查询:检查配置项是否正确
-- ============================================
SELECT `config_key`, `config_value`, `config_type`, `description`
FROM `agent_config`
WHERE `del_state` = 0
ORDER BY `config_type`, `config_key`;
-- ============================================
-- 执行完成后,请重新生成 agent_config 相关的 Model 代码
-- ============================================

View File

@@ -0,0 +1,32 @@
-- ============================================
-- 代理佣金冻结任务表
-- 说明:用于记录需要解冻的佣金冻结任务,保证异步任务的一致性和持久化
-- ============================================
CREATE TABLE `agent_freeze_task` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`agent_id` bigint NOT NULL COMMENT '代理ID',
`order_id` bigint NOT NULL COMMENT '订单ID',
`commission_id` bigint NOT NULL COMMENT '佣金记录ID',
`freeze_amount` decimal(10, 2) NOT NULL COMMENT '冻结金额',
`order_price` decimal(10, 2) NOT NULL COMMENT '订单单价',
`freeze_ratio` decimal(5, 4) NOT NULL DEFAULT 0.1000 COMMENT '冻结比例例如0.1000表示10%',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1=待解冻2=已解冻3=已取消',
`freeze_time` datetime NOT NULL COMMENT '冻结时间',
`unfreeze_time` datetime NOT NULL COMMENT '解冻时间(冻结时间+1个月',
`actual_unfreeze_time` datetime DEFAULT NULL COMMENT '实际解冻时间',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_order_id` (`order_id`),
KEY `idx_commission_id` (`commission_id`),
KEY `idx_status` (`status`),
KEY `idx_unfreeze_time` (`unfreeze_time`),
KEY `idx_agent_status` (`agent_id`, `status`),
KEY `idx_create_time` (`create_time`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '代理佣金冻结任务表';

View File

@@ -0,0 +1,386 @@
-- ============================================
-- 新代理系统数据表创建脚本
-- 说明:创建新代理系统的所有数据表
-- ============================================
-- ============================================
-- 1. 代理基本信息表
-- ============================================
CREATE TABLE `agent` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` bigint NOT NULL COMMENT '用户ID',
`level` tinyint NOT NULL DEFAULT 1 COMMENT '代理等级1=普通2=黄金3=钻石',
`region` varchar(50) DEFAULT NULL COMMENT '区域(可选)',
`mobile` varchar(50) NOT NULL DEFAULT '' COMMENT '手机号(加密)',
`wechat_id` varchar(100) DEFAULT NULL COMMENT '微信号',
`team_leader_id` bigint DEFAULT NULL COMMENT '团队首领ID钻石代理的ID普通/黄金代理指向其团队首领)',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_id` (`user_id`),
KEY `idx_mobile` (`mobile`),
KEY `idx_level` (`level`),
KEY `idx_team_leader_id` (`team_leader_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理基本信息表';
-- ============================================
-- 2. 代理钱包表注意agent_audit 表已废弃,新系统通过邀请码直接成为代理,无需审核)
-- ============================================
-- ============================================
CREATE TABLE `agent_wallet` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`agent_id` bigint NOT NULL COMMENT '代理ID',
`balance` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '可用余额',
`frozen_balance` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '冻结余额',
`total_earnings` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '累计收益',
`withdrawn_amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '累计提现金额',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_agent_id` (`agent_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理钱包表';
-- ============================================
-- 4. 代理上下级关系表(支持脱离关系)
-- ============================================
CREATE TABLE `agent_relation` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`parent_id` bigint NOT NULL COMMENT '上级代理ID',
`child_id` bigint NOT NULL COMMENT '下级代理ID',
`relation_type` tinyint NOT NULL DEFAULT 1 COMMENT '关系类型1=直接关系2=已脱离(历史记录)',
`detach_reason` varchar(100) DEFAULT NULL COMMENT '脱离原因upgrade=升级脱离',
`detach_time` datetime DEFAULT NULL COMMENT '脱离时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_parent_child_type` (`parent_id`, `child_id`, `relation_type`),
KEY `idx_parent_id` (`parent_id`),
KEY `idx_child_id` (`child_id`),
KEY `idx_relation_type` (`relation_type`),
KEY `idx_parent_relation` (`parent_id`, `relation_type`) COMMENT '复合索引:查询有效下级',
KEY `idx_child_relation` (`child_id`, `relation_type`) COMMENT '复合索引:查询有效上级',
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理上下级关系表';
-- ============================================
-- 5. 代理推广链接表
-- ============================================
CREATE TABLE `agent_link` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`agent_id` bigint NOT NULL COMMENT '代理ID',
`user_id` bigint NOT NULL COMMENT '用户ID',
`product_id` bigint NOT NULL COMMENT '产品ID',
`link_identifier` varchar(200) NOT NULL COMMENT '推广链接标识(加密)',
`set_price` decimal(10,2) NOT NULL COMMENT '代理设定价格',
`actual_base_price` decimal(10,2) NOT NULL COMMENT '实际底价(基础底价+等级加成)',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_link_identifier` (`link_identifier`),
UNIQUE KEY `uk_agent_product_price` (`agent_id`, `product_id`, `set_price`, `del_state`) COMMENT '唯一约束:同一代理、同一产品、同一价格只能有一个有效链接',
KEY `idx_agent_id` (`agent_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_product_id` (`product_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理推广链接表';
-- ============================================
-- 6. 代理订单关联表
-- ============================================
CREATE TABLE `agent_order` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`agent_id` bigint NOT NULL COMMENT '代理ID',
`order_id` bigint NOT NULL COMMENT '订单ID',
`product_id` bigint NOT NULL COMMENT '产品ID',
`order_amount` decimal(10,2) NOT NULL COMMENT '订单金额(用户实际支付金额,冗余字段)',
`set_price` decimal(10,2) NOT NULL COMMENT '代理设定价格',
`actual_base_price` decimal(10,2) NOT NULL COMMENT '实际底价(基础底价+等级加成)',
`price_cost` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '提价成本((设定价格-提价标准阈值)×提价手续费比例)',
`agent_profit` decimal(10,2) NOT NULL COMMENT '代理收益(设定价格-实际底价-提价成本)',
`process_status` tinyint NOT NULL DEFAULT 0 COMMENT '处理状态0=待处理1=处理成功2=处理失败',
`process_time` datetime DEFAULT NULL COMMENT '处理时间',
`process_remark` varchar(500) DEFAULT NULL COMMENT '处理备注',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_order_id` (`order_id`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_product_id` (`product_id`),
KEY `idx_process_status` (`process_status`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理订单关联表';
-- ============================================
-- 7. 代理佣金记录表
-- ============================================
CREATE TABLE `agent_commission` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`agent_id` bigint NOT NULL COMMENT '代理ID',
`order_id` bigint NOT NULL COMMENT '订单ID',
`product_id` bigint NOT NULL COMMENT '产品ID',
`amount` decimal(10,2) NOT NULL COMMENT '佣金金额',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1=已发放2=已冻结3=已取消',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_order_id` (`order_id`),
KEY `idx_product_id` (`product_id`),
KEY `idx_status` (`status`),
KEY `idx_agent_status` (`agent_id`, `status`) COMMENT '复合索引:查询代理的佣金记录',
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理佣金记录表';
-- ============================================
-- 8. 代理返佣记录表(等级加成返佣)
-- ============================================
CREATE TABLE `agent_rebate` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`agent_id` bigint NOT NULL COMMENT '获得返佣的代理ID',
`source_agent_id` bigint NOT NULL COMMENT '来源代理ID推广订单的代理',
`order_id` bigint NOT NULL COMMENT '订单ID',
`product_id` bigint NOT NULL COMMENT '产品ID',
`rebate_type` tinyint NOT NULL COMMENT '返佣类型1=直接上级返佣2=钻石上级返佣3=黄金上级返佣',
`level_bonus` decimal(10,2) NOT NULL COMMENT '等级加成金额(来源代理的等级加成)',
`rebate_amount` decimal(10,2) NOT NULL COMMENT '返佣金额',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1=已发放2=已冻结3=已取消',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_source_agent_id` (`source_agent_id`),
KEY `idx_order_id` (`order_id`),
KEY `idx_product_id` (`product_id`),
KEY `idx_rebate_type` (`rebate_type`),
KEY `idx_status` (`status`),
KEY `idx_order_rebate_type` (`order_id`, `rebate_type`) COMMENT '复合索引:查询订单的返佣明细',
KEY `idx_agent_status` (`agent_id`, `status`) COMMENT '复合索引:查询代理的返佣记录',
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理返佣记录表(等级加成返佣)';
-- ============================================
-- 9. 代理升级记录表
-- ============================================
CREATE TABLE `agent_upgrade` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`agent_id` bigint NOT NULL COMMENT '被升级的代理ID',
`from_level` tinyint NOT NULL COMMENT '原等级1=普通2=黄金3=钻石',
`to_level` tinyint NOT NULL COMMENT '目标等级1=普通2=黄金3=钻石',
`upgrade_type` tinyint NOT NULL COMMENT '升级类型1=自主付费2=钻石升级下级',
`upgrade_fee` decimal(10,2) DEFAULT 0.00 COMMENT '升级费用',
`rebate_amount` decimal(10,2) DEFAULT 0.00 COMMENT '返佣金额(给原直接上级)',
`rebate_agent_id` bigint DEFAULT NULL COMMENT '返佣代理ID原直接上级',
`operator_agent_id` bigint DEFAULT NULL COMMENT '操作代理ID如果是钻石升级下级记录操作者',
`order_no` varchar(100) DEFAULT NULL COMMENT '支付订单号(如果是自主付费)',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1=待处理2=已完成3=已失败',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_rebate_agent_id` (`rebate_agent_id`),
KEY `idx_operator_agent_id` (`operator_agent_id`),
KEY `idx_upgrade_type` (`upgrade_type`),
KEY `idx_status` (`status`),
KEY `idx_agent_status` (`agent_id`, `status`) COMMENT '复合索引:查询代理的升级记录',
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理升级记录表';
-- ============================================
-- 10. 代理提现表
-- ============================================
CREATE TABLE `agent_withdrawal` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`agent_id` bigint NOT NULL COMMENT '代理ID',
`withdraw_no` varchar(100) NOT NULL COMMENT '提现单号',
`payee_account` varchar(100) NOT NULL COMMENT '收款账户',
`payee_name` varchar(50) NOT NULL COMMENT '收款人姓名',
`amount` decimal(10,2) NOT NULL COMMENT '提现金额',
`actual_amount` decimal(10,2) NOT NULL COMMENT '实际到账金额(扣除税费后)',
`tax_amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '税费金额',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1=处理中2=成功3=失败',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_withdraw_no` (`withdraw_no`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_status` (`status`),
KEY `idx_agent_status` (`agent_id`, `status`) COMMENT '复合索引:查询代理的提现记录',
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理提现表';
-- ============================================
-- 11. 代理系统配置表
-- ============================================
CREATE TABLE `agent_config` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`config_key` varchar(100) NOT NULL COMMENT '配置键',
`config_value` varchar(500) NOT NULL COMMENT '配置值',
`config_type` varchar(50) NOT NULL COMMENT '配置类型price=价格bonus=等级加成upgrade=升级费用rebate=返佣tax=税费',
`description` varchar(500) DEFAULT NULL COMMENT '配置描述',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_config_key` (`config_key`),
KEY `idx_config_type` (`config_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理系统配置表';
-- ============================================
-- 12. 代理产品配置表(简化版)
-- ============================================
CREATE TABLE `agent_product_config` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`product_id` bigint NOT NULL COMMENT '产品ID',
`product_name` varchar(100) NOT NULL COMMENT '产品名称',
`base_price` decimal(10,2) NOT NULL COMMENT '基础底价BasePrice',
`system_max_price` decimal(10,2) NOT NULL COMMENT '系统价格上限SystemMaxPrice',
`price_threshold` decimal(10,2) DEFAULT NULL COMMENT '提价标准阈值PriceThreshold',
`price_fee_rate` decimal(5,4) DEFAULT NULL COMMENT '提价手续费比例PriceFeeRate',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_product_id` (`product_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理产品配置表';
-- ============================================
-- 13. 代理实名认证表
-- ============================================
CREATE TABLE `agent_real_name` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`agent_id` bigint NOT NULL COMMENT '代理ID',
`name` varchar(50) NOT NULL COMMENT '真实姓名',
`id_card` varchar(50) NOT NULL COMMENT '身份证号(加密)',
`mobile` varchar(50) NOT NULL COMMENT '手机号(加密)',
`verify_time` datetime DEFAULT NULL COMMENT '验证时间三要素验证通过时间NULL表示未验证',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_agent_id` (`agent_id`),
KEY `idx_verify_time` (`verify_time`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理实名认证表';
-- ============================================
-- 14. 代理提现扣税记录表
-- ============================================
CREATE TABLE `agent_withdrawal_tax` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`agent_id` bigint NOT NULL COMMENT '代理ID',
`withdrawal_id` bigint NOT NULL COMMENT '提现记录ID',
`year_month` int NOT NULL COMMENT '年月格式YYYYMM',
`withdrawal_amount` decimal(10,2) NOT NULL COMMENT '提现金额',
`taxable_amount` decimal(10,2) NOT NULL COMMENT '应税金额',
`tax_rate` decimal(5,4) NOT NULL COMMENT '税率',
`tax_amount` decimal(10,2) NOT NULL COMMENT '税费金额',
`actual_amount` decimal(10,2) NOT NULL COMMENT '实际到账金额',
`tax_status` tinyint NOT NULL DEFAULT 1 COMMENT '扣税状态1=待扣税2=已扣税3=扣税失败',
`tax_time` datetime DEFAULT NULL COMMENT '扣税时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_withdrawal_id` (`withdrawal_id`),
KEY `idx_year_month` (`year_month`),
KEY `idx_tax_status` (`tax_status`),
KEY `idx_agent_year_month` (`agent_id`, `year_month`) COMMENT '复合索引:查询代理的月度扣税记录'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理提现扣税记录表';
-- ============================================
-- 初始化系统配置数据
-- ============================================
INSERT INTO `agent_config` (`config_key`, `config_value`, `config_type`, `description`) VALUES
('base_price', '0.00', 'price', '系统基础底价BasePrice'),
('system_max_price', '9999.99', 'price', '系统价格上限SystemMaxPrice'),
('price_threshold', '0.00', 'price', '提价标准阈值PriceThreshold'),
('price_fee_rate', '0.0000', 'price', '提价手续费比例PriceFeeRate'),
('level_bonus_normal', '6.00', 'bonus', '普通代理等级加成6元'),
('level_bonus_gold', '3.00', 'bonus', '黄金代理等级加成3元'),
('level_bonus_diamond', '0.00', 'bonus', '钻石代理等级加成0元'),
('upgrade_fee_normal_to_gold', '199.00', 'upgrade', '普通→黄金升级费用199元'),
('upgrade_fee_to_diamond', '980.00', 'upgrade', '升级为钻石费用980元'),
('upgrade_rebate_normal_to_gold', '139.00', 'upgrade', '普通→黄金返佣金额139元'),
('upgrade_rebate_to_diamond', '680.00', 'upgrade', '升级为钻石返佣金额680元'),
('direct_parent_amount_diamond', '6.00', 'rebate', '直接上级是钻石的返佣金额6元'),
('direct_parent_amount_gold', '3.00', 'rebate', '直接上级是黄金的返佣金额3元'),
('direct_parent_amount_normal', '2.00', 'rebate', '直接上级是普通的返佣金额2元'),
('max_gold_rebate_amount', '3.00', 'rebate', '黄金代理最大返佣金额3元'),
('tax_rate', '0.0600', 'tax', '提现税率6%');
-- ============================================
-- 15. 代理邀请码表
-- ============================================
CREATE TABLE `agent_invite_code` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`code` varchar(50) NOT NULL COMMENT '邀请码(唯一)',
`agent_id` bigint DEFAULT NULL COMMENT '发放代理IDNULL表示平台发放的钻石邀请码',
`target_level` tinyint NOT NULL DEFAULT 1 COMMENT '目标等级1=普通2=黄金3=钻石',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态0=未使用1=已使用2=已失效(钻石邀请码只能使用一次,普通邀请码可无限使用)',
`used_user_id` bigint DEFAULT NULL COMMENT '使用用户ID',
`used_agent_id` bigint DEFAULT NULL COMMENT '使用代理ID',
`used_time` datetime DEFAULT NULL COMMENT '使用时间',
`expire_time` datetime DEFAULT NULL COMMENT '过期时间(可选)',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT 0 COMMENT '删除状态0=未删除1=已删除',
`version` bigint NOT NULL DEFAULT 0 COMMENT '版本号(乐观锁)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_status` (`status`),
KEY `idx_target_level` (`target_level`),
KEY `idx_used_user_id` (`used_user_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='代理邀请码表';
-- ============================================
-- 表创建完成
-- ============================================
-- 执行完成后请使用goctl生成新的Model代码
-- 参考命令见 generate_agent_models.md 文件

View File

@@ -0,0 +1,190 @@
# 生成新代理系统Model说明
## 一、执行数据库迁移
### 1.1 备份数据库(重要!)
```bash
# 备份整个数据库
mysqldump -u root -p your_database > backup_before_migration.sql
# 或者只备份agent相关表
mysqldump -u root -p your_database agent agent_audit agent_closure agent_commission agent_wallet agent_link agent_order agent_rewards agent_membership_config agent_product_config agent_real_name agent_withdrawal agent_withdrawal_tax agent_withdrawal_tax_exemption agent_active_stat agent_platform_deduction agent_commission_deduction agent_membership_recharge_order agent_membership_user_config > agent_tables_backup.sql
```
### 1.2 执行迁移SQL
```bash
# 方式1使用mysql命令行
mysql -u root -p your_database < deploy/sql/agent_system_migration.sql
# 方式2使用数据库客户端工具如Navicat、DBeaver等
# 直接执行 deploy/sql/agent_system_migration.sql 文件
```
## 二、生成Model代码
### 2.1 方式一:使用脚本批量生成(推荐)
**Windows (PowerShell):**
```powershell
# 修改脚本中的数据库配置
# 然后执行需要安装goctl工具
cd deploy/sql
bash generate_agent_models.sh
```
**Linux/Mac:**
```bash
# 修改脚本中的数据库配置
chmod +x deploy/sql/generate_agent_models.sh
cd deploy/sql
./generate_agent_models.sh
```
### 2.2 方式二使用goctl命令逐个生成
```bash
# 1. agent表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 2. agent_audit表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_audit" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 3. agent_wallet表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_wallet" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 4. agent_relation表新表替代agent_closure
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_relation" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 5. agent_link表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_link" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 6. agent_order表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_order" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 7. agent_commission表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_commission" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 8. agent_rebate表新表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_rebate" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 9. agent_upgrade表新表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_upgrade" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 10. agent_withdrawal表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_withdrawal" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 11. agent_config表新表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_config" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 12. agent_product_config表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_product_config" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 13. agent_real_name表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_real_name" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
# 14. agent_withdrawal_tax表
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent_withdrawal_tax" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
```
### 2.3 方式三使用goctl一次性生成所有表
```bash
# 生成所有agent相关表的Model
goctl model mysql datasource -url="root:password@tcp(localhost:3306)/database" -table="agent,agent_audit,agent_wallet,agent_relation,agent_link,agent_order,agent_commission,agent_rebate,agent_upgrade,agent_withdrawal,agent_config,agent_product_config,agent_real_name,agent_withdrawal_tax" -dir="app/main/model" -cache=true --style=goZero --home="./deploy/template"
```
## 三、表结构变化说明
### 3.1 删除的旧表
以下表在新系统中已删除,不再需要:
- `agent_closure` → 被 `agent_relation` 替代
- `agent_commission_deduction` → 新系统不需要
- `agent_rewards` → 新系统不需要
- `agent_membership_config` → 新系统不需要
- `agent_membership_recharge_order` → 新系统不需要
- `agent_membership_user_config` → 新系统不需要
- `agent_platform_deduction` → 新系统不需要
- `agent_active_stat` → 新系统不需要
- `agent_withdrawal_tax_exemption` → 新系统不需要
### 3.2 新增的表
- `agent_relation` - 替代 `agent_closure`,支持关系脱离
- `agent_rebate` - 等级加成返佣记录表
- `agent_upgrade` - 代理升级记录表
- `agent_config` - 代理系统配置表
### 3.3 结构变化的表
以下表结构有变化需要重新生成Model
- `agent` - 等级字段改为数值型,新增 `team_leader_id`
- `agent_audit` - 新增 `ancestor_mobile``audit_user_id` 字段
- `agent_wallet` - 字段保持不变
- `agent_link` - 新增唯一约束
- `agent_order` - 新增 `order_amount``process_status` 等字段
- `agent_commission` - 字段保持不变
- `agent_product_config` - 字段保持不变
- `agent_real_name` - 新增 `audit_user_id` 字段
- `agent_withdrawal` - 字段保持不变
- `agent_withdrawal_tax` - 字段保持不变
## 四、生成后的文件结构
生成后,会在 `app/main/model` 目录下创建以下文件:
```
app/main/model/
├── agentModel.go # agent表Model自定义方法
├── agentModel_gen.go # agent表Model自动生成
├── agentAuditModel.go # agent_audit表Model自定义方法
├── agentAuditModel_gen.go # agent_audit表Model自动生成
├── agentWalletModel.go # agent_wallet表Model自定义方法
├── agentWalletModel_gen.go # agent_wallet表Model自动生成
├── agentRelationModel.go # agent_relation表Model自定义方法
├── agentRelationModel_gen.go # agent_relation表Model自动生成
├── agentLinkModel.go # agent_link表Model自定义方法
├── agentLinkModel_gen.go # agent_link表Model自动生成
├── agentOrderModel.go # agent_order表Model自定义方法
├── agentOrderModel_gen.go # agent_order表Model自动生成
├── agentCommissionModel.go # agent_commission表Model自定义方法
├── agentCommissionModel_gen.go # agent_commission表Model自动生成
├── agentRebateModel.go # agent_rebate表Model自定义方法
├── agentRebateModel_gen.go # agent_rebate表Model自动生成
├── agentUpgradeModel.go # agent_upgrade表Model自定义方法
├── agentUpgradeModel_gen.go # agent_upgrade表Model自动生成
├── agentWithdrawalModel.go # agent_withdrawal表Model自定义方法
├── agentWithdrawalModel_gen.go # agent_withdrawal表Model自动生成
├── agentConfigModel.go # agent_config表Model自定义方法
├── agentConfigModel_gen.go # agent_config表Model自动生成
├── agentProductConfigModel.go # agent_product_config表Model自定义方法
├── agentProductConfigModel_gen.go # agent_product_config表Model自动生成
├── agentRealNameModel.go # agent_real_name表Model自定义方法
├── agentRealNameModel_gen.go # agent_real_name表Model自动生成
├── agentWithdrawalTaxModel.go # agent_withdrawal_tax表Model自定义方法
└── agentWithdrawalTaxModel_gen.go # agent_withdrawal_tax表Model自动生成
```
## 五、注意事项
1. **备份数据**:执行迁移前务必备份数据库
2. **测试环境**:建议先在测试环境执行,验证无误后再在生产环境执行
3. **代码兼容**生成新Model后需要更新相关业务代码以适配新的表结构
4. **删除旧Model**生成新Model后需要删除旧的Model文件`agentClosureModel.go`
5. **更新ServiceContext**:需要在 `svc/servicecontext.go` 中更新Model初始化代码
## 六、验证
生成Model后请验证
1. 所有新表都有对应的Model文件
2. Model文件可以正常编译
3. 数据库连接正常
4. 基本的CRUD操作可以正常执行

View File

@@ -0,0 +1,70 @@
#!/bin/bash
# ============================================
# 生成新代理系统Model脚本
# 使用goctl工具根据数据库表生成Model代码
# ============================================
# 数据库配置(请根据实际情况修改)
DB_HOST="localhost"
DB_PORT="3306"
DB_USER="root"
DB_PASSWORD="your_password"
DB_NAME="your_database"
# Model输出目录
MODEL_DIR="app/main/model"
# goctl模板目录
TEMPLATE_DIR="./deploy/template"
echo "============================================"
echo "开始生成新代理系统Model..."
echo "============================================"
# 生成各个表的Model
echo "1. 生成 agent Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "2. 生成 agent_audit Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_audit" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "3. 生成 agent_wallet Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_wallet" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "4. 生成 agent_relation Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_relation" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "5. 生成 agent_link Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_link" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "6. 生成 agent_order Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_order" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "7. 生成 agent_commission Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_commission" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "8. 生成 agent_rebate Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_rebate" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "9. 生成 agent_upgrade Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_upgrade" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "10. 生成 agent_withdrawal Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_withdrawal" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "11. 生成 agent_config Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_config" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "12. 生成 agent_product_config Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_product_config" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "13. 生成 agent_real_name Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_real_name" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "14. 生成 agent_withdrawal_tax Model..."
goctl model mysql datasource -url="${DB_USER}:${DB_PASSWORD}@tcp(${DB_HOST}:${DB_PORT})/${DB_NAME}" -table="agent_withdrawal_tax" -dir="${MODEL_DIR}" -cache=true --style=goZero --home="${TEMPLATE_DIR}"
echo "============================================"
echo "Model生成完成"
echo "============================================"

View File

@@ -0,0 +1,25 @@
-- ============================================
-- 移除代理产品配置表中的 product_name 字段
-- 说明:改为通过 product_id 关联查询 product 表获取产品名称
-- 执行时间2025-01-XX
-- ============================================
-- 删除 product_name 字段
ALTER TABLE `agent_product_config` DROP COLUMN `product_name`;
-- ============================================
-- 验证查询:检查字段是否已删除
-- ============================================
DESC `agent_product_config`;
-- ============================================
-- 验证查询:通过关联查询获取产品名称
-- ============================================
SELECT apc.id, apc.product_id, p.product_name, apc.base_price, apc.system_max_price, apc.price_threshold, apc.price_fee_rate, apc.del_state, apc.create_time
FROM
`agent_product_config` apc
LEFT JOIN `product` p ON apc.product_id = p.id
AND p.del_state = 0
WHERE
apc.del_state = 0
ORDER BY apc.product_id;

View File

@@ -0,0 +1,112 @@
-- ============================================
-- 同步产品表数据到代理产品配置表
-- 说明:为现有产品创建对应的代理产品配置记录
-- 执行时间2025-01-XX
-- ============================================
-- 方式1使用 INSERT IGNORE如果记录已存在则忽略
-- 注意product_name 字段已移除,改为通过 product_id 关联查询 product 表获取
INSERT IGNORE INTO
`agent_product_config` (
`product_id`,
`base_price`,
`system_max_price`,
`price_threshold`,
`price_fee_rate`,
`del_state`,
`version`
)
VALUES (
1,
0.00,
9999.99,
NULL,
NULL,
0,
0
),
(
2,
0.00,
9999.99,
NULL,
NULL,
0,
0
),
(
3,
0.00,
9999.99,
NULL,
NULL,
0,
0
),
(
4,
0.00,
9999.99,
NULL,
NULL,
0,
0
),
(
5,
0.00,
9999.99,
NULL,
NULL,
0,
0
),
(
6,
0.00,
9999.99,
NULL,
NULL,
0,
0
),
(
7,
0.00,
9999.99,
NULL,
NULL,
0,
0
);
-- ============================================
-- 方式2使用 INSERT ... ON DUPLICATE KEY UPDATE如果记录已存在则忽略
-- 注意product_name 字段已移除,不再需要更新
-- ============================================
/*
INSERT INTO `agent_product_config`
(`product_id`, `base_price`, `system_max_price`, `price_threshold`, `price_fee_rate`, `del_state`, `version`)
VALUES
(1, 0.00, 9999.99, NULL, NULL, 0, 0),
(2, 0.00, 9999.99, NULL, NULL, 0, 0),
(3, 0.00, 9999.99, NULL, NULL, 0, 0),
(4, 0.00, 9999.99, NULL, NULL, 0, 0),
(5, 0.00, 9999.99, NULL, NULL, 0, 0),
(6, 0.00, 9999.99, NULL, NULL, 0, 0),
(7, 0.00, 9999.99, NULL, NULL, 0, 0)
ON DUPLICATE KEY UPDATE
`product_id` = VALUES(`product_id`);
*/
-- ============================================
-- 验证查询:检查同步结果
-- ============================================
SELECT apc.id, apc.product_id, p.product_name, apc.base_price, apc.system_max_price, apc.price_threshold, apc.price_fee_rate, apc.del_state, apc.create_time
FROM
`agent_product_config` apc
LEFT JOIN `product` p ON apc.product_id = p.id
AND p.del_state = 0
WHERE
apc.del_state = 0
ORDER BY apc.product_id;

62
deploy/sql/template.sql Normal file
View File

@@ -0,0 +1,62 @@
-- ============================================
-- 表结构模板UUID版本
-- ============================================
-- 注意系统已迁移到UUID主键新表请使用此模板
-- ============================================
CREATE TABLE `` (
`id` CHAR(36) NOT NULL COMMENT 'UUID主键',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`delete_time` datetime DEFAULT NULL COMMENT '删除时间',
`del_state` tinyint NOT NULL DEFAULT '0',
`version` bigint NOT NULL DEFAULT '0' COMMENT '版本号',
/* 业务字段开始 */
`1` [] [DEFAULT ] [COMMENT '字段说明'],
`2` [] [DEFAULT ] [COMMENT '字段说明'],
/* 关联字段 - 软关联使用UUID */
`id` CHAR(36) [NOT NULL] [DEFAULT NULL] COMMENT '关联到XX表的UUID',
/* 业务字段结束 */
PRIMARY KEY (`id`),
/* 索引定义 */
UNIQUE KEY `` (``),
KEY `idx_关联字段` (`id`) COMMENT '优化关联查询'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='表说明';
-- ============================================
-- UUID生成说明
-- ============================================
-- 1. 应用层生成使用Go的uuid.NewString()生成UUID
-- 示例id := uuid.NewString()
-- 2. 数据库层生成使用MySQL的UUID()函数(不推荐,性能较差)
-- 示例INSERT INTO table (id, ...) VALUES (UUID(), ...)
-- 3. 推荐方式在应用层生成UUID然后插入数据库
-- ============================================
-- ============================================
-- 旧版本模板bigint主键已废弃
-- ============================================
-- CREATE TABLE `表名` (
-- `id` bigint NOT NULL AUTO_INCREMENT,
-- `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- `delete_time` datetime DEFAULT NULL COMMENT '删除时间',
-- `del_state` tinyint NOT NULL DEFAULT '0',
-- `version` bigint NOT NULL DEFAULT '0' COMMENT '版本号',
--
-- /* 业务字段开始 */
-- `字段1` 数据类型 [约束条件] [DEFAULT 默认值] [COMMENT '字段说明'],
-- `字段2` 数据类型 [约束条件] [DEFAULT 默认值] [COMMENT '字段说明'],
-- /* 关联字段 - 软关联 */
-- `关联表id` bigint [NOT NULL] [DEFAULT '0'] COMMENT '关联到XX表的id',
-- /* 业务字段结束 */
--
-- PRIMARY KEY (`id`),
-- /* 索引定义 */
-- UNIQUE KEY `索引名称` (`字段名`),
-- KEY `idx_关联字段` (`关联表id`) COMMENT '优化关联查询'
-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='表说明';
-- ============================================

View File

@@ -0,0 +1,48 @@
-- ============================================
-- 用户系统重构SQL脚本简化版 - 开发环境)
-- 根据《用户系统重构计划书》执行
-- ============================================
-- ============================================
-- 第一部分UserAuth表唯一索引
-- ============================================
-- 确保user_auth表的(auth_type, auth_key)唯一性
-- 如果已存在同名索引,先删除
ALTER TABLE `user_auth` DROP INDEX IF EXISTS `uk_auth_type_key`;
-- 添加唯一索引
ALTER TABLE `user_auth`
ADD UNIQUE INDEX `uk_auth_type_key` (`auth_type`, `auth_key`) COMMENT '确保同一个认证方式只能绑定一个用户';
-- 允许一个用户绑定同一认证类型的多个记录例如多个UUID
ALTER TABLE `user_auth` DROP INDEX IF EXISTS `unique_userId_key`;
ALTER TABLE `user_auth` ADD INDEX `idx_user_id_auth_type` (`user_id`, `auth_type`);
-- ============================================
-- 第二部分删除UserTemp表开发环境直接删除
-- ============================================
-- 注意:开发环境没有数据,直接删除表即可
-- 如果表不存在,会报错但可以忽略
DROP TABLE IF EXISTS `user_temp`;
-- ============================================
-- 第三部分:索引优化(可选)
-- ============================================
-- 为user_auth表添加user_id和auth_type的联合索引如果查询频繁
-- ALTER TABLE `user_auth`
-- ADD INDEX `idx_user_id_auth_type` (`user_id`, `auth_type`) COMMENT '优化按用户查询认证类型';
-- 为user表添加mobile的唯一索引如果不存在
-- ALTER TABLE `user`
-- ADD UNIQUE INDEX `uk_mobile` (`mobile`) COMMENT '确保手机号唯一性';
-- ============================================
-- 注意事项
-- ============================================
-- 1. 此脚本适用于开发环境直接删除UserTemp表
-- 2. 如果生产环境有数据,请使用完整版迁移脚本
-- 3. 执行后确保代码中已移除所有对UserTemp表的引用

View File

@@ -0,0 +1,45 @@
-- 将 user_temp 迁移为 usermobile 为空)与 user_auth
START TRANSACTION;
-- 1) 迁移临时用户到 usermobile 置为空)
INSERT INTO
`user` (
`delete_time`,
`del_state`,
`version`,
`mobile`,
`password`,
`nickname`,
`info`,
`inside`
)
SELECT NULL, 0, COALESCE(ut.version, 0), NULL, NULL, NULL, '', 0
FROM `user_temp` ut
WHERE
ut.del_state = 0;
-- 2) 将临时认证迁移到 user_auth按插入顺序关联最近插入的 user.id
INSERT INTO
`user_auth` (
`delete_time`,
`del_state`,
`version`,
`user_id`,
`auth_key`,
`auth_type`
)
SELECT NULL, 0, COALESCE(ut.version, 0), u.id, ut.auth_key, ut.auth_type
FROM `user_temp` ut
JOIN `user` u ON u.del_state = 0
AND u.mobile IS NULL
WHERE
ut.del_state = 0;
-- 注意以上为示意实际生产应通过显式映射如临时ID与新UserID映射表确保一一对应避免笛卡尔匹配。
COMMIT;
-- 唯一索引保障
ALTER TABLE `user_auth`
ADD UNIQUE INDEX `idx_auth_type_key` (`auth_type`, `auth_key`);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,446 @@
-- ============================================
-- UUID迁移脚本简化版 - 开发环境)
-- 将系统中所有bigint类型的ID字段改为CHAR(36)类型的UUID
-- 注意:此脚本直接修改表结构,不保留旧数据,适用于开发环境
-- ============================================
-- 注意user表和product表已经是CHAR(36)类型,跳过修改
-- ============================================
-- 第一部分:修改核心业务表
-- ============================================
-- user表已经是CHAR(36),跳过
-- product表已经是CHAR(36),跳过
-- order表修改主键和外键字段
ALTER TABLE `order`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL COMMENT '用户UUID',
MODIFY COLUMN `product_id` CHAR(36) NOT NULL COMMENT '产品UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_user_id` (`user_id`),
ADD INDEX `idx_product_id` (`product_id`);
-- query表修改主键和外键字段
ALTER TABLE `query`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `order_id` CHAR(36) NOT NULL COMMENT '订单UUID',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL COMMENT '用户UUID',
MODIFY COLUMN `product_id` CHAR(36) NOT NULL COMMENT '产品UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_order_id` (`order_id`),
ADD INDEX `idx_user_id` (`user_id`),
ADD INDEX `idx_product_id` (`product_id`);
-- user_auth表修改主键和外键字段注意user_id需要关联到user表的UUID
ALTER TABLE `user_auth`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL COMMENT '用户UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_user_id` (`user_id`),
ADD UNIQUE INDEX `uk_auth_type_key` (`auth_type`, `auth_key`) COMMENT '确保同一个认证方式只能绑定一个用户';
-- agent表修改主键和外键字段
ALTER TABLE `agent`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL COMMENT '用户UUID',
MODIFY COLUMN `team_leader_id` CHAR(36) NULL COMMENT '团队首领UUID',
MODIFY COLUMN `invite_code_id` CHAR(36) NULL COMMENT '邀请码UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD UNIQUE INDEX `uk_user_id` (`user_id`),
ADD INDEX `idx_team_leader_id` (`team_leader_id`),
ADD INDEX `idx_invite_code_id` (`invite_code_id`);
-- ============================================
-- 第二部分:修改代理相关表
-- ============================================
-- agent_commission表
ALTER TABLE `agent_commission`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
MODIFY COLUMN `order_id` CHAR(36) NOT NULL COMMENT '订单UUID',
MODIFY COLUMN `product_id` CHAR(36) NOT NULL COMMENT '产品UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_agent_id` (`agent_id`),
ADD INDEX `idx_order_id` (`order_id`),
ADD INDEX `idx_product_id` (`product_id`);
-- agent_invite_code表
ALTER TABLE `agent_invite_code`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NULL COMMENT '代理UUID',
MODIFY COLUMN `used_user_id` CHAR(36) NULL COMMENT '使用用户UUID',
MODIFY COLUMN `used_agent_id` CHAR(36) NULL COMMENT '使用代理UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_agent_id` (`agent_id`),
ADD INDEX `idx_used_user_id` (`used_user_id`),
ADD INDEX `idx_used_agent_id` (`used_agent_id`);
-- agent_link表
ALTER TABLE `agent_link`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL COMMENT '用户UUID',
MODIFY COLUMN `product_id` CHAR(36) NOT NULL COMMENT '产品UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_agent_id` (`agent_id`),
ADD INDEX `idx_user_id` (`user_id`),
ADD INDEX `idx_product_id` (`product_id`);
-- agent_order表
ALTER TABLE `agent_order`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
MODIFY COLUMN `order_id` CHAR(36) NOT NULL COMMENT '订单UUID',
MODIFY COLUMN `product_id` CHAR(36) NOT NULL COMMENT '产品UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_agent_id` (`agent_id`),
ADD INDEX `idx_order_id` (`order_id`),
ADD INDEX `idx_product_id` (`product_id`);
-- agent_wallet表
ALTER TABLE `agent_wallet`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD UNIQUE INDEX `uk_agent_id` (`agent_id`);
-- agent_withdrawal表
ALTER TABLE `agent_withdrawal`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
MODIFY COLUMN `wallet_id` CHAR(36) NOT NULL COMMENT '钱包UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_agent_id` (`agent_id`),
ADD INDEX `idx_wallet_id` (`wallet_id`);
-- agent_withdrawal_tax表
ALTER TABLE `agent_withdrawal_tax`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `withdrawal_id` CHAR(36) NOT NULL COMMENT '提现UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_withdrawal_id` (`withdrawal_id`);
-- agent_rebate表
ALTER TABLE `agent_rebate`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
MODIFY COLUMN `order_id` CHAR(36) NOT NULL COMMENT '订单UUID',
MODIFY COLUMN `product_id` CHAR(36) NOT NULL COMMENT '产品UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_agent_id` (`agent_id`),
ADD INDEX `idx_order_id` (`order_id`),
ADD INDEX `idx_product_id` (`product_id`);
-- agent_relation表
ALTER TABLE `agent_relation`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
MODIFY COLUMN `parent_agent_id` CHAR(36) NULL COMMENT '上级代理UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_agent_id` (`agent_id`),
ADD INDEX `idx_parent_agent_id` (`parent_agent_id`);
-- agent_upgrade表
ALTER TABLE `agent_upgrade`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_agent_id` (`agent_id`);
-- agent_real_name表
ALTER TABLE `agent_real_name`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_agent_id` (`agent_id`);
-- agent_config表
ALTER TABLE `agent_config`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- agent_product_config表
ALTER TABLE `agent_product_config`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `product_id` CHAR(36) NOT NULL COMMENT '产品UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_product_id` (`product_id`);
-- agent_short_link表
ALTER TABLE `agent_short_link`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `invite_code_id` CHAR(36) NULL COMMENT '邀请码UUID',
MODIFY COLUMN `link_id` CHAR(36) NULL COMMENT '链接UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_invite_code_id` (`invite_code_id`),
ADD INDEX `idx_link_id` (`link_id`);
-- agent_invite_code_usage表
ALTER TABLE `agent_invite_code_usage`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `invite_code_id` CHAR(36) NOT NULL COMMENT '邀请码UUID',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL COMMENT '用户UUID',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_invite_code_id` (`invite_code_id`),
ADD INDEX `idx_user_id` (`user_id`),
ADD INDEX `idx_agent_id` (`agent_id`);
-- agent_freeze_task表
ALTER TABLE `agent_freeze_task`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `agent_id` CHAR(36) NOT NULL COMMENT '代理UUID',
MODIFY COLUMN `order_id` CHAR(36) NOT NULL COMMENT '订单UUID',
MODIFY COLUMN `commission_id` CHAR(36) NOT NULL COMMENT '佣金UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_agent_id` (`agent_id`),
ADD INDEX `idx_order_id` (`order_id`),
ADD INDEX `idx_commission_id` (`commission_id`);
-- ============================================
-- 第三部分:修改订单相关表
-- ============================================
-- order_refund表
ALTER TABLE `order_refund`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `order_id` CHAR(36) NOT NULL COMMENT '订单UUID',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL COMMENT '用户UUID',
MODIFY COLUMN `product_id` CHAR(36) NOT NULL COMMENT '产品UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_order_id` (`order_id`),
ADD INDEX `idx_user_id` (`user_id`),
ADD INDEX `idx_product_id` (`product_id`);
-- ============================================
-- 第四部分:修改查询相关表
-- ============================================
-- query_cleanup_log表
ALTER TABLE `query_cleanup_log`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- query_cleanup_detail表
ALTER TABLE `query_cleanup_detail`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `cleanup_log_id` CHAR(36) NOT NULL COMMENT '清理日志UUID',
MODIFY COLUMN `query_id` CHAR(36) NOT NULL COMMENT '查询UUID',
MODIFY COLUMN `order_id` CHAR(36) NOT NULL COMMENT '订单UUID',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL COMMENT '用户UUID',
MODIFY COLUMN `product_id` CHAR(36) NOT NULL COMMENT '产品UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_cleanup_log_id` (`cleanup_log_id`),
ADD INDEX `idx_query_id` (`query_id`),
ADD INDEX `idx_order_id` (`order_id`),
ADD INDEX `idx_user_id` (`user_id`),
ADD INDEX `idx_product_id` (`product_id`);
-- query_cleanup_config表
ALTER TABLE `query_cleanup_config`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- ============================================
-- 第五部分:修改产品相关表
-- ============================================
-- product_feature表
ALTER TABLE `product_feature`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `product_id` CHAR(36) NOT NULL COMMENT '产品UUID',
MODIFY COLUMN `feature_id` CHAR(36) NOT NULL COMMENT '功能UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_product_id` (`product_id`),
ADD INDEX `idx_feature_id` (`feature_id`);
-- feature表
ALTER TABLE `feature`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- ============================================
-- 第六部分:修改其他表
-- ============================================
-- authorization_document表
ALTER TABLE `authorization_document`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL COMMENT '用户UUID',
MODIFY COLUMN `order_id` CHAR(36) NOT NULL COMMENT '订单UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_user_id` (`user_id`),
ADD INDEX `idx_order_id` (`order_id`);
-- global_notifications表注意原表id是int类型
ALTER TABLE `global_notifications`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- example表
ALTER TABLE `example`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `feature_id` CHAR(36) NOT NULL COMMENT '功能UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_feature_id` (`feature_id`);
-- ============================================
-- 第七部分:修改管理后台表
-- ============================================
-- admin_user表
ALTER TABLE `admin_user`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- admin_role表
ALTER TABLE `admin_role`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- admin_menu表注意字段名是pid不是parent_id
ALTER TABLE `admin_menu`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `pid` CHAR(36) NOT NULL DEFAULT '0' COMMENT '父菜单UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_pid` (`pid`);
-- admin_api表
ALTER TABLE `admin_api`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- admin_dict_type表
ALTER TABLE `admin_dict_type`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- admin_dict_data表注意没有dict_type_id字段使用dict_type字符串
-- 此表不需要修改外键字段因为使用的是dict_type字符串而不是ID
ALTER TABLE `admin_dict_data`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
-- admin_user_role表
ALTER TABLE `admin_user_role`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL DEFAULT '0' COMMENT '用户UUID',
MODIFY COLUMN `role_id` CHAR(36) NOT NULL DEFAULT '0' COMMENT '角色UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_user_id` (`user_id`),
ADD INDEX `idx_role_id` (`role_id`);
-- admin_role_menu表
ALTER TABLE `admin_role_menu`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `role_id` CHAR(36) NOT NULL DEFAULT '0' COMMENT '角色UUID',
MODIFY COLUMN `menu_id` CHAR(36) NOT NULL DEFAULT '0' COMMENT '菜单UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_role_id` (`role_id`),
ADD INDEX `idx_menu_id` (`menu_id`);
-- admin_role_api表
ALTER TABLE `admin_role_api`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `role_id` CHAR(36) NOT NULL DEFAULT '0' COMMENT '角色UUID',
MODIFY COLUMN `api_id` CHAR(36) NOT NULL DEFAULT '0' COMMENT 'API UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_role_id` (`role_id`),
ADD INDEX `idx_api_id` (`api_id`);
-- ============================================
-- 第八部分:修改推广相关表(新增)
-- ============================================
-- admin_promotion_link表
ALTER TABLE `admin_promotion_link`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `admin_user_id` CHAR(36) NOT NULL DEFAULT '0' COMMENT '推广者账号UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_admin_user_id` (`admin_user_id`);
-- admin_promotion_link_stats_history表
ALTER TABLE `admin_promotion_link_stats_history`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `link_id` CHAR(36) NOT NULL COMMENT '推广链接UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_link_id` (`link_id`);
-- admin_promotion_link_stats_total表
ALTER TABLE `admin_promotion_link_stats_total`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `link_id` CHAR(36) NOT NULL COMMENT '推广链接UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD INDEX `idx_link_id` (`link_id`);
-- admin_promotion_order表
ALTER TABLE `admin_promotion_order`
MODIFY COLUMN `id` CHAR(36) NOT NULL COMMENT 'UUID主键',
MODIFY COLUMN `link_id` CHAR(36) NOT NULL COMMENT '推广链接UUID',
MODIFY COLUMN `order_id` CHAR(36) NOT NULL COMMENT '订单UUID',
MODIFY COLUMN `user_id` CHAR(36) NOT NULL COMMENT '下单用户UUID',
MODIFY COLUMN `admin_user_id` CHAR(36) NOT NULL COMMENT '推广者账号UUID',
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`),
ADD UNIQUE INDEX `uk_order_id` (`order_id`) COMMENT '确保每个订单只有一条推广记录',
ADD INDEX `idx_link_id` (`link_id`),
ADD INDEX `idx_user_id` (`user_id`) COMMENT '优化用户查询',
ADD INDEX `idx_admin_user_id` (`admin_user_id`);
-- ============================================
-- 注意事项
-- ============================================
-- 1. 此脚本直接修改表结构,不保留旧数据
-- 2. user表和product表已经是CHAR(36)类型,已跳过
-- 3. 执行后所有ID字段都是CHAR(36)类型
-- 4. 插入新记录时需要在应用层生成UUID使用uuid.NewString()
-- 5. 如果表中有数据需要先清空数据或手动填充UUID
-- 6. 建议在开发环境先测试,确认无误后再应用到生产环境
-- 7. admin_menu表使用pid字段而不是parent_id
-- 8. admin_dict_data表使用dict_type字符串字段不是dict_type_id
-- 9. global_notifications表的id原为int类型现改为CHAR(36)

View File

@@ -0,0 +1,9 @@
package config
import {{.authImport}}
type Config struct {
rest.RestConf
{{.auth}}
{{.jwtTrans}}
}

View File

@@ -0,0 +1,17 @@
package svc
import (
{{.configImport}}
)
type ServiceContext struct {
Config {{.config}}
{{.middleware}}
}
func NewServiceContext(c {{.config}}) *ServiceContext {
return &ServiceContext{
Config: c,
{{.middlewareAssignment}}
}
}

View File

@@ -0,0 +1,3 @@
Name: {{.serviceName}}
Host: {{.host}}
Port: {{.port}}

View File

@@ -0,0 +1,27 @@
package {{.PkgName}}
import (
"net/http"
"qnc-server/common/result"
"qnc-server/pkg/lzkit/validator"
"github.com/zeromicro/go-zero/rest/httpx"
{{.ImportPackages}}
)
func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
{{if .HasRequest}}var req types.{{.RequestType}}
if err := httpx.Parse(r, &req); err != nil {
result.ParamErrorResult(r,w,err)
return
}
if err := validator.Validate(req); err != nil {
result.ParamValidateErrorResult(r, w, err)
return
}
{{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx)
{{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}&req{{end}})
result.HttpResult(r, w, {{if .HasResp}}resp{{else}}nil{{end}}, err)
}
}

View File

@@ -0,0 +1,25 @@
package {{.pkgName}}
import (
{{.imports}}
)
type {{.logic}} struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func New{{.logic}}(ctx context.Context, svcCtx *svc.ServiceContext) *{{.logic}} {
return &{{.logic}}{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *{{.logic}}) {{.function}}({{.request}}) {{.responseType}} {
// todo: add your logic here and delete this line
{{.returnString}}
}

View File

@@ -0,0 +1,27 @@
package main
import (
"flag"
"fmt"
{{.importPackages}}
"qnc-server/common/middleware"
)
var configFile = flag.String("f", "etc/{{.serviceName}}.yaml", "the config file")
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
ctx := svc.NewServiceContext(c)
server := rest.MustNewServer(c.RestConf)
defer server.Stop()
handler.RegisterHandlers(server, ctx)
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
server.Start()
}

View File

@@ -0,0 +1,20 @@
package middleware
import "net/http"
type {{.name}} struct {
}
func New{{.name}}() *{{.name}} {
return &{{.name}}{}
}
func (m *{{.name}})Handle(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// TODO generate middleware implement function, delete after code implementation
// Passthrough to next handler if need
next(w, r)
}
}

View File

@@ -0,0 +1,4 @@
server.AddRoutes(
{{.routes}} {{.jwt}}{{.signature}} {{.prefix}} {{.timeout}} {{.maxBytes}}
)

View File

@@ -0,0 +1,13 @@
// Code generated by goctl. DO NOT EDIT.
package handler
import (
"net/http"{{if .hasTimeout}}
"time"{{end}}
{{.importPackages}}
)
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
{{.routesAdditions}}
}

View File

@@ -0,0 +1,24 @@
syntax = "v1"
info (
title: // TODO: add title
desc: // TODO: add description
author: "{{.gitUser}}"
email: "{{.gitEmail}}"
)
type request {
// TODO: add members here and delete this comment
}
type response {
// TODO: add members here and delete this comment
}
service {{.serviceName}} {
@handler GetUser // TODO: set handler name and delete this comment
get /users/id/:userId(request) returns(response)
@handler CreateUser // TODO: set handler name and delete this comment
post /users/create(request)
}

View File

@@ -0,0 +1,6 @@
// Code generated by goctl. DO NOT EDIT.
package types{{if .containsTime}}
import (
"time"
){{end}}
{{.types}}

View File

@@ -0,0 +1,33 @@
FROM golang:{{.Version}}alpine AS builder
LABEL stage=gobuilder
ENV CGO_ENABLED 0
{{if .Chinese}}ENV GOPROXY https://goproxy.cn,direct
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
{{end}}{{if .HasTimezone}}
RUN apk update --no-cache && apk add --no-cache tzdata
{{end}}
WORKDIR /build
ADD go.mod .
ADD go.sum .
RUN go mod download
COPY . .
{{if .Argument}}COPY {{.GoRelPath}}/etc /app/etc
{{end}}RUN go build -ldflags="-s -w" -o /app/{{.ExeFile}} {{.GoMainFrom}}
FROM {{.BaseImage}}
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
{{if .HasTimezone}}COPY --from=builder /usr/share/zoneinfo/{{.Timezone}} /usr/share/zoneinfo/{{.Timezone}}
ENV TZ {{.Timezone}}
{{end}}
WORKDIR /app
COPY --from=builder /app/{{.ExeFile}} /app/{{.ExeFile}}{{if .Argument}}
COPY --from=builder /app/etc /app/etc{{end}}
{{if .HasPort}}
EXPOSE {{.Port}}
{{end}}
CMD ["./{{.ExeFile}}"{{.Argument}}]

View File

@@ -0,0 +1,18 @@
Name: gateway-example # gateway name
Host: localhost # gateway host
Port: 8888 # gateway port
Upstreams: # upstreams
- Grpc: # grpc upstream
Target: 0.0.0.0:8080 # grpc target,the direct grpc server address,for only one node
# Endpoints: [0.0.0.0:8080,192.168.120.1:8080] # grpc endpoints, the grpc server address list, for multiple nodes
# Etcd: # etcd config, if you want to use etcd to discover the grpc server address
# Hosts: [127.0.0.1:2378,127.0.0.1:2379] # etcd hosts
# Key: greet.grpc # the discovery key
# protoset mode
ProtoSets:
- hello.pb
# Mappings can also be written in proto options
# Mappings: # routes mapping
# - Method: get
# Path: /ping
# RpcPath: hello.Hello/Ping

View File

@@ -0,0 +1,20 @@
package main
import (
"flag"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/gateway"
)
var configFile = flag.String("f", "etc/gateway.yaml", "config file")
func main() {
flag.Parse()
var c gateway.GatewayConf
conf.MustLoad(*configFile, &c)
gw := gateway.MustNewServer(c)
defer gw.Stop()
gw.Start()
}

View File

@@ -0,0 +1,117 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{.Name}}
namespace: {{.Namespace}}
labels:
app: {{.Name}}
spec:
replicas: {{.Replicas}}
revisionHistoryLimit: {{.Revisions}}
selector:
matchLabels:
app: {{.Name}}
template:
metadata:
labels:
app: {{.Name}}
spec:{{if .ServiceAccount}}
serviceAccountName: {{.ServiceAccount}}{{end}}
containers:
- name: {{.Name}}
image: {{.Image}}
{{if .ImagePullPolicy}}imagePullPolicy: {{.ImagePullPolicy}}
{{end}}ports:
- containerPort: {{.Port}}
readinessProbe:
tcpSocket:
port: {{.Port}}
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: {{.Port}}
initialDelaySeconds: 15
periodSeconds: 20
resources:
requests:
cpu: {{.RequestCpu}}m
memory: {{.RequestMem}}Mi
limits:
cpu: {{.LimitCpu}}m
memory: {{.LimitMem}}Mi
volumeMounts:
- name: timezone
mountPath: /etc/localtime
{{if .Secret}}imagePullSecrets:
- name: {{.Secret}}
{{end}}volumes:
- name: timezone
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
---
apiVersion: v1
kind: Service
metadata:
name: {{.Name}}-svc
namespace: {{.Namespace}}
spec:
ports:
{{if .UseNodePort}}- nodePort: {{.NodePort}}
port: {{.Port}}
protocol: TCP
targetPort: {{.TargetPort}}
type: NodePort{{else}}- port: {{.Port}}
targetPort: {{.TargetPort}}{{end}}
selector:
app: {{.Name}}
---
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: {{.Name}}-hpa-c
namespace: {{.Namespace}}
labels:
app: {{.Name}}-hpa-c
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{.Name}}
minReplicas: {{.MinReplicas}}
maxReplicas: {{.MaxReplicas}}
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
---
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: {{.Name}}-hpa-m
namespace: {{.Namespace}}
labels:
app: {{.Name}}-hpa-m
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{.Name}}
minReplicas: {{.MinReplicas}}
maxReplicas: {{.MaxReplicas}}
metrics:
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80

View File

@@ -0,0 +1,37 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: {{.Name}}
namespace: {{.Namespace}}
spec:
successfulJobsHistoryLimit: {{.SuccessfulJobsHistoryLimit}}
schedule: "{{.Schedule}}"
jobTemplate:
spec:
template:
spec:{{if .ServiceAccount}}
serviceAccountName: {{.ServiceAccount}}{{end}}
{{end}}containers:
- name: {{.Name}}
image: # todo image url
resources:
requests:
cpu: {{.RequestCpu}}m
memory: {{.RequestMem}}Mi
limits:
cpu: {{.LimitCpu}}m
memory: {{.LimitMem}}Mi
command:
- ./{{.ServiceName}}
- -f
- ./{{.Name}}.yaml
volumeMounts:
- name: timezone
mountPath: /etc/localtime
imagePullSecrets:
- name: # registry secret, if no, remove this
restartPolicy: OnFailure
volumes:
- name: timezone
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai

View File

@@ -0,0 +1,21 @@
func (m *default{{.upperStartCamelObject}}Model) Delete(ctx context.Context, session sqlx.Session, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error {
{{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOne(ctx, {{.lowerStartCamelPrimaryKey}})
if err!=nil{
return err
}
{{end}} {{.keys}}
_, err {{if .containsIndexCache}}={{else}}:={{end}} m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("delete from %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}}", m.table)
if session!=nil{
return session.ExecCtx(ctx,query, {{.lowerStartCamelPrimaryKey}})
}
return conn.ExecCtx(ctx, query, {{.lowerStartCamelPrimaryKey}})
}, {{.keyValues}}){{else}}query := fmt.Sprintf("delete from %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}}", m.table)
if session!=nil{
_,err:= session.ExecCtx(ctx,query, {{.lowerStartCamelPrimaryKey}})
return err
}
_,err:=m.conn.ExecCtx(ctx, query, {{.lowerStartCamelPrimaryKey}}){{end}}
return err
}

View File

@@ -0,0 +1,9 @@
package {{.pkg}}
import (
"errors"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var ErrNotFound = sqlx.ErrNotFound
var ErrNoRowsUpdate = errors.New("update db no rows change")

View File

@@ -0,0 +1 @@
{{.name}} {{.type}} {{.tag}} {{if .hasComment}}// {{.comment}}{{end}}

View File

@@ -0,0 +1,7 @@
func (m *default{{.upperStartCamelObject}}Model) formatPrimary(primary interface{}) string {
return fmt.Sprintf("%s%v", {{.primaryKeyLeft}}, primary)
}
func (m *default{{.upperStartCamelObject}}Model) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error {
query := fmt.Sprintf("select %s from %s where {{.originalPrimaryField}} = {{if .postgreSql}}$1{{else}}?{{end}} and del_state = ? limit 1", {{.lowerStartCamelObject}}Rows, m.table )
return conn.QueryRowCtx(ctx, v, query, primary,globalkey.DelStateNo)
}

View File

@@ -0,0 +1,32 @@
func (m *default{{.upperStartCamelObject}}Model) FindOneBy{{.upperField}}(ctx context.Context, {{.in}}) (*{{.upperStartCamelObject}}, error) {
{{if .withCache}}{{.cacheKey}}
var resp {{.upperStartCamelObject}}
err := m.QueryRowIndexCtx(ctx, &resp, {{.cacheKeyVariable}}, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
query := fmt.Sprintf("select %s from %s where {{.originalField}} and del_state = ? limit 1", {{.lowerStartCamelObject}}Rows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, {{.lowerStartCamelField}},globalkey.DelStateNo); err != nil {
return nil, err
}
return resp.{{.upperStartCamelPrimaryKey}}, nil
}, m.queryPrimary)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}{{else}}var resp {{.upperStartCamelObject}}
query := fmt.Sprintf("select %s from %s where {{.originalField}} and del_state = ? limit 1", {{.lowerStartCamelObject}}Rows, m.table )
err := m.conn.QueryRowCtx(ctx, &resp, query, {{.lowerStartCamelField}},globalkey.DelStateNo)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}{{end}}

View File

@@ -0,0 +1,26 @@
func (m *default{{.upperStartCamelObject}}Model) FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error) {
{{if .withCache}}{{.cacheKey}}
var resp {{.upperStartCamelObject}}
err := m.QueryRowCtx(ctx, &resp, {{.cacheKeyVariable}}, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error {
query := fmt.Sprintf("select %s from %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}} and del_state = ? limit 1", {{.lowerStartCamelObject}}Rows, m.table)
return conn.QueryRowCtx(ctx, v, query, {{.lowerStartCamelPrimaryKey}},globalkey.DelStateNo)
})
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}{{else}}query := fmt.Sprintf("select %s from %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}} and del_state = ? limit 1", {{.lowerStartCamelObject}}Rows, m.table)
var resp {{.upperStartCamelObject}}
err := m.conn.QueryRowCtx(ctx, &resp, query, {{.lowerStartCamelPrimaryKey}},globalkey.DelStateNo)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}{{end}}
}

View File

@@ -0,0 +1,18 @@
import (
"context"
"database/sql"
"fmt"
"strings"
{{if .time}}"time"{{end}}
"reflect"
"qnc-server/common/globalkey"
"github.com/Masterminds/squirrel"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
"github.com/google/uuid"
)

View File

@@ -0,0 +1,19 @@
import (
"context"
"database/sql"
"fmt"
"strings"
{{if .time}}"time"{{end}}
"reflect"
"qnc-server/common/globalkey"
"github.com/Masterminds/squirrel"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
"github.com/google/uuid"
)

View File

@@ -0,0 +1,34 @@
func (m *default{{.upperStartCamelObject}}Model) Insert(ctx context.Context,session sqlx.Session, data *{{.upperStartCamelObject}}) (sql.Result,error) {
data.DelState = globalkey.DelStateNo
m.insertUUID(data)
{{if .withCache}}{{.keys}}
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet)
if session != nil{
return session.ExecCtx(ctx,query,{{.expressionValues}})
}
return conn.ExecCtx(ctx, query, {{.expressionValues}})
}, {{.keyValues}}){{else}}
query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet)
if session != nil{
return session.ExecCtx(ctx,query,{{.expressionValues}})
}
return m.conn.ExecCtx(ctx, query, {{.expressionValues}}){{end}}
}
func (m *default{{.upperStartCamelObject}}Model) insertUUID(data *{{.upperStartCamelObject}}) {
t := reflect.TypeOf(data).Elem()
v := reflect.ValueOf(data).Elem()
for i := 0; i < t.NumField(); i++ {
sf := t.Field(i)
if sf.Tag.Get("db") == "id" {
f := v.Field(i)
if f.IsValid() && f.CanSet() && f.Kind() == reflect.String {
if f.String() == "" {
f.SetString(uuid.NewString())
}
}
break
}
}
}

View File

@@ -0,0 +1 @@
Delete(ctx context.Context,session sqlx.Session, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error

View File

@@ -0,0 +1 @@
FindOneBy{{.upperField}}(ctx context.Context, {{.in}}) (*{{.upperStartCamelObject}}, error)

View File

@@ -0,0 +1 @@
FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error)

View File

@@ -0,0 +1 @@
Insert(ctx context.Context, session sqlx.Session,data *{{.upperStartCamelObject}}) (sql.Result,error)

View File

@@ -0,0 +1,12 @@
Update(ctx context.Context,session sqlx.Session, data *{{.upperStartCamelObject}}) (sql.Result, error)
UpdateWithVersion(ctx context.Context,session sqlx.Session,data *{{.upperStartCamelObject}}) error
Trans(ctx context.Context,fn func(context context.Context,session sqlx.Session) error) error
SelectBuilder() squirrel.SelectBuilder
DeleteSoft(ctx context.Context,session sqlx.Session, data *{{.upperStartCamelObject}}) error
FindSum(ctx context.Context,sumBuilder squirrel.SelectBuilder,field string) (float64,error)
FindCount(ctx context.Context,countBuilder squirrel.SelectBuilder,field string) (int64,error)
FindAll(ctx context.Context,rowBuilder squirrel.SelectBuilder,orderBy string) ([]*{{.upperStartCamelObject}},error)
FindPageListByPage(ctx context.Context,rowBuilder squirrel.SelectBuilder,page ,pageSize int64,orderBy string) ([]*{{.upperStartCamelObject}},error)
FindPageListByPageWithTotal(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*{{.upperStartCamelObject}}, int64, error)
FindPageListByIdDESC(ctx context.Context,rowBuilder squirrel.SelectBuilder ,preMinId ,pageSize int64) ([]*{{.upperStartCamelObject}},error)
FindPageListByIdASC(ctx context.Context,rowBuilder squirrel.SelectBuilder,preMaxId ,pageSize int64) ([]*{{.upperStartCamelObject}},error)

View File

@@ -0,0 +1,13 @@
// Code generated by goctl. DO NOT EDIT!
package {{.pkg}}
{{.imports}}
{{.vars}}
{{.types}}
{{.new}}
{{.insert}}
{{.find}}
{{.update}}
{{.delete}}
{{.extraMethod}}
{{.tableName}}

View File

@@ -0,0 +1,7 @@
func new{{.upperStartCamelObject}}Model(conn sqlx.SqlConn{{if .withCache}}, c cache.CacheConf{{end}}) *default{{.upperStartCamelObject}}Model {
return &default{{.upperStartCamelObject}}Model{
{{if .withCache}}CachedConn: sqlc.NewConn(conn, c){{else}}conn:conn{{end}},
table: {{.table}},
}
}

View File

@@ -0,0 +1,37 @@
package {{.pkg}}
{{if .withCache}}
import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
{{else}}
import (
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
{{end}}
var _ {{.upperStartCamelObject}}Model = (*custom{{.upperStartCamelObject}}Model)(nil)
type (
// {{.upperStartCamelObject}}Model is an interface to be customized, add more methods here,
// and implement the added methods in custom{{.upperStartCamelObject}}Model.
{{.upperStartCamelObject}}Model interface {
{{.lowerStartCamelObject}}Model
}
custom{{.upperStartCamelObject}}Model struct {
*default{{.upperStartCamelObject}}Model
}
)
// New{{.upperStartCamelObject}}Model returns a model for the database table.
func New{{.upperStartCamelObject}}Model(conn sqlx.SqlConn{{if .withCache}}, c cache.CacheConf{{end}}) {{.upperStartCamelObject}}Model {
return &custom{{.upperStartCamelObject}}Model{
default{{.upperStartCamelObject}}Model: new{{.upperStartCamelObject}}Model(conn{{if .withCache}}, c{{end}}),
}
}

View File

@@ -0,0 +1,4 @@
func (m *default{{.upperStartCamelObject}}Model) tableName() string {
return m.table
}

View File

@@ -0,0 +1 @@
`db:"{{.field}}"`

View File

@@ -0,0 +1,15 @@
type (
{{.lowerStartCamelObject}}Model interface{
{{.method}}
}
default{{.upperStartCamelObject}}Model struct {
{{if .withCache}}sqlc.CachedConn{{else}}conn sqlx.SqlConn{{end}}
table string
}
{{.upperStartCamelObject}} struct {
{{.fields}}
}
)

View File

@@ -0,0 +1,286 @@
func (m *default{{.upperStartCamelObject}}Model) Update(ctx context.Context,session sqlx.Session, {{if .containsIndexCache}}newData{{else}}data{{end}} *{{.upperStartCamelObject}}) (sql.Result,error) {
{{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOne(ctx, newData.{{.upperStartCamelPrimaryKey}})
if err!=nil{
return nil,err
}
{{end}}{{.keys}}
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}}", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
if session != nil{
return session.ExecCtx(ctx,query, {{.expressionValues}})
}
return conn.ExecCtx(ctx, query, {{.expressionValues}})
}, {{.keyValues}}){{else}}query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}}", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
if session != nil{
return session.ExecCtx(ctx,query, {{.expressionValues}})
}
return m.conn.ExecCtx(ctx, query, {{.expressionValues}}){{end}}
}
func (m *default{{.upperStartCamelObject}}Model) UpdateWithVersion(ctx context.Context,session sqlx.Session,{{if .containsIndexCache}}newData{{else}}data{{end}} *{{.upperStartCamelObject}}) error {
{{if .containsIndexCache}}
oldVersion := newData.Version
newData.Version += 1
{{else}}
oldVersion := data.Version
data.Version += 1
{{end}}
var sqlResult sql.Result
var err error
{{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOne(ctx, newData.{{.upperStartCamelPrimaryKey}})
if err!=nil{
return err
}
{{end}}{{.keys}}
sqlResult,err = m.ExecCtx(ctx,func(ctx context.Context,conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}} and version = ? ", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
if session != nil{
return session.ExecCtx(ctx,query, {{.expressionValues}},oldVersion)
}
return conn.ExecCtx(ctx,query, {{.expressionValues}},oldVersion)
}, {{.keyValues}}){{else}}query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}} and version = ? ", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
if session != nil{
sqlResult,err = session.ExecCtx(ctx,query, {{.expressionValues}},oldVersion)
}else{
sqlResult,err = m.conn.ExecCtx(ctx,query, {{.expressionValues}},oldVersion)
}
{{end}}
if err != nil {
return err
}
updateCount , err := sqlResult.RowsAffected()
if err != nil{
return err
}
if updateCount == 0 {
return ErrNoRowsUpdate
}
return nil
}
func (m *default{{.upperStartCamelObject}}Model) DeleteSoft(ctx context.Context,session sqlx.Session,data *{{.upperStartCamelObject}}) error {
data.DelState = globalkey.DelStateYes
data.DeleteTime = sql.NullTime{Time: time.Now(), Valid: true}
if err:= m.UpdateWithVersion(ctx,session, data);err!= nil{
return errors.Wrapf(errors.New("delete soft failed "),"{{.upperStartCamelObject}}Model delete err : %+v",err)
}
return nil
}
func (m *default{{.upperStartCamelObject}}Model) FindSum(ctx context.Context,builder squirrel.SelectBuilder, field string) (float64,error) {
if len(field) == 0 {
return 0, errors.Wrapf(errors.New("FindSum Least One Field"), "FindSum Least One Field")
}
builder = builder.Columns("IFNULL(SUM(" + field + "),0)")
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
if err != nil {
return 0, err
}
var resp float64
{{if .withCache}}err = m.QueryRowNoCacheCtx(ctx,&resp, query, values...){{else}}
err = m.conn.QueryRowCtx(ctx,&resp, query, values...)
{{end}}
switch err {
case nil:
return resp, nil
default:
return 0, err
}
}
func (m *default{{.upperStartCamelObject}}Model) FindCount(ctx context.Context, builder squirrel.SelectBuilder, field string) (int64,error) {
if len(field) == 0 {
return 0, errors.Wrapf(errors.New("FindCount Least One Field"), "FindCount Least One Field")
}
builder = builder.Columns("COUNT(" + field + ")")
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
if err != nil {
return 0, err
}
var resp int64
{{if .withCache}}err = m.QueryRowNoCacheCtx(ctx,&resp, query, values...){{else}}
err = m.conn.QueryRowCtx(ctx,&resp, query, values...)
{{end}}
switch err {
case nil:
return resp, nil
default:
return 0, err
}
}
func (m *default{{.upperStartCamelObject}}Model) FindAll(ctx context.Context,builder squirrel.SelectBuilder,orderBy string) ([]*{{.upperStartCamelObject}},error) {
builder = builder.Columns({{.lowerStartCamelObject}}Rows)
if orderBy == ""{
builder = builder.OrderBy("id DESC")
}else{
builder = builder.OrderBy(orderBy)
}
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
if err != nil {
return nil, err
}
var resp []*{{.upperStartCamelObject}}
{{if .withCache}}err = m.QueryRowsNoCacheCtx(ctx,&resp, query, values...){{else}}
err = m.conn.QueryRowsCtx(ctx,&resp, query, values...)
{{end}}
switch err {
case nil:
return resp, nil
default:
return nil, err
}
}
func (m *default{{.upperStartCamelObject}}Model) FindPageListByPage(ctx context.Context,builder squirrel.SelectBuilder,page ,pageSize int64,orderBy string) ([]*{{.upperStartCamelObject}},error) {
builder = builder.Columns({{.lowerStartCamelObject}}Rows)
if orderBy == ""{
builder = builder.OrderBy("id DESC")
}else{
builder = builder.OrderBy(orderBy)
}
if page < 1{
page = 1
}
offset := (page - 1) * pageSize
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
if err != nil {
return nil, err
}
var resp []*{{.upperStartCamelObject}}
{{if .withCache}}err = m.QueryRowsNoCacheCtx(ctx,&resp, query, values...){{else}}
err = m.conn.QueryRowsCtx(ctx,&resp, query, values...)
{{end}}
switch err {
case nil:
return resp, nil
default:
return nil, err
}
}
func (m *default{{.upperStartCamelObject}}Model) FindPageListByPageWithTotal(ctx context.Context,builder squirrel.SelectBuilder,page ,pageSize int64,orderBy string) ([]*{{.upperStartCamelObject}},int64,error) {
total, err := m.FindCount(ctx, builder, "id")
if err != nil {
return nil, 0, err
}
builder = builder.Columns({{.lowerStartCamelObject}}Rows)
if orderBy == ""{
builder = builder.OrderBy("id DESC")
}else{
builder = builder.OrderBy(orderBy)
}
if page < 1{
page = 1
}
offset := (page - 1) * pageSize
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
if err != nil {
return nil,total, err
}
var resp []*{{.upperStartCamelObject}}
{{if .withCache}}err = m.QueryRowsNoCacheCtx(ctx,&resp, query, values...){{else}}
err = m.conn.QueryRowsCtx(ctx,&resp, query, values...)
{{end}}
switch err {
case nil:
return resp,total, nil
default:
return nil,total, err
}
}
func (m *default{{.upperStartCamelObject}}Model) FindPageListByIdDESC(ctx context.Context,builder squirrel.SelectBuilder ,preMinId ,pageSize int64) ([]*{{.upperStartCamelObject}},error) {
builder = builder.Columns({{.lowerStartCamelObject}}Rows)
if preMinId > 0 {
builder = builder.Where(" id < ? " , preMinId)
}
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id DESC").Limit(uint64(pageSize)).ToSql()
if err != nil {
return nil, err
}
var resp []*{{.upperStartCamelObject}}
{{if .withCache}}err = m.QueryRowsNoCacheCtx(ctx,&resp, query, values...){{else}}
err = m.conn.QueryRowsCtx(ctx,&resp, query, values...)
{{end}}
switch err {
case nil:
return resp, nil
default:
return nil, err
}
}
func (m *default{{.upperStartCamelObject}}Model) FindPageListByIdASC(ctx context.Context,builder squirrel.SelectBuilder,preMaxId ,pageSize int64) ([]*{{.upperStartCamelObject}},error) {
builder = builder.Columns({{.lowerStartCamelObject}}Rows)
if preMaxId > 0 {
builder = builder.Where(" id > ? " , preMaxId)
}
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id ASC").Limit(uint64(pageSize)).ToSql()
if err != nil {
return nil, err
}
var resp []*{{.upperStartCamelObject}}
{{if .withCache}}err = m.QueryRowsNoCacheCtx(ctx,&resp, query, values...){{else}}
err = m.conn.QueryRowsCtx(ctx,&resp, query, values...)
{{end}}
switch err {
case nil:
return resp, nil
default:
return nil, err
}
}
func (m *default{{.upperStartCamelObject}}Model) Trans(ctx context.Context,fn func(ctx context.Context,session sqlx.Session) error) error {
{{if .withCache}}
return m.TransactCtx(ctx,func(ctx context.Context,session sqlx.Session) error {
return fn(ctx,session)
})
{{else}}
return m.conn.TransactCtx(ctx,func(ctx context.Context,session sqlx.Session) error {
return fn(ctx,session)
})
{{end}}
}
func(m *default{{.upperStartCamelObject}}Model) SelectBuilder() squirrel.SelectBuilder {
return squirrel.Select().From(m.table)
}

View File

@@ -0,0 +1,9 @@
var (
{{.lowerStartCamelObject}}FieldNames = builder.RawFieldNames(&{{.upperStartCamelObject}}{}{{if .postgreSql}},true{{end}})
{{.lowerStartCamelObject}}Rows = strings.Join({{.lowerStartCamelObject}}FieldNames, ",")
{{.lowerStartCamelObject}}RowsExpectAutoSet = {{if .postgreSql}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, {{if .autoIncrement}}"{{.originalPrimaryKey}}",{{end}} "create_time", "update_time"), ","){{else}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, {{if .autoIncrement}}"{{.originalPrimaryKey}}",{{end}} "`create_time`", "`update_time`"), ","){{end}}
{{.lowerStartCamelObject}}RowsWithPlaceHolder = {{if .postgreSql}}builder.PostgreSqlJoin(stringx.Remove({{.lowerStartCamelObject}}FieldNames, "{{.originalPrimaryKey}}", "create_time", "update_time")){{else}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, "{{.originalPrimaryKey}}", "`create_time`", "`update_time`"), "=?,") + "=?"{{end}}
{{if .withCache}}{{.cacheKeys}}{{end}}
)

View File

@@ -0,0 +1,12 @@
package model
import (
"errors"
"github.com/zeromicro/go-zero/core/stores/mon"
)
var (
ErrNotFound = mon.ErrNotFound
ErrInvalidObjectId = errors.New("invalid objectId")
)

View File

@@ -0,0 +1,78 @@
// Code generated by goctl. DO NOT EDIT.
package model
import (
"context"
"time"
{{if .Cache}}"github.com/zeromicro/go-zero/core/stores/monc"{{else}}"github.com/zeromicro/go-zero/core/stores/mon"{{end}}
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
{{if .Cache}}var prefix{{.Type}}CacheKey = "cache:{{.lowerType}}:"{{end}}
type {{.lowerType}}Model interface{
Insert(ctx context.Context,data *{{.Type}}) error
FindOne(ctx context.Context,id string) (*{{.Type}}, error)
Update(ctx context.Context,data *{{.Type}}) (*mongo.UpdateResult, error)
Delete(ctx context.Context,id string) (int64, error)
}
type default{{.Type}}Model struct {
conn {{if .Cache}}*monc.Model{{else}}*mon.Model{{end}}
}
func newDefault{{.Type}}Model(conn {{if .Cache}}*monc.Model{{else}}*mon.Model{{end}}) *default{{.Type}}Model {
return &default{{.Type}}Model{conn: conn}
}
func (m *default{{.Type}}Model) Insert(ctx context.Context, data *{{.Type}}) error {
if data.ID.IsZero() {
data.ID = primitive.NewObjectID()
data.CreateAt = time.Now()
data.UpdateAt = time.Now()
}
{{if .Cache}}key := prefix{{.Type}}CacheKey + data.ID.Hex(){{end}}
_, err := m.conn.InsertOne(ctx, {{if .Cache}}key, {{end}} data)
return err
}
func (m *default{{.Type}}Model) FindOne(ctx context.Context, id string) (*{{.Type}}, error) {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return nil, ErrInvalidObjectId
}
var data {{.Type}}
{{if .Cache}}key := prefix{{.Type}}CacheKey + id{{end}}
err = m.conn.FindOne(ctx, {{if .Cache}}key, {{end}}&data, bson.M{"_id": oid})
switch err {
case nil:
return &data, nil
case {{if .Cache}}monc{{else}}mon{{end}}.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *default{{.Type}}Model) Update(ctx context.Context, data *{{.Type}}) (*mongo.UpdateResult, error) {
data.UpdateAt = time.Now()
{{if .Cache}}key := prefix{{.Type}}CacheKey + data.ID.Hex(){{end}}
res, err := m.conn.UpdateOne(ctx, {{if .Cache}}key, {{end}}bson.M{"_id": data.ID}, bson.M{"$set": data})
return res, err
}
func (m *default{{.Type}}Model) Delete(ctx context.Context, id string) (int64, error) {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return 0, ErrInvalidObjectId
}
{{if .Cache}}key := prefix{{.Type}}CacheKey +id{{end}}
res, err := m.conn.DeleteOne(ctx, {{if .Cache}}key, {{end}}bson.M{"_id": oid})
return res, err
}

View File

@@ -0,0 +1,38 @@
package model
{{if .Cache}}import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/monc"
){{else}}import "github.com/zeromicro/go-zero/core/stores/mon"{{end}}
{{if .Easy}}
const {{.Type}}CollectionName = "{{.snakeType}}"
{{end}}
var _ {{.Type}}Model = (*custom{{.Type}}Model)(nil)
type (
// {{.Type}}Model is an interface to be customized, add more methods here,
// and implement the added methods in custom{{.Type}}Model.
{{.Type}}Model interface {
{{.lowerType}}Model
}
custom{{.Type}}Model struct {
*default{{.Type}}Model
}
)
// New{{.Type}}Model returns a model for the mongo.
{{if .Easy}}func New{{.Type}}Model(url, db string{{if .Cache}}, c cache.CacheConf{{end}}) {{.Type}}Model {
conn := {{if .Cache}}monc{{else}}mon{{end}}.MustNewModel(url, db, {{.Type}}CollectionName{{if .Cache}}, c{{end}})
return &custom{{.Type}}Model{
default{{.Type}}Model: newDefault{{.Type}}Model(conn),
}
}{{else}}func New{{.Type}}Model(url, db, collection string{{if .Cache}}, c cache.CacheConf{{end}}) {{.Type}}Model {
conn := {{if .Cache}}monc{{else}}mon{{end}}.MustNewModel(url, db, collection{{if .Cache}}, c{{end}})
return &custom{{.Type}}Model{
default{{.Type}}Model: newDefault{{.Type}}Model(conn),
}
}{{end}}

View File

@@ -0,0 +1,14 @@
package model
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type {{.Type}} struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
// TODO: Fill your own fields
UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"`
CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"`
}

View File

@@ -0,0 +1,12 @@
type Request {
Name string `path:"name,options=you|me"`
}
type Response {
Message string `json:"message"`
}
service {{.name}}-api {
@handler {{.handler}}Handler
get /from/:name(Request) returns (Response)
}

View File

@@ -0,0 +1,33 @@
{{.head}}
package {{.filePackage}}
import (
"context"
{{.pbPackage}}
{{if ne .pbPackage .protoGoPackage}}{{.protoGoPackage}}{{end}}
"github.com/zeromicro/go-zero/zrpc"
"google.golang.org/grpc"
)
type (
{{.alias}}
{{.serviceName}} interface {
{{.interface}}
}
default{{.serviceName}} struct {
cli zrpc.Client
}
)
func New{{.serviceName}}(cli zrpc.Client) {{.serviceName}} {
return &default{{.serviceName}}{
cli: cli,
}
}
{{.functions}}

View File

@@ -0,0 +1,7 @@
package config
import "github.com/zeromicro/go-zero/zrpc"
type Config struct {
zrpc.RpcServerConf
}

View File

@@ -0,0 +1,6 @@
Name: {{.serviceName}}.rpc
ListenOn: 0.0.0.0:8080
Etcd:
Hosts:
- 127.0.0.1:2379
Key: {{.serviceName}}.rpc

View File

@@ -0,0 +1,6 @@
{{if .hasComment}}{{.comment}}{{end}}
func (l *{{.logicName}}) {{.method}} ({{if .hasReq}}in {{.request}}{{if .stream}},stream {{.streamBody}}{{end}}{{else}}stream {{.streamBody}}{{end}}) ({{if .hasReply}}{{.response}},{{end}} error) {
// todo: add your logic here and delete this line
return {{if .hasReply}}&{{.responseType}}{},{{end}} nil
}

View File

@@ -0,0 +1,24 @@
package {{.packageName}}
import (
"context"
{{.imports}}
"github.com/zeromicro/go-zero/core/logx"
)
type {{.logicName}} struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func New{{.logicName}}(ctx context.Context,svcCtx *svc.ServiceContext) *{{.logicName}} {
return &{{.logicName}}{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
{{.functions}}

View File

@@ -0,0 +1,42 @@
package main
import (
"flag"
"fmt"
{{.imports}}
"qnc-server/common/interceptor/rpcserver"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/core/service"
"github.com/zeromicro/go-zero/zrpc"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
var configFile = flag.String("f", "etc/{{.serviceName}}.yaml", "the config file")
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
ctx := svc.NewServiceContext(c)
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
{{range .serviceNames}} {{.Pkg}}.Register{{.Service}}Server(grpcServer, {{.ServerPkg}}.New{{.Service}}Server(ctx))
{{end}}
if c.Mode == service.DevMode || c.Mode == service.TestMode {
reflection.Register(grpcServer)
}
})
//rpc log
s.AddUnaryInterceptors(rpcserver.LoggerInterceptor)
defer s.Stop()
fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
s.Start()
}

View File

@@ -0,0 +1,6 @@
{{if .hasComment}}{{.comment}}{{end}}
func (s *{{.server}}Server) {{.method}} ({{if .notStream}}ctx context.Context,{{if .hasReq}} in {{.request}}{{end}}{{else}}{{if .hasReq}} in {{.request}},{{end}}stream {{.streamBody}}{{end}}) ({{if .notStream}}{{.response}},{{end}}error) {
l := {{.logicPkg}}.New{{.logicName}}({{if .notStream}}ctx,{{else}}stream.Context(),{{end}}s.svcCtx)
return l.{{.method}}({{if .hasReq}}in{{if .stream}} ,stream{{end}}{{else}}{{if .stream}}stream{{end}}{{end}})
}

View File

@@ -0,0 +1,22 @@
{{.head}}
package server
import (
{{if .notStream}}"context"{{end}}
{{.imports}}
)
type {{.server}}Server struct {
svcCtx *svc.ServiceContext
{{.unimplementedServer}}
}
func New{{.server}}Server(svcCtx *svc.ServiceContext) *{{.server}}Server {
return &{{.server}}Server{
svcCtx: svcCtx,
}
}
{{.funcs}}

View File

@@ -0,0 +1,13 @@
package svc
import {{.imports}}
type ServiceContext struct {
Config config.Config
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config:c,
}
}

View File

@@ -0,0 +1,16 @@
syntax = "proto3";
package {{.package}};
option go_package="./{{.package}}";
message Request {
string ping = 1;
}
message Response {
string pong = 1;
}
service {{.serviceName}} {
rpc Ping(Request) returns(Response);
}