Compare commits
12 Commits
9d996acf5f
...
v1.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 62c624c88e | |||
| 4481c581e9 | |||
| 22cb2d50d3 | |||
| 51c377964d | |||
| 7e8d824ba6 | |||
| 75ad12efb3 | |||
| 5ffa151f58 | |||
| c9995ef566 | |||
| ad021f2faa | |||
| 9f7160edfc | |||
| 71f1c6f141 | |||
| bb895eccdf |
47
README.md
47
README.md
@@ -1,51 +1,18 @@
|
|||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
后端默认用户名不能是完整手机号
|
用户请求需要检查数据权限
|
||||||
|
|
||||||
前端需要 token 化改造,以避免每次 basic 认证流程中 bcrypt 对比导致的性能对比
|
|
||||||
|
|
||||||
优化中间件,配置通用限速
|
|
||||||
|
|
||||||
observe 部署,蓝狐部署
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
用反射实现环境变量解析,以简化函数签名
|
用反射实现环境变量解析,以简化函数签名
|
||||||
|
|
||||||
分离 task 的客户端,支持多进程(prefork 必要!)
|
|
||||||
|
|
||||||
调整目录结构:
|
|
||||||
|
|
||||||
```
|
|
||||||
- /util 工具函数
|
|
||||||
|
|
||||||
- /models 模型
|
|
||||||
- /queries 数据库层
|
|
||||||
- /clients 三方依赖的客户端实例
|
|
||||||
|
|
||||||
- /services 服务层
|
|
||||||
- /auth 认证相关,特化服务
|
|
||||||
|
|
||||||
- /app 应用相关,初始化日志,环境变量,错误类型等
|
|
||||||
- /http 协议层,http 服务
|
|
||||||
- /cmd 主函数
|
|
||||||
|
|
||||||
逐层向上依赖
|
|
||||||
cmd 调用 app, http 的初始化函数
|
|
||||||
http 调用 clients 的初始化函数
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
数据库转模型文件
|
分离 task 的客户端,支持多进程(prefork 必要!)
|
||||||
|
|
||||||
jsonb 类型转换问题,考虑一个高效的 any 到 struct 转换工具
|
jsonb 类型转换问题,考虑一个高效的 any 到 struct 转换工具
|
||||||
|
|
||||||
慢速请求底层调用埋点监控
|
慢速请求底层调用埋点监控
|
||||||
|
|
||||||
- redis
|
数据库转模型文件
|
||||||
- gorm
|
|
||||||
- 三方接口
|
|
||||||
|
|
||||||
冷数据迁移方案
|
冷数据迁移方案
|
||||||
|
|
||||||
@@ -63,6 +30,14 @@ jsonb 类型转换问题,考虑一个高效的 any 到 struct 转换工具
|
|||||||
3. 创建 model 文件,并将其添加到 gen 代码中
|
3. 创建 model 文件,并将其添加到 gen 代码中
|
||||||
4. 生成查询文件
|
4. 生成查询文件
|
||||||
|
|
||||||
|
### 权限管理
|
||||||
|
|
||||||
|
在 `web/core/scopes.go` 下定义了系统所有静态权限
|
||||||
|
|
||||||
|
新增系统权限需要在数据库中配套添加权限
|
||||||
|
|
||||||
|
前端也需要新增配套权限定义
|
||||||
|
|
||||||
## 业务逻辑
|
## 业务逻辑
|
||||||
|
|
||||||
### 订单关闭的几种方式
|
### 订单关闭的几种方式
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ func main() {
|
|||||||
m.UserRole{},
|
m.UserRole{},
|
||||||
m.Whitelist{},
|
m.Whitelist{},
|
||||||
m.Inquiry{},
|
m.Inquiry{},
|
||||||
|
m.ProductDiscount{},
|
||||||
|
m.BalanceActivity{},
|
||||||
)
|
)
|
||||||
g.Execute()
|
g.Execute()
|
||||||
}
|
}
|
||||||
|
|||||||
2
pkg/env/env.go
vendored
2
pkg/env/env.go
vendored
@@ -20,7 +20,7 @@ const (
|
|||||||
var (
|
var (
|
||||||
RunMode = RunModeProd
|
RunMode = RunModeProd
|
||||||
LogLevel = slog.LevelDebug
|
LogLevel = slog.LevelDebug
|
||||||
TradeExpire = 15 * 60 // 交易过期时间,单位秒。默认 15 分钟
|
TradeExpire = 15 * 60 // 交易过期时间,单位秒。默认 900 秒(15 分钟)
|
||||||
SessionAccessExpire = 60 * 60 * 2 // 访问令牌过期时间,单位秒。默认 2 小时
|
SessionAccessExpire = 60 * 60 * 2 // 访问令牌过期时间,单位秒。默认 2 小时
|
||||||
SessionRefreshExpire = 60 * 60 * 24 * 7 // 刷新令牌过期时间,单位秒。默认 7 天
|
SessionRefreshExpire = 60 * 60 * 24 * 7 // 刷新令牌过期时间,单位秒。默认 7 天
|
||||||
DebugHttpDump = false // 是否打印请求和响应的原始数据
|
DebugHttpDump = false // 是否打印请求和响应的原始数据
|
||||||
|
|||||||
10
pkg/u/u.go
10
pkg/u/u.go
@@ -17,14 +17,6 @@ func Else[T any](v *T, or T) T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ElseTo[A any, B any](a *A, f func(A) B) *B {
|
|
||||||
if a == nil {
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
return P(f(*a))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 三元表达式
|
// 三元表达式
|
||||||
func Ternary[T any](condition bool, trueValue T, falseValue T) T {
|
func Ternary[T any](condition bool, trueValue T, falseValue T) T {
|
||||||
if condition {
|
if condition {
|
||||||
@@ -82,7 +74,7 @@ func DateHead(date time.Time) time.Time {
|
|||||||
return time.Date(y, m, d, 0, 0, 0, 0, date.Location())
|
return time.Date(y, m, d, 0, 0, 0, 0, date.Location())
|
||||||
}
|
}
|
||||||
|
|
||||||
func DateFoot(date time.Time) time.Time {
|
func DateTail(date time.Time) time.Time {
|
||||||
var y, m, d = date.Date()
|
var y, m, d = date.Date()
|
||||||
return time.Date(y, m, d, 23, 59, 59, 999999999, date.Location())
|
return time.Date(y, m, d, 23, 59, 59, 999999999, date.Location())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ if ($confrim -ne "y") {
|
|||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
docker build -t 43.226.58.254:53000/lanhu/platform:latest .
|
docker build -t repo.lanhuip.com:8554/lanhu/platform:latest .
|
||||||
docker build -t 43.226.58.254:53000/lanhu/platform:$($args[0]) .
|
docker build -t repo.lanhuip.com:8554/lanhu/platform:$($args[0]) .
|
||||||
|
|
||||||
docker push 43.226.58.254:53000/lanhu/platform:latest
|
docker push repo.lanhuip.com:8554/lanhu/platform:latest
|
||||||
docker push 43.226.58.254:53000/lanhu/platform:$($args[0])
|
docker push repo.lanhuip.com:8554/lanhu/platform:$($args[0])
|
||||||
|
|||||||
@@ -2,115 +2,20 @@
|
|||||||
-- region 填充数据
|
-- region 填充数据
|
||||||
-- ====================
|
-- ====================
|
||||||
|
|
||||||
insert into client
|
insert into client (type, spec, name, client_id, client_secret, redirect_uri) values (1, 3, 'web', 'web', '$2a$10$Ss12mXQgpYyo1CKIZ3URouDm.Lc2KcYJzsvEK2PTIXlv6fHQht45a', '');
|
||||||
(client_id, client_secret, redirect_uri, spec, name, type)
|
insert into client (type, spec, name, client_id, client_secret, redirect_uri) values (1, 3, 'admin', 'admin', '$2a$10$dlfvX5Uf3iVsUWgwlb0Wt.oYsw/OEXgS.Aior3yoT63Ju7ZSsJr/2', '');
|
||||||
|
|
||||||
|
insert into product (code, name, description) values ('short', '短效动态', '短效动态');
|
||||||
|
insert into product (code, name, description) values ('long', '长效动态', '长效动态');
|
||||||
|
insert into product (code, name, description) values ('static', '长效静态', '长效静态');
|
||||||
|
|
||||||
|
delete from permission where true;
|
||||||
|
insert into permission
|
||||||
|
(name, description)
|
||||||
values
|
values
|
||||||
('web', '$2a$10$Ss12mXQgpYyo1CKIZ3URouDm.Lc2KcYJzsvEK2PTIXlv6fHQht45a', '', 3, 'web', 1);
|
('permission:read', '读取权限列表'),
|
||||||
|
('permission:write', '写入权限'),
|
||||||
with pid as (
|
('admin-role:read', '读取管理员角色列表'),
|
||||||
insert into app.public.product
|
('admin-role:write', '写入管理员角色')
|
||||||
(code, name, description)
|
|
||||||
values
|
|
||||||
('dynamic-short', '短效动态', '短效动态')
|
|
||||||
returning id
|
|
||||||
)
|
|
||||||
insert into app.public.product_sku
|
|
||||||
(product_id, code, name, price, discount)
|
|
||||||
select pid.id, 'mode=quota,live=3,expire=0', '短效动态包量 3 分钟', 50, 1 from pid
|
|
||||||
union all select pid.id, 'mode=quota,live=5,expire=0', '短效动态包量 5 分钟', 100, 1 from pid
|
|
||||||
union all select pid.id, 'mode=quota,live=10,expire=0', '短效动态包量 10 分钟', 200, 1 from pid
|
|
||||||
union all select pid.id, 'mode=quota,live=20,expire=0', '短效动态包量 20 分钟', 300, 1 from pid
|
|
||||||
union all select pid.id, 'mode=quota,live=30,expire=0', '短效动态包量 30 分钟', 600, 1 from pid
|
|
||||||
|
|
||||||
union all select pid.id, 'mode=time,live=3,expire=7', '短效动态包时 7 天 3 分钟', 56, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=3,expire=15', '短效动态包时 15 天 3 分钟', 90, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=3,expire=30', '短效动态包时 30 天 3 分钟', 180, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=3,expire=90', '短效动态包时 90 天 3 分钟', 450, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=3,expire=180', '短效动态包时 180 天 3 分钟', 900, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=3,expire=365', '短效动态包时 365 天 3 分钟', 1642.5, 1 from pid
|
|
||||||
|
|
||||||
union all select pid.id, 'mode=time,live=5,expire=7', '短效动态包时 7 天 5 分钟', 56, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=5,expire=15', '短效动态包时 15 天 5 分钟', 90, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=5,expire=30', '短效动态包时 30 天 5 分钟', 180, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=5,expire=90', '短效动态包时 90 天 5 分钟', 450, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=5,expire=180', '短效动态包时 180 天 5 分钟', 900, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=5,expire=365', '短效动态包时 365 天 5 分钟', 1642.5, 1 from pid
|
|
||||||
|
|
||||||
union all select pid.id, 'mode=time,live=10,expire=7', '短效动态包时 7 天 10 分钟', 56, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=10,expire=15', '短效动态包时 15 天 10 分钟', 90, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=10,expire=30', '短效动态包时 30 天 10 分钟', 180, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=10,expire=90', '短效动态包时 90 天 10 分钟', 450, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=10,expire=180', '短效动态包时 180 天 10 分钟', 900, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=10,expire=365', '短效动态包时 365 天 10 分钟', 1642.5, 1 from pid
|
|
||||||
|
|
||||||
union all select pid.id, 'mode=time,live=20,expire=7', '短效动态包时 7 天 20 分钟', 56, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=20,expire=15', '短效动态包时 15 天 20 分钟', 90, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=20,expire=30', '短效动态包时 30 天 20 分钟', 180, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=20,expire=90', '短效动态包时 90 天 20 分钟', 450, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=20,expire=180', '短效动态包时 180 天 20 分钟', 900, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=20,expire=365', '短效动态包时 365 天 20 分钟', 1642.5, 1 from pid
|
|
||||||
|
|
||||||
union all select pid.id, 'mode=time,live=30,expire=7', '短效动态包时 7 天 30 分钟', 56, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=30,expire=15', '短效动态包时 15 天 30 分钟', 90, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=30,expire=30', '短效动态包时 30 天 30 分钟', 180, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=30,expire=90', '短效动态包时 90 天 30 分钟', 450, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=30,expire=180', '短效动态包时 180 天 30 分钟', 900, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=30,expire=365', '短效动态包时 365 天 30 分钟', 1642.5, 1 from pid
|
|
||||||
;
|
;
|
||||||
|
|
||||||
with pid as (
|
|
||||||
insert into app.public.product
|
|
||||||
(code, name, description)
|
|
||||||
values
|
|
||||||
('dynamic-long', '长效动态', '长效动态')
|
|
||||||
returning id
|
|
||||||
)
|
|
||||||
insert into app.public.product_sku
|
|
||||||
(product_id, code, name, price, discount)
|
|
||||||
select pid.id, 'mode=quota,live=60,expire=0', '长效动态包量 60 分钟', 50, 1 from pid
|
|
||||||
union all select pid.id, 'mode=quota,live=240,expire=0', '长效动态包量 240 分钟', 100, 1 from pid
|
|
||||||
union all select pid.id, 'mode=quota,live=480,expire=0', '长效动态包量 480 分钟', 200, 1 from pid
|
|
||||||
union all select pid.id, 'mode=quota,live=720,expire=0', '长效动态包量 720 分钟', 300, 1 from pid
|
|
||||||
union all select pid.id, 'mode=quota,live=1440,expire=0', '长效动态包量 1440 分钟', 600, 1 from pid
|
|
||||||
|
|
||||||
union all select pid.id, 'mode=time,live=60,expire=7', '长效动态包时 7 天 60 分钟', 56, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=60,expire=15', '长效动态包时 15 天 60 分钟', 90, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=60,expire=30', '长效动态包时 30 天 60 分钟', 180, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=60,expire=90', '长效动态包时 90 天 60 分钟', 450, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=60,expire=180', '长效动态包时 180 天 60 分钟', 900, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=60,expire=365', '长效动态包时 365 天 60 分钟', 1642.5, 1 from pid
|
|
||||||
|
|
||||||
union all select pid.id, 'mode=time,live=240,expire=7', '长效动态包时 7 天 240 分钟', 56, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=240,expire=15', '长效动态包时 15 天 240 分钟', 90, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=240,expire=30', '长效动态包时 30 天 240 分钟', 180, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=240,expire=90', '长效动态包时 90 天 240 分钟', 450, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=240,expire=180', '长效动态包时 180 天 240 分钟', 900, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=240,expire=365', '长效动态包时 365 天 240 分钟', 1642.5, 1 from pid
|
|
||||||
|
|
||||||
union all select pid.id, 'mode=time,live=480,expire=7', '长效动态包时 7 天 480 分钟', 56, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=480,expire=15', '长效动态包时 15 天 480 分钟', 90, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=480,expire=30', '长效动态包时 30 天 480 分钟', 180, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=480,expire=90', '长效动态包时 90 天 480 分钟', 450, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=480,expire=180', '长效动态包时 180 天 480 分钟', 900, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=480,expire=365', '长效动态包时 365 天 480 分钟', 1642.5, 1 from pid
|
|
||||||
|
|
||||||
union all select pid.id, 'mode=time,live=720,expire=7', '长效动态包时 7 天 720 分钟', 56, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=720,expire=15', '长效动态包时 15 天 720 分钟', 90, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=720,expire=30', '长效动态包时 30 天 720 分钟', 180, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=720,expire=90', '长效动态包时 90 天 720 分钟', 450, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=720,expire=180', '长效动态包时 180 天 720 分钟', 900, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=720,expire=365', '长效动态包时 365 天 720 分钟', 1642.5, 1 from pid
|
|
||||||
|
|
||||||
union all select pid.id, 'mode=time,live=1440,expire=7', '长效动态包时 7 天 1440 分钟', 56, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=1440,expire=15', '长效动态包时 15 天 1440 分钟', 90, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=1440,expire=30', '长效动态包时 30 天 1440 分钟', 180, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=1440,expire=90', '长效动态包时 90 天 1440 分钟', 450, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=1440,expire=180', '长效动态包时 180 天 1440 分钟', 900, 1 from pid
|
|
||||||
union all select pid.id, 'mode=time,live=1440,expire=365', '长效动态包时 365 天 1440 分钟', 1642.5, 1 from pid
|
|
||||||
;
|
|
||||||
|
|
||||||
insert into app.public.product
|
|
||||||
(code, name, description)
|
|
||||||
values
|
|
||||||
('static', '长效静态', '长效静态');
|
|
||||||
-- endregion
|
-- endregion
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ create table admin (
|
|||||||
updated_at timestamptz default current_timestamp,
|
updated_at timestamptz default current_timestamp,
|
||||||
deleted_at timestamptz
|
deleted_at timestamptz
|
||||||
);
|
);
|
||||||
create unique index udx_admin_username on admin (username);
|
create unique index udx_admin_username on admin (username) where deleted_at is null;
|
||||||
create index idx_admin_status on admin (status) where deleted_at is null;
|
create index idx_admin_status on admin (status) where deleted_at is null;
|
||||||
create index idx_admin_created_at on admin (created_at) where deleted_at is null;
|
create index idx_admin_created_at on admin (created_at) where deleted_at is null;
|
||||||
|
|
||||||
@@ -227,8 +227,8 @@ create table admin_role (
|
|||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
name text not null,
|
name text not null,
|
||||||
description text,
|
description text,
|
||||||
active bool default true,
|
active bool not null default true,
|
||||||
sort int default 0,
|
sort int not null default 0,
|
||||||
created_at timestamptz default current_timestamp,
|
created_at timestamptz default current_timestamp,
|
||||||
updated_at timestamptz default current_timestamp,
|
updated_at timestamptz default current_timestamp,
|
||||||
deleted_at timestamptz
|
deleted_at timestamptz
|
||||||
@@ -258,10 +258,12 @@ drop table if exists "user" cascade;
|
|||||||
create table "user" (
|
create table "user" (
|
||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
admin_id int,
|
admin_id int,
|
||||||
|
discount_id int,
|
||||||
phone text not null unique,
|
phone text not null unique,
|
||||||
username text,
|
username text,
|
||||||
email text,
|
email text,
|
||||||
password text,
|
password text,
|
||||||
|
source int default 0,
|
||||||
name text,
|
name text,
|
||||||
avatar text,
|
avatar text,
|
||||||
status int not null default 1,
|
status int not null default 1,
|
||||||
@@ -279,6 +281,7 @@ create table "user" (
|
|||||||
deleted_at timestamptz
|
deleted_at timestamptz
|
||||||
);
|
);
|
||||||
create index idx_user_admin_id on "user" (admin_id) where deleted_at is null;
|
create index idx_user_admin_id on "user" (admin_id) where deleted_at is null;
|
||||||
|
create index idx_user_discount_id on "user" (discount_id) where deleted_at is null;
|
||||||
create unique index udx_user_phone on "user" (phone) where deleted_at is null;
|
create unique index udx_user_phone on "user" (phone) where deleted_at is null;
|
||||||
create unique index udx_user_username on "user" (username) where deleted_at is null;
|
create unique index udx_user_username on "user" (username) where deleted_at is null;
|
||||||
create unique index udx_user_email on "user" (email) where deleted_at is null;
|
create unique index udx_user_email on "user" (email) where deleted_at is null;
|
||||||
@@ -288,9 +291,11 @@ create index idx_user_created_at on "user" (created_at) where deleted_at is null
|
|||||||
comment on table "user" is '用户表';
|
comment on table "user" is '用户表';
|
||||||
comment on column "user".id is '用户ID';
|
comment on column "user".id is '用户ID';
|
||||||
comment on column "user".admin_id is '管理员ID';
|
comment on column "user".admin_id is '管理员ID';
|
||||||
|
comment on column "user".discount_id is '折扣ID';
|
||||||
comment on column "user".password is '用户密码';
|
comment on column "user".password is '用户密码';
|
||||||
comment on column "user".username is '用户名';
|
comment on column "user".username is '用户名';
|
||||||
comment on column "user".phone is '手机号码';
|
comment on column "user".phone is '手机号码';
|
||||||
|
comment on column "user".source is '用户来源:0-官网注册,1-管理员添加,2-代理商注册,3-代理商添加';
|
||||||
comment on column "user".name is '真实姓名';
|
comment on column "user".name is '真实姓名';
|
||||||
comment on column "user".avatar is '头像URL';
|
comment on column "user".avatar is '头像URL';
|
||||||
comment on column "user".status is '用户状态:0-禁用,1-正常';
|
comment on column "user".status is '用户状态:0-禁用,1-正常';
|
||||||
@@ -428,6 +433,7 @@ create table permission (
|
|||||||
parent_id int,
|
parent_id int,
|
||||||
name text not null,
|
name text not null,
|
||||||
description text,
|
description text,
|
||||||
|
sort int,
|
||||||
created_at timestamptz default current_timestamp,
|
created_at timestamptz default current_timestamp,
|
||||||
updated_at timestamptz default current_timestamp,
|
updated_at timestamptz default current_timestamp,
|
||||||
deleted_at timestamptz
|
deleted_at timestamptz
|
||||||
@@ -442,6 +448,7 @@ comment on column permission.id is '权限ID';
|
|||||||
comment on column permission.parent_id is '父权限ID';
|
comment on column permission.parent_id is '父权限ID';
|
||||||
comment on column permission.name is '权限名称';
|
comment on column permission.name is '权限名称';
|
||||||
comment on column permission.description is '权限描述';
|
comment on column permission.description is '权限描述';
|
||||||
|
comment on column permission.sort is '排序';
|
||||||
comment on column permission.created_at is '创建时间';
|
comment on column permission.created_at is '创建时间';
|
||||||
comment on column permission.updated_at is '更新时间';
|
comment on column permission.updated_at is '更新时间';
|
||||||
comment on column permission.deleted_at is '删除时间';
|
comment on column permission.deleted_at is '删除时间';
|
||||||
@@ -449,65 +456,65 @@ comment on column permission.deleted_at is '删除时间';
|
|||||||
-- link_user_role
|
-- link_user_role
|
||||||
drop table if exists link_user_role cascade;
|
drop table if exists link_user_role cascade;
|
||||||
create table link_user_role (
|
create table link_user_role (
|
||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
user_id int not null,
|
user_id int not null,
|
||||||
role_id int not null
|
user_role_id int not null
|
||||||
);
|
);
|
||||||
create index idx_link_user_role_user_id on link_user_role (user_id);
|
create index idx_link_user_role_user_id on link_user_role (user_id);
|
||||||
create index idx_link_user_role_role_id on link_user_role (role_id);
|
create index idx_link_user_role_role_id on link_user_role (user_role_id);
|
||||||
|
|
||||||
-- link_user_role表字段注释
|
-- link_user_role表字段注释
|
||||||
comment on table link_user_role is '用户角色关联表';
|
comment on table link_user_role is '用户角色关联表';
|
||||||
comment on column link_user_role.id is '关联ID';
|
comment on column link_user_role.id is '关联ID';
|
||||||
comment on column link_user_role.user_id is '用户ID';
|
comment on column link_user_role.user_id is '用户ID';
|
||||||
comment on column link_user_role.role_id is '角色ID';
|
comment on column link_user_role.user_role_id is '角色ID';
|
||||||
|
|
||||||
-- link_admin_role
|
-- link_admin_role
|
||||||
drop table if exists link_admin_role cascade;
|
drop table if exists link_admin_role cascade;
|
||||||
create table link_admin_role (
|
create table link_admin_role (
|
||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
admin_id int not null,
|
admin_id int not null,
|
||||||
role_id int not null
|
admin_role_id int not null
|
||||||
);
|
);
|
||||||
create index idx_link_admin_role_admin_id on link_admin_role (admin_id);
|
create index idx_link_admin_role_admin_id on link_admin_role (admin_id);
|
||||||
create index idx_link_admin_role_role_id on link_admin_role (role_id);
|
create index idx_link_admin_role_role_id on link_admin_role (admin_role_id);
|
||||||
|
|
||||||
-- link_admin_role表字段注释
|
-- link_admin_role表字段注释
|
||||||
comment on table link_admin_role is '管理员角色关联表';
|
comment on table link_admin_role is '管理员角色关联表';
|
||||||
comment on column link_admin_role.id is '关联ID';
|
comment on column link_admin_role.id is '关联ID';
|
||||||
comment on column link_admin_role.admin_id is '管理员ID';
|
comment on column link_admin_role.admin_id is '管理员ID';
|
||||||
comment on column link_admin_role.role_id is '角色ID';
|
comment on column link_admin_role.admin_role_id is '角色ID';
|
||||||
|
|
||||||
-- link_user_role_permission
|
-- link_user_role_permission
|
||||||
drop table if exists link_user_role_permission cascade;
|
drop table if exists link_user_role_permission cascade;
|
||||||
create table link_user_role_permission (
|
create table link_user_role_permission (
|
||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
role_id int not null,
|
user_role_id int not null,
|
||||||
permission_id int not null
|
permission_id int not null
|
||||||
);
|
);
|
||||||
create index idx_link_user_role_permission_role_id on link_user_role_permission (role_id);
|
create index idx_link_user_role_permission_role_id on link_user_role_permission (user_role_id);
|
||||||
create index idx_link_user_role_permission_permission_id on link_user_role_permission (permission_id);
|
create index idx_link_user_role_permission_permission_id on link_user_role_permission (permission_id);
|
||||||
|
|
||||||
-- link_user_role_permission表字段注释
|
-- link_user_role_permission表字段注释
|
||||||
comment on table link_user_role_permission is '用户角色权限关联表';
|
comment on table link_user_role_permission is '用户角色权限关联表';
|
||||||
comment on column link_user_role_permission.id is '关联ID';
|
comment on column link_user_role_permission.id is '关联ID';
|
||||||
comment on column link_user_role_permission.role_id is '角色ID';
|
comment on column link_user_role_permission.user_role_id is '角色ID';
|
||||||
comment on column link_user_role_permission.permission_id is '权限ID';
|
comment on column link_user_role_permission.permission_id is '权限ID';
|
||||||
|
|
||||||
-- link_admin_role_permission
|
-- link_admin_role_permission
|
||||||
drop table if exists link_admin_role_permission cascade;
|
drop table if exists link_admin_role_permission cascade;
|
||||||
create table link_admin_role_permission (
|
create table link_admin_role_permission (
|
||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
role_id int not null,
|
admin_role_id int not null,
|
||||||
permission_id int not null
|
permission_id int not null
|
||||||
);
|
);
|
||||||
create index idx_link_admin_role_permission_role_id on link_admin_role_permission (role_id);
|
create index idx_link_admin_role_permission_role_id on link_admin_role_permission (admin_role_id);
|
||||||
create index idx_link_admin_role_permission_permission_id on link_admin_role_permission (permission_id);
|
create index idx_link_admin_role_permission_permission_id on link_admin_role_permission (permission_id);
|
||||||
|
|
||||||
-- link_admin_role_permission表字段注释
|
-- link_admin_role_permission表字段注释
|
||||||
comment on table link_admin_role_permission is '管理员角色权限关联表';
|
comment on table link_admin_role_permission is '管理员角色权限关联表';
|
||||||
comment on column link_admin_role_permission.id is '关联ID';
|
comment on column link_admin_role_permission.id is '关联ID';
|
||||||
comment on column link_admin_role_permission.role_id is '角色ID';
|
comment on column link_admin_role_permission.admin_role_id is '角色ID';
|
||||||
comment on column link_admin_role_permission.permission_id is '权限ID';
|
comment on column link_admin_role_permission.permission_id is '权限ID';
|
||||||
|
|
||||||
-- link_client_permission
|
-- link_client_permission
|
||||||
@@ -720,30 +727,52 @@ comment on column product.created_at is '创建时间';
|
|||||||
comment on column product.updated_at is '更新时间';
|
comment on column product.updated_at is '更新时间';
|
||||||
comment on column product.deleted_at is '删除时间';
|
comment on column product.deleted_at is '删除时间';
|
||||||
|
|
||||||
-- product_sku
|
|
||||||
drop table if exists product_sku cascade;
|
-- product_discount
|
||||||
create table product_sku (
|
drop table if exists product_discount cascade;
|
||||||
|
create table product_discount (
|
||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
product_id int not null,
|
name text,
|
||||||
code text not null,
|
discount int,
|
||||||
name text not null,
|
|
||||||
price decimal not null,
|
|
||||||
discount float not null,
|
|
||||||
created_at timestamptz default current_timestamp,
|
created_at timestamptz default current_timestamp,
|
||||||
updated_at timestamptz default current_timestamp,
|
updated_at timestamptz default current_timestamp,
|
||||||
deleted_at timestamptz
|
deleted_at timestamptz
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- product_discount表字段注释
|
||||||
|
comment on table product_discount is '产品折扣表';
|
||||||
|
comment on column product_discount.id is 'ID';
|
||||||
|
comment on column product_discount.name is '折扣名称';
|
||||||
|
comment on column product_discount.discount is '折扣,0 - 100 的整数,表示 xx 折';
|
||||||
|
comment on column product_discount.created_at is '创建时间';
|
||||||
|
comment on column product_discount.updated_at is '更新时间';
|
||||||
|
comment on column product_discount.deleted_at is '删除时间';
|
||||||
|
|
||||||
|
-- product_sku
|
||||||
|
drop table if exists product_sku cascade;
|
||||||
|
create table product_sku (
|
||||||
|
id int generated by default as identity primary key,
|
||||||
|
product_id int not null,
|
||||||
|
discount_id int,
|
||||||
|
code text not null unique,
|
||||||
|
name text not null,
|
||||||
|
price decimal not null,
|
||||||
|
created_at timestamptz default current_timestamp,
|
||||||
|
updated_at timestamptz default current_timestamp,
|
||||||
|
deleted_at timestamptz
|
||||||
|
);
|
||||||
create index idx_product_sku_product_id on product_sku (product_id) where deleted_at is null;
|
create index idx_product_sku_product_id on product_sku (product_id) where deleted_at is null;
|
||||||
create index idx_product_sku_code on product_sku (code) where deleted_at is null;
|
create index idx_product_sku_discount_id on product_sku (discount_id) where deleted_at is null;
|
||||||
|
create unique index idx_product_sku_code on product_sku (code) where deleted_at is null;
|
||||||
|
|
||||||
-- product_sku表字段注释
|
-- product_sku表字段注释
|
||||||
comment on table product_sku is '产品SKU表';
|
comment on table product_sku is '产品SKU表';
|
||||||
comment on column product_sku.id is 'SKU ID';
|
comment on column product_sku.id is 'SKU ID';
|
||||||
comment on column product_sku.product_id is '产品ID';
|
comment on column product_sku.product_id is '产品ID';
|
||||||
|
comment on column product_sku.discount_id is '折扣ID';
|
||||||
comment on column product_sku.code is 'SKU 代码:格式为 key=value,key=value,...,其中,key:value 是 SKU 的属性,多个属性用逗号分隔';
|
comment on column product_sku.code is 'SKU 代码:格式为 key=value,key=value,...,其中,key:value 是 SKU 的属性,多个属性用逗号分隔';
|
||||||
comment on column product_sku.name is 'SKU 可读名称';
|
comment on column product_sku.name is 'SKU 可读名称';
|
||||||
comment on column product_sku.price is '定价';
|
comment on column product_sku.price is '定价';
|
||||||
comment on column product_sku.discount is '折扣,0 - 1 的小数,表示 xx 折';
|
|
||||||
comment on column product_sku.created_at is '创建时间';
|
comment on column product_sku.created_at is '创建时间';
|
||||||
comment on column product_sku.updated_at is '更新时间';
|
comment on column product_sku.updated_at is '更新时间';
|
||||||
comment on column product_sku.deleted_at is '删除时间';
|
comment on column product_sku.deleted_at is '删除时间';
|
||||||
@@ -754,21 +783,20 @@ create table product_sku_user (
|
|||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
user_id int not null,
|
user_id int not null,
|
||||||
product_sku_id int not null,
|
product_sku_id int not null,
|
||||||
price decimal,
|
discount_id int,
|
||||||
discount float,
|
|
||||||
created_at timestamptz default current_timestamp,
|
created_at timestamptz default current_timestamp,
|
||||||
updated_at timestamptz default current_timestamp
|
updated_at timestamptz default current_timestamp
|
||||||
);
|
);
|
||||||
create index idx_product_sku_user_user_id on product_sku_user (user_id);
|
create index idx_product_sku_user_user_id on product_sku_user (user_id);
|
||||||
create index idx_product_sku_user_product_sku_id on product_sku_user (product_sku_id);
|
create index idx_product_sku_user_product_sku_id on product_sku_user (product_sku_id);
|
||||||
|
create index idx_product_sku_user_discount_id on product_sku_user (discount_id);
|
||||||
|
|
||||||
-- product_sku_user表字段注释
|
-- product_sku_user表字段注释
|
||||||
comment on table product_sku_user is '用户产品SKU表';
|
comment on table product_sku_user is '用户产品SKU表';
|
||||||
comment on column product_sku_user.id is 'ID';
|
comment on column product_sku_user.id is 'ID';
|
||||||
comment on column product_sku_user.user_id is '用户ID';
|
comment on column product_sku_user.user_id is '用户ID';
|
||||||
comment on column product_sku_user.product_sku_id is '产品SKU ID';
|
comment on column product_sku_user.product_sku_id is '产品SKU ID';
|
||||||
comment on column product_sku_user.price is '定价';
|
comment on column product_sku_user.discount_id is '折扣ID';
|
||||||
comment on column product_sku_user.discount is '折扣,0 - 1 的小数,表示 xx 折';
|
|
||||||
comment on column product_sku_user.created_at is '创建时间';
|
comment on column product_sku_user.created_at is '创建时间';
|
||||||
comment on column product_sku_user.updated_at is '更新时间';
|
comment on column product_sku_user.updated_at is '更新时间';
|
||||||
|
|
||||||
@@ -777,9 +805,10 @@ drop table if exists resource cascade;
|
|||||||
create table resource (
|
create table resource (
|
||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
user_id int not null,
|
user_id int not null,
|
||||||
resource_no text,
|
resource_no text not null,
|
||||||
active bool not null default true,
|
code text,
|
||||||
type int not null,
|
type int not null,
|
||||||
|
active bool not null default true,
|
||||||
created_at timestamptz default current_timestamp,
|
created_at timestamptz default current_timestamp,
|
||||||
updated_at timestamptz default current_timestamp,
|
updated_at timestamptz default current_timestamp,
|
||||||
deleted_at timestamptz
|
deleted_at timestamptz
|
||||||
@@ -787,6 +816,7 @@ create table resource (
|
|||||||
create unique index udx_resource_resource_no on resource (resource_no);
|
create unique index udx_resource_resource_no on resource (resource_no);
|
||||||
create index idx_resource_user_id on resource (user_id) where deleted_at is null;
|
create index idx_resource_user_id on resource (user_id) where deleted_at is null;
|
||||||
create index idx_resource_created_at on resource (created_at) where deleted_at is null;
|
create index idx_resource_created_at on resource (created_at) where deleted_at is null;
|
||||||
|
create index idx_resource_code on resource (code) where deleted_at is null;
|
||||||
|
|
||||||
-- resource表字段注释
|
-- resource表字段注释
|
||||||
comment on table resource is '套餐表';
|
comment on table resource is '套餐表';
|
||||||
@@ -795,6 +825,7 @@ comment on column resource.user_id is '用户ID';
|
|||||||
comment on column resource.resource_no is '套餐编号';
|
comment on column resource.resource_no is '套餐编号';
|
||||||
comment on column resource.active is '套餐状态';
|
comment on column resource.active is '套餐状态';
|
||||||
comment on column resource.type is '套餐类型:1-短效动态,2-长效动态';
|
comment on column resource.type is '套餐类型:1-短效动态,2-长效动态';
|
||||||
|
comment on column resource.code is '产品编码';
|
||||||
comment on column resource.created_at is '创建时间';
|
comment on column resource.created_at is '创建时间';
|
||||||
comment on column resource.updated_at is '更新时间';
|
comment on column resource.updated_at is '更新时间';
|
||||||
comment on column resource.deleted_at is '删除时间';
|
comment on column resource.deleted_at is '删除时间';
|
||||||
@@ -804,6 +835,7 @@ drop table if exists resource_short cascade;
|
|||||||
create table resource_short (
|
create table resource_short (
|
||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
resource_id int not null,
|
resource_id int not null,
|
||||||
|
code text,
|
||||||
live int not null,
|
live int not null,
|
||||||
type int not null,
|
type int not null,
|
||||||
quota int not null,
|
quota int not null,
|
||||||
@@ -813,11 +845,13 @@ create table resource_short (
|
|||||||
last_at timestamptz
|
last_at timestamptz
|
||||||
);
|
);
|
||||||
create index idx_resource_short_resource_id on resource_short (resource_id);
|
create index idx_resource_short_resource_id on resource_short (resource_id);
|
||||||
|
create index idx_resource_short_code on resource_short (code);
|
||||||
|
|
||||||
-- resource_short表字段注释
|
-- resource_short表字段注释
|
||||||
comment on table resource_short is '短效动态套餐表';
|
comment on table resource_short is '短效动态套餐表';
|
||||||
comment on column resource_short.id is 'ID';
|
comment on column resource_short.id is 'ID';
|
||||||
comment on column resource_short.resource_id is '套餐ID';
|
comment on column resource_short.resource_id is '套餐ID';
|
||||||
|
comment on column resource_short.code is '产品套餐编码';
|
||||||
comment on column resource_short.live is '可用时长(秒)';
|
comment on column resource_short.live is '可用时长(秒)';
|
||||||
comment on column resource_short.type is '套餐类型:1-包时,2-包量';
|
comment on column resource_short.type is '套餐类型:1-包时,2-包量';
|
||||||
comment on column resource_short.quota is '每日配额(包时)或总配额(包量)';
|
comment on column resource_short.quota is '每日配额(包时)或总配额(包量)';
|
||||||
@@ -831,6 +865,7 @@ drop table if exists resource_long cascade;
|
|||||||
create table resource_long (
|
create table resource_long (
|
||||||
id int generated by default as identity primary key,
|
id int generated by default as identity primary key,
|
||||||
resource_id int not null,
|
resource_id int not null,
|
||||||
|
code text,
|
||||||
live int not null,
|
live int not null,
|
||||||
type int not null,
|
type int not null,
|
||||||
quota int not null,
|
quota int not null,
|
||||||
@@ -840,11 +875,13 @@ create table resource_long (
|
|||||||
last_at timestamptz
|
last_at timestamptz
|
||||||
);
|
);
|
||||||
create index idx_resource_long_resource_id on resource_long (resource_id);
|
create index idx_resource_long_resource_id on resource_long (resource_id);
|
||||||
|
create index idx_resource_long_code on resource_long (code);
|
||||||
|
|
||||||
-- resource_long表字段注释
|
-- resource_long表字段注释
|
||||||
comment on table resource_long is '长效动态套餐表';
|
comment on table resource_long is '长效动态套餐表';
|
||||||
comment on column resource_long.id is 'ID';
|
comment on column resource_long.id is 'ID';
|
||||||
comment on column resource_long.resource_id is '套餐ID';
|
comment on column resource_long.resource_id is '套餐ID';
|
||||||
|
comment on column resource_long.code is '产品套餐编码';
|
||||||
comment on column resource_long.live is '可用时长(小时)';
|
comment on column resource_long.live is '可用时长(小时)';
|
||||||
comment on column resource_long.type is '套餐类型:1-包时,2-包量';
|
comment on column resource_long.type is '套餐类型:1-包时,2-包量';
|
||||||
comment on column resource_long.quota is '每日配额(包时)或总配额(包量)';
|
comment on column resource_long.quota is '每日配额(包时)或总配额(包量)';
|
||||||
@@ -947,10 +984,12 @@ create table bill (
|
|||||||
trade_id int,
|
trade_id int,
|
||||||
resource_id int,
|
resource_id int,
|
||||||
refund_id int,
|
refund_id int,
|
||||||
|
coupon_id int,
|
||||||
bill_no text not null,
|
bill_no text not null,
|
||||||
info text,
|
info text,
|
||||||
type int not null,
|
type int not null,
|
||||||
amount decimal(12, 2) not null default 0,
|
amount decimal(12, 2) not null default 0,
|
||||||
|
actual decimal(12, 2) not null default 0,
|
||||||
created_at timestamptz default current_timestamp,
|
created_at timestamptz default current_timestamp,
|
||||||
updated_at timestamptz default current_timestamp,
|
updated_at timestamptz default current_timestamp,
|
||||||
deleted_at timestamptz
|
deleted_at timestamptz
|
||||||
@@ -960,6 +999,7 @@ create index idx_bill_user_id on bill (user_id) where deleted_at is null;
|
|||||||
create index idx_bill_trade_id on bill (trade_id) where deleted_at is null;
|
create index idx_bill_trade_id on bill (trade_id) where deleted_at is null;
|
||||||
create index idx_bill_resource_id on bill (resource_id) where deleted_at is null;
|
create index idx_bill_resource_id on bill (resource_id) where deleted_at is null;
|
||||||
create index idx_bill_refund_id on bill (refund_id) where deleted_at is null;
|
create index idx_bill_refund_id on bill (refund_id) where deleted_at is null;
|
||||||
|
create index idx_bill_coupon_id on bill (coupon_id) where deleted_at is null;
|
||||||
create index idx_bill_created_at on bill (created_at) where deleted_at is null;
|
create index idx_bill_created_at on bill (created_at) where deleted_at is null;
|
||||||
|
|
||||||
-- bill表字段注释
|
-- bill表字段注释
|
||||||
@@ -972,11 +1012,42 @@ comment on column bill.refund_id is '退款ID';
|
|||||||
comment on column bill.bill_no is '易读账单号';
|
comment on column bill.bill_no is '易读账单号';
|
||||||
comment on column bill.info is '产品可读信息';
|
comment on column bill.info is '产品可读信息';
|
||||||
comment on column bill.type is '账单类型:1-消费,2-退款,3-充值';
|
comment on column bill.type is '账单类型:1-消费,2-退款,3-充值';
|
||||||
comment on column bill.amount is '账单金额';
|
comment on column bill.amount is '应付金额';
|
||||||
|
comment on column bill.actual is '实付金额';
|
||||||
comment on column bill.created_at is '创建时间';
|
comment on column bill.created_at is '创建时间';
|
||||||
comment on column bill.updated_at is '更新时间';
|
comment on column bill.updated_at is '更新时间';
|
||||||
comment on column bill.deleted_at is '删除时间';
|
comment on column bill.deleted_at is '删除时间';
|
||||||
|
|
||||||
|
-- balance_activity 余额变动记录
|
||||||
|
drop table if exists balance_activity cascade;
|
||||||
|
create table balance_activity (
|
||||||
|
id int generated by default as identity primary key,
|
||||||
|
user_id int not null,
|
||||||
|
bill_id int,
|
||||||
|
admin_id int,
|
||||||
|
amount text not null,
|
||||||
|
balance_prev text not null,
|
||||||
|
balance_curr text not null,
|
||||||
|
remark text,
|
||||||
|
created_at timestamptz default current_timestamp
|
||||||
|
);
|
||||||
|
create index idx_balance_activity_user_id on balance_activity (user_id);
|
||||||
|
create index idx_balance_activity_bill_id on balance_activity (bill_id);
|
||||||
|
create index idx_balance_activity_admin_id on balance_activity (admin_id);
|
||||||
|
create index idx_balance_activity_created_at on balance_activity (created_at);
|
||||||
|
|
||||||
|
-- balance_activity表字段注释
|
||||||
|
comment on table balance_activity is '余额变动记录表';
|
||||||
|
comment on column balance_activity.id is '记录ID';
|
||||||
|
comment on column balance_activity.user_id is '用户ID';
|
||||||
|
comment on column balance_activity.bill_id is '账单ID';
|
||||||
|
comment on column balance_activity.admin_id is '管理员ID';
|
||||||
|
comment on column balance_activity.amount is '变动金额';
|
||||||
|
comment on column balance_activity.balance_prev is '变动前余额';
|
||||||
|
comment on column balance_activity.balance_curr is '变动后余额';
|
||||||
|
comment on column balance_activity.remark is '备注';
|
||||||
|
comment on column balance_activity.created_at is '创建时间';
|
||||||
|
|
||||||
-- coupon 优惠券
|
-- coupon 优惠券
|
||||||
drop table if exists coupon cascade;
|
drop table if exists coupon cascade;
|
||||||
create table coupon (
|
create table coupon (
|
||||||
@@ -1019,6 +1090,8 @@ comment on column coupon.deleted_at is '删除时间';
|
|||||||
-- user表外键
|
-- user表外键
|
||||||
alter table "user"
|
alter table "user"
|
||||||
add constraint fk_user_admin_id foreign key (admin_id) references admin (id) on delete set null;
|
add constraint fk_user_admin_id foreign key (admin_id) references admin (id) on delete set null;
|
||||||
|
alter table "user"
|
||||||
|
add constraint fk_user_discount_id foreign key (discount_id) references product_discount (id) on delete set null;
|
||||||
|
|
||||||
-- session表外键
|
-- session表外键
|
||||||
alter table session
|
alter table session
|
||||||
@@ -1034,23 +1107,23 @@ alter table permission
|
|||||||
alter table link_user_role
|
alter table link_user_role
|
||||||
add constraint fk_link_user_role_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
add constraint fk_link_user_role_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||||||
alter table link_user_role
|
alter table link_user_role
|
||||||
add constraint fk_link_user_role_role_id foreign key (role_id) references user_role (id) on delete cascade;
|
add constraint fk_link_user_role_role_id foreign key (user_role_id) references user_role (id) on delete cascade;
|
||||||
|
|
||||||
-- link_admin_role表外键
|
-- link_admin_role表外键
|
||||||
alter table link_admin_role
|
alter table link_admin_role
|
||||||
add constraint fk_link_admin_role_admin_id foreign key (admin_id) references admin (id) on delete cascade;
|
add constraint fk_link_admin_role_admin_id foreign key (admin_id) references admin (id) on delete cascade;
|
||||||
alter table link_admin_role
|
alter table link_admin_role
|
||||||
add constraint fk_link_admin_role_role_id foreign key (role_id) references admin_role (id) on delete cascade;
|
add constraint fk_link_admin_role_role_id foreign key (admin_role_id) references admin_role (id) on delete cascade;
|
||||||
|
|
||||||
-- link_user_role_permission表外键
|
-- link_user_role_permission表外键
|
||||||
alter table link_user_role_permission
|
alter table link_user_role_permission
|
||||||
add constraint fk_link_user_role_permission_role_id foreign key (role_id) references user_role (id) on delete cascade;
|
add constraint fk_link_user_role_permission_role_id foreign key (user_role_id) references user_role (id) on delete cascade;
|
||||||
alter table link_user_role_permission
|
alter table link_user_role_permission
|
||||||
add constraint fk_link_user_role_permission_permission_id foreign key (permission_id) references permission (id) on delete cascade;
|
add constraint fk_link_user_role_permission_permission_id foreign key (permission_id) references permission (id) on delete cascade;
|
||||||
|
|
||||||
-- link_admin_role_permission表外键
|
-- link_admin_role_permission表外键
|
||||||
alter table link_admin_role_permission
|
alter table link_admin_role_permission
|
||||||
add constraint fk_link_admin_role_permission_role_id foreign key (role_id) references admin_role (id) on delete cascade;
|
add constraint fk_link_admin_role_permission_role_id foreign key (admin_role_id) references admin_role (id) on delete cascade;
|
||||||
alter table link_admin_role_permission
|
alter table link_admin_role_permission
|
||||||
add constraint fk_link_admin_role_permission_permission_id foreign key (permission_id) references permission (id) on delete cascade;
|
add constraint fk_link_admin_role_permission_permission_id foreign key (permission_id) references permission (id) on delete cascade;
|
||||||
|
|
||||||
@@ -1077,14 +1150,20 @@ alter table channel
|
|||||||
-- resource表外键
|
-- resource表外键
|
||||||
alter table resource
|
alter table resource
|
||||||
add constraint fk_resource_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
add constraint fk_resource_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||||||
|
alter table resource
|
||||||
|
add constraint fk_product_code foreign key (code) references product (code) on update cascade on delete restrict;
|
||||||
|
|
||||||
-- resource_short表外键
|
-- resource_short表外键
|
||||||
alter table resource_short
|
alter table resource_short
|
||||||
add constraint fk_resource_short_resource_id foreign key (resource_id) references resource (id) on delete cascade;
|
add constraint fk_resource_short_resource_id foreign key (resource_id) references resource (id) on delete cascade;
|
||||||
|
alter table resource_short
|
||||||
|
add constraint fk_resource_short_code foreign key (code) references product_sku (code) on update cascade on delete restrict;
|
||||||
|
|
||||||
-- resource_long表外键
|
-- resource_long表外键
|
||||||
alter table resource_long
|
alter table resource_long
|
||||||
add constraint fk_resource_long_resource_id foreign key (resource_id) references resource (id) on delete cascade;
|
add constraint fk_resource_long_resource_id foreign key (resource_id) references resource (id) on delete cascade;
|
||||||
|
alter table resource_long
|
||||||
|
add constraint fk_resource_long_code foreign key (code) references product_sku (code) on update cascade on delete restrict;
|
||||||
|
|
||||||
-- trade表外键
|
-- trade表外键
|
||||||
alter table trade
|
alter table trade
|
||||||
@@ -1105,6 +1184,8 @@ alter table bill
|
|||||||
add constraint fk_bill_resource_id foreign key (resource_id) references resource (id) on delete set null;
|
add constraint fk_bill_resource_id foreign key (resource_id) references resource (id) on delete set null;
|
||||||
alter table bill
|
alter table bill
|
||||||
add constraint fk_bill_refund_id foreign key (refund_id) references refund (id) on delete set null;
|
add constraint fk_bill_refund_id foreign key (refund_id) references refund (id) on delete set null;
|
||||||
|
alter table bill
|
||||||
|
add constraint fk_bill_coupon_id foreign key (coupon_id) references coupon (id) on delete set null;
|
||||||
|
|
||||||
-- coupon表外键
|
-- coupon表外键
|
||||||
alter table coupon
|
alter table coupon
|
||||||
@@ -1113,11 +1194,21 @@ alter table coupon
|
|||||||
-- product_sku表外键
|
-- product_sku表外键
|
||||||
alter table product_sku
|
alter table product_sku
|
||||||
add constraint fk_product_sku_product_id foreign key (product_id) references product (id) on delete cascade;
|
add constraint fk_product_sku_product_id foreign key (product_id) references product (id) on delete cascade;
|
||||||
|
alter table product_sku
|
||||||
|
add constraint fk_product_sku_discount_id foreign key (discount_id) references product_discount (id) on delete restrict;
|
||||||
|
|
||||||
-- product_sku_user表外键
|
-- product_sku_user表外键
|
||||||
alter table product_sku_user
|
alter table product_sku_user
|
||||||
add constraint fk_product_sku_user_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
add constraint fk_product_sku_user_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||||||
alter table product_sku_user
|
alter table product_sku_user
|
||||||
add constraint fk_product_sku_user_product_sku_id foreign key (product_sku_id) references product_sku (id) on delete cascade;
|
add constraint fk_product_sku_user_product_sku_id foreign key (product_sku_id) references product_sku (id) on delete cascade;
|
||||||
|
alter table product_sku_user
|
||||||
|
add constraint fk_product_sku_user_discount_id foreign key (discount_id) references product_discount (id) on delete restrict;
|
||||||
|
|
||||||
|
--balance_activity表外键
|
||||||
|
alter table balance_activity
|
||||||
|
add constraint fk_balance_activity_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||||||
|
alter table balance_activity
|
||||||
|
add constraint fk_balance_activity_bill_id foreign key (bill_id) references bill (id) on delete set null;
|
||||||
|
|
||||||
-- endregion
|
-- endregion
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ func authClient(clientId string, clientSecrets ...string) (*m.Client, error) {
|
|||||||
|
|
||||||
// 获取客户端信息
|
// 获取客户端信息
|
||||||
client, err := q.Client.
|
client, err := q.Client.
|
||||||
|
Preload(q.Client.Permissions).
|
||||||
Where(
|
Where(
|
||||||
q.Client.ClientID.Eq(clientId),
|
q.Client.ClientID.Eq(clientId),
|
||||||
q.Client.Status.Eq(1)).
|
q.Client.Status.Eq(1)).
|
||||||
@@ -36,8 +37,6 @@ func authClient(clientId string, clientSecrets ...string) (*m.Client, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo 查询客户端关联权限
|
|
||||||
|
|
||||||
// 组织授权信息(一次性请求)
|
// 组织授权信息(一次性请求)
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
@@ -154,3 +153,23 @@ func authAdminByPassword(tx *q.Query, username, password string) (*m.Admin, erro
|
|||||||
|
|
||||||
return admin, nil
|
return admin, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func adminScopes(admin *m.Admin) ([]string, error) {
|
||||||
|
var scopes []struct{ Name string }
|
||||||
|
err := q.Admin.
|
||||||
|
LeftJoin(q.LinkAdminRole, q.LinkAdminRole.AdminID.EqCol(q.Admin.ID)).
|
||||||
|
LeftJoin(q.LinkAdminRolePermission, q.LinkAdminRolePermission.RoleID.EqCol(q.LinkAdminRole.RoleID)).
|
||||||
|
LeftJoin(q.Permission, q.Permission.ID.EqCol(q.LinkAdminRolePermission.PermissionID)).
|
||||||
|
Where(q.Admin.ID.Eq(admin.ID)).
|
||||||
|
Select(q.Permission.Name).
|
||||||
|
Scan(&scopes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
scopeNames := make([]string, 0, len(scopes))
|
||||||
|
for _, scope := range scopes {
|
||||||
|
scopeNames = append(scopeNames, scope.Name)
|
||||||
|
}
|
||||||
|
return scopeNames, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package auth
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
@@ -12,7 +13,6 @@ type AuthCtx struct {
|
|||||||
Client *m.Client `json:"client,omitempty"`
|
Client *m.Client `json:"client,omitempty"`
|
||||||
Scopes []string `json:"scopes,omitempty"`
|
Scopes []string `json:"scopes,omitempty"`
|
||||||
Session *m.Session `json:"session,omitempty"`
|
Session *m.Session `json:"session,omitempty"`
|
||||||
smap map[string]struct{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AuthCtx) PermitUser(scopes ...string) (*AuthCtx, error) {
|
func (a *AuthCtx) PermitUser(scopes ...string) (*AuthCtx, error) {
|
||||||
@@ -68,14 +68,11 @@ func (a *AuthCtx) checkScopes(scopes ...string) bool {
|
|||||||
if len(scopes) == 0 || len(a.Scopes) == 0 {
|
if len(scopes) == 0 || len(a.Scopes) == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if len(a.smap) == 0 && len(a.Scopes) > 0 {
|
|
||||||
for _, scope := range scopes {
|
|
||||||
a.smap[scope] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, scope := range scopes {
|
for _, scope := range scopes {
|
||||||
if _, ok := a.smap[scope]; ok {
|
for _, prefix := range a.Scopes {
|
||||||
return true
|
if strings.HasPrefix(scope, prefix) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -288,6 +288,7 @@ func authAuthorizationCode(c *fiber.Ctx, auth *AuthCtx, req *TokenReq, now time.
|
|||||||
|
|
||||||
func authClientCredential(c *fiber.Ctx, auth *AuthCtx, _ *TokenReq, now time.Time) (*m.Session, error) {
|
func authClientCredential(c *fiber.Ctx, auth *AuthCtx, _ *TokenReq, now time.Time) (*m.Session, error) {
|
||||||
// todo 检查 scope
|
// todo 检查 scope
|
||||||
|
scopes := strings.Join(auth.Scopes, " ")
|
||||||
|
|
||||||
// 生成会话
|
// 生成会话
|
||||||
ip, _ := orm.ParseInet(c.IP()) // 可空字段,忽略异常
|
ip, _ := orm.ParseInet(c.IP()) // 可空字段,忽略异常
|
||||||
@@ -298,6 +299,7 @@ func authClientCredential(c *fiber.Ctx, auth *AuthCtx, _ *TokenReq, now time.Tim
|
|||||||
ClientID: &auth.Client.ID,
|
ClientID: &auth.Client.ID,
|
||||||
AccessToken: uuid.NewString(),
|
AccessToken: uuid.NewString(),
|
||||||
AccessTokenExpires: now.Add(time.Duration(env.SessionAccessExpire) * time.Second),
|
AccessTokenExpires: now.Add(time.Duration(env.SessionAccessExpire) * time.Second),
|
||||||
|
Scopes: &scopes,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存会话
|
// 保存会话
|
||||||
@@ -318,6 +320,8 @@ func authPassword(c *fiber.Ctx, auth *AuthCtx, req *TokenReq, now time.Time) (*m
|
|||||||
var user *m.User
|
var user *m.User
|
||||||
var admin *m.Admin
|
var admin *m.Admin
|
||||||
|
|
||||||
|
var scopes []string
|
||||||
|
|
||||||
pool := req.LoginPool
|
pool := req.LoginPool
|
||||||
if pool == "" {
|
if pool == "" {
|
||||||
pool = PwdLoginAsUser
|
pool = PwdLoginAsUser
|
||||||
@@ -332,9 +336,8 @@ func authPassword(c *fiber.Ctx, auth *AuthCtx, req *TokenReq, now time.Time) (*m
|
|||||||
|
|
||||||
// 手机号首次登录的自动创建用户
|
// 手机号首次登录的自动创建用户
|
||||||
user = &m.User{
|
user = &m.User{
|
||||||
Phone: req.Username,
|
Phone: req.Username,
|
||||||
Username: u.P(req.Username),
|
Status: m.UserStatusEnabled,
|
||||||
Status: m.UserStatusEnabled,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,6 +351,10 @@ func authPassword(c *fiber.Ctx, auth *AuthCtx, req *TokenReq, now time.Time) (*m
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
scopes, err = adminScopes(admin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// 更新管理员登录时间
|
// 更新管理员登录时间
|
||||||
admin.LastLogin = u.P(time.Now())
|
admin.LastLogin = u.P(time.Now())
|
||||||
@@ -363,7 +370,7 @@ func authPassword(c *fiber.Ctx, auth *AuthCtx, req *TokenReq, now time.Time) (*m
|
|||||||
IP: ip,
|
IP: ip,
|
||||||
UA: ua,
|
UA: ua,
|
||||||
ClientID: &auth.Client.ID,
|
ClientID: &auth.Client.ID,
|
||||||
Scopes: u.X(req.Scope),
|
Scopes: u.X(strings.Join(scopes, " ")),
|
||||||
AccessToken: uuid.NewString(),
|
AccessToken: uuid.NewString(),
|
||||||
AccessTokenExpires: now.Add(time.Duration(env.SessionAccessExpire) * time.Second),
|
AccessTokenExpires: now.Add(time.Duration(env.SessionAccessExpire) * time.Second),
|
||||||
}
|
}
|
||||||
@@ -541,22 +548,30 @@ func introspectUser(ctx *fiber.Ctx, authCtx *AuthCtx) error {
|
|||||||
func introspectAdmin(ctx *fiber.Ctx, authCtx *AuthCtx) error {
|
func introspectAdmin(ctx *fiber.Ctx, authCtx *AuthCtx) error {
|
||||||
// 获取管理员信息
|
// 获取管理员信息
|
||||||
profile, err := q.Admin.
|
profile, err := q.Admin.
|
||||||
|
Preload(q.Admin.Roles, q.Admin.Roles.Permissions).
|
||||||
Where(q.Admin.ID.Eq(authCtx.Admin.ID)).
|
Where(q.Admin.ID.Eq(authCtx.Admin.ID)).
|
||||||
Omit(q.Admin.DeletedAt).
|
Omit(q.Admin.DeletedAt, q.Admin.Password).
|
||||||
Take()
|
Take()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 不返回密码
|
// 整理权限列表
|
||||||
profile.Password = ""
|
scopes := make(map[string]struct{}, 0)
|
||||||
|
for _, role := range profile.Roles {
|
||||||
// 掩码敏感信息
|
for _, permission := range role.Permissions {
|
||||||
if profile.Phone != nil && *profile.Phone != "" {
|
scopes[permission.Name] = struct{}{}
|
||||||
profile.Phone = u.P(maskPhone(*profile.Phone))
|
}
|
||||||
|
}
|
||||||
|
list := make([]string, 0, len(scopes))
|
||||||
|
for scope := range scopes {
|
||||||
|
list = append(list, scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.JSON(profile)
|
return ctx.JSON(struct {
|
||||||
|
*m.Admin
|
||||||
|
Scopes []string `json:"scopes"`
|
||||||
|
}{profile, list})
|
||||||
}
|
}
|
||||||
|
|
||||||
func maskPhone(phone string) string {
|
func maskPhone(phone string) string {
|
||||||
|
|||||||
@@ -113,8 +113,14 @@ func authBasic(_ context.Context, token string) (*AuthCtx, error) {
|
|||||||
return nil, fmt.Errorf("客户端认证失败:%w", err)
|
return nil, fmt.Errorf("客户端认证失败:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scopes := []string{}
|
||||||
|
if client.Permissions != nil {
|
||||||
|
for _, p := range client.Permissions {
|
||||||
|
scopes = append(scopes, p.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
return &AuthCtx{
|
return &AuthCtx{
|
||||||
Client: client,
|
Client: client,
|
||||||
Scopes: []string{},
|
Scopes: scopes,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,3 +130,8 @@ func Query(in any) url.Values {
|
|||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 数据请求
|
||||||
|
type IdReq struct {
|
||||||
|
Id int32 `json:"id"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type Model struct {
|
|||||||
ID int32 `json:"id" gorm:"column:id;primaryKey"`
|
ID int32 `json:"id" gorm:"column:id;primaryKey"`
|
||||||
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
|
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
|
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
|
||||||
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"column:deleted_at"`
|
DeletedAt gorm.DeletedAt `json:"-" gorm:"column:deleted_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) GetID() int32 {
|
func (m *Model) GetID() int32 {
|
||||||
|
|||||||
8
web/core/product.go
Normal file
8
web/core/product.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
type ProductCode string
|
||||||
|
|
||||||
|
var (
|
||||||
|
ProductShort ProductCode = "short"
|
||||||
|
ProductLong ProductCode = "long"
|
||||||
|
)
|
||||||
58
web/core/scopes.go
Normal file
58
web/core/scopes.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
const (
|
||||||
|
ScopePermission = string("permission") // 权限
|
||||||
|
ScopePermissionRead = string("permission:read") // 读取权限列表
|
||||||
|
ScopePermissionWrite = string("permission:write") // 写入权限
|
||||||
|
|
||||||
|
ScopeAdminRole = string("admin_role") // 管理员角色
|
||||||
|
ScopeAdminRoleRead = string("admin_role:read") // 读取管理员角色列表
|
||||||
|
ScopeAdminRoleWrite = string("admin_role:write") // 写入管理员角色
|
||||||
|
|
||||||
|
ScopeAdmin = string("admin") // 管理员
|
||||||
|
ScopeAdminRead = string("admin:read") // 读取管理员列表
|
||||||
|
ScopeAdminWrite = string("admin:write") // 写入管理员
|
||||||
|
|
||||||
|
ScopeProduct = string("product") // 产品
|
||||||
|
ScopeProductRead = string("product:read") // 读取产品列表
|
||||||
|
ScopeProductWrite = string("product:write") // 写入产品
|
||||||
|
|
||||||
|
ScopeProductSku = string("product_sku") // 产品套餐
|
||||||
|
ScopeProductSkuRead = string("product_sku:read") // 读取产品套餐列表
|
||||||
|
ScopeProductSkuWrite = string("product_sku:write") // 写入产品套餐
|
||||||
|
|
||||||
|
ScopeDiscount = string("discount") // 折扣
|
||||||
|
ScopeDiscountRead = string("discount:read") // 读取折扣列表
|
||||||
|
ScopeDiscountWrite = string("discount:write") // 写入折扣
|
||||||
|
|
||||||
|
ScopeResource = string("resource") // 用户套餐
|
||||||
|
ScopeResourceRead = string("resource:read") // 读取用户套餐列表
|
||||||
|
ScopeResourceWrite = string("resource:write") // 写入用户套餐
|
||||||
|
|
||||||
|
ScopeUser = string("user") // 用户
|
||||||
|
ScopeUserRead = string("user:read") // 读取用户列表
|
||||||
|
ScopeUserReadOne = string("user:read:one") // 读取单个用户
|
||||||
|
ScopeUserWrite = string("user:write") // 写入用户
|
||||||
|
ScopeUserWriteBalance = string("user:write:balance") // 写入用户余额
|
||||||
|
ScopeUserWriteBind = string("user:write:bind") // 用户认领
|
||||||
|
|
||||||
|
ScopeCoupon = string("coupon") // 优惠券
|
||||||
|
ScopeCouponRead = string("coupon:read") // 读取优惠券列表
|
||||||
|
ScopeCouponWrite = string("coupon:write") // 写入优惠券
|
||||||
|
|
||||||
|
ScopeBatch = string("batch") // 批次
|
||||||
|
ScopeBatchRead = string("batch:read") // 读取批次列表
|
||||||
|
ScopeBatchWrite = string("batch:write") // 写入批次
|
||||||
|
|
||||||
|
ScopeChannel = string("channel") // IP
|
||||||
|
ScopeChannelRead = string("channel:read") // 读取 IP 列表
|
||||||
|
ScopeChannelWrite = string("channel:write") // 写入 IP
|
||||||
|
|
||||||
|
ScopeTrade = string("trade") // 交易
|
||||||
|
ScopeTradeRead = string("trade:read") // 读取交易列表
|
||||||
|
ScopeTradeWrite = string("trade:write") // 写入交易
|
||||||
|
|
||||||
|
ScopeBill = string("bill") // 账单
|
||||||
|
ScopeBillRead = string("bill:read") // 读取账单列表
|
||||||
|
ScopeBillWrite = string("bill:write") // 写入账单
|
||||||
|
)
|
||||||
29
web/error.go
29
web/error.go
@@ -1,11 +1,14 @@
|
|||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
@@ -19,6 +22,9 @@ func ErrorHandler(c *fiber.Ctx, err error) error {
|
|||||||
var authErr auth.AuthErr
|
var authErr auth.AuthErr
|
||||||
var bizErr *core.BizErr
|
var bizErr *core.BizErr
|
||||||
var servErr *core.ServErr
|
var servErr *core.ServErr
|
||||||
|
var timeErr *time.ParseError
|
||||||
|
var jsonErr *json.UnmarshalTypeError
|
||||||
|
var jsonSyntaxErr *json.SyntaxError
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
|
||||||
@@ -48,11 +54,32 @@ func ErrorHandler(c *fiber.Ctx, err error) error {
|
|||||||
code = fiber.StatusInternalServerError
|
code = fiber.StatusInternalServerError
|
||||||
message = err.Error()
|
message = err.Error()
|
||||||
|
|
||||||
|
case errors.As(err, &timeErr):
|
||||||
|
code = fiber.StatusBadRequest
|
||||||
|
message = fmt.Sprintf("时间格式不正确,传入值为 %s,检查传参是否为时间类型", timeErr.Value)
|
||||||
|
|
||||||
|
case errors.As(err, &jsonErr):
|
||||||
|
code = fiber.StatusBadRequest
|
||||||
|
message = fmt.Sprintf("参数 %s 类型不正确,传入类型为 %s,正确类型应该为 %s", jsonErr.Field, jsonErr.Value, jsonErr.Type.Name())
|
||||||
|
|
||||||
|
case errors.As(err, &jsonSyntaxErr):
|
||||||
|
code = fiber.StatusBadRequest
|
||||||
|
message = "参数格式不正确,检查传参是否为 JSON 格式"
|
||||||
|
|
||||||
// 所有未手动声明的错误类型
|
// 所有未手动声明的错误类型
|
||||||
default:
|
default:
|
||||||
slog.Warn("未处理的异常", slog.String("type", reflect.TypeOf(err).Name()), slog.String("error", err.Error()))
|
t := reflect.TypeOf(err)
|
||||||
|
for {
|
||||||
|
if t.Kind() == reflect.Pointer {
|
||||||
|
t = t.Elem()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
slog.Warn("未处理的异常", slog.String("type", t.String()), slog.String("error", err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
slog.Warn(message)
|
||||||
c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
|
c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
|
||||||
return c.Status(code).SendString(message)
|
return c.Status(code).SendString(message)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,18 +9,23 @@ import (
|
|||||||
"github.com/hibiken/asynq"
|
"github.com/hibiken/asynq"
|
||||||
)
|
)
|
||||||
|
|
||||||
const CompleteTrade = "trade:update"
|
const CloseTrade = "trade:update"
|
||||||
|
|
||||||
type CompleteTradeData struct {
|
type CloseTradeData struct {
|
||||||
|
UserId int32 `json:"user_id" validate:"required"`
|
||||||
TradeNo string `json:"trade_no" validate:"required"`
|
TradeNo string `json:"trade_no" validate:"required"`
|
||||||
Method m.TradeMethod `json:"method" validate:"required"`
|
Method m.TradeMethod `json:"method" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCancelTrade(data CompleteTradeData) *asynq.Task {
|
func NewCloseTradeTask(uid int32, tradeNo string, method m.TradeMethod) *asynq.Task {
|
||||||
bytes, err := json.Marshal(data)
|
bytes, err := json.Marshal(CloseTradeData{
|
||||||
|
UserId: uid,
|
||||||
|
TradeNo: tradeNo,
|
||||||
|
Method: method,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("序列化更新交易任务失败", "error", err)
|
slog.Error("序列化更新交易任务失败", "error", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return asynq.NewTask(CompleteTrade, bytes)
|
return asynq.NewTask(CloseTrade, bytes)
|
||||||
}
|
}
|
||||||
|
|||||||
30
web/globals/orm/timez.go
Normal file
30
web/globals/orm/timez.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DateTime struct {
|
||||||
|
time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dt *DateTime) Scan(value any) error {
|
||||||
|
switch v := value.(type) {
|
||||||
|
case time.Time:
|
||||||
|
dt.Time = v
|
||||||
|
case string:
|
||||||
|
t, err := time.Parse(time.RFC3339, v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dt.Time = t
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported type: %T", value)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dt DateTime) Value() (any, error) {
|
||||||
|
return dt.Time.Format(time.RFC3339), nil
|
||||||
|
}
|
||||||
106
web/handlers/admin.go
Normal file
106
web/handlers/admin.go
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/auth"
|
||||||
|
"platform/web/core"
|
||||||
|
g "platform/web/globals"
|
||||||
|
s "platform/web/services"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PageAdminByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req PageAdminsReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, total, err := s.Admin.PageAdmins(req.PageReq)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(core.PageResp{
|
||||||
|
List: list,
|
||||||
|
Total: int(total),
|
||||||
|
Page: req.GetPage(),
|
||||||
|
Size: req.GetSize(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type PageAdminsReq struct {
|
||||||
|
core.PageReq
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllAdminByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := s.Admin.All()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.CreateAdmin
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Admin.CreateAdmin(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.UpdateAdmin
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Admin.UpdateAdmin(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req core.IdReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Admin.RemoveAdmin(req.Id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
103
web/handlers/admin_role.go
Normal file
103
web/handlers/admin_role.go
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/auth"
|
||||||
|
"platform/web/core"
|
||||||
|
g "platform/web/globals"
|
||||||
|
s "platform/web/services"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AllAdminRoleByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminRoleRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := s.AdminRole.ListRoles()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PageAdminRoleByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminRoleRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req PageAdminRolesReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, total, err := s.AdminRole.PageRoles(req.PageReq)
|
||||||
|
|
||||||
|
return c.JSON(core.PageResp{
|
||||||
|
List: list,
|
||||||
|
Total: int(total),
|
||||||
|
Page: req.GetPage(),
|
||||||
|
Size: req.GetSize(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type PageAdminRolesReq struct {
|
||||||
|
core.PageReq
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateAdminRole(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminRoleWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.CreateAdminRole
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.AdminRole.CreateAdminRole(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateAdminRole(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminRoleWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.UpdateAdminRole
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.AdminRole.UpdateAdminRole(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveAdminRole(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeAdminRoleWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req core.IdReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.AdminRole.RemoveAdminRole(req.Id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"platform/pkg/u"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
c "platform/web/core"
|
c "platform/web/core"
|
||||||
@@ -11,8 +12,8 @@ import (
|
|||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PageResourceBatch 分页查询套餐提取记录
|
// PageBatch 分页查询套餐提取记录
|
||||||
func PageResourceBatch(ctx *fiber.Ctx) error {
|
func PageBatch(ctx *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
authCtx, err := auth.GetAuthCtx(ctx).PermitUser()
|
authCtx, err := auth.GetAuthCtx(ctx).PermitUser()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -58,17 +59,55 @@ type PageResourceBatchReq struct {
|
|||||||
|
|
||||||
// PageBatchByAdmin 分页查询所有提取记录
|
// PageBatchByAdmin 分页查询所有提取记录
|
||||||
func PageBatchByAdmin(c *fiber.Ctx) error {
|
func PageBatchByAdmin(c *fiber.Ctx) error {
|
||||||
_, err := auth.GetAuthCtx(c).PermitAdmin()
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeBatchRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
req := new(struct{ core.PageReq })
|
var req PageBatchByAdminReq
|
||||||
if err = g.Validator.ParseBody(c, req); err != nil {
|
if err = g.Validator.ParseBody(c, &req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
list, total, err := q.LogsUserUsage.FindByPage(req.GetOffset(), req.GetLimit())
|
do := q.LogsUserUsage.Where()
|
||||||
|
if req.UserPhone != nil {
|
||||||
|
do = do.Where(q.User.Phone.Eq(*req.UserPhone))
|
||||||
|
}
|
||||||
|
if req.ResourceNo != nil {
|
||||||
|
do = do.Where(q.Resource.ResourceNo.Eq(*req.ResourceNo))
|
||||||
|
}
|
||||||
|
if req.BatchNo != nil {
|
||||||
|
do = do.Where(q.LogsUserUsage.BatchNo.Eq(*req.BatchNo))
|
||||||
|
}
|
||||||
|
if req.Prov != nil {
|
||||||
|
do = do.Where(q.LogsUserUsage.Prov.Eq(*req.Prov))
|
||||||
|
}
|
||||||
|
if req.City != nil {
|
||||||
|
do = do.Where(q.LogsUserUsage.City.Eq(*req.City))
|
||||||
|
}
|
||||||
|
if req.Isp != nil {
|
||||||
|
do = do.Where(q.LogsUserUsage.ISP.Eq(*req.Isp))
|
||||||
|
}
|
||||||
|
if req.CreatedAtStart != nil {
|
||||||
|
time := u.DateHead(*req.CreatedAtStart)
|
||||||
|
do = do.Where(q.LogsUserUsage.Time.Gte(time))
|
||||||
|
}
|
||||||
|
if req.CreatedAtEnd != nil {
|
||||||
|
time := u.DateTail(*req.CreatedAtEnd)
|
||||||
|
do = do.Where(q.LogsUserUsage.Time.Lte(time))
|
||||||
|
}
|
||||||
|
|
||||||
|
list, total, err := q.LogsUserUsage.
|
||||||
|
Joins(q.LogsUserUsage.User, q.LogsUserUsage.Resource).
|
||||||
|
Select(
|
||||||
|
q.LogsUserUsage.ALL,
|
||||||
|
q.User.As("User").Phone.As("User__phone"),
|
||||||
|
q.User.As("User").Name.As("User__name"),
|
||||||
|
q.Resource.As("Resource").ResourceNo.As("Resource__resource_no"),
|
||||||
|
).
|
||||||
|
Where(do).
|
||||||
|
Order(q.LogsUserUsage.Time.Desc()).
|
||||||
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
|
|
||||||
return c.JSON(core.PageResp{
|
return c.JSON(core.PageResp{
|
||||||
List: list,
|
List: list,
|
||||||
@@ -77,3 +116,15 @@ func PageBatchByAdmin(c *fiber.Ctx) error {
|
|||||||
Size: req.GetSize(),
|
Size: req.GetSize(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PageBatchByAdminReq struct {
|
||||||
|
c.PageReq
|
||||||
|
UserPhone *string `json:"user_phone"`
|
||||||
|
ResourceNo *string `json:"resource_no"`
|
||||||
|
BatchNo *string `json:"batch_no"`
|
||||||
|
Prov *string `json:"prov"`
|
||||||
|
City *string `json:"city"`
|
||||||
|
Isp *string `json:"isp"`
|
||||||
|
CreatedAtStart *time.Time `json:"created_at_start"`
|
||||||
|
CreatedAtEnd *time.Time `json:"created_at_end"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"platform/pkg/u"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
@@ -13,19 +14,68 @@ import (
|
|||||||
// PageBillByAdmin 分页查询全部账单
|
// PageBillByAdmin 分页查询全部账单
|
||||||
func PageBillByAdmin(c *fiber.Ctx) error {
|
func PageBillByAdmin(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
_, err := auth.GetAuthCtx(c).PermitAdmin()
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeBillRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析请求参数
|
// 解析请求参数
|
||||||
req := new(core.PageReq)
|
req := new(PageBillByAdminReq)
|
||||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 构造查询条件
|
||||||
|
do := q.Bill.Where()
|
||||||
|
if req.UserPhone != nil {
|
||||||
|
do = do.Where(q.User.As("User").Phone.Eq(*req.UserPhone))
|
||||||
|
}
|
||||||
|
if req.TradeInnerNo != nil {
|
||||||
|
do = do.Where(q.Trade.As("Trade").InnerNo.Eq(*req.TradeInnerNo))
|
||||||
|
}
|
||||||
|
if req.ResourceNo != nil {
|
||||||
|
do = do.Where(q.Resource.As("Resource").ResourceNo.Eq(*req.ResourceNo))
|
||||||
|
}
|
||||||
|
if req.BillNo != nil {
|
||||||
|
do = do.Where(q.Bill.BillNo.Eq(*req.BillNo))
|
||||||
|
}
|
||||||
|
if req.CreatedAtStart != nil {
|
||||||
|
time := u.DateHead(*req.CreatedAtStart)
|
||||||
|
do = do.Where(q.Bill.CreatedAt.Gte(time))
|
||||||
|
}
|
||||||
|
if req.CreatedAtEnd != nil {
|
||||||
|
time := u.DateHead(*req.CreatedAtEnd)
|
||||||
|
do = do.Where(q.Bill.CreatedAt.Lte(time))
|
||||||
|
}
|
||||||
|
if req.ProductCode != nil {
|
||||||
|
do = do.Where(q.Resource.As("Resource").Code.Eq(*req.ProductCode))
|
||||||
|
}
|
||||||
|
if req.SkuCode != nil {
|
||||||
|
do = do.Where(q.Bill.
|
||||||
|
Where(q.ResourceShort.As("Resource__Short").Code.Eq(*req.SkuCode)).
|
||||||
|
Or(q.ResourceLong.As("Resource__Long").Code.Eq(*req.SkuCode)))
|
||||||
|
}
|
||||||
|
|
||||||
// 查询用户列表
|
// 查询用户列表
|
||||||
list, total, err := q.Bill.FindByPage(req.GetOffset(), req.GetLimit())
|
list, total, err := q.Bill.
|
||||||
|
Joins(
|
||||||
|
q.Bill.User,
|
||||||
|
q.Bill.Resource,
|
||||||
|
q.Bill.Trade,
|
||||||
|
q.Bill.Resource.Short,
|
||||||
|
q.Bill.Resource.Long,
|
||||||
|
).
|
||||||
|
Select(
|
||||||
|
q.Bill.ALL,
|
||||||
|
q.User.As("User").Phone.As("User__phone"),
|
||||||
|
q.User.As("User").Name.As("User__name"),
|
||||||
|
q.Trade.As("Trade").InnerNo.As("Trade__inner_no"),
|
||||||
|
q.Trade.As("Trade").Acquirer.As("Trade__acquirer"),
|
||||||
|
q.Resource.As("Resource").ResourceNo.As("Resource__resource_no"),
|
||||||
|
).
|
||||||
|
Where(do).
|
||||||
|
Order(q.Bill.CreatedAt.Desc()).
|
||||||
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -39,6 +89,18 @@ func PageBillByAdmin(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PageBillByAdminReq struct {
|
||||||
|
core.PageReq
|
||||||
|
UserPhone *string `json:"user_phone,omitempty"`
|
||||||
|
TradeInnerNo *string `json:"trade_inner_no,omitempty"`
|
||||||
|
ResourceNo *string `json:"resource_no,omitempty"`
|
||||||
|
BillNo *string `json:"bill_no,omitempty"`
|
||||||
|
CreatedAtStart *time.Time `json:"created_at_start,omitempty"`
|
||||||
|
CreatedAtEnd *time.Time `json:"created_at_end,omitempty"`
|
||||||
|
ProductCode *string `json:"product_code,omitempty"`
|
||||||
|
SkuCode *string `json:"sku_code,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListBill 获取账单列表
|
// ListBill 获取账单列表
|
||||||
func ListBill(c *fiber.Ctx) error {
|
func ListBill(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
|
"platform/web/globals/orm"
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
@@ -14,22 +15,65 @@ import (
|
|||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PageChannelsByAdmin 分页查询所有通道
|
// PageChannelByAdmin 分页查询所有通道
|
||||||
func PageChannelsByAdmin(c *fiber.Ctx) error {
|
func PageChannelByAdmin(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
_, err := auth.GetAuthCtx(c).PermitAdmin()
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeChannelRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析请求参数
|
// 解析请求参数
|
||||||
req := new(core.PageReq)
|
var req PageChannelsByAdminReq
|
||||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 构建查询条件
|
||||||
|
do := q.Channel.Where()
|
||||||
|
if req.UserPhone != nil {
|
||||||
|
do = do.Where(q.User.As("User").Phone.Eq(*req.UserPhone))
|
||||||
|
}
|
||||||
|
if req.ResourceNo != nil {
|
||||||
|
do = do.Where(q.Resource.As("Resource").ResourceNo.Eq(*req.ResourceNo))
|
||||||
|
}
|
||||||
|
if req.BatchNo != nil {
|
||||||
|
do = do.Where(q.Channel.BatchNo.Eq(*req.BatchNo))
|
||||||
|
}
|
||||||
|
if req.ProxyHost != nil {
|
||||||
|
do = do.Where(q.Channel.Host.Eq(*req.ProxyHost))
|
||||||
|
}
|
||||||
|
if req.ProxyPort != nil {
|
||||||
|
do = do.Where(q.Channel.Port.Eq(*req.ProxyPort))
|
||||||
|
}
|
||||||
|
if req.NodeIP != nil {
|
||||||
|
ip, err := orm.ParseInet(*req.NodeIP)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewBizErr("查询参数 ip 格式不正确")
|
||||||
|
}
|
||||||
|
do = do.Where(q.Channel.IP.Eq(ip))
|
||||||
|
}
|
||||||
|
if req.ExpiredAtStart != nil {
|
||||||
|
time := u.DateHead(*req.ExpiredAtStart)
|
||||||
|
do = do.Where(q.Channel.ExpiredAt.Gte(time))
|
||||||
|
}
|
||||||
|
if req.ExpiredAtEnd != nil {
|
||||||
|
time := u.DateHead(*req.ExpiredAtEnd)
|
||||||
|
do = do.Where(q.Channel.ExpiredAt.Lte(time))
|
||||||
|
}
|
||||||
|
|
||||||
// 查询通道列表
|
// 查询通道列表
|
||||||
list, total, err := q.Channel.FindByPage(req.GetOffset(), req.GetLimit())
|
list, total, err := q.Channel.
|
||||||
|
Joins(q.Channel.User, q.Channel.Resource).
|
||||||
|
Select(
|
||||||
|
q.Channel.ALL,
|
||||||
|
q.Resource.As("Resource").ResourceNo.As("Resource__resource_no"),
|
||||||
|
q.User.As("User").Phone.As("User__phone"),
|
||||||
|
q.User.As("User").Name.As("User__name"),
|
||||||
|
).
|
||||||
|
Where(do).
|
||||||
|
Order(q.Channel.CreatedAt.Desc()).
|
||||||
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -43,8 +87,20 @@ func PageChannelsByAdmin(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页查询当前用户通道
|
type PageChannelsByAdminReq struct {
|
||||||
func ListChannels(c *fiber.Ctx) error {
|
core.PageReq
|
||||||
|
UserPhone *string `json:"user_phone"`
|
||||||
|
ResourceNo *string `json:"resource_no"`
|
||||||
|
BatchNo *string `json:"batch_no"`
|
||||||
|
ProxyHost *string `json:"proxy_host"`
|
||||||
|
ProxyPort *uint16 `json:"proxy_port"`
|
||||||
|
NodeIP *string `json:"node_ip" validator:"omitempty,ip"`
|
||||||
|
ExpiredAtStart *time.Time `json:"expired_at_start"`
|
||||||
|
ExpiredAtEnd *time.Time `json:"expired_at_end"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListChannel 分页查询当前用户通道
|
||||||
|
func ListChannel(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
authContext, err := auth.GetAuthCtx(c).PermitUser()
|
authContext, err := auth.GetAuthCtx(c).PermitUser()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -114,9 +170,15 @@ type ListChannelsReq struct {
|
|||||||
ExpireBefore *time.Time `json:"expire_before"`
|
ExpireBefore *time.Time `json:"expire_before"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建新通道
|
// CreateChannel 创建新通道
|
||||||
func CreateChannel(c *fiber.Ctx) error {
|
func CreateChannel(c *fiber.Ctx) error {
|
||||||
|
|
||||||
|
// 检查权限
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitUser()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// 解析参数
|
// 解析参数
|
||||||
req := new(CreateChannelReq)
|
req := new(CreateChannelReq)
|
||||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||||
@@ -129,6 +191,10 @@ func CreateChannel(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建通道
|
// 创建通道
|
||||||
|
var isp *m.EdgeISP
|
||||||
|
if req.Isp != nil {
|
||||||
|
isp = u.X(m.ToEdgeISP(*req.Isp))
|
||||||
|
}
|
||||||
result, err := s.Channel.CreateChannels(
|
result, err := s.Channel.CreateChannels(
|
||||||
ip,
|
ip,
|
||||||
req.ResourceId,
|
req.ResourceId,
|
||||||
@@ -136,7 +202,7 @@ func CreateChannel(c *fiber.Ctx) error {
|
|||||||
req.AuthType == s.ChannelAuthTypePass,
|
req.AuthType == s.ChannelAuthTypePass,
|
||||||
req.Count,
|
req.Count,
|
||||||
s.EdgeFilter{
|
s.EdgeFilter{
|
||||||
Isp: u.ElseTo(req.Isp, m.ToEdgeISP),
|
Isp: isp,
|
||||||
Prov: req.Prov,
|
Prov: req.Prov,
|
||||||
City: req.City,
|
City: req.City,
|
||||||
},
|
},
|
||||||
|
|||||||
105
web/handlers/coupon.go
Normal file
105
web/handlers/coupon.go
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/auth"
|
||||||
|
"platform/web/core"
|
||||||
|
g "platform/web/globals"
|
||||||
|
s "platform/web/services"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PageCouponByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeCouponRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req core.PageReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, total, err := s.Coupon.Page(&req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(core.PageResp{
|
||||||
|
Total: int(total),
|
||||||
|
Page: req.GetPage(),
|
||||||
|
Size: req.GetSize(),
|
||||||
|
List: list,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllCouponByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeCouponRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := s.Coupon.All()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateCoupon(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeCouponWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.CreateCouponData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Coupon.Create(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateCoupon(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeCouponWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.UpdateCouponData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Coupon.Update(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteCoupon(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeCouponWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req core.IdReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Coupon.Delete(req.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -142,7 +142,7 @@ func IdentifyCallbackNew(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新用户实名认证状态
|
// 更新用户实名认证状态
|
||||||
_, err = q.User.Debug().
|
_, err = q.User.
|
||||||
Where(q.User.ID.Eq(info.Uid)).
|
Where(q.User.ID.Eq(info.Uid)).
|
||||||
UpdateSimple(
|
UpdateSimple(
|
||||||
q.User.IDType.Value(info.Type),
|
q.User.IDType.Value(info.Type),
|
||||||
|
|||||||
53
web/handlers/permission.go
Normal file
53
web/handlers/permission.go
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/auth"
|
||||||
|
"platform/web/core"
|
||||||
|
g "platform/web/globals"
|
||||||
|
s "platform/web/services"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AllPermissionByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopePermissionRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := s.Permission.ListPermissions()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PagePermissionByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopePermissionRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req PagePermissionByAdminReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取权限列表
|
||||||
|
list, total, err := s.Permission.PagePermissions(req.PageReq)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("获取权限列表失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(core.PageResp{
|
||||||
|
List: list,
|
||||||
|
Total: int(total),
|
||||||
|
Page: req.GetPage(),
|
||||||
|
Size: req.GetSize(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type PagePermissionByAdminReq struct {
|
||||||
|
core.PageReq
|
||||||
|
}
|
||||||
220
web/handlers/product.go
Normal file
220
web/handlers/product.go
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/auth"
|
||||||
|
"platform/web/core"
|
||||||
|
g "platform/web/globals"
|
||||||
|
s "platform/web/services"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AllProductByAdmin(c *fiber.Ctx) error {
|
||||||
|
// 检查权限
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析请求参数
|
||||||
|
// var req AllProductsByAdminReq
|
||||||
|
// if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 查询产品
|
||||||
|
products, err := s.Product.AllProducts()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(products)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllProductsByAdminReq struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateProduct(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.CreateProductData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Product.CreateProduct(&req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateProduct(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.UpdateProductData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Product.UpdateProduct(&req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteProduct(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req core.IdReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Product.DeleteProduct(req.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllProductSkuByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req AllProductSkuByAdminReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := s.ProductSku.All(req.Code)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllProductSkuByAdminReq struct {
|
||||||
|
Code string `json:"product_code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func PageProductSkuByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req PageProductSkuByAdminReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, total, err := s.ProductSku.Page(&req.PageReq, req.ProductId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(core.PageResp{
|
||||||
|
Total: int(total),
|
||||||
|
Page: req.GetPage(),
|
||||||
|
Size: req.GetSize(),
|
||||||
|
List: list,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type PageProductSkuByAdminReq struct {
|
||||||
|
core.PageReq
|
||||||
|
ProductId *int32 `json:"product_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateProductSku(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.CreateProductSkuData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.ProductSku.Create(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateProductSku(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.UpdateProductSkuData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.ProductSku.Update(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func BatchUpdateProductSkuDiscount(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.BatchUpdateSkuDiscountData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.ProductSku.BatchUpdateDiscount(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteProductSku(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req core.IdReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.ProductSku.Delete(req.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
105
web/handlers/product_discount.go
Normal file
105
web/handlers/product_discount.go
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/auth"
|
||||||
|
"platform/web/core"
|
||||||
|
g "platform/web/globals"
|
||||||
|
s "platform/web/services"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PageDiscountByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeDiscountRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req core.PageReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, total, err := s.ProductDiscount.Page(&req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(core.PageResp{
|
||||||
|
Total: int(total),
|
||||||
|
Page: req.GetPage(),
|
||||||
|
Size: req.GetSize(),
|
||||||
|
List: list,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllDiscountByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeDiscountRead)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := s.ProductDiscount.All()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateDiscount(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeDiscountWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.CreateProductDiscountData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.ProductDiscount.Create(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateDiscount(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeDiscountWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.UpdateProductDiscountData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.ProductDiscount.Update(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteDiscount(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeDiscountWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req core.IdReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.ProductDiscount.Delete(req.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -209,20 +209,78 @@ type PageResourceLongReq struct {
|
|||||||
|
|
||||||
// PageResourceShortByAdmin 分页查询全部短效套餐
|
// PageResourceShortByAdmin 分页查询全部短效套餐
|
||||||
func PageResourceShortByAdmin(c *fiber.Ctx) error {
|
func PageResourceShortByAdmin(c *fiber.Ctx) error {
|
||||||
_, err := auth.GetAuthCtx(c).PermitAdmin()
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeResourceRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
req := new(struct{ core.PageReq })
|
var req PageResourceShortByAdminReq
|
||||||
if err = g.Validator.ParseBody(c, req); err != nil {
|
if err = g.Validator.ParseBody(c, &req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do := q.Resource.Where()
|
||||||
|
if req.UserPhone != nil {
|
||||||
|
do = do.Where(q.User.As("User").Phone.Eq(*req.UserPhone))
|
||||||
|
}
|
||||||
|
if req.ResourceNo != nil {
|
||||||
|
do = do.Where(q.Resource.ResourceNo.Eq(*req.ResourceNo))
|
||||||
|
}
|
||||||
|
if req.Active != nil {
|
||||||
|
do = do.Where(q.Resource.Active.Is(*req.Active))
|
||||||
|
}
|
||||||
|
if req.Mode != nil {
|
||||||
|
do = do.Where(q.ResourceShort.As("Short").Type.Eq(int(*req.Mode)))
|
||||||
|
}
|
||||||
|
if req.CreatedAtStart != nil {
|
||||||
|
time := u.DateHead(*req.CreatedAtStart)
|
||||||
|
do = do.Where(q.Resource.CreatedAt.Gte(time))
|
||||||
|
}
|
||||||
|
if req.CreatedAtEnd != nil {
|
||||||
|
time := u.DateTail(*req.CreatedAtEnd)
|
||||||
|
do = do.Where(q.Resource.CreatedAt.Lte(time))
|
||||||
|
}
|
||||||
|
if req.Expired != nil {
|
||||||
|
if *req.Expired {
|
||||||
|
do = do.Where(q.Resource.Where(
|
||||||
|
q.ResourceShort.As("Short").Type.Eq(int(m.ResourceModeTime)),
|
||||||
|
q.ResourceShort.As("Short").ExpireAt.Lte(time.Now()),
|
||||||
|
).Or(
|
||||||
|
q.ResourceShort.As("Short").Type.Eq(int(m.ResourceModeQuota)),
|
||||||
|
q.ResourceShort.As("Short").Quota.LteCol(q.ResourceShort.As("Short").Used),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
do = do.Where(q.Resource.Where(
|
||||||
|
q.ResourceShort.As("Short").Type.Eq(int(m.ResourceModeTime)),
|
||||||
|
q.ResourceShort.As("Short").ExpireAt.Gt(time.Now()),
|
||||||
|
).Or(
|
||||||
|
q.ResourceShort.As("Short").Type.Eq(int(m.ResourceModeQuota)),
|
||||||
|
q.ResourceShort.As("Short").Quota.GtCol(q.ResourceShort.As("Short").Used),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list, total, err := q.Resource.
|
list, total, err := q.Resource.
|
||||||
LeftJoin(q.ResourceShort, q.ResourceShort.ResourceID.EqCol(q.Resource.ID)).
|
Joins(q.Resource.User, q.Resource.Short, q.Resource.Short.Sku).
|
||||||
Where(q.Resource.Type.Eq(int(m.ResourceTypeShort))).
|
Select(
|
||||||
|
q.Resource.ALL,
|
||||||
|
q.User.As("User").Phone.As("User__phone"),
|
||||||
|
q.User.As("User").Name.As("User__name"),
|
||||||
|
q.ResourceShort.As("Short").Type.As("Short__type"),
|
||||||
|
q.ResourceShort.As("Short").Live.As("Short__live"),
|
||||||
|
q.ResourceShort.As("Short").Quota.As("Short__quota"),
|
||||||
|
q.ResourceShort.As("Short").Used.As("Short__used"),
|
||||||
|
q.ResourceShort.As("Short").Daily.As("Short__daily"),
|
||||||
|
q.ResourceShort.As("Short").LastAt.As("Short__last_at"),
|
||||||
|
q.ResourceShort.As("Short").ExpireAt.As("Short__expire_at"),
|
||||||
|
q.ProductSku.As("Short__Sku").Name.As("Short__Sku__name"),
|
||||||
|
).
|
||||||
|
Where(q.Resource.Type.Eq(int(m.ResourceTypeShort)), do).
|
||||||
|
Order(q.Resource.CreatedAt.Desc()).
|
||||||
FindByPage(req.GetOffset(), req.GetLimit())
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return c.JSON(core.PageResp{
|
return c.JSON(core.PageResp{
|
||||||
List: list,
|
List: list,
|
||||||
@@ -232,22 +290,89 @@ func PageResourceShortByAdmin(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// PageResourceLongByAdmin 分页查询全部短效套餐
|
type PageResourceShortByAdminReq struct {
|
||||||
|
core.PageReq
|
||||||
|
UserPhone *string `json:"user_phone" form:"user_phone"`
|
||||||
|
ResourceNo *string `json:"resource_no" form:"resource_no"`
|
||||||
|
Active *bool `json:"active" form:"active"`
|
||||||
|
Mode *int `json:"mode" form:"mode"`
|
||||||
|
CreatedAtStart *time.Time `json:"created_at_start" form:"created_at_start"`
|
||||||
|
CreatedAtEnd *time.Time `json:"created_at_end" form:"created_at_end"`
|
||||||
|
Expired *bool `json:"expired" form:"expired"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PageResourceLongByAdmin 分页查询全部长效套餐
|
||||||
func PageResourceLongByAdmin(c *fiber.Ctx) error {
|
func PageResourceLongByAdmin(c *fiber.Ctx) error {
|
||||||
_, err := auth.GetAuthCtx(c).PermitAdmin()
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeResourceRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
req := new(struct{ core.PageReq })
|
var req PageResourceLongByAdminReq
|
||||||
if err = g.Validator.ParseBody(c, req); err != nil {
|
if err = g.Validator.ParseBody(c, &req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do := q.Resource.Where()
|
||||||
|
if req.UserPhone != nil {
|
||||||
|
do = do.Where(q.User.As("User").Phone.Eq(*req.UserPhone))
|
||||||
|
}
|
||||||
|
if req.ResourceNo != nil {
|
||||||
|
do = do.Where(q.Resource.ResourceNo.Eq(*req.ResourceNo))
|
||||||
|
}
|
||||||
|
if req.Active != nil {
|
||||||
|
do = do.Where(q.Resource.Active.Is(*req.Active))
|
||||||
|
}
|
||||||
|
if req.Mode != nil {
|
||||||
|
do = do.Where(q.ResourceLong.As("Long").Type.Eq(*req.Mode))
|
||||||
|
}
|
||||||
|
if req.CreatedAtStart != nil {
|
||||||
|
do = do.Where(q.Resource.CreatedAt.Gte(*req.CreatedAtStart))
|
||||||
|
}
|
||||||
|
if req.CreatedAtEnd != nil {
|
||||||
|
do = do.Where(q.Resource.CreatedAt.Lte(*req.CreatedAtEnd))
|
||||||
|
}
|
||||||
|
if req.Expired != nil {
|
||||||
|
if *req.Expired {
|
||||||
|
do = do.Where(q.Resource.Where(
|
||||||
|
q.ResourceLong.As("Long").Type.Eq(int(m.ResourceModeTime)),
|
||||||
|
q.ResourceLong.As("Long").ExpireAt.Lte(time.Now()),
|
||||||
|
).Or(
|
||||||
|
q.ResourceLong.As("Long").Type.Eq(int(m.ResourceModeQuota)),
|
||||||
|
q.ResourceLong.As("Long").Quota.LteCol(q.ResourceLong.As("Long").Used),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
do = do.Where(q.Resource.Where(
|
||||||
|
q.ResourceLong.As("Long").Type.Eq(int(m.ResourceModeTime)),
|
||||||
|
q.ResourceLong.As("Long").ExpireAt.Gt(time.Now()),
|
||||||
|
).Or(
|
||||||
|
q.ResourceLong.As("Long").Type.Eq(int(m.ResourceModeQuota)),
|
||||||
|
q.ResourceLong.As("Long").Quota.GtCol(q.ResourceLong.As("Long").Used),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list, total, err := q.Resource.
|
list, total, err := q.Resource.
|
||||||
LeftJoin(q.ResourceLong, q.ResourceLong.ResourceID.EqCol(q.Resource.ID)).
|
Joins(q.Resource.User, q.Resource.Long, q.Resource.Long.Sku).
|
||||||
Where(q.Resource.Type.Eq(int(m.ResourceTypeLong))).
|
Select(
|
||||||
|
q.Resource.ALL,
|
||||||
|
q.User.As("User").Phone.As("User__phone"),
|
||||||
|
q.User.As("User").Name.As("User__name"),
|
||||||
|
q.ResourceLong.As("Long").Type.As("Long__type"),
|
||||||
|
q.ResourceLong.As("Long").Live.As("Long__live"),
|
||||||
|
q.ResourceLong.As("Long").Quota.As("Long__quota"),
|
||||||
|
q.ResourceLong.As("Long").Used.As("Long__used"),
|
||||||
|
q.ResourceLong.As("Long").Daily.As("Long__daily"),
|
||||||
|
q.ResourceLong.As("Long").LastAt.As("Long__last_at"),
|
||||||
|
q.ResourceLong.As("Long").ExpireAt.As("Long__expire_at"),
|
||||||
|
q.ProductSku.As("Long__Sku").Name.As("Long__Sku__name"),
|
||||||
|
).
|
||||||
|
Where(q.Resource.Type.Eq(int(m.ResourceTypeLong)), do).
|
||||||
|
Order(q.Resource.CreatedAt.Desc()).
|
||||||
FindByPage(req.GetOffset(), req.GetLimit())
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return c.JSON(core.PageResp{
|
return c.JSON(core.PageResp{
|
||||||
List: list,
|
List: list,
|
||||||
@@ -257,6 +382,17 @@ func PageResourceLongByAdmin(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PageResourceLongByAdminReq struct {
|
||||||
|
core.PageReq
|
||||||
|
UserPhone *string `json:"user_phone" form:"user_phone"`
|
||||||
|
ResourceNo *string `json:"resource_no" form:"resource_no"`
|
||||||
|
Active *bool `json:"active" form:"active"`
|
||||||
|
Mode *int `json:"mode" form:"mode"`
|
||||||
|
CreatedAtStart *time.Time `json:"created_at_start" form:"created_at_start"`
|
||||||
|
CreatedAtEnd *time.Time `json:"created_at_end" form:"created_at_end"`
|
||||||
|
Expired *bool `json:"expired" form:"expired"`
|
||||||
|
}
|
||||||
|
|
||||||
// AllActiveResource 所有可用套餐
|
// AllActiveResource 所有可用套餐
|
||||||
func AllActiveResource(c *fiber.Ctx) error {
|
func AllActiveResource(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
@@ -316,6 +452,24 @@ func AllActiveResource(c *fiber.Ctx) error {
|
|||||||
type AllResourceReq struct {
|
type AllResourceReq struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UpdateResourceByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeResourceWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.UpdateResourceData
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Resource.Update(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
|
|
||||||
// StatisticResourceFree 统计每日可用
|
// StatisticResourceFree 统计每日可用
|
||||||
func StatisticResourceFree(c *fiber.Ctx) error {
|
func StatisticResourceFree(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
@@ -489,7 +643,7 @@ func CreateResource(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建套餐
|
// 创建套餐
|
||||||
err = s.Resource.CreateResourceByBalance(authCtx.User.ID, time.Now(), req.CreateResourceData)
|
err = s.Resource.CreateResourceByBalance(authCtx.User, req.CreateResourceData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -516,26 +670,28 @@ func ResourcePrice(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取套餐价格
|
// 获取套餐价格
|
||||||
sku, err := s.Resource.GetSku(req.CreateResourceData)
|
// sku, err := s.Resource.GetSku(req.CreateResourceData.Code())
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
|
||||||
before, after, err := s.Resource.GetPrice(sku, req.Count(), nil)
|
// _, amount, discounted, couponApplied, err := s.Resource.GetPrice(sku, req.Count(), nil, nil)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
detail, err := req.TradeDetail(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算折扣
|
// 计算折扣
|
||||||
return c.JSON(ResourcePriceResp{
|
return c.JSON(ResourcePriceResp{
|
||||||
Price: before.StringFixed(2),
|
Price: detail.Amount.StringFixed(2),
|
||||||
Discounted: sku.Discount,
|
Discounted: detail.Actual.StringFixed(2),
|
||||||
DiscountedPrice: after.StringFixed(2),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResourcePriceResp struct {
|
type ResourcePriceResp struct {
|
||||||
Price string `json:"price"`
|
Price string `json:"price"`
|
||||||
Discounted float32 `json:"discounted"`
|
Discounted string `json:"discounted_price"`
|
||||||
DiscountedPrice string `json:"discounted_price"`
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
|
"platform/pkg/u"
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
g "platform/web/globals"
|
g "platform/web/globals"
|
||||||
@@ -20,19 +21,57 @@ import (
|
|||||||
// PageTradeByAdmin 分页查询所有订单
|
// PageTradeByAdmin 分页查询所有订单
|
||||||
func PageTradeByAdmin(c *fiber.Ctx) error {
|
func PageTradeByAdmin(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
_, err := auth.GetAuthCtx(c).PermitAdmin()
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeTradeRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析请求参数
|
// 解析请求参数
|
||||||
req := new(core.PageReq)
|
req := new(PageTradeByAdminReq)
|
||||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 构建查询语句
|
||||||
|
do := q.Trade.Where()
|
||||||
|
if req.UserPhone != nil {
|
||||||
|
do = do.Where(q.User.As("User").Phone.Eq(*req.UserPhone))
|
||||||
|
}
|
||||||
|
if req.InnerNo != nil {
|
||||||
|
do = do.Where(q.Trade.InnerNo.Eq(*req.InnerNo))
|
||||||
|
}
|
||||||
|
if req.OuterNo != nil {
|
||||||
|
do = do.Where(q.Trade.OuterNo.Eq(*req.OuterNo))
|
||||||
|
}
|
||||||
|
if req.Method != nil {
|
||||||
|
do = do.Where(q.Trade.Method.Eq(*req.Method))
|
||||||
|
}
|
||||||
|
if req.Platform != nil {
|
||||||
|
do = do.Where(q.Trade.Platform.Eq(*req.Platform))
|
||||||
|
}
|
||||||
|
if req.Status != nil {
|
||||||
|
do = do.Where(q.Trade.Status.Eq(*req.Status))
|
||||||
|
}
|
||||||
|
if req.CreatedAtStart != nil {
|
||||||
|
time := u.DateHead(*req.CreatedAtStart)
|
||||||
|
do = do.Where(q.Trade.CreatedAt.Gte(time))
|
||||||
|
}
|
||||||
|
if req.CreatedAtEnd != nil {
|
||||||
|
time := u.DateTail(*req.CreatedAtEnd)
|
||||||
|
do = do.Where(q.Trade.CreatedAt.Lte(time))
|
||||||
|
}
|
||||||
|
|
||||||
// 查询用户列表
|
// 查询用户列表
|
||||||
list, total, err := q.Trade.FindByPage(req.GetOffset(), req.GetLimit())
|
list, total, err := q.Trade.
|
||||||
|
Joins(q.Trade.User).
|
||||||
|
Select(
|
||||||
|
q.Trade.ALL,
|
||||||
|
q.User.As("User").Phone.As("User__phone"),
|
||||||
|
q.User.As("User").Name.As("User__name"),
|
||||||
|
).
|
||||||
|
Where(do).
|
||||||
|
Order(q.Trade.CreatedAt.Desc()).
|
||||||
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -46,6 +85,18 @@ func PageTradeByAdmin(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PageTradeByAdminReq struct {
|
||||||
|
core.PageReq
|
||||||
|
UserPhone *string `json:"user_phone,omitempty"`
|
||||||
|
InnerNo *string `json:"inner_no,omitempty"`
|
||||||
|
OuterNo *string `json:"outer_no,omitempty"`
|
||||||
|
Method *int `json:"method,omitempty"`
|
||||||
|
Platform *int `json:"platform,omitempty"`
|
||||||
|
Status *int `json:"status,omitempty"`
|
||||||
|
CreatedAtStart *time.Time `json:"created_at_start,omitempty"`
|
||||||
|
CreatedAtEnd *time.Time `json:"created_at_end,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// 创建订单
|
// 创建订单
|
||||||
func TradeCreate(c *fiber.Ctx) error {
|
func TradeCreate(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
@@ -59,53 +110,43 @@ func TradeCreate(c *fiber.Ctx) error {
|
|||||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var product s.ProductInfo
|
|
||||||
switch req.Type {
|
switch req.Type {
|
||||||
case m.TradeTypePurchase:
|
case m.TradeTypePurchase:
|
||||||
if req.Resource == nil {
|
if req.Resource == nil {
|
||||||
return core.NewBizErr("购买信息不能为空")
|
return core.NewBizErr("购买信息不能为空")
|
||||||
}
|
}
|
||||||
product, err = s.NewCreateResourceByTradeData(req.Resource)
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("处理购买产品信息失败", err)
|
|
||||||
}
|
|
||||||
case m.TradeTypeRecharge:
|
case m.TradeTypeRecharge:
|
||||||
if req.Recharge == nil {
|
if req.Recharge == nil {
|
||||||
return core.NewBizErr("充值信息不能为空")
|
return core.NewBizErr("充值信息不能为空")
|
||||||
}
|
}
|
||||||
product = req.Recharge
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建交易
|
// 处理订单
|
||||||
result, err := s.Trade.CreateTrade(authCtx.User.ID, time.Now(), &req.CreateTradeData, product)
|
var result *s.CreateTradeResult
|
||||||
|
switch req.Type {
|
||||||
|
case m.TradeTypePurchase:
|
||||||
|
result, err = s.Trade.Create(authCtx.User, req.CreateTradeData, req.Resource)
|
||||||
|
case m.TradeTypeRecharge:
|
||||||
|
result, err = s.Trade.Create(authCtx.User, req.CreateTradeData, req.Recharge)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("创建交易失败", "error", err)
|
return core.NewServErr("处理购买产品信息失败", err)
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "创建交易失败"})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(&TradeCreateResp{
|
return c.JSON(result)
|
||||||
PayUrl: result.PaymentUrl,
|
|
||||||
TradeNo: result.TradeNo,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TradeCreateReq struct {
|
type TradeCreateReq struct {
|
||||||
s.CreateTradeData
|
*s.CreateTradeData
|
||||||
Type m.TradeType `json:"type" validate:"required"`
|
Type m.TradeType `json:"type" validate:"required"`
|
||||||
Resource *s.CreateResourceData `json:"resource,omitempty"`
|
Resource *s.CreateResourceData `json:"resource,omitempty"`
|
||||||
Recharge *s.RechargeProductInfo `json:"recharge,omitempty"`
|
Recharge *s.UpdateBalanceData `json:"recharge,omitempty"`
|
||||||
}
|
|
||||||
|
|
||||||
type TradeCreateResp struct {
|
|
||||||
PayUrl string `json:"pay_url"`
|
|
||||||
TradeNo string `json:"trade_no"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 完成订单
|
// 完成订单
|
||||||
func TradeComplete(c *fiber.Ctx) error {
|
func TradeComplete(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
_, err := auth.GetAuthCtx(c).PermitUser()
|
authCtx, err := auth.GetAuthCtx(c).PermitUser()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -117,7 +158,7 @@ func TradeComplete(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查订单状态
|
// 检查订单状态
|
||||||
err = s.Trade.CompleteTrade(&req.ModifyTradeData)
|
err = s.Trade.CompleteTrade(authCtx.User, &req.TradeRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -126,7 +167,7 @@ func TradeComplete(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TradeCompleteReq struct {
|
type TradeCompleteReq struct {
|
||||||
s.ModifyTradeData
|
s.TradeRef
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取消订单
|
// 取消订单
|
||||||
@@ -144,7 +185,7 @@ func TradeCancel(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 取消交易
|
// 取消交易
|
||||||
err = s.Trade.CancelTrade(&req.ModifyTradeData, time.Now())
|
err = s.Trade.CancelTrade(&req.TradeRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("取消交易失败", "trade_no", req.TradeNo, "error", err)
|
slog.Error("取消交易失败", "trade_no", req.TradeNo, "error", err)
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "取消交易失败"})
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "取消交易失败"})
|
||||||
@@ -154,11 +195,13 @@ func TradeCancel(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TradeCancelReq struct {
|
type TradeCancelReq struct {
|
||||||
s.ModifyTradeData
|
s.TradeRef
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查订单
|
// 检查订单
|
||||||
func TradeCheck(c *fiber.Ctx) error {
|
func TradeCheck(c *fiber.Ctx) error {
|
||||||
|
// 检查权限:sse 接口暂时不检查权限
|
||||||
|
|
||||||
// 解析请求参数
|
// 解析请求参数
|
||||||
req := new(TradeCheckReq)
|
req := new(TradeCheckReq)
|
||||||
if err := g.Validator.ParseQuery(c, req); err != nil {
|
if err := g.Validator.ParseQuery(c, req); err != nil {
|
||||||
@@ -175,7 +218,7 @@ func TradeCheck(c *fiber.Ctx) error {
|
|||||||
interval := 5
|
interval := 5
|
||||||
for range expire / interval {
|
for range expire / interval {
|
||||||
// 检查订单状态
|
// 检查订单状态
|
||||||
result, err := s.Trade.CheckTrade(&req.ModifyTradeData)
|
result, err := s.Trade.CheckTrade(&req.TradeRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("检查订单状态失败", "trade_no", req.TradeNo, "error", err)
|
slog.Error("检查订单状态失败", "trade_no", req.TradeNo, "error", err)
|
||||||
return
|
return
|
||||||
@@ -206,5 +249,5 @@ func TradeCheck(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TradeCheckReq struct {
|
type TradeCheckReq struct {
|
||||||
s.ModifyTradeData
|
s.TradeRef
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,27 +9,67 @@ import (
|
|||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 分页获取用户
|
// 分页获取用户
|
||||||
func PageUserByAdmin(c *fiber.Ctx) error {
|
func PageUserByAdmin(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
_, err := auth.GetAuthCtx(c).PermitAdmin()
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析请求参数
|
// 解析请求参数
|
||||||
req := new(core.PageReq)
|
req := new(PageUserByAdminReq)
|
||||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 构建查询条件
|
||||||
|
do := q.User.Where()
|
||||||
|
if req.Account != nil {
|
||||||
|
do = do.Where(q.User.Where(
|
||||||
|
q.User.Username.Like("%" + *req.Account + "%"),
|
||||||
|
).Or(
|
||||||
|
q.User.Phone.Like("%" + *req.Account + "%"),
|
||||||
|
).Or(
|
||||||
|
q.User.Email.Like("%" + *req.Account + "%"),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
if req.Name != nil {
|
||||||
|
do = do.Where(q.User.Name.Eq(*req.Name))
|
||||||
|
}
|
||||||
|
if req.Identified != nil {
|
||||||
|
if *req.Identified {
|
||||||
|
do = do.Where(q.User.IDType.Gt(0))
|
||||||
|
} else {
|
||||||
|
do = do.Where(q.User.IDType.Eq(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.Enabled != nil {
|
||||||
|
if *req.Enabled {
|
||||||
|
do = do.Where(q.User.Status.Eq(1))
|
||||||
|
} else {
|
||||||
|
do = do.Where(q.User.Status.Eq(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.Assigned != nil {
|
||||||
|
if *req.Assigned {
|
||||||
|
do = do.Where(q.User.AdminID.IsNotNull())
|
||||||
|
} else {
|
||||||
|
do = do.Where(q.User.AdminID.IsNull())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 查询用户列表
|
// 查询用户列表
|
||||||
users, total, err := q.User.
|
users, total, err := q.User.
|
||||||
Preload(q.User.Admin).
|
Preload(q.User.Admin, q.User.Discount).
|
||||||
Omit(q.User.Password).
|
Omit(q.User.Password).
|
||||||
|
Where(do).
|
||||||
|
Order(q.User.CreatedAt.Desc()).
|
||||||
FindByPage(req.GetOffset(), req.GetLimit())
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -52,10 +92,167 @@ func PageUserByAdmin(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PageUserByAdminReq struct {
|
||||||
|
core.PageReq
|
||||||
|
Account *string `json:"account,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Identified *bool `json:"identified,omitempty"`
|
||||||
|
Enabled *bool `json:"enabled,omitempty"`
|
||||||
|
Assigned *bool `json:"assigned,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 管理员获取单个用户
|
||||||
|
func GetUserByAdmin(c *fiber.Ctx) error {
|
||||||
|
// 检查权限
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserReadOne)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析请求参数
|
||||||
|
var req GetUserByAdminReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建查询条件
|
||||||
|
do := q.User.Where()
|
||||||
|
if req.Account != nil {
|
||||||
|
do = do.Where(q.User.Where(
|
||||||
|
q.User.Username.Like("%" + *req.Account + "%"),
|
||||||
|
).Or(
|
||||||
|
q.User.Phone.Like("%" + *req.Account + "%"),
|
||||||
|
).Or(
|
||||||
|
q.User.Email.Like("%" + *req.Account + "%"),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
if req.Name != nil {
|
||||||
|
do = do.Where(q.User.Name.Eq(*req.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询用户
|
||||||
|
user, err := q.User.
|
||||||
|
Preload(q.User.Admin, q.User.Discount).
|
||||||
|
Omit(q.User.Password).
|
||||||
|
Where(do).
|
||||||
|
Order(q.User.CreatedAt.Desc()).
|
||||||
|
First()
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return core.NewBizErr("找不到用户")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 仅保留管理员名称
|
||||||
|
if user.Admin != nil {
|
||||||
|
user.Admin = &m.Admin{
|
||||||
|
Name: user.Admin.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回结果
|
||||||
|
return c.JSON(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetUserByAdminReq struct {
|
||||||
|
Account *string `json:"account,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 管理员创建用户
|
||||||
|
func CreateUserByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.CreateUserByAdminData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.User.CreateByAdmin(req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 管理员更新用户
|
||||||
|
func UpdateUserByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req s.UpdateUserByAdminData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.User.UpdateByAdmin(req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 管理员删除用户
|
||||||
|
func RemoveUserByAdmin(c *fiber.Ctx) error {
|
||||||
|
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWrite)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req core.IdReq
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.User.RemoveByAdmin(req.Id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 管理员更新用户余额
|
||||||
|
func UpdateUserBalanceByAdmin(c *fiber.Ctx) error {
|
||||||
|
authCtx, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWriteBalance)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var req UpdateUserBalanceByAdminData
|
||||||
|
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := s.User.Get(q.Q, req.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
balance, err := decimal.NewFromString(req.Balance)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.User.UpdateBalanceByAdmin(user, balance, &authCtx.Admin.ID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateUserBalanceByAdminData struct {
|
||||||
|
UserID int32 `json:"user_id" validate:"required"`
|
||||||
|
Balance string `json:"balance" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
// 绑定管理员
|
// 绑定管理员
|
||||||
func BindAdmin(c *fiber.Ctx) error {
|
func BindAdmin(c *fiber.Ctx) error {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
authCtx, err := auth.GetAuthCtx(c).PermitAdmin()
|
authCtx, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWrite)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ type Admin struct {
|
|||||||
LastLogin *time.Time `json:"last_login,omitempty" gorm:"column:last_login"` // 最后登录时间
|
LastLogin *time.Time `json:"last_login,omitempty" gorm:"column:last_login"` // 最后登录时间
|
||||||
LastLoginIP *orm.Inet `json:"last_login_ip,omitempty" gorm:"column:last_login_ip"` // 最后登录地址
|
LastLoginIP *orm.Inet `json:"last_login_ip,omitempty" gorm:"column:last_login_ip"` // 最后登录地址
|
||||||
LastLoginUA *string `json:"last_login_ua,omitempty" gorm:"column:last_login_ua"` // 最后登录代理
|
LastLoginUA *string `json:"last_login_ua,omitempty" gorm:"column:last_login_ua"` // 最后登录代理
|
||||||
|
|
||||||
|
Roles []*AdminRole `json:"roles" gorm:"many2many:link_admin_role"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdminStatus 管理员状态枚举
|
// AdminStatus 管理员状态枚举
|
||||||
|
|||||||
@@ -11,4 +11,6 @@ type AdminRole struct {
|
|||||||
Description *string `json:"description,omitempty" gorm:"column:description"` // 角色描述
|
Description *string `json:"description,omitempty" gorm:"column:description"` // 角色描述
|
||||||
Active bool `json:"active" gorm:"column:active"` // 是否激活
|
Active bool `json:"active" gorm:"column:active"` // 是否激活
|
||||||
Sort int32 `json:"sort" gorm:"column:sort"` // 排序
|
Sort int32 `json:"sort" gorm:"column:sort"` // 排序
|
||||||
|
|
||||||
|
Permissions []*Permission `json:"permissions" gorm:"many2many:link_admin_role_permission"`
|
||||||
}
|
}
|
||||||
|
|||||||
22
web/models/balance_activity.go
Normal file
22
web/models/balance_activity.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BalanceActivity 余额变动记录表
|
||||||
|
type BalanceActivity struct {
|
||||||
|
ID int32 `json:"id" gorm:"column:id;primaryKey"` // 记录ID
|
||||||
|
UserID int32 `json:"user_id" gorm:"column:user_id"` // 用户ID
|
||||||
|
BillID *int32 `json:"bill_id,omitempty" gorm:"column:bill_id"` // 账单ID
|
||||||
|
AdminID *int32 `json:"admin_id,omitempty" gorm:"column:admin_id"` // 管理员ID
|
||||||
|
Amount string `json:"amount" gorm:"column:amount"` // 变动金额
|
||||||
|
BalancePrev string `json:"balance_prev" gorm:"column:balance_prev"` // 变动前余额
|
||||||
|
BalanceCurr string `json:"balance_curr" gorm:"column:balance_curr"` // 变动后余额
|
||||||
|
Remark *string `json:"remark,omitempty" gorm:"column:remark"` // 备注
|
||||||
|
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` // 创建时间
|
||||||
|
|
||||||
|
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||||
|
Bill *Bill `json:"bill,omitempty" gorm:"foreignKey:BillID"`
|
||||||
|
Admin *User `json:"admin,omitempty" gorm:"foreignKey:AdminID"`
|
||||||
|
}
|
||||||
@@ -13,10 +13,12 @@ type Bill struct {
|
|||||||
TradeID *int32 `json:"trade_id,omitempty" gorm:"column:trade_id"` // 订单ID
|
TradeID *int32 `json:"trade_id,omitempty" gorm:"column:trade_id"` // 订单ID
|
||||||
ResourceID *int32 `json:"resource_id,omitempty" gorm:"column:resource_id"` // 套餐ID
|
ResourceID *int32 `json:"resource_id,omitempty" gorm:"column:resource_id"` // 套餐ID
|
||||||
RefundID *int32 `json:"refund_id,omitempty" gorm:"column:refund_id"` // 退款ID
|
RefundID *int32 `json:"refund_id,omitempty" gorm:"column:refund_id"` // 退款ID
|
||||||
|
CouponID *int32 `json:"coupon_id,omitempty" gorm:"column:coupon_id"` // 优惠券ID
|
||||||
BillNo string `json:"bill_no" gorm:"column:bill_no"` // 易读账单号
|
BillNo string `json:"bill_no" gorm:"column:bill_no"` // 易读账单号
|
||||||
Info *string `json:"info,omitempty" gorm:"column:info"` // 产品可读信息
|
Info *string `json:"info,omitempty" gorm:"column:info"` // 产品可读信息
|
||||||
Type BillType `json:"type" gorm:"column:type"` // 账单类型:1-消费,2-退款,3-充值
|
Type BillType `json:"type" gorm:"column:type"` // 账单类型:1-消费,2-退款,3-充值
|
||||||
Amount decimal.Decimal `json:"amount" gorm:"column:amount"` // 账单金额
|
Amount decimal.Decimal `json:"amount" gorm:"column:amount"` // 应付金额
|
||||||
|
Actual decimal.Decimal `json:"actual" gorm:"column:actual"` // 实付金额
|
||||||
|
|
||||||
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||||
Trade *Trade `json:"trade,omitempty" gorm:"foreignKey:TradeID"`
|
Trade *Trade `json:"trade,omitempty" gorm:"foreignKey:TradeID"`
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ type Client struct {
|
|||||||
Icon *string `json:"icon,omitempty" gorm:"column:icon"` // 图标URL
|
Icon *string `json:"icon,omitempty" gorm:"column:icon"` // 图标URL
|
||||||
Status ClientStatus `json:"status" gorm:"column:status"` // 状态:0-禁用,1-正常
|
Status ClientStatus `json:"status" gorm:"column:status"` // 状态:0-禁用,1-正常
|
||||||
Type ClientType `json:"type" gorm:"column:type"` // 类型:0-普通,1-官方
|
Type ClientType `json:"type" gorm:"column:type"` // 类型:0-普通,1-官方
|
||||||
|
|
||||||
|
Permissions []*Permission `json:"permissions" gorm:"many2many:link_client_permission"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientSpec 客户端安全规范枚举
|
// ClientSpec 客户端安全规范枚举
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package models
|
|||||||
|
|
||||||
// LinkAdminRole 管理员角色关联表
|
// LinkAdminRole 管理员角色关联表
|
||||||
type LinkAdminRole struct {
|
type LinkAdminRole struct {
|
||||||
ID int32 `json:"id" gorm:"column:id"` // 关联ID
|
ID int32 `json:"id" gorm:"column:id"` // 关联ID
|
||||||
AdminID int32 `json:"admin_id" gorm:"column:admin_id"` // 管理员ID
|
AdminID int32 `json:"admin_id" gorm:"column:admin_id"` // 管理员ID
|
||||||
RoleID int32 `json:"role_id" gorm:"column:role_id"` // 角色ID
|
RoleID int32 `json:"role_id" gorm:"column:admin_role_id"` // 角色ID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ package models
|
|||||||
// LinkAdminRolePermission 管理员角色权限关联表
|
// LinkAdminRolePermission 管理员角色权限关联表
|
||||||
type LinkAdminRolePermission struct {
|
type LinkAdminRolePermission struct {
|
||||||
ID int32 `json:"id" gorm:"column:id"` // 关联ID
|
ID int32 `json:"id" gorm:"column:id"` // 关联ID
|
||||||
RoleID int32 `json:"role_id" gorm:"column:role_id"` // 角色ID
|
RoleID int32 `json:"role_id" gorm:"column:admin_role_id"` // 角色ID
|
||||||
PermissionID int32 `json:"permission_id" gorm:"column:permission_id"` // 权限ID
|
PermissionID int32 `json:"permission_id" gorm:"column:permission_id"` // 权限ID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package models
|
|||||||
|
|
||||||
// LinkUserRole 用户角色关联表
|
// LinkUserRole 用户角色关联表
|
||||||
type LinkUserRole struct {
|
type LinkUserRole struct {
|
||||||
ID int32 `json:"id" gorm:"column:id"` // 关联ID
|
ID int32 `json:"id" gorm:"column:id"` // 关联ID
|
||||||
UserID int32 `json:"user_id" gorm:"column:user_id"` // 用户ID
|
UserID int32 `json:"user_id" gorm:"column:user_id"` // 用户ID
|
||||||
RoleID int32 `json:"role_id" gorm:"column:role_id"` // 角色ID
|
RoleID int32 `json:"role_id" gorm:"column:user_role_id"` // 角色ID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ package models
|
|||||||
// LinkUserRolePermission 用户角色权限关联表
|
// LinkUserRolePermission 用户角色权限关联表
|
||||||
type LinkUserRolePermission struct {
|
type LinkUserRolePermission struct {
|
||||||
ID int32 `json:"id" gorm:"column:id"` // 关联ID
|
ID int32 `json:"id" gorm:"column:id"` // 关联ID
|
||||||
RoleID int32 `json:"role_id" gorm:"column:role_id"` // 角色ID
|
RoleID int32 `json:"role_id" gorm:"column:user_role_id"` // 角色ID
|
||||||
PermissionID int32 `json:"permission_id" gorm:"column:permission_id"` // 权限ID
|
PermissionID int32 `json:"permission_id" gorm:"column:permission_id"` // 权限ID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,4 +17,7 @@ type LogsUserUsage struct {
|
|||||||
ISP *string `json:"isp,omitempty" gorm:"column:isp"` // 运营商
|
ISP *string `json:"isp,omitempty" gorm:"column:isp"` // 运营商
|
||||||
IP orm.Inet `json:"ip" gorm:"column:ip"` // IP地址
|
IP orm.Inet `json:"ip" gorm:"column:ip"` // IP地址
|
||||||
Time time.Time `json:"time" gorm:"column:time"` // 提取时间
|
Time time.Time `json:"time" gorm:"column:time"` // 提取时间
|
||||||
|
|
||||||
|
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||||
|
Resource *Resource `json:"resource,omitempty" gorm:"foreignKey:ResourceID"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ type Permission struct {
|
|||||||
ParentID *int32 `json:"parent_id,omitempty" gorm:"column:parent_id"` // 父权限ID
|
ParentID *int32 `json:"parent_id,omitempty" gorm:"column:parent_id"` // 父权限ID
|
||||||
Name string `json:"name" gorm:"column:name"` // 权限名称
|
Name string `json:"name" gorm:"column:name"` // 权限名称
|
||||||
Description *string `json:"description,omitempty" gorm:"column:description"` // 权限描述
|
Description *string `json:"description,omitempty" gorm:"column:description"` // 权限描述
|
||||||
|
Sort int `json:"sort" gorm:"column:sort"` // 排序
|
||||||
|
|
||||||
Parent *Permission `json:"parent,omitempty" gorm:"foreignKey:ParentID"`
|
Parent *Permission `json:"parent,omitempty" gorm:"foreignKey:ParentID"`
|
||||||
Children []*Permission `json:"children,omitempty" gorm:"foreignKey:ParentID"`
|
Children []*Permission `json:"children,omitempty" gorm:"foreignKey:ParentID"`
|
||||||
|
|||||||
19
web/models/product_discount.go
Normal file
19
web/models/product_discount.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/core"
|
||||||
|
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProductDiscount 产品折扣表
|
||||||
|
type ProductDiscount struct {
|
||||||
|
core.Model
|
||||||
|
Name string `json:"name" gorm:"column:name"` // 产品名称
|
||||||
|
Discount int32 `json:"discount" gorm:"column:discount"` // 产品折扣
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pd ProductDiscount) Rate() decimal.Decimal {
|
||||||
|
return decimal.NewFromInt32(pd.Discount).
|
||||||
|
Div(decimal.NewFromInt32(100))
|
||||||
|
}
|
||||||
@@ -9,11 +9,12 @@ import (
|
|||||||
// ProductSku 产品SKU表
|
// ProductSku 产品SKU表
|
||||||
type ProductSku struct {
|
type ProductSku struct {
|
||||||
core.Model
|
core.Model
|
||||||
ProductID int32 `json:"product_id" gorm:"column:product_id"` // 产品ID
|
ProductID int32 `json:"product_id" gorm:"column:product_id"` // 产品ID
|
||||||
Code string `json:"code" gorm:"column:code"` // SSKU 代码:格式为 key=value,key=value,...,其中,key:value 是 SKU 的属性,多个属性用逗号分隔
|
DiscountId int32 `json:"discount_id" gorm:"column:discount_id"` // 折扣,0 - 1 的小数,表示 xx 折
|
||||||
Name string `json:"name" gorm:"column:name"` // SKU 可读名称
|
Code string `json:"code" gorm:"column:code"` // SSKU 代码:格式为 key=value,key=value,...,其中,key:value 是 SKU 的属性,多个属性用逗号分隔
|
||||||
Price decimal.Decimal `json:"price" gorm:"column:price"` // 定价
|
Name string `json:"name" gorm:"column:name"` // SKU 可读名称
|
||||||
Discount float32 `json:"discount" gorm:"column:discount"` // 折扣,0 - 1 的小数,表示 xx 折
|
Price decimal.Decimal `json:"price" gorm:"column:price"` // 定价
|
||||||
|
|
||||||
Product *Product `json:"product,omitempty" gorm:"foreignKey:ProductID"`
|
Product *Product `json:"product,omitempty" gorm:"foreignKey:ProductID"`
|
||||||
|
Discount *ProductDiscount `json:"discount,omitempty" gorm:"foreignKey:DiscountId"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,20 +2,18 @@ package models
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProductSkuUser 用户产品SKU表
|
// ProductSkuUser 用户产品SKU表
|
||||||
type ProductSkuUser struct {
|
type ProductSkuUser struct {
|
||||||
ID int32 `json:"id" gorm:"column:id;primaryKey"`
|
ID int32 `json:"id" gorm:"column:id;primaryKey"`
|
||||||
UserID int32 `json:"user_id" gorm:"column:user_id"` // 用户ID
|
UserID int32 `json:"user_id" gorm:"column:user_id"` // 用户ID
|
||||||
ProductSkuID int32 `json:"product_sku_id" gorm:"column:product_sku_id"` // 产品SKU ID
|
ProductSkuID int32 `json:"product_sku_id" gorm:"column:product_sku_id"` // 产品SKU ID
|
||||||
Price *decimal.Decimal `json:"price,omitempty" gorm:"column:price"` // 定价(覆盖SKU定价)
|
DiscountId int32 `json:"discount_id" gorm:"column:discount_id"` // 折扣ID
|
||||||
Discount *float32 `json:"discount,omitempty" gorm:"column:discount"` // 折扣(覆盖SKU折扣)
|
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
|
||||||
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
|
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
|
|
||||||
|
|
||||||
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||||
ProductSku *ProductSku `json:"product_sku,omitempty" gorm:"foreignKey:ProductSkuID"`
|
ProductSku *ProductSku `json:"product_sku,omitempty" gorm:"foreignKey:ProductSkuID"`
|
||||||
|
Discount *ProductDiscount `json:"discount,omitempty" gorm:"foreignKey:DiscountId"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ type Resource struct {
|
|||||||
ResourceNo *string `json:"resource_no,omitempty" gorm:"column:resource_no"` // 套餐编号
|
ResourceNo *string `json:"resource_no,omitempty" gorm:"column:resource_no"` // 套餐编号
|
||||||
Active bool `json:"active" gorm:"column:active"` // 套餐状态
|
Active bool `json:"active" gorm:"column:active"` // 套餐状态
|
||||||
Type ResourceType `json:"type" gorm:"column:type"` // 套餐类型:1-短效动态,2-长效动态
|
Type ResourceType `json:"type" gorm:"column:type"` // 套餐类型:1-短效动态,2-长效动态
|
||||||
|
Code string `json:"code" gorm:"column:code"` // 产品编码
|
||||||
|
|
||||||
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||||
Short *ResourceShort `json:"short,omitempty" gorm:"foreignKey:ResourceID"`
|
Short *ResourceShort `json:"short,omitempty" gorm:"foreignKey:ResourceID"`
|
||||||
Long *ResourceLong `json:"long,omitempty" gorm:"foreignKey:ResourceID"`
|
Long *ResourceLong `json:"long,omitempty" gorm:"foreignKey:ResourceID"`
|
||||||
|
Product *Product `json:"product,omitempty" gorm:"foreignKey:Code;references:Code"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceType 套餐类型枚举
|
// ResourceType 套餐类型枚举
|
||||||
@@ -25,7 +27,18 @@ const (
|
|||||||
ResourceTypeLong ResourceType = 2 // 长效动态
|
ResourceTypeLong ResourceType = 2 // 长效动态
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResourceLongType 套餐计费模式枚举
|
func (t ResourceType) Code() string {
|
||||||
|
switch t {
|
||||||
|
case ResourceTypeShort:
|
||||||
|
return "short"
|
||||||
|
case ResourceTypeLong:
|
||||||
|
return "long"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceMode 套餐计费模式枚举
|
||||||
type ResourceMode int
|
type ResourceMode int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
type ResourceLong struct {
|
type ResourceLong struct {
|
||||||
ID int32 `json:"id" gorm:"column:id"` // ID
|
ID int32 `json:"id" gorm:"column:id"` // ID
|
||||||
ResourceID int32 `json:"resource_id" gorm:"column:resource_id"` // 套餐ID
|
ResourceID int32 `json:"resource_id" gorm:"column:resource_id"` // 套餐ID
|
||||||
|
Code string `json:"code" gorm:"column:code"` // 套餐编码
|
||||||
Live int32 `json:"live" gorm:"column:live"` // 可用时长(小时)
|
Live int32 `json:"live" gorm:"column:live"` // 可用时长(小时)
|
||||||
Type ResourceMode `json:"type" gorm:"column:type"` // 套餐类型:1-包时,2-包量
|
Type ResourceMode `json:"type" gorm:"column:type"` // 套餐类型:1-包时,2-包量
|
||||||
Quota int32 `json:"quota" gorm:"column:quota"` // 每日配额(包时)或总配额(包量)
|
Quota int32 `json:"quota" gorm:"column:quota"` // 每日配额(包时)或总配额(包量)
|
||||||
@@ -15,4 +16,6 @@ type ResourceLong struct {
|
|||||||
Used int32 `json:"used" gorm:"column:used"` // 总用量
|
Used int32 `json:"used" gorm:"column:used"` // 总用量
|
||||||
Daily int32 `json:"daily" gorm:"column:daily"` // 当日用量
|
Daily int32 `json:"daily" gorm:"column:daily"` // 当日用量
|
||||||
LastAt *time.Time `json:"last_at,omitempty" gorm:"column:last_at"` // 最后使用时间
|
LastAt *time.Time `json:"last_at,omitempty" gorm:"column:last_at"` // 最后使用时间
|
||||||
|
|
||||||
|
Sku *ProductSku `json:"sku,omitempty" gorm:"foreignKey:Code;references:Code"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
type ResourceShort struct {
|
type ResourceShort struct {
|
||||||
ID int32 `json:"id" gorm:"column:id"` // ID
|
ID int32 `json:"id" gorm:"column:id"` // ID
|
||||||
ResourceID int32 `json:"resource_id" gorm:"column:resource_id"` // 套餐ID
|
ResourceID int32 `json:"resource_id" gorm:"column:resource_id"` // 套餐ID
|
||||||
|
Code string `json:"code" gorm:"column:code"` // 套餐编码
|
||||||
Live int32 `json:"live" gorm:"column:live"` // 可用时长(秒)
|
Live int32 `json:"live" gorm:"column:live"` // 可用时长(秒)
|
||||||
Type ResourceMode `json:"type" gorm:"column:type"` // 套餐类型:1-包时,2-包量
|
Type ResourceMode `json:"type" gorm:"column:type"` // 套餐类型:1-包时,2-包量
|
||||||
Quota int32 `json:"quota" gorm:"column:quota"` // 每日配额(包时)或总配额(包量)
|
Quota int32 `json:"quota" gorm:"column:quota"` // 每日配额(包时)或总配额(包量)
|
||||||
@@ -15,4 +16,6 @@ type ResourceShort struct {
|
|||||||
Used int32 `json:"used" gorm:"column:used"` // 总用量
|
Used int32 `json:"used" gorm:"column:used"` // 总用量
|
||||||
Daily int32 `json:"daily" gorm:"column:daily"` // 当日用量
|
Daily int32 `json:"daily" gorm:"column:daily"` // 当日用量
|
||||||
LastAt *time.Time `json:"last_at,omitempty" gorm:"column:last_at"` // 最后使用时间
|
LastAt *time.Time `json:"last_at,omitempty" gorm:"column:last_at"` // 最后使用时间
|
||||||
|
|
||||||
|
Sku *ProductSku `json:"sku,omitempty" gorm:"foreignKey:Code;references:Code"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ type Trade struct {
|
|||||||
PaymentURL *string `json:"payment_url,omitempty" gorm:"column:payment_url"` // 支付链接
|
PaymentURL *string `json:"payment_url,omitempty" gorm:"column:payment_url"` // 支付链接
|
||||||
CompletedAt *time.Time `json:"completed_at,omitempty" gorm:"column:completed_at"` // 支付时间
|
CompletedAt *time.Time `json:"completed_at,omitempty" gorm:"column:completed_at"` // 支付时间
|
||||||
CanceledAt *time.Time `json:"canceled_at,omitempty" gorm:"column:canceled_at"` // 取消时间
|
CanceledAt *time.Time `json:"canceled_at,omitempty" gorm:"column:canceled_at"` // 取消时间
|
||||||
|
|
||||||
|
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TradeType 订单类型枚举
|
// TradeType 订单类型枚举
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ import (
|
|||||||
type User struct {
|
type User struct {
|
||||||
core.Model
|
core.Model
|
||||||
AdminID *int32 `json:"admin_id,omitempty" gorm:"column:admin_id"` // 管理员ID
|
AdminID *int32 `json:"admin_id,omitempty" gorm:"column:admin_id"` // 管理员ID
|
||||||
|
DiscountID *int32 `json:"discount_id,omitempty" gorm:"column:discount_id"` // 折扣ID
|
||||||
Phone string `json:"phone" gorm:"column:phone"` // 手机号码
|
Phone string `json:"phone" gorm:"column:phone"` // 手机号码
|
||||||
Username *string `json:"username,omitempty" gorm:"column:username"` // 用户名
|
Username *string `json:"username,omitempty" gorm:"column:username"` // 用户名
|
||||||
Email *string `json:"email,omitempty" gorm:"column:email"` // 邮箱
|
Email *string `json:"email,omitempty" gorm:"column:email"` // 邮箱
|
||||||
Password *string `json:"password,omitempty" gorm:"column:password"` // 用户密码
|
Password *string `json:"password,omitempty" gorm:"column:password"` // 用户密码
|
||||||
|
Source *UserSource `json:"source,omitempty" gorm:"column:source"` // 用户来源:0-官网注册,1-管理员添加,2-代理商注册,3-代理商添加
|
||||||
Name *string `json:"name,omitempty" gorm:"column:name"` // 真实姓名
|
Name *string `json:"name,omitempty" gorm:"column:name"` // 真实姓名
|
||||||
Avatar *string `json:"avatar,omitempty" gorm:"column:avatar"` // 头像URL
|
Avatar *string `json:"avatar,omitempty" gorm:"column:avatar"` // 头像URL
|
||||||
Status UserStatus `json:"status" gorm:"column:status"` // 用户状态:0-禁用,1-正常
|
Status UserStatus `json:"status" gorm:"column:status"` // 用户状态:0-禁用,1-正常
|
||||||
@@ -29,7 +31,9 @@ type User struct {
|
|||||||
LastLoginIP *orm.Inet `json:"last_login_ip,omitempty" gorm:"column:last_login_ip"` // 最后登录地址
|
LastLoginIP *orm.Inet `json:"last_login_ip,omitempty" gorm:"column:last_login_ip"` // 最后登录地址
|
||||||
LastLoginUA *string `json:"last_login_ua,omitempty" gorm:"column:last_login_ua"` // 最后登录代理
|
LastLoginUA *string `json:"last_login_ua,omitempty" gorm:"column:last_login_ua"` // 最后登录代理
|
||||||
|
|
||||||
Admin *Admin `json:"admin,omitempty" gorm:"foreignKey:AdminID"`
|
Admin *Admin `json:"admin,omitempty" gorm:"foreignKey:AdminID"`
|
||||||
|
Roles []*UserRole `json:"roles" gorm:"many2many:link_user_role"`
|
||||||
|
Discount *ProductDiscount `json:"discount,omitempty" gorm:"foreignKey:DiscountID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserStatus 用户状态枚举
|
// UserStatus 用户状态枚举
|
||||||
@@ -48,3 +52,13 @@ const (
|
|||||||
UserIDTypePersonal UserIDType = 1 // 个人认证
|
UserIDTypePersonal UserIDType = 1 // 个人认证
|
||||||
UserIDTypeEnterprise UserIDType = 2 // 企业认证
|
UserIDTypeEnterprise UserIDType = 2 // 企业认证
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// UserSource 用户来源枚举
|
||||||
|
type UserSource int
|
||||||
|
|
||||||
|
const (
|
||||||
|
UserSourceReg UserSource = 0 // 官网注册
|
||||||
|
UserSourceAdd UserSource = 1 // 管理员添加
|
||||||
|
UserSourceAgentReg UserSource = 2 // 代理商注册
|
||||||
|
UserSourceAgentAdd UserSource = 3 // 代理商添加
|
||||||
|
)
|
||||||
|
|||||||
@@ -11,4 +11,6 @@ type UserRole struct {
|
|||||||
Description *string `json:"description,omitempty" gorm:"column:description"` // 角色描述
|
Description *string `json:"description,omitempty" gorm:"column:description"` // 角色描述
|
||||||
Active bool `json:"active" gorm:"column:active"` // 是否激活
|
Active bool `json:"active" gorm:"column:active"` // 是否激活
|
||||||
Sort int32 `json:"sort" gorm:"column:sort"` // 排序
|
Sort int32 `json:"sort" gorm:"column:sort"` // 排序
|
||||||
|
|
||||||
|
Permissions []*Permission `json:"permissions" gorm:"many2many:link_user_role_permission"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,32 @@ func newAdmin(db *gorm.DB, opts ...gen.DOOption) admin {
|
|||||||
_admin.LastLogin = field.NewTime(tableName, "last_login")
|
_admin.LastLogin = field.NewTime(tableName, "last_login")
|
||||||
_admin.LastLoginIP = field.NewField(tableName, "last_login_ip")
|
_admin.LastLoginIP = field.NewField(tableName, "last_login_ip")
|
||||||
_admin.LastLoginUA = field.NewString(tableName, "last_login_ua")
|
_admin.LastLoginUA = field.NewString(tableName, "last_login_ua")
|
||||||
|
_admin.Roles = adminManyToManyRoles{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
_admin.fillFieldMap()
|
_admin.fillFieldMap()
|
||||||
|
|
||||||
@@ -65,6 +91,7 @@ type admin struct {
|
|||||||
LastLogin field.Time
|
LastLogin field.Time
|
||||||
LastLoginIP field.Field
|
LastLoginIP field.Field
|
||||||
LastLoginUA field.String
|
LastLoginUA field.String
|
||||||
|
Roles adminManyToManyRoles
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -111,7 +138,7 @@ func (a *admin) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *admin) fillFieldMap() {
|
func (a *admin) fillFieldMap() {
|
||||||
a.fieldMap = make(map[string]field.Expr, 14)
|
a.fieldMap = make(map[string]field.Expr, 15)
|
||||||
a.fieldMap["id"] = a.ID
|
a.fieldMap["id"] = a.ID
|
||||||
a.fieldMap["created_at"] = a.CreatedAt
|
a.fieldMap["created_at"] = a.CreatedAt
|
||||||
a.fieldMap["updated_at"] = a.UpdatedAt
|
a.fieldMap["updated_at"] = a.UpdatedAt
|
||||||
@@ -126,18 +153,113 @@ func (a *admin) fillFieldMap() {
|
|||||||
a.fieldMap["last_login"] = a.LastLogin
|
a.fieldMap["last_login"] = a.LastLogin
|
||||||
a.fieldMap["last_login_ip"] = a.LastLoginIP
|
a.fieldMap["last_login_ip"] = a.LastLoginIP
|
||||||
a.fieldMap["last_login_ua"] = a.LastLoginUA
|
a.fieldMap["last_login_ua"] = a.LastLoginUA
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a admin) clone(db *gorm.DB) admin {
|
func (a admin) clone(db *gorm.DB) admin {
|
||||||
a.adminDo.ReplaceConnPool(db.Statement.ConnPool)
|
a.adminDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
a.Roles.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
a.Roles.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a admin) replaceDB(db *gorm.DB) admin {
|
func (a admin) replaceDB(db *gorm.DB) admin {
|
||||||
a.adminDo.ReplaceDB(db)
|
a.adminDo.ReplaceDB(db)
|
||||||
|
a.Roles.db = db.Session(&gorm.Session{})
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type adminManyToManyRoles struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRoles) Where(conds ...field.Expr) *adminManyToManyRoles {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRoles) WithContext(ctx context.Context) *adminManyToManyRoles {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRoles) Session(session *gorm.Session) *adminManyToManyRoles {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRoles) Model(m *models.Admin) *adminManyToManyRolesTx {
|
||||||
|
return &adminManyToManyRolesTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRoles) Unscoped() *adminManyToManyRoles {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type adminManyToManyRolesTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a adminManyToManyRolesTx) Find() (result []*models.AdminRole, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRolesTx) Append(values ...*models.AdminRole) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRolesTx) Replace(values ...*models.AdminRole) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRolesTx) Delete(values ...*models.AdminRole) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRolesTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRolesTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminManyToManyRolesTx) Unscoped() *adminManyToManyRolesTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type adminDo struct{ gen.DO }
|
type adminDo struct{ gen.DO }
|
||||||
|
|
||||||
func (a adminDo) Debug() *adminDo {
|
func (a adminDo) Debug() *adminDo {
|
||||||
|
|||||||
@@ -35,6 +35,21 @@ func newAdminRole(db *gorm.DB, opts ...gen.DOOption) adminRole {
|
|||||||
_adminRole.Description = field.NewString(tableName, "description")
|
_adminRole.Description = field.NewString(tableName, "description")
|
||||||
_adminRole.Active = field.NewBool(tableName, "active")
|
_adminRole.Active = field.NewBool(tableName, "active")
|
||||||
_adminRole.Sort = field.NewInt32(tableName, "sort")
|
_adminRole.Sort = field.NewInt32(tableName, "sort")
|
||||||
|
_adminRole.Permissions = adminRoleManyToManyPermissions{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
_adminRole.fillFieldMap()
|
_adminRole.fillFieldMap()
|
||||||
|
|
||||||
@@ -53,6 +68,7 @@ type adminRole struct {
|
|||||||
Description field.String
|
Description field.String
|
||||||
Active field.Bool
|
Active field.Bool
|
||||||
Sort field.Int32
|
Sort field.Int32
|
||||||
|
Permissions adminRoleManyToManyPermissions
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -93,7 +109,7 @@ func (a *adminRole) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *adminRole) fillFieldMap() {
|
func (a *adminRole) fillFieldMap() {
|
||||||
a.fieldMap = make(map[string]field.Expr, 8)
|
a.fieldMap = make(map[string]field.Expr, 9)
|
||||||
a.fieldMap["id"] = a.ID
|
a.fieldMap["id"] = a.ID
|
||||||
a.fieldMap["created_at"] = a.CreatedAt
|
a.fieldMap["created_at"] = a.CreatedAt
|
||||||
a.fieldMap["updated_at"] = a.UpdatedAt
|
a.fieldMap["updated_at"] = a.UpdatedAt
|
||||||
@@ -102,18 +118,110 @@ func (a *adminRole) fillFieldMap() {
|
|||||||
a.fieldMap["description"] = a.Description
|
a.fieldMap["description"] = a.Description
|
||||||
a.fieldMap["active"] = a.Active
|
a.fieldMap["active"] = a.Active
|
||||||
a.fieldMap["sort"] = a.Sort
|
a.fieldMap["sort"] = a.Sort
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a adminRole) clone(db *gorm.DB) adminRole {
|
func (a adminRole) clone(db *gorm.DB) adminRole {
|
||||||
a.adminRoleDo.ReplaceConnPool(db.Statement.ConnPool)
|
a.adminRoleDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
a.Permissions.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
a.Permissions.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a adminRole) replaceDB(db *gorm.DB) adminRole {
|
func (a adminRole) replaceDB(db *gorm.DB) adminRole {
|
||||||
a.adminRoleDo.ReplaceDB(db)
|
a.adminRoleDo.ReplaceDB(db)
|
||||||
|
a.Permissions.db = db.Session(&gorm.Session{})
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type adminRoleManyToManyPermissions struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissions) Where(conds ...field.Expr) *adminRoleManyToManyPermissions {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissions) WithContext(ctx context.Context) *adminRoleManyToManyPermissions {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissions) Session(session *gorm.Session) *adminRoleManyToManyPermissions {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissions) Model(m *models.AdminRole) *adminRoleManyToManyPermissionsTx {
|
||||||
|
return &adminRoleManyToManyPermissionsTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissions) Unscoped() *adminRoleManyToManyPermissions {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type adminRoleManyToManyPermissionsTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissionsTx) Find() (result []*models.Permission, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissionsTx) Append(values ...*models.Permission) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissionsTx) Replace(values ...*models.Permission) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissionsTx) Delete(values ...*models.Permission) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissionsTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissionsTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a adminRoleManyToManyPermissionsTx) Unscoped() *adminRoleManyToManyPermissionsTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type adminRoleDo struct{ gen.DO }
|
type adminRoleDo struct{ gen.DO }
|
||||||
|
|
||||||
func (a adminRoleDo) Debug() *adminRoleDo {
|
func (a adminRoleDo) Debug() *adminRoleDo {
|
||||||
|
|||||||
871
web/queries/balance_activity.gen.go
Normal file
871
web/queries/balance_activity.gen.go
Normal file
@@ -0,0 +1,871 @@
|
|||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package queries
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
|
|
||||||
|
"gorm.io/gen"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
|
||||||
|
"gorm.io/plugin/dbresolver"
|
||||||
|
|
||||||
|
"platform/web/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||||
|
_balanceActivity := balanceActivity{}
|
||||||
|
|
||||||
|
_balanceActivity.balanceActivityDo.UseDB(db, opts...)
|
||||||
|
_balanceActivity.balanceActivityDo.UseModel(&models.BalanceActivity{})
|
||||||
|
|
||||||
|
tableName := _balanceActivity.balanceActivityDo.TableName()
|
||||||
|
_balanceActivity.ALL = field.NewAsterisk(tableName)
|
||||||
|
_balanceActivity.ID = field.NewInt32(tableName, "id")
|
||||||
|
_balanceActivity.UserID = field.NewInt32(tableName, "user_id")
|
||||||
|
_balanceActivity.BillID = field.NewInt32(tableName, "bill_id")
|
||||||
|
_balanceActivity.AdminID = field.NewInt32(tableName, "admin_id")
|
||||||
|
_balanceActivity.Amount = field.NewString(tableName, "amount")
|
||||||
|
_balanceActivity.BalancePrev = field.NewString(tableName, "balance_prev")
|
||||||
|
_balanceActivity.BalanceCurr = field.NewString(tableName, "balance_curr")
|
||||||
|
_balanceActivity.Remark = field.NewString(tableName, "remark")
|
||||||
|
_balanceActivity.CreatedAt = field.NewTime(tableName, "created_at")
|
||||||
|
_balanceActivity.Admin = balanceActivityHasOneAdmin{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Admin", "models.User"),
|
||||||
|
Admin: struct {
|
||||||
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_balanceActivity.User = balanceActivityBelongsToUser{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("User", "models.User"),
|
||||||
|
}
|
||||||
|
|
||||||
|
_balanceActivity.Bill = balanceActivityBelongsToBill{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Bill", "models.Bill"),
|
||||||
|
User: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.User", "models.User"),
|
||||||
|
},
|
||||||
|
Trade: struct {
|
||||||
|
field.RelationField
|
||||||
|
User struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Trade", "models.Trade"),
|
||||||
|
User: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Trade.User", "models.User"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Resource: struct {
|
||||||
|
field.RelationField
|
||||||
|
User struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Short struct {
|
||||||
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Long struct {
|
||||||
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Resource", "models.Resource"),
|
||||||
|
User: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Resource.User", "models.User"),
|
||||||
|
},
|
||||||
|
Short: struct {
|
||||||
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Resource.Short", "models.ResourceShort"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Resource.Short.Sku", "models.ProductSku"),
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Resource.Short.Sku.Product", "models.Product"),
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Resource.Short.Sku.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Long: struct {
|
||||||
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Resource.Long", "models.ResourceLong"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Resource.Long.Sku", "models.ProductSku"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Resource.Product", "models.Product"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Refund: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Bill.Refund", "models.Refund"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_balanceActivity.fillFieldMap()
|
||||||
|
|
||||||
|
return _balanceActivity
|
||||||
|
}
|
||||||
|
|
||||||
|
type balanceActivity struct {
|
||||||
|
balanceActivityDo
|
||||||
|
|
||||||
|
ALL field.Asterisk
|
||||||
|
ID field.Int32
|
||||||
|
UserID field.Int32
|
||||||
|
BillID field.Int32
|
||||||
|
AdminID field.Int32
|
||||||
|
Amount field.String
|
||||||
|
BalancePrev field.String
|
||||||
|
BalanceCurr field.String
|
||||||
|
Remark field.String
|
||||||
|
CreatedAt field.Time
|
||||||
|
Admin balanceActivityHasOneAdmin
|
||||||
|
|
||||||
|
User balanceActivityBelongsToUser
|
||||||
|
|
||||||
|
Bill balanceActivityBelongsToBill
|
||||||
|
|
||||||
|
fieldMap map[string]field.Expr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivity) Table(newTableName string) *balanceActivity {
|
||||||
|
b.balanceActivityDo.UseTable(newTableName)
|
||||||
|
return b.updateTableName(newTableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivity) As(alias string) *balanceActivity {
|
||||||
|
b.balanceActivityDo.DO = *(b.balanceActivityDo.As(alias).(*gen.DO))
|
||||||
|
return b.updateTableName(alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *balanceActivity) updateTableName(table string) *balanceActivity {
|
||||||
|
b.ALL = field.NewAsterisk(table)
|
||||||
|
b.ID = field.NewInt32(table, "id")
|
||||||
|
b.UserID = field.NewInt32(table, "user_id")
|
||||||
|
b.BillID = field.NewInt32(table, "bill_id")
|
||||||
|
b.AdminID = field.NewInt32(table, "admin_id")
|
||||||
|
b.Amount = field.NewString(table, "amount")
|
||||||
|
b.BalancePrev = field.NewString(table, "balance_prev")
|
||||||
|
b.BalanceCurr = field.NewString(table, "balance_curr")
|
||||||
|
b.Remark = field.NewString(table, "remark")
|
||||||
|
b.CreatedAt = field.NewTime(table, "created_at")
|
||||||
|
|
||||||
|
b.fillFieldMap()
|
||||||
|
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *balanceActivity) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||||
|
_f, ok := b.fieldMap[fieldName]
|
||||||
|
if !ok || _f == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
_oe, ok := _f.(field.OrderExpr)
|
||||||
|
return _oe, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *balanceActivity) fillFieldMap() {
|
||||||
|
b.fieldMap = make(map[string]field.Expr, 12)
|
||||||
|
b.fieldMap["id"] = b.ID
|
||||||
|
b.fieldMap["user_id"] = b.UserID
|
||||||
|
b.fieldMap["bill_id"] = b.BillID
|
||||||
|
b.fieldMap["admin_id"] = b.AdminID
|
||||||
|
b.fieldMap["amount"] = b.Amount
|
||||||
|
b.fieldMap["balance_prev"] = b.BalancePrev
|
||||||
|
b.fieldMap["balance_curr"] = b.BalanceCurr
|
||||||
|
b.fieldMap["remark"] = b.Remark
|
||||||
|
b.fieldMap["created_at"] = b.CreatedAt
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivity) clone(db *gorm.DB) balanceActivity {
|
||||||
|
b.balanceActivityDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
b.Admin.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
b.Admin.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
|
b.User.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
b.User.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
|
b.Bill.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
b.Bill.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivity) replaceDB(db *gorm.DB) balanceActivity {
|
||||||
|
b.balanceActivityDo.ReplaceDB(db)
|
||||||
|
b.Admin.db = db.Session(&gorm.Session{})
|
||||||
|
b.User.db = db.Session(&gorm.Session{})
|
||||||
|
b.Bill.db = db.Session(&gorm.Session{})
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
type balanceActivityHasOneAdmin struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
Admin struct {
|
||||||
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdmin) Where(conds ...field.Expr) *balanceActivityHasOneAdmin {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdmin) WithContext(ctx context.Context) *balanceActivityHasOneAdmin {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdmin) Session(session *gorm.Session) *balanceActivityHasOneAdmin {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdmin) Model(m *models.BalanceActivity) *balanceActivityHasOneAdminTx {
|
||||||
|
return &balanceActivityHasOneAdminTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdmin) Unscoped() *balanceActivityHasOneAdmin {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type balanceActivityHasOneAdminTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdminTx) Find() (result *models.User, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdminTx) Append(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdminTx) Replace(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdminTx) Delete(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdminTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdminTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityHasOneAdminTx) Unscoped() *balanceActivityHasOneAdminTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type balanceActivityBelongsToUser struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUser) Where(conds ...field.Expr) *balanceActivityBelongsToUser {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUser) WithContext(ctx context.Context) *balanceActivityBelongsToUser {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUser) Session(session *gorm.Session) *balanceActivityBelongsToUser {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUser) Model(m *models.BalanceActivity) *balanceActivityBelongsToUserTx {
|
||||||
|
return &balanceActivityBelongsToUserTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUser) Unscoped() *balanceActivityBelongsToUser {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type balanceActivityBelongsToUserTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUserTx) Find() (result *models.User, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUserTx) Append(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUserTx) Replace(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUserTx) Delete(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUserTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUserTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToUserTx) Unscoped() *balanceActivityBelongsToUserTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type balanceActivityBelongsToBill struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
User struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Trade struct {
|
||||||
|
field.RelationField
|
||||||
|
User struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Resource struct {
|
||||||
|
field.RelationField
|
||||||
|
User struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Short struct {
|
||||||
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Long struct {
|
||||||
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Refund struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBill) Where(conds ...field.Expr) *balanceActivityBelongsToBill {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBill) WithContext(ctx context.Context) *balanceActivityBelongsToBill {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBill) Session(session *gorm.Session) *balanceActivityBelongsToBill {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBill) Model(m *models.BalanceActivity) *balanceActivityBelongsToBillTx {
|
||||||
|
return &balanceActivityBelongsToBillTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBill) Unscoped() *balanceActivityBelongsToBill {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type balanceActivityBelongsToBillTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBillTx) Find() (result *models.Bill, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBillTx) Append(values ...*models.Bill) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBillTx) Replace(values ...*models.Bill) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBillTx) Delete(values ...*models.Bill) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBillTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBillTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a balanceActivityBelongsToBillTx) Unscoped() *balanceActivityBelongsToBillTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type balanceActivityDo struct{ gen.DO }
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Debug() *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Debug())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) WithContext(ctx context.Context) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.WithContext(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) ReadDB() *balanceActivityDo {
|
||||||
|
return b.Clauses(dbresolver.Read)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) WriteDB() *balanceActivityDo {
|
||||||
|
return b.Clauses(dbresolver.Write)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Session(config *gorm.Session) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Session(config))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Clauses(conds ...clause.Expression) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Clauses(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Returning(value interface{}, columns ...string) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Returning(value, columns...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Not(conds ...gen.Condition) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Not(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Or(conds ...gen.Condition) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Or(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Select(conds ...field.Expr) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Select(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Where(conds ...gen.Condition) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Where(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Order(conds ...field.Expr) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Order(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Distinct(cols ...field.Expr) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Distinct(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Omit(cols ...field.Expr) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Omit(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Join(table schema.Tabler, on ...field.Expr) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Join(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) LeftJoin(table schema.Tabler, on ...field.Expr) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.LeftJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) RightJoin(table schema.Tabler, on ...field.Expr) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.RightJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Group(cols ...field.Expr) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Group(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Having(conds ...gen.Condition) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Having(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Limit(limit int) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Limit(limit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Offset(offset int) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Offset(offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Scopes(funcs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Unscoped() *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Unscoped())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Create(values ...*models.BalanceActivity) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return b.DO.Create(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) CreateInBatches(values []*models.BalanceActivity, batchSize int) error {
|
||||||
|
return b.DO.CreateInBatches(values, batchSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save : !!! underlying implementation is different with GORM
|
||||||
|
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||||
|
func (b balanceActivityDo) Save(values ...*models.BalanceActivity) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return b.DO.Save(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) First() (*models.BalanceActivity, error) {
|
||||||
|
if result, err := b.DO.First(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.BalanceActivity), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Take() (*models.BalanceActivity, error) {
|
||||||
|
if result, err := b.DO.Take(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.BalanceActivity), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Last() (*models.BalanceActivity, error) {
|
||||||
|
if result, err := b.DO.Last(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.BalanceActivity), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Find() ([]*models.BalanceActivity, error) {
|
||||||
|
result, err := b.DO.Find()
|
||||||
|
return result.([]*models.BalanceActivity), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.BalanceActivity, err error) {
|
||||||
|
buf := make([]*models.BalanceActivity, 0, batchSize)
|
||||||
|
err = b.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||||
|
defer func() { results = append(results, buf...) }()
|
||||||
|
return fc(tx, batch)
|
||||||
|
})
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) FindInBatches(result *[]*models.BalanceActivity, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||||
|
return b.DO.FindInBatches(result, batchSize, fc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Attrs(attrs ...field.AssignExpr) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Attrs(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Assign(attrs ...field.AssignExpr) *balanceActivityDo {
|
||||||
|
return b.withDO(b.DO.Assign(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Joins(fields ...field.RelationField) *balanceActivityDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
b = *b.withDO(b.DO.Joins(_f))
|
||||||
|
}
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Preload(fields ...field.RelationField) *balanceActivityDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
b = *b.withDO(b.DO.Preload(_f))
|
||||||
|
}
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) FirstOrInit() (*models.BalanceActivity, error) {
|
||||||
|
if result, err := b.DO.FirstOrInit(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.BalanceActivity), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) FirstOrCreate() (*models.BalanceActivity, error) {
|
||||||
|
if result, err := b.DO.FirstOrCreate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.BalanceActivity), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) FindByPage(offset int, limit int) (result []*models.BalanceActivity, count int64, err error) {
|
||||||
|
result, err = b.Offset(offset).Limit(limit).Find()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||||
|
count = int64(size + offset)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err = b.Offset(-1).Limit(-1).Count()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||||
|
count, err = b.Count()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = b.Offset(offset).Limit(limit).Scan(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Scan(result interface{}) (err error) {
|
||||||
|
return b.DO.Scan(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b balanceActivityDo) Delete(models ...*models.BalanceActivity) (result gen.ResultInfo, err error) {
|
||||||
|
return b.DO.Delete(models)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *balanceActivityDo) withDO(do gen.Dao) *balanceActivityDo {
|
||||||
|
b.DO = *do.(*gen.DO)
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -35,18 +35,85 @@ func newBill(db *gorm.DB, opts ...gen.DOOption) bill {
|
|||||||
_bill.TradeID = field.NewInt32(tableName, "trade_id")
|
_bill.TradeID = field.NewInt32(tableName, "trade_id")
|
||||||
_bill.ResourceID = field.NewInt32(tableName, "resource_id")
|
_bill.ResourceID = field.NewInt32(tableName, "resource_id")
|
||||||
_bill.RefundID = field.NewInt32(tableName, "refund_id")
|
_bill.RefundID = field.NewInt32(tableName, "refund_id")
|
||||||
|
_bill.CouponID = field.NewInt32(tableName, "coupon_id")
|
||||||
_bill.BillNo = field.NewString(tableName, "bill_no")
|
_bill.BillNo = field.NewString(tableName, "bill_no")
|
||||||
_bill.Info = field.NewString(tableName, "info")
|
_bill.Info = field.NewString(tableName, "info")
|
||||||
_bill.Type = field.NewInt(tableName, "type")
|
_bill.Type = field.NewInt(tableName, "type")
|
||||||
_bill.Amount = field.NewField(tableName, "amount")
|
_bill.Amount = field.NewField(tableName, "amount")
|
||||||
|
_bill.Actual = field.NewField(tableName, "actual")
|
||||||
_bill.User = billBelongsToUser{
|
_bill.User = billBelongsToUser{
|
||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
RelationField: field.NewRelation("User", "models.User"),
|
RelationField: field.NewRelation("User", "models.User"),
|
||||||
Admin: struct {
|
Admin: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +121,11 @@ func newBill(db *gorm.DB, opts ...gen.DOOption) bill {
|
|||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
RelationField: field.NewRelation("Trade", "models.Trade"),
|
RelationField: field.NewRelation("Trade", "models.Trade"),
|
||||||
|
User: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Trade.User", "models.User"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_bill.Resource = billBelongsToResource{
|
_bill.Resource = billBelongsToResource{
|
||||||
@@ -67,13 +139,56 @@ func newBill(db *gorm.DB, opts ...gen.DOOption) bill {
|
|||||||
},
|
},
|
||||||
Short: struct {
|
Short: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("Resource.Short", "models.ResourceShort"),
|
RelationField: field.NewRelation("Resource.Short", "models.ResourceShort"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Short.Sku", "models.ProductSku"),
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Short.Sku.Product", "models.Product"),
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Short.Sku.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Long: struct {
|
Long: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("Resource.Long", "models.ResourceLong"),
|
RelationField: field.NewRelation("Resource.Long", "models.ResourceLong"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Long.Sku", "models.ProductSku"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Product", "models.Product"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,10 +215,12 @@ type bill struct {
|
|||||||
TradeID field.Int32
|
TradeID field.Int32
|
||||||
ResourceID field.Int32
|
ResourceID field.Int32
|
||||||
RefundID field.Int32
|
RefundID field.Int32
|
||||||
|
CouponID field.Int32
|
||||||
BillNo field.String
|
BillNo field.String
|
||||||
Info field.String
|
Info field.String
|
||||||
Type field.Int
|
Type field.Int
|
||||||
Amount field.Field
|
Amount field.Field
|
||||||
|
Actual field.Field
|
||||||
User billBelongsToUser
|
User billBelongsToUser
|
||||||
|
|
||||||
Trade billBelongsToTrade
|
Trade billBelongsToTrade
|
||||||
@@ -135,10 +252,12 @@ func (b *bill) updateTableName(table string) *bill {
|
|||||||
b.TradeID = field.NewInt32(table, "trade_id")
|
b.TradeID = field.NewInt32(table, "trade_id")
|
||||||
b.ResourceID = field.NewInt32(table, "resource_id")
|
b.ResourceID = field.NewInt32(table, "resource_id")
|
||||||
b.RefundID = field.NewInt32(table, "refund_id")
|
b.RefundID = field.NewInt32(table, "refund_id")
|
||||||
|
b.CouponID = field.NewInt32(table, "coupon_id")
|
||||||
b.BillNo = field.NewString(table, "bill_no")
|
b.BillNo = field.NewString(table, "bill_no")
|
||||||
b.Info = field.NewString(table, "info")
|
b.Info = field.NewString(table, "info")
|
||||||
b.Type = field.NewInt(table, "type")
|
b.Type = field.NewInt(table, "type")
|
||||||
b.Amount = field.NewField(table, "amount")
|
b.Amount = field.NewField(table, "amount")
|
||||||
|
b.Actual = field.NewField(table, "actual")
|
||||||
|
|
||||||
b.fillFieldMap()
|
b.fillFieldMap()
|
||||||
|
|
||||||
@@ -155,7 +274,7 @@ func (b *bill) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *bill) fillFieldMap() {
|
func (b *bill) fillFieldMap() {
|
||||||
b.fieldMap = make(map[string]field.Expr, 16)
|
b.fieldMap = make(map[string]field.Expr, 18)
|
||||||
b.fieldMap["id"] = b.ID
|
b.fieldMap["id"] = b.ID
|
||||||
b.fieldMap["created_at"] = b.CreatedAt
|
b.fieldMap["created_at"] = b.CreatedAt
|
||||||
b.fieldMap["updated_at"] = b.UpdatedAt
|
b.fieldMap["updated_at"] = b.UpdatedAt
|
||||||
@@ -164,10 +283,12 @@ func (b *bill) fillFieldMap() {
|
|||||||
b.fieldMap["trade_id"] = b.TradeID
|
b.fieldMap["trade_id"] = b.TradeID
|
||||||
b.fieldMap["resource_id"] = b.ResourceID
|
b.fieldMap["resource_id"] = b.ResourceID
|
||||||
b.fieldMap["refund_id"] = b.RefundID
|
b.fieldMap["refund_id"] = b.RefundID
|
||||||
|
b.fieldMap["coupon_id"] = b.CouponID
|
||||||
b.fieldMap["bill_no"] = b.BillNo
|
b.fieldMap["bill_no"] = b.BillNo
|
||||||
b.fieldMap["info"] = b.Info
|
b.fieldMap["info"] = b.Info
|
||||||
b.fieldMap["type"] = b.Type
|
b.fieldMap["type"] = b.Type
|
||||||
b.fieldMap["amount"] = b.Amount
|
b.fieldMap["amount"] = b.Amount
|
||||||
|
b.fieldMap["actual"] = b.Actual
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,6 +321,27 @@ type billBelongsToUser struct {
|
|||||||
|
|
||||||
Admin struct {
|
Admin struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,6 +424,10 @@ type billBelongsToTrade struct {
|
|||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
|
||||||
|
User struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a billBelongsToTrade) Where(conds ...field.Expr) *billBelongsToTrade {
|
func (a billBelongsToTrade) Where(conds ...field.Expr) *billBelongsToTrade {
|
||||||
@@ -369,9 +515,24 @@ type billBelongsToResource struct {
|
|||||||
}
|
}
|
||||||
Short struct {
|
Short struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Long struct {
|
Long struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,73 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel {
|
|||||||
RelationField: field.NewRelation("User", "models.User"),
|
RelationField: field.NewRelation("User", "models.User"),
|
||||||
Admin: struct {
|
Admin: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,13 +134,56 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel {
|
|||||||
},
|
},
|
||||||
Short: struct {
|
Short: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("Resource.Short", "models.ResourceShort"),
|
RelationField: field.NewRelation("Resource.Short", "models.ResourceShort"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Short.Sku", "models.ProductSku"),
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Short.Sku.Product", "models.Product"),
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Short.Sku.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Long: struct {
|
Long: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("Resource.Long", "models.ResourceLong"),
|
RelationField: field.NewRelation("Resource.Long", "models.ResourceLong"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Long.Sku", "models.ProductSku"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Product", "models.Product"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,6 +377,27 @@ type channelBelongsToUser struct {
|
|||||||
|
|
||||||
Admin struct {
|
Admin struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,9 +486,24 @@ type channelBelongsToResource struct {
|
|||||||
}
|
}
|
||||||
Short struct {
|
Short struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Long struct {
|
Long struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,21 @@ func newClient(db *gorm.DB, opts ...gen.DOOption) client {
|
|||||||
_client.Icon = field.NewString(tableName, "icon")
|
_client.Icon = field.NewString(tableName, "icon")
|
||||||
_client.Status = field.NewInt(tableName, "status")
|
_client.Status = field.NewInt(tableName, "status")
|
||||||
_client.Type = field.NewInt(tableName, "type")
|
_client.Type = field.NewInt(tableName, "type")
|
||||||
|
_client.Permissions = clientManyToManyPermissions{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
_client.fillFieldMap()
|
_client.fillFieldMap()
|
||||||
|
|
||||||
@@ -61,6 +76,7 @@ type client struct {
|
|||||||
Icon field.String
|
Icon field.String
|
||||||
Status field.Int
|
Status field.Int
|
||||||
Type field.Int
|
Type field.Int
|
||||||
|
Permissions clientManyToManyPermissions
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -105,7 +121,7 @@ func (c *client) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) fillFieldMap() {
|
func (c *client) fillFieldMap() {
|
||||||
c.fieldMap = make(map[string]field.Expr, 12)
|
c.fieldMap = make(map[string]field.Expr, 13)
|
||||||
c.fieldMap["id"] = c.ID
|
c.fieldMap["id"] = c.ID
|
||||||
c.fieldMap["created_at"] = c.CreatedAt
|
c.fieldMap["created_at"] = c.CreatedAt
|
||||||
c.fieldMap["updated_at"] = c.UpdatedAt
|
c.fieldMap["updated_at"] = c.UpdatedAt
|
||||||
@@ -118,18 +134,110 @@ func (c *client) fillFieldMap() {
|
|||||||
c.fieldMap["icon"] = c.Icon
|
c.fieldMap["icon"] = c.Icon
|
||||||
c.fieldMap["status"] = c.Status
|
c.fieldMap["status"] = c.Status
|
||||||
c.fieldMap["type"] = c.Type
|
c.fieldMap["type"] = c.Type
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c client) clone(db *gorm.DB) client {
|
func (c client) clone(db *gorm.DB) client {
|
||||||
c.clientDo.ReplaceConnPool(db.Statement.ConnPool)
|
c.clientDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
c.Permissions.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
c.Permissions.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c client) replaceDB(db *gorm.DB) client {
|
func (c client) replaceDB(db *gorm.DB) client {
|
||||||
c.clientDo.ReplaceDB(db)
|
c.clientDo.ReplaceDB(db)
|
||||||
|
c.Permissions.db = db.Session(&gorm.Session{})
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type clientManyToManyPermissions struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissions) Where(conds ...field.Expr) *clientManyToManyPermissions {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissions) WithContext(ctx context.Context) *clientManyToManyPermissions {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissions) Session(session *gorm.Session) *clientManyToManyPermissions {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissions) Model(m *models.Client) *clientManyToManyPermissionsTx {
|
||||||
|
return &clientManyToManyPermissionsTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissions) Unscoped() *clientManyToManyPermissions {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type clientManyToManyPermissionsTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissionsTx) Find() (result []*models.Permission, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissionsTx) Append(values ...*models.Permission) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissionsTx) Replace(values ...*models.Permission) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissionsTx) Delete(values ...*models.Permission) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissionsTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissionsTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a clientManyToManyPermissionsTx) Unscoped() *clientManyToManyPermissionsTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type clientDo struct{ gen.DO }
|
type clientDo struct{ gen.DO }
|
||||||
|
|
||||||
func (c clientDo) Debug() *clientDo {
|
func (c clientDo) Debug() *clientDo {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ var (
|
|||||||
Admin *admin
|
Admin *admin
|
||||||
AdminRole *adminRole
|
AdminRole *adminRole
|
||||||
Announcement *announcement
|
Announcement *announcement
|
||||||
|
BalanceActivity *balanceActivity
|
||||||
Bill *bill
|
Bill *bill
|
||||||
Channel *channel
|
Channel *channel
|
||||||
Client *client
|
Client *client
|
||||||
@@ -37,6 +38,7 @@ var (
|
|||||||
LogsUserUsage *logsUserUsage
|
LogsUserUsage *logsUserUsage
|
||||||
Permission *permission
|
Permission *permission
|
||||||
Product *product
|
Product *product
|
||||||
|
ProductDiscount *productDiscount
|
||||||
ProductSku *productSku
|
ProductSku *productSku
|
||||||
ProductSkuUser *productSkuUser
|
ProductSkuUser *productSkuUser
|
||||||
Proxy *proxy
|
Proxy *proxy
|
||||||
@@ -56,6 +58,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
|||||||
Admin = &Q.Admin
|
Admin = &Q.Admin
|
||||||
AdminRole = &Q.AdminRole
|
AdminRole = &Q.AdminRole
|
||||||
Announcement = &Q.Announcement
|
Announcement = &Q.Announcement
|
||||||
|
BalanceActivity = &Q.BalanceActivity
|
||||||
Bill = &Q.Bill
|
Bill = &Q.Bill
|
||||||
Channel = &Q.Channel
|
Channel = &Q.Channel
|
||||||
Client = &Q.Client
|
Client = &Q.Client
|
||||||
@@ -73,6 +76,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
|||||||
LogsUserUsage = &Q.LogsUserUsage
|
LogsUserUsage = &Q.LogsUserUsage
|
||||||
Permission = &Q.Permission
|
Permission = &Q.Permission
|
||||||
Product = &Q.Product
|
Product = &Q.Product
|
||||||
|
ProductDiscount = &Q.ProductDiscount
|
||||||
ProductSku = &Q.ProductSku
|
ProductSku = &Q.ProductSku
|
||||||
ProductSkuUser = &Q.ProductSkuUser
|
ProductSkuUser = &Q.ProductSkuUser
|
||||||
Proxy = &Q.Proxy
|
Proxy = &Q.Proxy
|
||||||
@@ -93,6 +97,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
|||||||
Admin: newAdmin(db, opts...),
|
Admin: newAdmin(db, opts...),
|
||||||
AdminRole: newAdminRole(db, opts...),
|
AdminRole: newAdminRole(db, opts...),
|
||||||
Announcement: newAnnouncement(db, opts...),
|
Announcement: newAnnouncement(db, opts...),
|
||||||
|
BalanceActivity: newBalanceActivity(db, opts...),
|
||||||
Bill: newBill(db, opts...),
|
Bill: newBill(db, opts...),
|
||||||
Channel: newChannel(db, opts...),
|
Channel: newChannel(db, opts...),
|
||||||
Client: newClient(db, opts...),
|
Client: newClient(db, opts...),
|
||||||
@@ -110,6 +115,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
|||||||
LogsUserUsage: newLogsUserUsage(db, opts...),
|
LogsUserUsage: newLogsUserUsage(db, opts...),
|
||||||
Permission: newPermission(db, opts...),
|
Permission: newPermission(db, opts...),
|
||||||
Product: newProduct(db, opts...),
|
Product: newProduct(db, opts...),
|
||||||
|
ProductDiscount: newProductDiscount(db, opts...),
|
||||||
ProductSku: newProductSku(db, opts...),
|
ProductSku: newProductSku(db, opts...),
|
||||||
ProductSkuUser: newProductSkuUser(db, opts...),
|
ProductSkuUser: newProductSkuUser(db, opts...),
|
||||||
Proxy: newProxy(db, opts...),
|
Proxy: newProxy(db, opts...),
|
||||||
@@ -131,6 +137,7 @@ type Query struct {
|
|||||||
Admin admin
|
Admin admin
|
||||||
AdminRole adminRole
|
AdminRole adminRole
|
||||||
Announcement announcement
|
Announcement announcement
|
||||||
|
BalanceActivity balanceActivity
|
||||||
Bill bill
|
Bill bill
|
||||||
Channel channel
|
Channel channel
|
||||||
Client client
|
Client client
|
||||||
@@ -148,6 +155,7 @@ type Query struct {
|
|||||||
LogsUserUsage logsUserUsage
|
LogsUserUsage logsUserUsage
|
||||||
Permission permission
|
Permission permission
|
||||||
Product product
|
Product product
|
||||||
|
ProductDiscount productDiscount
|
||||||
ProductSku productSku
|
ProductSku productSku
|
||||||
ProductSkuUser productSkuUser
|
ProductSkuUser productSkuUser
|
||||||
Proxy proxy
|
Proxy proxy
|
||||||
@@ -170,6 +178,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
|
|||||||
Admin: q.Admin.clone(db),
|
Admin: q.Admin.clone(db),
|
||||||
AdminRole: q.AdminRole.clone(db),
|
AdminRole: q.AdminRole.clone(db),
|
||||||
Announcement: q.Announcement.clone(db),
|
Announcement: q.Announcement.clone(db),
|
||||||
|
BalanceActivity: q.BalanceActivity.clone(db),
|
||||||
Bill: q.Bill.clone(db),
|
Bill: q.Bill.clone(db),
|
||||||
Channel: q.Channel.clone(db),
|
Channel: q.Channel.clone(db),
|
||||||
Client: q.Client.clone(db),
|
Client: q.Client.clone(db),
|
||||||
@@ -187,6 +196,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
|
|||||||
LogsUserUsage: q.LogsUserUsage.clone(db),
|
LogsUserUsage: q.LogsUserUsage.clone(db),
|
||||||
Permission: q.Permission.clone(db),
|
Permission: q.Permission.clone(db),
|
||||||
Product: q.Product.clone(db),
|
Product: q.Product.clone(db),
|
||||||
|
ProductDiscount: q.ProductDiscount.clone(db),
|
||||||
ProductSku: q.ProductSku.clone(db),
|
ProductSku: q.ProductSku.clone(db),
|
||||||
ProductSkuUser: q.ProductSkuUser.clone(db),
|
ProductSkuUser: q.ProductSkuUser.clone(db),
|
||||||
Proxy: q.Proxy.clone(db),
|
Proxy: q.Proxy.clone(db),
|
||||||
@@ -216,6 +226,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
|||||||
Admin: q.Admin.replaceDB(db),
|
Admin: q.Admin.replaceDB(db),
|
||||||
AdminRole: q.AdminRole.replaceDB(db),
|
AdminRole: q.AdminRole.replaceDB(db),
|
||||||
Announcement: q.Announcement.replaceDB(db),
|
Announcement: q.Announcement.replaceDB(db),
|
||||||
|
BalanceActivity: q.BalanceActivity.replaceDB(db),
|
||||||
Bill: q.Bill.replaceDB(db),
|
Bill: q.Bill.replaceDB(db),
|
||||||
Channel: q.Channel.replaceDB(db),
|
Channel: q.Channel.replaceDB(db),
|
||||||
Client: q.Client.replaceDB(db),
|
Client: q.Client.replaceDB(db),
|
||||||
@@ -233,6 +244,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
|||||||
LogsUserUsage: q.LogsUserUsage.replaceDB(db),
|
LogsUserUsage: q.LogsUserUsage.replaceDB(db),
|
||||||
Permission: q.Permission.replaceDB(db),
|
Permission: q.Permission.replaceDB(db),
|
||||||
Product: q.Product.replaceDB(db),
|
Product: q.Product.replaceDB(db),
|
||||||
|
ProductDiscount: q.ProductDiscount.replaceDB(db),
|
||||||
ProductSku: q.ProductSku.replaceDB(db),
|
ProductSku: q.ProductSku.replaceDB(db),
|
||||||
ProductSkuUser: q.ProductSkuUser.replaceDB(db),
|
ProductSkuUser: q.ProductSkuUser.replaceDB(db),
|
||||||
Proxy: q.Proxy.replaceDB(db),
|
Proxy: q.Proxy.replaceDB(db),
|
||||||
@@ -252,6 +264,7 @@ type queryCtx struct {
|
|||||||
Admin *adminDo
|
Admin *adminDo
|
||||||
AdminRole *adminRoleDo
|
AdminRole *adminRoleDo
|
||||||
Announcement *announcementDo
|
Announcement *announcementDo
|
||||||
|
BalanceActivity *balanceActivityDo
|
||||||
Bill *billDo
|
Bill *billDo
|
||||||
Channel *channelDo
|
Channel *channelDo
|
||||||
Client *clientDo
|
Client *clientDo
|
||||||
@@ -269,6 +282,7 @@ type queryCtx struct {
|
|||||||
LogsUserUsage *logsUserUsageDo
|
LogsUserUsage *logsUserUsageDo
|
||||||
Permission *permissionDo
|
Permission *permissionDo
|
||||||
Product *productDo
|
Product *productDo
|
||||||
|
ProductDiscount *productDiscountDo
|
||||||
ProductSku *productSkuDo
|
ProductSku *productSkuDo
|
||||||
ProductSkuUser *productSkuUserDo
|
ProductSkuUser *productSkuUserDo
|
||||||
Proxy *proxyDo
|
Proxy *proxyDo
|
||||||
@@ -288,6 +302,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
|||||||
Admin: q.Admin.WithContext(ctx),
|
Admin: q.Admin.WithContext(ctx),
|
||||||
AdminRole: q.AdminRole.WithContext(ctx),
|
AdminRole: q.AdminRole.WithContext(ctx),
|
||||||
Announcement: q.Announcement.WithContext(ctx),
|
Announcement: q.Announcement.WithContext(ctx),
|
||||||
|
BalanceActivity: q.BalanceActivity.WithContext(ctx),
|
||||||
Bill: q.Bill.WithContext(ctx),
|
Bill: q.Bill.WithContext(ctx),
|
||||||
Channel: q.Channel.WithContext(ctx),
|
Channel: q.Channel.WithContext(ctx),
|
||||||
Client: q.Client.WithContext(ctx),
|
Client: q.Client.WithContext(ctx),
|
||||||
@@ -305,6 +320,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
|||||||
LogsUserUsage: q.LogsUserUsage.WithContext(ctx),
|
LogsUserUsage: q.LogsUserUsage.WithContext(ctx),
|
||||||
Permission: q.Permission.WithContext(ctx),
|
Permission: q.Permission.WithContext(ctx),
|
||||||
Product: q.Product.WithContext(ctx),
|
Product: q.Product.WithContext(ctx),
|
||||||
|
ProductDiscount: q.ProductDiscount.WithContext(ctx),
|
||||||
ProductSku: q.ProductSku.WithContext(ctx),
|
ProductSku: q.ProductSku.WithContext(ctx),
|
||||||
ProductSkuUser: q.ProductSkuUser.WithContext(ctx),
|
ProductSkuUser: q.ProductSkuUser.WithContext(ctx),
|
||||||
Proxy: q.Proxy.WithContext(ctx),
|
Proxy: q.Proxy.WithContext(ctx),
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func newLinkAdminRole(db *gorm.DB, opts ...gen.DOOption) linkAdminRole {
|
|||||||
_linkAdminRole.ALL = field.NewAsterisk(tableName)
|
_linkAdminRole.ALL = field.NewAsterisk(tableName)
|
||||||
_linkAdminRole.ID = field.NewInt32(tableName, "id")
|
_linkAdminRole.ID = field.NewInt32(tableName, "id")
|
||||||
_linkAdminRole.AdminID = field.NewInt32(tableName, "admin_id")
|
_linkAdminRole.AdminID = field.NewInt32(tableName, "admin_id")
|
||||||
_linkAdminRole.RoleID = field.NewInt32(tableName, "role_id")
|
_linkAdminRole.RoleID = field.NewInt32(tableName, "admin_role_id")
|
||||||
|
|
||||||
_linkAdminRole.fillFieldMap()
|
_linkAdminRole.fillFieldMap()
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ func (l *linkAdminRole) updateTableName(table string) *linkAdminRole {
|
|||||||
l.ALL = field.NewAsterisk(table)
|
l.ALL = field.NewAsterisk(table)
|
||||||
l.ID = field.NewInt32(table, "id")
|
l.ID = field.NewInt32(table, "id")
|
||||||
l.AdminID = field.NewInt32(table, "admin_id")
|
l.AdminID = field.NewInt32(table, "admin_id")
|
||||||
l.RoleID = field.NewInt32(table, "role_id")
|
l.RoleID = field.NewInt32(table, "admin_role_id")
|
||||||
|
|
||||||
l.fillFieldMap()
|
l.fillFieldMap()
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ func (l *linkAdminRole) fillFieldMap() {
|
|||||||
l.fieldMap = make(map[string]field.Expr, 3)
|
l.fieldMap = make(map[string]field.Expr, 3)
|
||||||
l.fieldMap["id"] = l.ID
|
l.fieldMap["id"] = l.ID
|
||||||
l.fieldMap["admin_id"] = l.AdminID
|
l.fieldMap["admin_id"] = l.AdminID
|
||||||
l.fieldMap["role_id"] = l.RoleID
|
l.fieldMap["admin_role_id"] = l.RoleID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l linkAdminRole) clone(db *gorm.DB) linkAdminRole {
|
func (l linkAdminRole) clone(db *gorm.DB) linkAdminRole {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func newLinkAdminRolePermission(db *gorm.DB, opts ...gen.DOOption) linkAdminRole
|
|||||||
tableName := _linkAdminRolePermission.linkAdminRolePermissionDo.TableName()
|
tableName := _linkAdminRolePermission.linkAdminRolePermissionDo.TableName()
|
||||||
_linkAdminRolePermission.ALL = field.NewAsterisk(tableName)
|
_linkAdminRolePermission.ALL = field.NewAsterisk(tableName)
|
||||||
_linkAdminRolePermission.ID = field.NewInt32(tableName, "id")
|
_linkAdminRolePermission.ID = field.NewInt32(tableName, "id")
|
||||||
_linkAdminRolePermission.RoleID = field.NewInt32(tableName, "role_id")
|
_linkAdminRolePermission.RoleID = field.NewInt32(tableName, "admin_role_id")
|
||||||
_linkAdminRolePermission.PermissionID = field.NewInt32(tableName, "permission_id")
|
_linkAdminRolePermission.PermissionID = field.NewInt32(tableName, "permission_id")
|
||||||
|
|
||||||
_linkAdminRolePermission.fillFieldMap()
|
_linkAdminRolePermission.fillFieldMap()
|
||||||
@@ -60,7 +60,7 @@ func (l linkAdminRolePermission) As(alias string) *linkAdminRolePermission {
|
|||||||
func (l *linkAdminRolePermission) updateTableName(table string) *linkAdminRolePermission {
|
func (l *linkAdminRolePermission) updateTableName(table string) *linkAdminRolePermission {
|
||||||
l.ALL = field.NewAsterisk(table)
|
l.ALL = field.NewAsterisk(table)
|
||||||
l.ID = field.NewInt32(table, "id")
|
l.ID = field.NewInt32(table, "id")
|
||||||
l.RoleID = field.NewInt32(table, "role_id")
|
l.RoleID = field.NewInt32(table, "admin_role_id")
|
||||||
l.PermissionID = field.NewInt32(table, "permission_id")
|
l.PermissionID = field.NewInt32(table, "permission_id")
|
||||||
|
|
||||||
l.fillFieldMap()
|
l.fillFieldMap()
|
||||||
@@ -80,7 +80,7 @@ func (l *linkAdminRolePermission) GetFieldByName(fieldName string) (field.OrderE
|
|||||||
func (l *linkAdminRolePermission) fillFieldMap() {
|
func (l *linkAdminRolePermission) fillFieldMap() {
|
||||||
l.fieldMap = make(map[string]field.Expr, 3)
|
l.fieldMap = make(map[string]field.Expr, 3)
|
||||||
l.fieldMap["id"] = l.ID
|
l.fieldMap["id"] = l.ID
|
||||||
l.fieldMap["role_id"] = l.RoleID
|
l.fieldMap["admin_role_id"] = l.RoleID
|
||||||
l.fieldMap["permission_id"] = l.PermissionID
|
l.fieldMap["permission_id"] = l.PermissionID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func newLinkUserRole(db *gorm.DB, opts ...gen.DOOption) linkUserRole {
|
|||||||
_linkUserRole.ALL = field.NewAsterisk(tableName)
|
_linkUserRole.ALL = field.NewAsterisk(tableName)
|
||||||
_linkUserRole.ID = field.NewInt32(tableName, "id")
|
_linkUserRole.ID = field.NewInt32(tableName, "id")
|
||||||
_linkUserRole.UserID = field.NewInt32(tableName, "user_id")
|
_linkUserRole.UserID = field.NewInt32(tableName, "user_id")
|
||||||
_linkUserRole.RoleID = field.NewInt32(tableName, "role_id")
|
_linkUserRole.RoleID = field.NewInt32(tableName, "user_role_id")
|
||||||
|
|
||||||
_linkUserRole.fillFieldMap()
|
_linkUserRole.fillFieldMap()
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ func (l *linkUserRole) updateTableName(table string) *linkUserRole {
|
|||||||
l.ALL = field.NewAsterisk(table)
|
l.ALL = field.NewAsterisk(table)
|
||||||
l.ID = field.NewInt32(table, "id")
|
l.ID = field.NewInt32(table, "id")
|
||||||
l.UserID = field.NewInt32(table, "user_id")
|
l.UserID = field.NewInt32(table, "user_id")
|
||||||
l.RoleID = field.NewInt32(table, "role_id")
|
l.RoleID = field.NewInt32(table, "user_role_id")
|
||||||
|
|
||||||
l.fillFieldMap()
|
l.fillFieldMap()
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ func (l *linkUserRole) fillFieldMap() {
|
|||||||
l.fieldMap = make(map[string]field.Expr, 3)
|
l.fieldMap = make(map[string]field.Expr, 3)
|
||||||
l.fieldMap["id"] = l.ID
|
l.fieldMap["id"] = l.ID
|
||||||
l.fieldMap["user_id"] = l.UserID
|
l.fieldMap["user_id"] = l.UserID
|
||||||
l.fieldMap["role_id"] = l.RoleID
|
l.fieldMap["user_role_id"] = l.RoleID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l linkUserRole) clone(db *gorm.DB) linkUserRole {
|
func (l linkUserRole) clone(db *gorm.DB) linkUserRole {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func newLinkUserRolePermission(db *gorm.DB, opts ...gen.DOOption) linkUserRolePe
|
|||||||
tableName := _linkUserRolePermission.linkUserRolePermissionDo.TableName()
|
tableName := _linkUserRolePermission.linkUserRolePermissionDo.TableName()
|
||||||
_linkUserRolePermission.ALL = field.NewAsterisk(tableName)
|
_linkUserRolePermission.ALL = field.NewAsterisk(tableName)
|
||||||
_linkUserRolePermission.ID = field.NewInt32(tableName, "id")
|
_linkUserRolePermission.ID = field.NewInt32(tableName, "id")
|
||||||
_linkUserRolePermission.RoleID = field.NewInt32(tableName, "role_id")
|
_linkUserRolePermission.RoleID = field.NewInt32(tableName, "user_role_id")
|
||||||
_linkUserRolePermission.PermissionID = field.NewInt32(tableName, "permission_id")
|
_linkUserRolePermission.PermissionID = field.NewInt32(tableName, "permission_id")
|
||||||
|
|
||||||
_linkUserRolePermission.fillFieldMap()
|
_linkUserRolePermission.fillFieldMap()
|
||||||
@@ -60,7 +60,7 @@ func (l linkUserRolePermission) As(alias string) *linkUserRolePermission {
|
|||||||
func (l *linkUserRolePermission) updateTableName(table string) *linkUserRolePermission {
|
func (l *linkUserRolePermission) updateTableName(table string) *linkUserRolePermission {
|
||||||
l.ALL = field.NewAsterisk(table)
|
l.ALL = field.NewAsterisk(table)
|
||||||
l.ID = field.NewInt32(table, "id")
|
l.ID = field.NewInt32(table, "id")
|
||||||
l.RoleID = field.NewInt32(table, "role_id")
|
l.RoleID = field.NewInt32(table, "user_role_id")
|
||||||
l.PermissionID = field.NewInt32(table, "permission_id")
|
l.PermissionID = field.NewInt32(table, "permission_id")
|
||||||
|
|
||||||
l.fillFieldMap()
|
l.fillFieldMap()
|
||||||
@@ -80,7 +80,7 @@ func (l *linkUserRolePermission) GetFieldByName(fieldName string) (field.OrderEx
|
|||||||
func (l *linkUserRolePermission) fillFieldMap() {
|
func (l *linkUserRolePermission) fillFieldMap() {
|
||||||
l.fieldMap = make(map[string]field.Expr, 3)
|
l.fieldMap = make(map[string]field.Expr, 3)
|
||||||
l.fieldMap["id"] = l.ID
|
l.fieldMap["id"] = l.ID
|
||||||
l.fieldMap["role_id"] = l.RoleID
|
l.fieldMap["user_role_id"] = l.RoleID
|
||||||
l.fieldMap["permission_id"] = l.PermissionID
|
l.fieldMap["permission_id"] = l.PermissionID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,73 @@ func newLogsLogin(db *gorm.DB, opts ...gen.DOOption) logsLogin {
|
|||||||
RelationField: field.NewRelation("User", "models.User"),
|
RelationField: field.NewRelation("User", "models.User"),
|
||||||
Admin: struct {
|
Admin: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,6 +201,27 @@ type logsLoginBelongsToUser struct {
|
|||||||
|
|
||||||
Admin struct {
|
Admin struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,27 @@ func newLogsRequest(db *gorm.DB, opts ...gen.DOOption) logsRequest {
|
|||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
RelationField: field.NewRelation("Client", "models.Client"),
|
RelationField: field.NewRelation("Client", "models.Client"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Client.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Client.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Client.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_logsRequest.User = logsRequestBelongsToUser{
|
_logsRequest.User = logsRequestBelongsToUser{
|
||||||
@@ -50,8 +71,45 @@ func newLogsRequest(db *gorm.DB, opts ...gen.DOOption) logsRequest {
|
|||||||
RelationField: field.NewRelation("User", "models.User"),
|
RelationField: field.NewRelation("User", "models.User"),
|
||||||
Admin: struct {
|
Admin: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +214,16 @@ type logsRequestHasOneClient struct {
|
|||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a logsRequestHasOneClient) Where(conds ...field.Expr) *logsRequestHasOneClient {
|
func (a logsRequestHasOneClient) Where(conds ...field.Expr) *logsRequestHasOneClient {
|
||||||
@@ -240,6 +308,21 @@ type logsRequestBelongsToUser struct {
|
|||||||
|
|
||||||
Admin struct {
|
Admin struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,145 @@ func newLogsUserUsage(db *gorm.DB, opts ...gen.DOOption) logsUserUsage {
|
|||||||
_logsUserUsage.ISP = field.NewString(tableName, "isp")
|
_logsUserUsage.ISP = field.NewString(tableName, "isp")
|
||||||
_logsUserUsage.IP = field.NewField(tableName, "ip")
|
_logsUserUsage.IP = field.NewField(tableName, "ip")
|
||||||
_logsUserUsage.Time = field.NewTime(tableName, "time")
|
_logsUserUsage.Time = field.NewTime(tableName, "time")
|
||||||
|
_logsUserUsage.User = logsUserUsageBelongsToUser{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("User", "models.User"),
|
||||||
|
Admin: struct {
|
||||||
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_logsUserUsage.Resource = logsUserUsageBelongsToResource{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Resource", "models.Resource"),
|
||||||
|
User: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.User", "models.User"),
|
||||||
|
},
|
||||||
|
Short: struct {
|
||||||
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Short", "models.ResourceShort"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Short.Sku", "models.ProductSku"),
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Short.Sku.Product", "models.Product"),
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Short.Sku.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Long: struct {
|
||||||
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Long", "models.ResourceLong"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Long.Sku", "models.ProductSku"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Resource.Product", "models.Product"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
_logsUserUsage.fillFieldMap()
|
_logsUserUsage.fillFieldMap()
|
||||||
|
|
||||||
@@ -57,6 +196,9 @@ type logsUserUsage struct {
|
|||||||
ISP field.String
|
ISP field.String
|
||||||
IP field.Field
|
IP field.Field
|
||||||
Time field.Time
|
Time field.Time
|
||||||
|
User logsUserUsageBelongsToUser
|
||||||
|
|
||||||
|
Resource logsUserUsageBelongsToResource
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -99,7 +241,7 @@ func (l *logsUserUsage) GetFieldByName(fieldName string) (field.OrderExpr, bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *logsUserUsage) fillFieldMap() {
|
func (l *logsUserUsage) fillFieldMap() {
|
||||||
l.fieldMap = make(map[string]field.Expr, 10)
|
l.fieldMap = make(map[string]field.Expr, 12)
|
||||||
l.fieldMap["id"] = l.ID
|
l.fieldMap["id"] = l.ID
|
||||||
l.fieldMap["user_id"] = l.UserID
|
l.fieldMap["user_id"] = l.UserID
|
||||||
l.fieldMap["resource_id"] = l.ResourceID
|
l.fieldMap["resource_id"] = l.ResourceID
|
||||||
@@ -110,18 +252,237 @@ func (l *logsUserUsage) fillFieldMap() {
|
|||||||
l.fieldMap["isp"] = l.ISP
|
l.fieldMap["isp"] = l.ISP
|
||||||
l.fieldMap["ip"] = l.IP
|
l.fieldMap["ip"] = l.IP
|
||||||
l.fieldMap["time"] = l.Time
|
l.fieldMap["time"] = l.Time
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l logsUserUsage) clone(db *gorm.DB) logsUserUsage {
|
func (l logsUserUsage) clone(db *gorm.DB) logsUserUsage {
|
||||||
l.logsUserUsageDo.ReplaceConnPool(db.Statement.ConnPool)
|
l.logsUserUsageDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
l.User.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
l.User.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
|
l.Resource.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
l.Resource.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l logsUserUsage) replaceDB(db *gorm.DB) logsUserUsage {
|
func (l logsUserUsage) replaceDB(db *gorm.DB) logsUserUsage {
|
||||||
l.logsUserUsageDo.ReplaceDB(db)
|
l.logsUserUsageDo.ReplaceDB(db)
|
||||||
|
l.User.db = db.Session(&gorm.Session{})
|
||||||
|
l.Resource.db = db.Session(&gorm.Session{})
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type logsUserUsageBelongsToUser struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
Admin struct {
|
||||||
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUser) Where(conds ...field.Expr) *logsUserUsageBelongsToUser {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUser) WithContext(ctx context.Context) *logsUserUsageBelongsToUser {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUser) Session(session *gorm.Session) *logsUserUsageBelongsToUser {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUser) Model(m *models.LogsUserUsage) *logsUserUsageBelongsToUserTx {
|
||||||
|
return &logsUserUsageBelongsToUserTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUser) Unscoped() *logsUserUsageBelongsToUser {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type logsUserUsageBelongsToUserTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUserTx) Find() (result *models.User, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUserTx) Append(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUserTx) Replace(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUserTx) Delete(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUserTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUserTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToUserTx) Unscoped() *logsUserUsageBelongsToUserTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type logsUserUsageBelongsToResource struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
User struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Short struct {
|
||||||
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Long struct {
|
||||||
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResource) Where(conds ...field.Expr) *logsUserUsageBelongsToResource {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResource) WithContext(ctx context.Context) *logsUserUsageBelongsToResource {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResource) Session(session *gorm.Session) *logsUserUsageBelongsToResource {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResource) Model(m *models.LogsUserUsage) *logsUserUsageBelongsToResourceTx {
|
||||||
|
return &logsUserUsageBelongsToResourceTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResource) Unscoped() *logsUserUsageBelongsToResource {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type logsUserUsageBelongsToResourceTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResourceTx) Find() (result *models.Resource, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResourceTx) Append(values ...*models.Resource) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResourceTx) Replace(values ...*models.Resource) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResourceTx) Delete(values ...*models.Resource) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResourceTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResourceTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a logsUserUsageBelongsToResourceTx) Unscoped() *logsUserUsageBelongsToResourceTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type logsUserUsageDo struct{ gen.DO }
|
type logsUserUsageDo struct{ gen.DO }
|
||||||
|
|
||||||
func (l logsUserUsageDo) Debug() *logsUserUsageDo {
|
func (l logsUserUsageDo) Debug() *logsUserUsageDo {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ func newPermission(db *gorm.DB, opts ...gen.DOOption) permission {
|
|||||||
_permission.ParentID = field.NewInt32(tableName, "parent_id")
|
_permission.ParentID = field.NewInt32(tableName, "parent_id")
|
||||||
_permission.Name = field.NewString(tableName, "name")
|
_permission.Name = field.NewString(tableName, "name")
|
||||||
_permission.Description = field.NewString(tableName, "description")
|
_permission.Description = field.NewString(tableName, "description")
|
||||||
|
_permission.Sort = field.NewInt(tableName, "sort")
|
||||||
_permission.Children = permissionHasManyChildren{
|
_permission.Children = permissionHasManyChildren{
|
||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
@@ -72,6 +73,7 @@ type permission struct {
|
|||||||
ParentID field.Int32
|
ParentID field.Int32
|
||||||
Name field.String
|
Name field.String
|
||||||
Description field.String
|
Description field.String
|
||||||
|
Sort field.Int
|
||||||
Children permissionHasManyChildren
|
Children permissionHasManyChildren
|
||||||
|
|
||||||
Parent permissionBelongsToParent
|
Parent permissionBelongsToParent
|
||||||
@@ -98,6 +100,7 @@ func (p *permission) updateTableName(table string) *permission {
|
|||||||
p.ParentID = field.NewInt32(table, "parent_id")
|
p.ParentID = field.NewInt32(table, "parent_id")
|
||||||
p.Name = field.NewString(table, "name")
|
p.Name = field.NewString(table, "name")
|
||||||
p.Description = field.NewString(table, "description")
|
p.Description = field.NewString(table, "description")
|
||||||
|
p.Sort = field.NewInt(table, "sort")
|
||||||
|
|
||||||
p.fillFieldMap()
|
p.fillFieldMap()
|
||||||
|
|
||||||
@@ -114,7 +117,7 @@ func (p *permission) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *permission) fillFieldMap() {
|
func (p *permission) fillFieldMap() {
|
||||||
p.fieldMap = make(map[string]field.Expr, 9)
|
p.fieldMap = make(map[string]field.Expr, 10)
|
||||||
p.fieldMap["id"] = p.ID
|
p.fieldMap["id"] = p.ID
|
||||||
p.fieldMap["created_at"] = p.CreatedAt
|
p.fieldMap["created_at"] = p.CreatedAt
|
||||||
p.fieldMap["updated_at"] = p.UpdatedAt
|
p.fieldMap["updated_at"] = p.UpdatedAt
|
||||||
@@ -122,6 +125,7 @@ func (p *permission) fillFieldMap() {
|
|||||||
p.fieldMap["parent_id"] = p.ParentID
|
p.fieldMap["parent_id"] = p.ParentID
|
||||||
p.fieldMap["name"] = p.Name
|
p.fieldMap["name"] = p.Name
|
||||||
p.fieldMap["description"] = p.Description
|
p.fieldMap["description"] = p.Description
|
||||||
|
p.fieldMap["sort"] = p.Sort
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
339
web/queries/product_discount.gen.go
Normal file
339
web/queries/product_discount.gen.go
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package queries
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
|
|
||||||
|
"gorm.io/gen"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
|
||||||
|
"gorm.io/plugin/dbresolver"
|
||||||
|
|
||||||
|
"platform/web/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newProductDiscount(db *gorm.DB, opts ...gen.DOOption) productDiscount {
|
||||||
|
_productDiscount := productDiscount{}
|
||||||
|
|
||||||
|
_productDiscount.productDiscountDo.UseDB(db, opts...)
|
||||||
|
_productDiscount.productDiscountDo.UseModel(&models.ProductDiscount{})
|
||||||
|
|
||||||
|
tableName := _productDiscount.productDiscountDo.TableName()
|
||||||
|
_productDiscount.ALL = field.NewAsterisk(tableName)
|
||||||
|
_productDiscount.ID = field.NewInt32(tableName, "id")
|
||||||
|
_productDiscount.CreatedAt = field.NewTime(tableName, "created_at")
|
||||||
|
_productDiscount.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
|
_productDiscount.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
|
_productDiscount.Name = field.NewString(tableName, "name")
|
||||||
|
_productDiscount.Discount = field.NewInt32(tableName, "discount")
|
||||||
|
|
||||||
|
_productDiscount.fillFieldMap()
|
||||||
|
|
||||||
|
return _productDiscount
|
||||||
|
}
|
||||||
|
|
||||||
|
type productDiscount struct {
|
||||||
|
productDiscountDo
|
||||||
|
|
||||||
|
ALL field.Asterisk
|
||||||
|
ID field.Int32
|
||||||
|
CreatedAt field.Time
|
||||||
|
UpdatedAt field.Time
|
||||||
|
DeletedAt field.Field
|
||||||
|
Name field.String
|
||||||
|
Discount field.Int32
|
||||||
|
|
||||||
|
fieldMap map[string]field.Expr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscount) Table(newTableName string) *productDiscount {
|
||||||
|
p.productDiscountDo.UseTable(newTableName)
|
||||||
|
return p.updateTableName(newTableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscount) As(alias string) *productDiscount {
|
||||||
|
p.productDiscountDo.DO = *(p.productDiscountDo.As(alias).(*gen.DO))
|
||||||
|
return p.updateTableName(alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *productDiscount) updateTableName(table string) *productDiscount {
|
||||||
|
p.ALL = field.NewAsterisk(table)
|
||||||
|
p.ID = field.NewInt32(table, "id")
|
||||||
|
p.CreatedAt = field.NewTime(table, "created_at")
|
||||||
|
p.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
|
p.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
|
p.Name = field.NewString(table, "name")
|
||||||
|
p.Discount = field.NewInt32(table, "discount")
|
||||||
|
|
||||||
|
p.fillFieldMap()
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *productDiscount) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||||
|
_f, ok := p.fieldMap[fieldName]
|
||||||
|
if !ok || _f == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
_oe, ok := _f.(field.OrderExpr)
|
||||||
|
return _oe, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *productDiscount) fillFieldMap() {
|
||||||
|
p.fieldMap = make(map[string]field.Expr, 6)
|
||||||
|
p.fieldMap["id"] = p.ID
|
||||||
|
p.fieldMap["created_at"] = p.CreatedAt
|
||||||
|
p.fieldMap["updated_at"] = p.UpdatedAt
|
||||||
|
p.fieldMap["deleted_at"] = p.DeletedAt
|
||||||
|
p.fieldMap["name"] = p.Name
|
||||||
|
p.fieldMap["discount"] = p.Discount
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscount) clone(db *gorm.DB) productDiscount {
|
||||||
|
p.productDiscountDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscount) replaceDB(db *gorm.DB) productDiscount {
|
||||||
|
p.productDiscountDo.ReplaceDB(db)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
type productDiscountDo struct{ gen.DO }
|
||||||
|
|
||||||
|
func (p productDiscountDo) Debug() *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Debug())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) WithContext(ctx context.Context) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.WithContext(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) ReadDB() *productDiscountDo {
|
||||||
|
return p.Clauses(dbresolver.Read)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) WriteDB() *productDiscountDo {
|
||||||
|
return p.Clauses(dbresolver.Write)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Session(config *gorm.Session) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Session(config))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Clauses(conds ...clause.Expression) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Clauses(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Returning(value interface{}, columns ...string) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Returning(value, columns...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Not(conds ...gen.Condition) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Not(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Or(conds ...gen.Condition) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Or(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Select(conds ...field.Expr) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Select(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Where(conds ...gen.Condition) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Where(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Order(conds ...field.Expr) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Order(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Distinct(cols ...field.Expr) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Distinct(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Omit(cols ...field.Expr) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Omit(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Join(table schema.Tabler, on ...field.Expr) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Join(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) LeftJoin(table schema.Tabler, on ...field.Expr) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.LeftJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) RightJoin(table schema.Tabler, on ...field.Expr) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.RightJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Group(cols ...field.Expr) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Group(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Having(conds ...gen.Condition) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Having(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Limit(limit int) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Limit(limit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Offset(offset int) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Offset(offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Scopes(funcs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Unscoped() *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Unscoped())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Create(values ...*models.ProductDiscount) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return p.DO.Create(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) CreateInBatches(values []*models.ProductDiscount, batchSize int) error {
|
||||||
|
return p.DO.CreateInBatches(values, batchSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save : !!! underlying implementation is different with GORM
|
||||||
|
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||||
|
func (p productDiscountDo) Save(values ...*models.ProductDiscount) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return p.DO.Save(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) First() (*models.ProductDiscount, error) {
|
||||||
|
if result, err := p.DO.First(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.ProductDiscount), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Take() (*models.ProductDiscount, error) {
|
||||||
|
if result, err := p.DO.Take(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.ProductDiscount), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Last() (*models.ProductDiscount, error) {
|
||||||
|
if result, err := p.DO.Last(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.ProductDiscount), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Find() ([]*models.ProductDiscount, error) {
|
||||||
|
result, err := p.DO.Find()
|
||||||
|
return result.([]*models.ProductDiscount), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.ProductDiscount, err error) {
|
||||||
|
buf := make([]*models.ProductDiscount, 0, batchSize)
|
||||||
|
err = p.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||||
|
defer func() { results = append(results, buf...) }()
|
||||||
|
return fc(tx, batch)
|
||||||
|
})
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) FindInBatches(result *[]*models.ProductDiscount, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||||
|
return p.DO.FindInBatches(result, batchSize, fc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Attrs(attrs ...field.AssignExpr) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Attrs(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Assign(attrs ...field.AssignExpr) *productDiscountDo {
|
||||||
|
return p.withDO(p.DO.Assign(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Joins(fields ...field.RelationField) *productDiscountDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
p = *p.withDO(p.DO.Joins(_f))
|
||||||
|
}
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Preload(fields ...field.RelationField) *productDiscountDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
p = *p.withDO(p.DO.Preload(_f))
|
||||||
|
}
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) FirstOrInit() (*models.ProductDiscount, error) {
|
||||||
|
if result, err := p.DO.FirstOrInit(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.ProductDiscount), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) FirstOrCreate() (*models.ProductDiscount, error) {
|
||||||
|
if result, err := p.DO.FirstOrCreate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*models.ProductDiscount), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) FindByPage(offset int, limit int) (result []*models.ProductDiscount, count int64, err error) {
|
||||||
|
result, err = p.Offset(offset).Limit(limit).Find()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||||
|
count = int64(size + offset)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err = p.Offset(-1).Limit(-1).Count()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||||
|
count, err = p.Count()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = p.Offset(offset).Limit(limit).Scan(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Scan(result interface{}) (err error) {
|
||||||
|
return p.DO.Scan(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p productDiscountDo) Delete(models ...*models.ProductDiscount) (result gen.ResultInfo, err error) {
|
||||||
|
return p.DO.Delete(models)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *productDiscountDo) withDO(do gen.Dao) *productDiscountDo {
|
||||||
|
p.DO = *do.(*gen.DO)
|
||||||
|
return p
|
||||||
|
}
|
||||||
@@ -32,16 +32,22 @@ func newProductSku(db *gorm.DB, opts ...gen.DOOption) productSku {
|
|||||||
_productSku.UpdatedAt = field.NewTime(tableName, "updated_at")
|
_productSku.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
_productSku.DeletedAt = field.NewField(tableName, "deleted_at")
|
_productSku.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
_productSku.ProductID = field.NewInt32(tableName, "product_id")
|
_productSku.ProductID = field.NewInt32(tableName, "product_id")
|
||||||
|
_productSku.DiscountId = field.NewInt32(tableName, "discount_id")
|
||||||
_productSku.Code = field.NewString(tableName, "code")
|
_productSku.Code = field.NewString(tableName, "code")
|
||||||
_productSku.Name = field.NewString(tableName, "name")
|
_productSku.Name = field.NewString(tableName, "name")
|
||||||
_productSku.Price = field.NewField(tableName, "price")
|
_productSku.Price = field.NewField(tableName, "price")
|
||||||
_productSku.Discount = field.NewFloat32(tableName, "discount")
|
|
||||||
_productSku.Product = productSkuBelongsToProduct{
|
_productSku.Product = productSkuBelongsToProduct{
|
||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
RelationField: field.NewRelation("Product", "models.Product"),
|
RelationField: field.NewRelation("Product", "models.Product"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_productSku.Discount = productSkuBelongsToDiscount{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Discount", "models.ProductDiscount"),
|
||||||
|
}
|
||||||
|
|
||||||
_productSku.fillFieldMap()
|
_productSku.fillFieldMap()
|
||||||
|
|
||||||
return _productSku
|
return _productSku
|
||||||
@@ -50,17 +56,19 @@ func newProductSku(db *gorm.DB, opts ...gen.DOOption) productSku {
|
|||||||
type productSku struct {
|
type productSku struct {
|
||||||
productSkuDo
|
productSkuDo
|
||||||
|
|
||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
ID field.Int32
|
ID field.Int32
|
||||||
CreatedAt field.Time
|
CreatedAt field.Time
|
||||||
UpdatedAt field.Time
|
UpdatedAt field.Time
|
||||||
DeletedAt field.Field
|
DeletedAt field.Field
|
||||||
ProductID field.Int32
|
ProductID field.Int32
|
||||||
Code field.String
|
DiscountId field.Int32
|
||||||
Name field.String
|
Code field.String
|
||||||
Price field.Field
|
Name field.String
|
||||||
Discount field.Float32
|
Price field.Field
|
||||||
Product productSkuBelongsToProduct
|
Product productSkuBelongsToProduct
|
||||||
|
|
||||||
|
Discount productSkuBelongsToDiscount
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -82,10 +90,10 @@ func (p *productSku) updateTableName(table string) *productSku {
|
|||||||
p.UpdatedAt = field.NewTime(table, "updated_at")
|
p.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
p.DeletedAt = field.NewField(table, "deleted_at")
|
p.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
p.ProductID = field.NewInt32(table, "product_id")
|
p.ProductID = field.NewInt32(table, "product_id")
|
||||||
|
p.DiscountId = field.NewInt32(table, "discount_id")
|
||||||
p.Code = field.NewString(table, "code")
|
p.Code = field.NewString(table, "code")
|
||||||
p.Name = field.NewString(table, "name")
|
p.Name = field.NewString(table, "name")
|
||||||
p.Price = field.NewField(table, "price")
|
p.Price = field.NewField(table, "price")
|
||||||
p.Discount = field.NewFloat32(table, "discount")
|
|
||||||
|
|
||||||
p.fillFieldMap()
|
p.fillFieldMap()
|
||||||
|
|
||||||
@@ -102,16 +110,16 @@ func (p *productSku) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *productSku) fillFieldMap() {
|
func (p *productSku) fillFieldMap() {
|
||||||
p.fieldMap = make(map[string]field.Expr, 10)
|
p.fieldMap = make(map[string]field.Expr, 11)
|
||||||
p.fieldMap["id"] = p.ID
|
p.fieldMap["id"] = p.ID
|
||||||
p.fieldMap["created_at"] = p.CreatedAt
|
p.fieldMap["created_at"] = p.CreatedAt
|
||||||
p.fieldMap["updated_at"] = p.UpdatedAt
|
p.fieldMap["updated_at"] = p.UpdatedAt
|
||||||
p.fieldMap["deleted_at"] = p.DeletedAt
|
p.fieldMap["deleted_at"] = p.DeletedAt
|
||||||
p.fieldMap["product_id"] = p.ProductID
|
p.fieldMap["product_id"] = p.ProductID
|
||||||
|
p.fieldMap["discount_id"] = p.DiscountId
|
||||||
p.fieldMap["code"] = p.Code
|
p.fieldMap["code"] = p.Code
|
||||||
p.fieldMap["name"] = p.Name
|
p.fieldMap["name"] = p.Name
|
||||||
p.fieldMap["price"] = p.Price
|
p.fieldMap["price"] = p.Price
|
||||||
p.fieldMap["discount"] = p.Discount
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,12 +127,15 @@ func (p productSku) clone(db *gorm.DB) productSku {
|
|||||||
p.productSkuDo.ReplaceConnPool(db.Statement.ConnPool)
|
p.productSkuDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
p.Product.db = db.Session(&gorm.Session{Initialized: true})
|
p.Product.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
p.Product.db.Statement.ConnPool = db.Statement.ConnPool
|
p.Product.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
|
p.Discount.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
p.Discount.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p productSku) replaceDB(db *gorm.DB) productSku {
|
func (p productSku) replaceDB(db *gorm.DB) productSku {
|
||||||
p.productSkuDo.ReplaceDB(db)
|
p.productSkuDo.ReplaceDB(db)
|
||||||
p.Product.db = db.Session(&gorm.Session{})
|
p.Product.db = db.Session(&gorm.Session{})
|
||||||
|
p.Discount.db = db.Session(&gorm.Session{})
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,6 +220,87 @@ func (a productSkuBelongsToProductTx) Unscoped() *productSkuBelongsToProductTx {
|
|||||||
return &a
|
return &a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type productSkuBelongsToDiscount struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscount) Where(conds ...field.Expr) *productSkuBelongsToDiscount {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscount) WithContext(ctx context.Context) *productSkuBelongsToDiscount {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscount) Session(session *gorm.Session) *productSkuBelongsToDiscount {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscount) Model(m *models.ProductSku) *productSkuBelongsToDiscountTx {
|
||||||
|
return &productSkuBelongsToDiscountTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscount) Unscoped() *productSkuBelongsToDiscount {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type productSkuBelongsToDiscountTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscountTx) Find() (result *models.ProductDiscount, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscountTx) Append(values ...*models.ProductDiscount) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscountTx) Replace(values ...*models.ProductDiscount) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscountTx) Delete(values ...*models.ProductDiscount) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscountTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscountTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuBelongsToDiscountTx) Unscoped() *productSkuBelongsToDiscountTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type productSkuDo struct{ gen.DO }
|
type productSkuDo struct{ gen.DO }
|
||||||
|
|
||||||
func (p productSkuDo) Debug() *productSkuDo {
|
func (p productSkuDo) Debug() *productSkuDo {
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ func newProductSkuUser(db *gorm.DB, opts ...gen.DOOption) productSkuUser {
|
|||||||
_productSkuUser.ID = field.NewInt32(tableName, "id")
|
_productSkuUser.ID = field.NewInt32(tableName, "id")
|
||||||
_productSkuUser.UserID = field.NewInt32(tableName, "user_id")
|
_productSkuUser.UserID = field.NewInt32(tableName, "user_id")
|
||||||
_productSkuUser.ProductSkuID = field.NewInt32(tableName, "product_sku_id")
|
_productSkuUser.ProductSkuID = field.NewInt32(tableName, "product_sku_id")
|
||||||
_productSkuUser.Price = field.NewField(tableName, "price")
|
_productSkuUser.DiscountId = field.NewInt32(tableName, "discount_id")
|
||||||
_productSkuUser.Discount = field.NewFloat32(tableName, "discount")
|
|
||||||
_productSkuUser.CreatedAt = field.NewTime(tableName, "created_at")
|
_productSkuUser.CreatedAt = field.NewTime(tableName, "created_at")
|
||||||
_productSkuUser.UpdatedAt = field.NewTime(tableName, "updated_at")
|
_productSkuUser.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
_productSkuUser.User = productSkuUserBelongsToUser{
|
_productSkuUser.User = productSkuUserBelongsToUser{
|
||||||
@@ -40,8 +39,73 @@ func newProductSkuUser(db *gorm.DB, opts ...gen.DOOption) productSkuUser {
|
|||||||
RelationField: field.NewRelation("User", "models.User"),
|
RelationField: field.NewRelation("User", "models.User"),
|
||||||
Admin: struct {
|
Admin: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +118,17 @@ func newProductSkuUser(db *gorm.DB, opts ...gen.DOOption) productSkuUser {
|
|||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("ProductSku.Product", "models.Product"),
|
RelationField: field.NewRelation("ProductSku.Product", "models.Product"),
|
||||||
},
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("ProductSku.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_productSkuUser.Discount = productSkuUserBelongsToDiscount{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Discount", "models.ProductDiscount"),
|
||||||
}
|
}
|
||||||
|
|
||||||
_productSkuUser.fillFieldMap()
|
_productSkuUser.fillFieldMap()
|
||||||
@@ -68,14 +143,15 @@ type productSkuUser struct {
|
|||||||
ID field.Int32
|
ID field.Int32
|
||||||
UserID field.Int32
|
UserID field.Int32
|
||||||
ProductSkuID field.Int32
|
ProductSkuID field.Int32
|
||||||
Price field.Field
|
DiscountId field.Int32
|
||||||
Discount field.Float32
|
|
||||||
CreatedAt field.Time
|
CreatedAt field.Time
|
||||||
UpdatedAt field.Time
|
UpdatedAt field.Time
|
||||||
User productSkuUserBelongsToUser
|
User productSkuUserBelongsToUser
|
||||||
|
|
||||||
ProductSku productSkuUserBelongsToProductSku
|
ProductSku productSkuUserBelongsToProductSku
|
||||||
|
|
||||||
|
Discount productSkuUserBelongsToDiscount
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,8 +170,7 @@ func (p *productSkuUser) updateTableName(table string) *productSkuUser {
|
|||||||
p.ID = field.NewInt32(table, "id")
|
p.ID = field.NewInt32(table, "id")
|
||||||
p.UserID = field.NewInt32(table, "user_id")
|
p.UserID = field.NewInt32(table, "user_id")
|
||||||
p.ProductSkuID = field.NewInt32(table, "product_sku_id")
|
p.ProductSkuID = field.NewInt32(table, "product_sku_id")
|
||||||
p.Price = field.NewField(table, "price")
|
p.DiscountId = field.NewInt32(table, "discount_id")
|
||||||
p.Discount = field.NewFloat32(table, "discount")
|
|
||||||
p.CreatedAt = field.NewTime(table, "created_at")
|
p.CreatedAt = field.NewTime(table, "created_at")
|
||||||
p.UpdatedAt = field.NewTime(table, "updated_at")
|
p.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
|
|
||||||
@@ -118,8 +193,7 @@ func (p *productSkuUser) fillFieldMap() {
|
|||||||
p.fieldMap["id"] = p.ID
|
p.fieldMap["id"] = p.ID
|
||||||
p.fieldMap["user_id"] = p.UserID
|
p.fieldMap["user_id"] = p.UserID
|
||||||
p.fieldMap["product_sku_id"] = p.ProductSkuID
|
p.fieldMap["product_sku_id"] = p.ProductSkuID
|
||||||
p.fieldMap["price"] = p.Price
|
p.fieldMap["discount_id"] = p.DiscountId
|
||||||
p.fieldMap["discount"] = p.Discount
|
|
||||||
p.fieldMap["created_at"] = p.CreatedAt
|
p.fieldMap["created_at"] = p.CreatedAt
|
||||||
p.fieldMap["updated_at"] = p.UpdatedAt
|
p.fieldMap["updated_at"] = p.UpdatedAt
|
||||||
|
|
||||||
@@ -131,6 +205,8 @@ func (p productSkuUser) clone(db *gorm.DB) productSkuUser {
|
|||||||
p.User.db.Statement.ConnPool = db.Statement.ConnPool
|
p.User.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
p.ProductSku.db = db.Session(&gorm.Session{Initialized: true})
|
p.ProductSku.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
p.ProductSku.db.Statement.ConnPool = db.Statement.ConnPool
|
p.ProductSku.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
|
p.Discount.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
p.Discount.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +214,7 @@ func (p productSkuUser) replaceDB(db *gorm.DB) productSkuUser {
|
|||||||
p.productSkuUserDo.ReplaceDB(db)
|
p.productSkuUserDo.ReplaceDB(db)
|
||||||
p.User.db = db.Session(&gorm.Session{})
|
p.User.db = db.Session(&gorm.Session{})
|
||||||
p.ProductSku.db = db.Session(&gorm.Session{})
|
p.ProductSku.db = db.Session(&gorm.Session{})
|
||||||
|
p.Discount.db = db.Session(&gorm.Session{})
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +225,27 @@ type productSkuUserBelongsToUser struct {
|
|||||||
|
|
||||||
Admin struct {
|
Admin struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,6 +332,9 @@ type productSkuUserBelongsToProductSku struct {
|
|||||||
Product struct {
|
Product struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
}
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a productSkuUserBelongsToProductSku) Where(conds ...field.Expr) *productSkuUserBelongsToProductSku {
|
func (a productSkuUserBelongsToProductSku) Where(conds ...field.Expr) *productSkuUserBelongsToProductSku {
|
||||||
@@ -311,6 +412,87 @@ func (a productSkuUserBelongsToProductSkuTx) Unscoped() *productSkuUserBelongsTo
|
|||||||
return &a
|
return &a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type productSkuUserBelongsToDiscount struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscount) Where(conds ...field.Expr) *productSkuUserBelongsToDiscount {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscount) WithContext(ctx context.Context) *productSkuUserBelongsToDiscount {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscount) Session(session *gorm.Session) *productSkuUserBelongsToDiscount {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscount) Model(m *models.ProductSkuUser) *productSkuUserBelongsToDiscountTx {
|
||||||
|
return &productSkuUserBelongsToDiscountTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscount) Unscoped() *productSkuUserBelongsToDiscount {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type productSkuUserBelongsToDiscountTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscountTx) Find() (result *models.ProductDiscount, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscountTx) Append(values ...*models.ProductDiscount) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscountTx) Replace(values ...*models.ProductDiscount) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscountTx) Delete(values ...*models.ProductDiscount) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscountTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscountTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a productSkuUserBelongsToDiscountTx) Unscoped() *productSkuUserBelongsToDiscountTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type productSkuUserDo struct{ gen.DO }
|
type productSkuUserDo struct{ gen.DO }
|
||||||
|
|
||||||
func (p productSkuUserDo) Debug() *productSkuUserDo {
|
func (p productSkuUserDo) Debug() *productSkuUserDo {
|
||||||
|
|||||||
@@ -47,13 +47,99 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy {
|
|||||||
field.RelationField
|
field.RelationField
|
||||||
Admin struct {
|
Admin struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("Channels.User", "models.User"),
|
RelationField: field.NewRelation("Channels.User", "models.User"),
|
||||||
Admin: struct {
|
Admin: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("Channels.User.Admin", "models.Admin"),
|
RelationField: field.NewRelation("Channels.User.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.User.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.User.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.User.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.User.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.User.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.User.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.User.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Resource: struct {
|
Resource: struct {
|
||||||
@@ -63,9 +149,24 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy {
|
|||||||
}
|
}
|
||||||
Short struct {
|
Short struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Long struct {
|
Long struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
}
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("Channels.Resource", "models.Resource"),
|
RelationField: field.NewRelation("Channels.Resource", "models.Resource"),
|
||||||
@@ -76,13 +177,56 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy {
|
|||||||
},
|
},
|
||||||
Short: struct {
|
Short: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("Channels.Resource.Short", "models.ResourceShort"),
|
RelationField: field.NewRelation("Channels.Resource.Short", "models.ResourceShort"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.Resource.Short.Sku", "models.ProductSku"),
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.Resource.Short.Sku.Product", "models.Product"),
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.Resource.Short.Sku.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Long: struct {
|
Long: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("Channels.Resource.Long", "models.ResourceLong"),
|
RelationField: field.NewRelation("Channels.Resource.Long", "models.ResourceLong"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.Resource.Long.Sku", "models.ProductSku"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Channels.Resource.Product", "models.Product"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Proxy: struct {
|
Proxy: struct {
|
||||||
@@ -209,6 +353,27 @@ type proxyHasManyChannels struct {
|
|||||||
field.RelationField
|
field.RelationField
|
||||||
Admin struct {
|
Admin struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Resource struct {
|
Resource struct {
|
||||||
@@ -218,9 +383,24 @@ type proxyHasManyChannels struct {
|
|||||||
}
|
}
|
||||||
Short struct {
|
Short struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Long struct {
|
Long struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Proxy struct {
|
Proxy struct {
|
||||||
|
|||||||
@@ -35,16 +35,49 @@ func newResource(db *gorm.DB, opts ...gen.DOOption) resource {
|
|||||||
_resource.ResourceNo = field.NewString(tableName, "resource_no")
|
_resource.ResourceNo = field.NewString(tableName, "resource_no")
|
||||||
_resource.Active = field.NewBool(tableName, "active")
|
_resource.Active = field.NewBool(tableName, "active")
|
||||||
_resource.Type = field.NewInt(tableName, "type")
|
_resource.Type = field.NewInt(tableName, "type")
|
||||||
|
_resource.Code = field.NewString(tableName, "code")
|
||||||
_resource.Short = resourceHasOneShort{
|
_resource.Short = resourceHasOneShort{
|
||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
RelationField: field.NewRelation("Short", "models.ResourceShort"),
|
RelationField: field.NewRelation("Short", "models.ResourceShort"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Short.Sku", "models.ProductSku"),
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Short.Sku.Product", "models.Product"),
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Short.Sku.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_resource.Long = resourceHasOneLong{
|
_resource.Long = resourceHasOneLong{
|
||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
RelationField: field.NewRelation("Long", "models.ResourceLong"),
|
RelationField: field.NewRelation("Long", "models.ResourceLong"),
|
||||||
|
Sku: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Long.Sku", "models.ProductSku"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_resource.Product = resourceHasOneProduct{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Product", "models.Product"),
|
||||||
}
|
}
|
||||||
|
|
||||||
_resource.User = resourceBelongsToUser{
|
_resource.User = resourceBelongsToUser{
|
||||||
@@ -53,8 +86,73 @@ func newResource(db *gorm.DB, opts ...gen.DOOption) resource {
|
|||||||
RelationField: field.NewRelation("User", "models.User"),
|
RelationField: field.NewRelation("User", "models.User"),
|
||||||
Admin: struct {
|
Admin: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,10 +173,13 @@ type resource struct {
|
|||||||
ResourceNo field.String
|
ResourceNo field.String
|
||||||
Active field.Bool
|
Active field.Bool
|
||||||
Type field.Int
|
Type field.Int
|
||||||
|
Code field.String
|
||||||
Short resourceHasOneShort
|
Short resourceHasOneShort
|
||||||
|
|
||||||
Long resourceHasOneLong
|
Long resourceHasOneLong
|
||||||
|
|
||||||
|
Product resourceHasOneProduct
|
||||||
|
|
||||||
User resourceBelongsToUser
|
User resourceBelongsToUser
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
@@ -104,6 +205,7 @@ func (r *resource) updateTableName(table string) *resource {
|
|||||||
r.ResourceNo = field.NewString(table, "resource_no")
|
r.ResourceNo = field.NewString(table, "resource_no")
|
||||||
r.Active = field.NewBool(table, "active")
|
r.Active = field.NewBool(table, "active")
|
||||||
r.Type = field.NewInt(table, "type")
|
r.Type = field.NewInt(table, "type")
|
||||||
|
r.Code = field.NewString(table, "code")
|
||||||
|
|
||||||
r.fillFieldMap()
|
r.fillFieldMap()
|
||||||
|
|
||||||
@@ -120,7 +222,7 @@ func (r *resource) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *resource) fillFieldMap() {
|
func (r *resource) fillFieldMap() {
|
||||||
r.fieldMap = make(map[string]field.Expr, 11)
|
r.fieldMap = make(map[string]field.Expr, 13)
|
||||||
r.fieldMap["id"] = r.ID
|
r.fieldMap["id"] = r.ID
|
||||||
r.fieldMap["created_at"] = r.CreatedAt
|
r.fieldMap["created_at"] = r.CreatedAt
|
||||||
r.fieldMap["updated_at"] = r.UpdatedAt
|
r.fieldMap["updated_at"] = r.UpdatedAt
|
||||||
@@ -129,6 +231,7 @@ func (r *resource) fillFieldMap() {
|
|||||||
r.fieldMap["resource_no"] = r.ResourceNo
|
r.fieldMap["resource_no"] = r.ResourceNo
|
||||||
r.fieldMap["active"] = r.Active
|
r.fieldMap["active"] = r.Active
|
||||||
r.fieldMap["type"] = r.Type
|
r.fieldMap["type"] = r.Type
|
||||||
|
r.fieldMap["code"] = r.Code
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +241,8 @@ func (r resource) clone(db *gorm.DB) resource {
|
|||||||
r.Short.db.Statement.ConnPool = db.Statement.ConnPool
|
r.Short.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
r.Long.db = db.Session(&gorm.Session{Initialized: true})
|
r.Long.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
r.Long.db.Statement.ConnPool = db.Statement.ConnPool
|
r.Long.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
|
r.Product.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
r.Product.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
r.User.db = db.Session(&gorm.Session{Initialized: true})
|
r.User.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
r.User.db.Statement.ConnPool = db.Statement.ConnPool
|
r.User.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return r
|
return r
|
||||||
@@ -147,6 +252,7 @@ func (r resource) replaceDB(db *gorm.DB) resource {
|
|||||||
r.resourceDo.ReplaceDB(db)
|
r.resourceDo.ReplaceDB(db)
|
||||||
r.Short.db = db.Session(&gorm.Session{})
|
r.Short.db = db.Session(&gorm.Session{})
|
||||||
r.Long.db = db.Session(&gorm.Session{})
|
r.Long.db = db.Session(&gorm.Session{})
|
||||||
|
r.Product.db = db.Session(&gorm.Session{})
|
||||||
r.User.db = db.Session(&gorm.Session{})
|
r.User.db = db.Session(&gorm.Session{})
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -155,6 +261,16 @@ type resourceHasOneShort struct {
|
|||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a resourceHasOneShort) Where(conds ...field.Expr) *resourceHasOneShort {
|
func (a resourceHasOneShort) Where(conds ...field.Expr) *resourceHasOneShort {
|
||||||
@@ -236,6 +352,10 @@ type resourceHasOneLong struct {
|
|||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
|
||||||
|
Sku struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a resourceHasOneLong) Where(conds ...field.Expr) *resourceHasOneLong {
|
func (a resourceHasOneLong) Where(conds ...field.Expr) *resourceHasOneLong {
|
||||||
@@ -313,6 +433,87 @@ func (a resourceHasOneLongTx) Unscoped() *resourceHasOneLongTx {
|
|||||||
return &a
|
return &a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type resourceHasOneProduct struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProduct) Where(conds ...field.Expr) *resourceHasOneProduct {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProduct) WithContext(ctx context.Context) *resourceHasOneProduct {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProduct) Session(session *gorm.Session) *resourceHasOneProduct {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProduct) Model(m *models.Resource) *resourceHasOneProductTx {
|
||||||
|
return &resourceHasOneProductTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProduct) Unscoped() *resourceHasOneProduct {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type resourceHasOneProductTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a resourceHasOneProductTx) Find() (result *models.Product, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProductTx) Append(values ...*models.Product) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProductTx) Replace(values ...*models.Product) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProductTx) Delete(values ...*models.Product) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProductTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProductTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceHasOneProductTx) Unscoped() *resourceHasOneProductTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type resourceBelongsToUser struct {
|
type resourceBelongsToUser struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|
||||||
@@ -320,6 +521,27 @@ type resourceBelongsToUser struct {
|
|||||||
|
|
||||||
Admin struct {
|
Admin struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ func newResourceLong(db *gorm.DB, opts ...gen.DOOption) resourceLong {
|
|||||||
_resourceLong.ALL = field.NewAsterisk(tableName)
|
_resourceLong.ALL = field.NewAsterisk(tableName)
|
||||||
_resourceLong.ID = field.NewInt32(tableName, "id")
|
_resourceLong.ID = field.NewInt32(tableName, "id")
|
||||||
_resourceLong.ResourceID = field.NewInt32(tableName, "resource_id")
|
_resourceLong.ResourceID = field.NewInt32(tableName, "resource_id")
|
||||||
|
_resourceLong.Code = field.NewString(tableName, "code")
|
||||||
_resourceLong.Live = field.NewInt32(tableName, "live")
|
_resourceLong.Live = field.NewInt32(tableName, "live")
|
||||||
_resourceLong.Type = field.NewInt(tableName, "type")
|
_resourceLong.Type = field.NewInt(tableName, "type")
|
||||||
_resourceLong.Quota = field.NewInt32(tableName, "quota")
|
_resourceLong.Quota = field.NewInt32(tableName, "quota")
|
||||||
@@ -36,6 +37,21 @@ func newResourceLong(db *gorm.DB, opts ...gen.DOOption) resourceLong {
|
|||||||
_resourceLong.Used = field.NewInt32(tableName, "used")
|
_resourceLong.Used = field.NewInt32(tableName, "used")
|
||||||
_resourceLong.Daily = field.NewInt32(tableName, "daily")
|
_resourceLong.Daily = field.NewInt32(tableName, "daily")
|
||||||
_resourceLong.LastAt = field.NewTime(tableName, "last_at")
|
_resourceLong.LastAt = field.NewTime(tableName, "last_at")
|
||||||
|
_resourceLong.Sku = resourceLongHasOneSku{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Sku", "models.ProductSku"),
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Sku.Product", "models.Product"),
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Sku.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
_resourceLong.fillFieldMap()
|
_resourceLong.fillFieldMap()
|
||||||
|
|
||||||
@@ -48,6 +64,7 @@ type resourceLong struct {
|
|||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
ID field.Int32
|
ID field.Int32
|
||||||
ResourceID field.Int32
|
ResourceID field.Int32
|
||||||
|
Code field.String
|
||||||
Live field.Int32
|
Live field.Int32
|
||||||
Type field.Int
|
Type field.Int
|
||||||
Quota field.Int32
|
Quota field.Int32
|
||||||
@@ -55,6 +72,7 @@ type resourceLong struct {
|
|||||||
Used field.Int32
|
Used field.Int32
|
||||||
Daily field.Int32
|
Daily field.Int32
|
||||||
LastAt field.Time
|
LastAt field.Time
|
||||||
|
Sku resourceLongHasOneSku
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -73,6 +91,7 @@ func (r *resourceLong) updateTableName(table string) *resourceLong {
|
|||||||
r.ALL = field.NewAsterisk(table)
|
r.ALL = field.NewAsterisk(table)
|
||||||
r.ID = field.NewInt32(table, "id")
|
r.ID = field.NewInt32(table, "id")
|
||||||
r.ResourceID = field.NewInt32(table, "resource_id")
|
r.ResourceID = field.NewInt32(table, "resource_id")
|
||||||
|
r.Code = field.NewString(table, "code")
|
||||||
r.Live = field.NewInt32(table, "live")
|
r.Live = field.NewInt32(table, "live")
|
||||||
r.Type = field.NewInt(table, "type")
|
r.Type = field.NewInt(table, "type")
|
||||||
r.Quota = field.NewInt32(table, "quota")
|
r.Quota = field.NewInt32(table, "quota")
|
||||||
@@ -96,9 +115,10 @@ func (r *resourceLong) GetFieldByName(fieldName string) (field.OrderExpr, bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *resourceLong) fillFieldMap() {
|
func (r *resourceLong) fillFieldMap() {
|
||||||
r.fieldMap = make(map[string]field.Expr, 9)
|
r.fieldMap = make(map[string]field.Expr, 11)
|
||||||
r.fieldMap["id"] = r.ID
|
r.fieldMap["id"] = r.ID
|
||||||
r.fieldMap["resource_id"] = r.ResourceID
|
r.fieldMap["resource_id"] = r.ResourceID
|
||||||
|
r.fieldMap["code"] = r.Code
|
||||||
r.fieldMap["live"] = r.Live
|
r.fieldMap["live"] = r.Live
|
||||||
r.fieldMap["type"] = r.Type
|
r.fieldMap["type"] = r.Type
|
||||||
r.fieldMap["quota"] = r.Quota
|
r.fieldMap["quota"] = r.Quota
|
||||||
@@ -106,18 +126,110 @@ func (r *resourceLong) fillFieldMap() {
|
|||||||
r.fieldMap["used"] = r.Used
|
r.fieldMap["used"] = r.Used
|
||||||
r.fieldMap["daily"] = r.Daily
|
r.fieldMap["daily"] = r.Daily
|
||||||
r.fieldMap["last_at"] = r.LastAt
|
r.fieldMap["last_at"] = r.LastAt
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r resourceLong) clone(db *gorm.DB) resourceLong {
|
func (r resourceLong) clone(db *gorm.DB) resourceLong {
|
||||||
r.resourceLongDo.ReplaceConnPool(db.Statement.ConnPool)
|
r.resourceLongDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
r.Sku.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
r.Sku.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r resourceLong) replaceDB(db *gorm.DB) resourceLong {
|
func (r resourceLong) replaceDB(db *gorm.DB) resourceLong {
|
||||||
r.resourceLongDo.ReplaceDB(db)
|
r.resourceLongDo.ReplaceDB(db)
|
||||||
|
r.Sku.db = db.Session(&gorm.Session{})
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type resourceLongHasOneSku struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSku) Where(conds ...field.Expr) *resourceLongHasOneSku {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSku) WithContext(ctx context.Context) *resourceLongHasOneSku {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSku) Session(session *gorm.Session) *resourceLongHasOneSku {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSku) Model(m *models.ResourceLong) *resourceLongHasOneSkuTx {
|
||||||
|
return &resourceLongHasOneSkuTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSku) Unscoped() *resourceLongHasOneSku {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type resourceLongHasOneSkuTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSkuTx) Find() (result *models.ProductSku, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSkuTx) Append(values ...*models.ProductSku) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSkuTx) Replace(values ...*models.ProductSku) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSkuTx) Delete(values ...*models.ProductSku) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSkuTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSkuTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceLongHasOneSkuTx) Unscoped() *resourceLongHasOneSkuTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type resourceLongDo struct{ gen.DO }
|
type resourceLongDo struct{ gen.DO }
|
||||||
|
|
||||||
func (r resourceLongDo) Debug() *resourceLongDo {
|
func (r resourceLongDo) Debug() *resourceLongDo {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ func newResourceShort(db *gorm.DB, opts ...gen.DOOption) resourceShort {
|
|||||||
_resourceShort.ALL = field.NewAsterisk(tableName)
|
_resourceShort.ALL = field.NewAsterisk(tableName)
|
||||||
_resourceShort.ID = field.NewInt32(tableName, "id")
|
_resourceShort.ID = field.NewInt32(tableName, "id")
|
||||||
_resourceShort.ResourceID = field.NewInt32(tableName, "resource_id")
|
_resourceShort.ResourceID = field.NewInt32(tableName, "resource_id")
|
||||||
|
_resourceShort.Code = field.NewString(tableName, "code")
|
||||||
_resourceShort.Live = field.NewInt32(tableName, "live")
|
_resourceShort.Live = field.NewInt32(tableName, "live")
|
||||||
_resourceShort.Type = field.NewInt(tableName, "type")
|
_resourceShort.Type = field.NewInt(tableName, "type")
|
||||||
_resourceShort.Quota = field.NewInt32(tableName, "quota")
|
_resourceShort.Quota = field.NewInt32(tableName, "quota")
|
||||||
@@ -36,6 +37,21 @@ func newResourceShort(db *gorm.DB, opts ...gen.DOOption) resourceShort {
|
|||||||
_resourceShort.Used = field.NewInt32(tableName, "used")
|
_resourceShort.Used = field.NewInt32(tableName, "used")
|
||||||
_resourceShort.Daily = field.NewInt32(tableName, "daily")
|
_resourceShort.Daily = field.NewInt32(tableName, "daily")
|
||||||
_resourceShort.LastAt = field.NewTime(tableName, "last_at")
|
_resourceShort.LastAt = field.NewTime(tableName, "last_at")
|
||||||
|
_resourceShort.Sku = resourceShortHasOneSku{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Sku", "models.ProductSku"),
|
||||||
|
Product: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Sku.Product", "models.Product"),
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Sku.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
_resourceShort.fillFieldMap()
|
_resourceShort.fillFieldMap()
|
||||||
|
|
||||||
@@ -48,6 +64,7 @@ type resourceShort struct {
|
|||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
ID field.Int32
|
ID field.Int32
|
||||||
ResourceID field.Int32
|
ResourceID field.Int32
|
||||||
|
Code field.String
|
||||||
Live field.Int32
|
Live field.Int32
|
||||||
Type field.Int
|
Type field.Int
|
||||||
Quota field.Int32
|
Quota field.Int32
|
||||||
@@ -55,6 +72,7 @@ type resourceShort struct {
|
|||||||
Used field.Int32
|
Used field.Int32
|
||||||
Daily field.Int32
|
Daily field.Int32
|
||||||
LastAt field.Time
|
LastAt field.Time
|
||||||
|
Sku resourceShortHasOneSku
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -73,6 +91,7 @@ func (r *resourceShort) updateTableName(table string) *resourceShort {
|
|||||||
r.ALL = field.NewAsterisk(table)
|
r.ALL = field.NewAsterisk(table)
|
||||||
r.ID = field.NewInt32(table, "id")
|
r.ID = field.NewInt32(table, "id")
|
||||||
r.ResourceID = field.NewInt32(table, "resource_id")
|
r.ResourceID = field.NewInt32(table, "resource_id")
|
||||||
|
r.Code = field.NewString(table, "code")
|
||||||
r.Live = field.NewInt32(table, "live")
|
r.Live = field.NewInt32(table, "live")
|
||||||
r.Type = field.NewInt(table, "type")
|
r.Type = field.NewInt(table, "type")
|
||||||
r.Quota = field.NewInt32(table, "quota")
|
r.Quota = field.NewInt32(table, "quota")
|
||||||
@@ -96,9 +115,10 @@ func (r *resourceShort) GetFieldByName(fieldName string) (field.OrderExpr, bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *resourceShort) fillFieldMap() {
|
func (r *resourceShort) fillFieldMap() {
|
||||||
r.fieldMap = make(map[string]field.Expr, 9)
|
r.fieldMap = make(map[string]field.Expr, 11)
|
||||||
r.fieldMap["id"] = r.ID
|
r.fieldMap["id"] = r.ID
|
||||||
r.fieldMap["resource_id"] = r.ResourceID
|
r.fieldMap["resource_id"] = r.ResourceID
|
||||||
|
r.fieldMap["code"] = r.Code
|
||||||
r.fieldMap["live"] = r.Live
|
r.fieldMap["live"] = r.Live
|
||||||
r.fieldMap["type"] = r.Type
|
r.fieldMap["type"] = r.Type
|
||||||
r.fieldMap["quota"] = r.Quota
|
r.fieldMap["quota"] = r.Quota
|
||||||
@@ -106,18 +126,110 @@ func (r *resourceShort) fillFieldMap() {
|
|||||||
r.fieldMap["used"] = r.Used
|
r.fieldMap["used"] = r.Used
|
||||||
r.fieldMap["daily"] = r.Daily
|
r.fieldMap["daily"] = r.Daily
|
||||||
r.fieldMap["last_at"] = r.LastAt
|
r.fieldMap["last_at"] = r.LastAt
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r resourceShort) clone(db *gorm.DB) resourceShort {
|
func (r resourceShort) clone(db *gorm.DB) resourceShort {
|
||||||
r.resourceShortDo.ReplaceConnPool(db.Statement.ConnPool)
|
r.resourceShortDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
r.Sku.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
r.Sku.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r resourceShort) replaceDB(db *gorm.DB) resourceShort {
|
func (r resourceShort) replaceDB(db *gorm.DB) resourceShort {
|
||||||
r.resourceShortDo.ReplaceDB(db)
|
r.resourceShortDo.ReplaceDB(db)
|
||||||
|
r.Sku.db = db.Session(&gorm.Session{})
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type resourceShortHasOneSku struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
Product struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSku) Where(conds ...field.Expr) *resourceShortHasOneSku {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSku) WithContext(ctx context.Context) *resourceShortHasOneSku {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSku) Session(session *gorm.Session) *resourceShortHasOneSku {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSku) Model(m *models.ResourceShort) *resourceShortHasOneSkuTx {
|
||||||
|
return &resourceShortHasOneSkuTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSku) Unscoped() *resourceShortHasOneSku {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type resourceShortHasOneSkuTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSkuTx) Find() (result *models.ProductSku, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSkuTx) Append(values ...*models.ProductSku) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSkuTx) Replace(values ...*models.ProductSku) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSkuTx) Delete(values ...*models.ProductSku) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSkuTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSkuTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a resourceShortHasOneSkuTx) Unscoped() *resourceShortHasOneSkuTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type resourceShortDo struct{ gen.DO }
|
type resourceShortDo struct{ gen.DO }
|
||||||
|
|
||||||
func (r resourceShortDo) Debug() *resourceShortDo {
|
func (r resourceShortDo) Debug() *resourceShortDo {
|
||||||
|
|||||||
@@ -47,8 +47,73 @@ func newSession(db *gorm.DB, opts ...gen.DOOption) session {
|
|||||||
RelationField: field.NewRelation("User", "models.User"),
|
RelationField: field.NewRelation("User", "models.User"),
|
||||||
Admin: struct {
|
Admin: struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}{
|
}{
|
||||||
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +127,11 @@ func newSession(db *gorm.DB, opts ...gen.DOOption) session {
|
|||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
RelationField: field.NewRelation("Client", "models.Client"),
|
RelationField: field.NewRelation("Client", "models.Client"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Client.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_session.fillFieldMap()
|
_session.fillFieldMap()
|
||||||
@@ -182,6 +252,27 @@ type sessionBelongsToUser struct {
|
|||||||
|
|
||||||
Admin struct {
|
Admin struct {
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,6 +436,10 @@ type sessionBelongsToClient struct {
|
|||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a sessionBelongsToClient) Where(conds ...field.Expr) *sessionBelongsToClient {
|
func (a sessionBelongsToClient) Where(conds ...field.Expr) *sessionBelongsToClient {
|
||||||
|
|||||||
@@ -47,6 +47,81 @@ func newTrade(db *gorm.DB, opts ...gen.DOOption) trade {
|
|||||||
_trade.PaymentURL = field.NewString(tableName, "payment_url")
|
_trade.PaymentURL = field.NewString(tableName, "payment_url")
|
||||||
_trade.CompletedAt = field.NewTime(tableName, "completed_at")
|
_trade.CompletedAt = field.NewTime(tableName, "completed_at")
|
||||||
_trade.CanceledAt = field.NewTime(tableName, "canceled_at")
|
_trade.CanceledAt = field.NewTime(tableName, "canceled_at")
|
||||||
|
_trade.User = tradeBelongsToUser{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("User", "models.User"),
|
||||||
|
Admin: struct {
|
||||||
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Discount: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Discount", "models.ProductDiscount"),
|
||||||
|
},
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("User.Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
_trade.fillFieldMap()
|
_trade.fillFieldMap()
|
||||||
|
|
||||||
@@ -77,6 +152,7 @@ type trade struct {
|
|||||||
PaymentURL field.String
|
PaymentURL field.String
|
||||||
CompletedAt field.Time
|
CompletedAt field.Time
|
||||||
CanceledAt field.Time
|
CanceledAt field.Time
|
||||||
|
User tradeBelongsToUser
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -129,7 +205,7 @@ func (t *trade) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *trade) fillFieldMap() {
|
func (t *trade) fillFieldMap() {
|
||||||
t.fieldMap = make(map[string]field.Expr, 20)
|
t.fieldMap = make(map[string]field.Expr, 21)
|
||||||
t.fieldMap["id"] = t.ID
|
t.fieldMap["id"] = t.ID
|
||||||
t.fieldMap["created_at"] = t.CreatedAt
|
t.fieldMap["created_at"] = t.CreatedAt
|
||||||
t.fieldMap["updated_at"] = t.UpdatedAt
|
t.fieldMap["updated_at"] = t.UpdatedAt
|
||||||
@@ -150,18 +226,128 @@ func (t *trade) fillFieldMap() {
|
|||||||
t.fieldMap["payment_url"] = t.PaymentURL
|
t.fieldMap["payment_url"] = t.PaymentURL
|
||||||
t.fieldMap["completed_at"] = t.CompletedAt
|
t.fieldMap["completed_at"] = t.CompletedAt
|
||||||
t.fieldMap["canceled_at"] = t.CanceledAt
|
t.fieldMap["canceled_at"] = t.CanceledAt
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t trade) clone(db *gorm.DB) trade {
|
func (t trade) clone(db *gorm.DB) trade {
|
||||||
t.tradeDo.ReplaceConnPool(db.Statement.ConnPool)
|
t.tradeDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
t.User.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
t.User.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t trade) replaceDB(db *gorm.DB) trade {
|
func (t trade) replaceDB(db *gorm.DB) trade {
|
||||||
t.tradeDo.ReplaceDB(db)
|
t.tradeDo.ReplaceDB(db)
|
||||||
|
t.User.db = db.Session(&gorm.Session{})
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tradeBelongsToUser struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
Admin struct {
|
||||||
|
field.RelationField
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Discount struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUser) Where(conds ...field.Expr) *tradeBelongsToUser {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUser) WithContext(ctx context.Context) *tradeBelongsToUser {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUser) Session(session *gorm.Session) *tradeBelongsToUser {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUser) Model(m *models.Trade) *tradeBelongsToUserTx {
|
||||||
|
return &tradeBelongsToUserTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUser) Unscoped() *tradeBelongsToUser {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type tradeBelongsToUserTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a tradeBelongsToUserTx) Find() (result *models.User, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUserTx) Append(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUserTx) Replace(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUserTx) Delete(values ...*models.User) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUserTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUserTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a tradeBelongsToUserTx) Unscoped() *tradeBelongsToUserTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type tradeDo struct{ gen.DO }
|
type tradeDo struct{ gen.DO }
|
||||||
|
|
||||||
func (t tradeDo) Debug() *tradeDo {
|
func (t tradeDo) Debug() *tradeDo {
|
||||||
|
|||||||
@@ -32,10 +32,12 @@ func newUser(db *gorm.DB, opts ...gen.DOOption) user {
|
|||||||
_user.UpdatedAt = field.NewTime(tableName, "updated_at")
|
_user.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
_user.DeletedAt = field.NewField(tableName, "deleted_at")
|
_user.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
_user.AdminID = field.NewInt32(tableName, "admin_id")
|
_user.AdminID = field.NewInt32(tableName, "admin_id")
|
||||||
|
_user.DiscountID = field.NewInt32(tableName, "discount_id")
|
||||||
_user.Phone = field.NewString(tableName, "phone")
|
_user.Phone = field.NewString(tableName, "phone")
|
||||||
_user.Username = field.NewString(tableName, "username")
|
_user.Username = field.NewString(tableName, "username")
|
||||||
_user.Email = field.NewString(tableName, "email")
|
_user.Email = field.NewString(tableName, "email")
|
||||||
_user.Password = field.NewString(tableName, "password")
|
_user.Password = field.NewString(tableName, "password")
|
||||||
|
_user.Source = field.NewInt(tableName, "source")
|
||||||
_user.Name = field.NewString(tableName, "name")
|
_user.Name = field.NewString(tableName, "name")
|
||||||
_user.Avatar = field.NewString(tableName, "avatar")
|
_user.Avatar = field.NewString(tableName, "avatar")
|
||||||
_user.Status = field.NewInt(tableName, "status")
|
_user.Status = field.NewInt(tableName, "status")
|
||||||
@@ -52,6 +54,58 @@ func newUser(db *gorm.DB, opts ...gen.DOOption) user {
|
|||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
RelationField: field.NewRelation("Admin", "models.Admin"),
|
RelationField: field.NewRelation("Admin", "models.Admin"),
|
||||||
|
Roles: struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Roles", "models.AdminRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Roles.Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Admin.Roles.Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_user.Discount = userBelongsToDiscount{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Discount", "models.ProductDiscount"),
|
||||||
|
}
|
||||||
|
|
||||||
|
_user.Roles = userManyToManyRoles{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Roles", "models.UserRole"),
|
||||||
|
Permissions: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Roles.Permissions", "models.Permission"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_user.fillFieldMap()
|
_user.fillFieldMap()
|
||||||
@@ -68,10 +122,12 @@ type user struct {
|
|||||||
UpdatedAt field.Time
|
UpdatedAt field.Time
|
||||||
DeletedAt field.Field
|
DeletedAt field.Field
|
||||||
AdminID field.Int32
|
AdminID field.Int32
|
||||||
|
DiscountID field.Int32
|
||||||
Phone field.String
|
Phone field.String
|
||||||
Username field.String
|
Username field.String
|
||||||
Email field.String
|
Email field.String
|
||||||
Password field.String
|
Password field.String
|
||||||
|
Source field.Int
|
||||||
Name field.String
|
Name field.String
|
||||||
Avatar field.String
|
Avatar field.String
|
||||||
Status field.Int
|
Status field.Int
|
||||||
@@ -86,6 +142,10 @@ type user struct {
|
|||||||
LastLoginUA field.String
|
LastLoginUA field.String
|
||||||
Admin userBelongsToAdmin
|
Admin userBelongsToAdmin
|
||||||
|
|
||||||
|
Discount userBelongsToDiscount
|
||||||
|
|
||||||
|
Roles userManyToManyRoles
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,10 +166,12 @@ func (u *user) updateTableName(table string) *user {
|
|||||||
u.UpdatedAt = field.NewTime(table, "updated_at")
|
u.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
u.DeletedAt = field.NewField(table, "deleted_at")
|
u.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
u.AdminID = field.NewInt32(table, "admin_id")
|
u.AdminID = field.NewInt32(table, "admin_id")
|
||||||
|
u.DiscountID = field.NewInt32(table, "discount_id")
|
||||||
u.Phone = field.NewString(table, "phone")
|
u.Phone = field.NewString(table, "phone")
|
||||||
u.Username = field.NewString(table, "username")
|
u.Username = field.NewString(table, "username")
|
||||||
u.Email = field.NewString(table, "email")
|
u.Email = field.NewString(table, "email")
|
||||||
u.Password = field.NewString(table, "password")
|
u.Password = field.NewString(table, "password")
|
||||||
|
u.Source = field.NewInt(table, "source")
|
||||||
u.Name = field.NewString(table, "name")
|
u.Name = field.NewString(table, "name")
|
||||||
u.Avatar = field.NewString(table, "avatar")
|
u.Avatar = field.NewString(table, "avatar")
|
||||||
u.Status = field.NewInt(table, "status")
|
u.Status = field.NewInt(table, "status")
|
||||||
@@ -138,16 +200,18 @@ func (u *user) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *user) fillFieldMap() {
|
func (u *user) fillFieldMap() {
|
||||||
u.fieldMap = make(map[string]field.Expr, 22)
|
u.fieldMap = make(map[string]field.Expr, 26)
|
||||||
u.fieldMap["id"] = u.ID
|
u.fieldMap["id"] = u.ID
|
||||||
u.fieldMap["created_at"] = u.CreatedAt
|
u.fieldMap["created_at"] = u.CreatedAt
|
||||||
u.fieldMap["updated_at"] = u.UpdatedAt
|
u.fieldMap["updated_at"] = u.UpdatedAt
|
||||||
u.fieldMap["deleted_at"] = u.DeletedAt
|
u.fieldMap["deleted_at"] = u.DeletedAt
|
||||||
u.fieldMap["admin_id"] = u.AdminID
|
u.fieldMap["admin_id"] = u.AdminID
|
||||||
|
u.fieldMap["discount_id"] = u.DiscountID
|
||||||
u.fieldMap["phone"] = u.Phone
|
u.fieldMap["phone"] = u.Phone
|
||||||
u.fieldMap["username"] = u.Username
|
u.fieldMap["username"] = u.Username
|
||||||
u.fieldMap["email"] = u.Email
|
u.fieldMap["email"] = u.Email
|
||||||
u.fieldMap["password"] = u.Password
|
u.fieldMap["password"] = u.Password
|
||||||
|
u.fieldMap["source"] = u.Source
|
||||||
u.fieldMap["name"] = u.Name
|
u.fieldMap["name"] = u.Name
|
||||||
u.fieldMap["avatar"] = u.Avatar
|
u.fieldMap["avatar"] = u.Avatar
|
||||||
u.fieldMap["status"] = u.Status
|
u.fieldMap["status"] = u.Status
|
||||||
@@ -167,12 +231,18 @@ func (u user) clone(db *gorm.DB) user {
|
|||||||
u.userDo.ReplaceConnPool(db.Statement.ConnPool)
|
u.userDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
u.Admin.db = db.Session(&gorm.Session{Initialized: true})
|
u.Admin.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
u.Admin.db.Statement.ConnPool = db.Statement.ConnPool
|
u.Admin.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
|
u.Discount.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
u.Discount.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
|
u.Roles.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
u.Roles.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u user) replaceDB(db *gorm.DB) user {
|
func (u user) replaceDB(db *gorm.DB) user {
|
||||||
u.userDo.ReplaceDB(db)
|
u.userDo.ReplaceDB(db)
|
||||||
u.Admin.db = db.Session(&gorm.Session{})
|
u.Admin.db = db.Session(&gorm.Session{})
|
||||||
|
u.Discount.db = db.Session(&gorm.Session{})
|
||||||
|
u.Roles.db = db.Session(&gorm.Session{})
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,6 +250,19 @@ type userBelongsToAdmin struct {
|
|||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|
||||||
field.RelationField
|
field.RelationField
|
||||||
|
|
||||||
|
Roles struct {
|
||||||
|
field.RelationField
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a userBelongsToAdmin) Where(conds ...field.Expr) *userBelongsToAdmin {
|
func (a userBelongsToAdmin) Where(conds ...field.Expr) *userBelongsToAdmin {
|
||||||
@@ -257,6 +340,172 @@ func (a userBelongsToAdminTx) Unscoped() *userBelongsToAdminTx {
|
|||||||
return &a
|
return &a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type userBelongsToDiscount struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscount) Where(conds ...field.Expr) *userBelongsToDiscount {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscount) WithContext(ctx context.Context) *userBelongsToDiscount {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscount) Session(session *gorm.Session) *userBelongsToDiscount {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscount) Model(m *models.User) *userBelongsToDiscountTx {
|
||||||
|
return &userBelongsToDiscountTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscount) Unscoped() *userBelongsToDiscount {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type userBelongsToDiscountTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a userBelongsToDiscountTx) Find() (result *models.ProductDiscount, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscountTx) Append(values ...*models.ProductDiscount) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscountTx) Replace(values ...*models.ProductDiscount) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscountTx) Delete(values ...*models.ProductDiscount) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscountTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscountTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userBelongsToDiscountTx) Unscoped() *userBelongsToDiscountTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type userManyToManyRoles struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
Permissions struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRoles) Where(conds ...field.Expr) *userManyToManyRoles {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRoles) WithContext(ctx context.Context) *userManyToManyRoles {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRoles) Session(session *gorm.Session) *userManyToManyRoles {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRoles) Model(m *models.User) *userManyToManyRolesTx {
|
||||||
|
return &userManyToManyRolesTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRoles) Unscoped() *userManyToManyRoles {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type userManyToManyRolesTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a userManyToManyRolesTx) Find() (result []*models.UserRole, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRolesTx) Append(values ...*models.UserRole) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRolesTx) Replace(values ...*models.UserRole) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRolesTx) Delete(values ...*models.UserRole) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRolesTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRolesTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userManyToManyRolesTx) Unscoped() *userManyToManyRolesTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type userDo struct{ gen.DO }
|
type userDo struct{ gen.DO }
|
||||||
|
|
||||||
func (u userDo) Debug() *userDo {
|
func (u userDo) Debug() *userDo {
|
||||||
|
|||||||
@@ -35,6 +35,21 @@ func newUserRole(db *gorm.DB, opts ...gen.DOOption) userRole {
|
|||||||
_userRole.Description = field.NewString(tableName, "description")
|
_userRole.Description = field.NewString(tableName, "description")
|
||||||
_userRole.Active = field.NewBool(tableName, "active")
|
_userRole.Active = field.NewBool(tableName, "active")
|
||||||
_userRole.Sort = field.NewInt32(tableName, "sort")
|
_userRole.Sort = field.NewInt32(tableName, "sort")
|
||||||
|
_userRole.Permissions = userRoleManyToManyPermissions{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Permissions", "models.Permission"),
|
||||||
|
Parent: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Permissions.Parent", "models.Permission"),
|
||||||
|
},
|
||||||
|
Children: struct {
|
||||||
|
field.RelationField
|
||||||
|
}{
|
||||||
|
RelationField: field.NewRelation("Permissions.Children", "models.Permission"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
_userRole.fillFieldMap()
|
_userRole.fillFieldMap()
|
||||||
|
|
||||||
@@ -53,6 +68,7 @@ type userRole struct {
|
|||||||
Description field.String
|
Description field.String
|
||||||
Active field.Bool
|
Active field.Bool
|
||||||
Sort field.Int32
|
Sort field.Int32
|
||||||
|
Permissions userRoleManyToManyPermissions
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -93,7 +109,7 @@ func (u *userRole) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *userRole) fillFieldMap() {
|
func (u *userRole) fillFieldMap() {
|
||||||
u.fieldMap = make(map[string]field.Expr, 8)
|
u.fieldMap = make(map[string]field.Expr, 9)
|
||||||
u.fieldMap["id"] = u.ID
|
u.fieldMap["id"] = u.ID
|
||||||
u.fieldMap["created_at"] = u.CreatedAt
|
u.fieldMap["created_at"] = u.CreatedAt
|
||||||
u.fieldMap["updated_at"] = u.UpdatedAt
|
u.fieldMap["updated_at"] = u.UpdatedAt
|
||||||
@@ -102,18 +118,110 @@ func (u *userRole) fillFieldMap() {
|
|||||||
u.fieldMap["description"] = u.Description
|
u.fieldMap["description"] = u.Description
|
||||||
u.fieldMap["active"] = u.Active
|
u.fieldMap["active"] = u.Active
|
||||||
u.fieldMap["sort"] = u.Sort
|
u.fieldMap["sort"] = u.Sort
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u userRole) clone(db *gorm.DB) userRole {
|
func (u userRole) clone(db *gorm.DB) userRole {
|
||||||
u.userRoleDo.ReplaceConnPool(db.Statement.ConnPool)
|
u.userRoleDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
u.Permissions.db = db.Session(&gorm.Session{Initialized: true})
|
||||||
|
u.Permissions.db.Statement.ConnPool = db.Statement.ConnPool
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u userRole) replaceDB(db *gorm.DB) userRole {
|
func (u userRole) replaceDB(db *gorm.DB) userRole {
|
||||||
u.userRoleDo.ReplaceDB(db)
|
u.userRoleDo.ReplaceDB(db)
|
||||||
|
u.Permissions.db = db.Session(&gorm.Session{})
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type userRoleManyToManyPermissions struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
|
||||||
|
Parent struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
Children struct {
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissions) Where(conds ...field.Expr) *userRoleManyToManyPermissions {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissions) WithContext(ctx context.Context) *userRoleManyToManyPermissions {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissions) Session(session *gorm.Session) *userRoleManyToManyPermissions {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissions) Model(m *models.UserRole) *userRoleManyToManyPermissionsTx {
|
||||||
|
return &userRoleManyToManyPermissionsTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissions) Unscoped() *userRoleManyToManyPermissions {
|
||||||
|
a.db = a.db.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
type userRoleManyToManyPermissionsTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissionsTx) Find() (result []*models.Permission, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissionsTx) Append(values ...*models.Permission) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissionsTx) Replace(values ...*models.Permission) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissionsTx) Delete(values ...*models.Permission) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissionsTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissionsTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userRoleManyToManyPermissionsTx) Unscoped() *userRoleManyToManyPermissionsTx {
|
||||||
|
a.tx = a.tx.Unscoped()
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
type userRoleDo struct{ gen.DO }
|
type userRoleDo struct{ gen.DO }
|
||||||
|
|
||||||
func (u userRoleDo) Debug() *userRoleDo {
|
func (u userRoleDo) Debug() *userRoleDo {
|
||||||
|
|||||||
107
web/routes.go
107
web/routes.go
@@ -4,6 +4,9 @@ import (
|
|||||||
"platform/pkg/env"
|
"platform/pkg/env"
|
||||||
auth2 "platform/web/auth"
|
auth2 "platform/web/auth"
|
||||||
"platform/web/handlers"
|
"platform/web/handlers"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
q "platform/web/queries"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
@@ -12,6 +15,7 @@ func ApplyRouters(app *fiber.App) {
|
|||||||
api := app.Group("/api")
|
api := app.Group("/api")
|
||||||
userRouter(api)
|
userRouter(api)
|
||||||
adminRouter(api)
|
adminRouter(api)
|
||||||
|
clientRouter(api)
|
||||||
|
|
||||||
// 回调
|
// 回调
|
||||||
callbacks := app.Group("/callback")
|
callbacks := app.Group("/callback")
|
||||||
@@ -23,6 +27,13 @@ func ApplyRouters(app *fiber.App) {
|
|||||||
debug.Get("/sms/:phone", handlers.DebugGetSmsCode)
|
debug.Get("/sms/:phone", handlers.DebugGetSmsCode)
|
||||||
debug.Get("/proxy/register", handlers.DebugRegisterProxyBaiYin)
|
debug.Get("/proxy/register", handlers.DebugRegisterProxyBaiYin)
|
||||||
debug.Get("/iden/clear/:phone", handlers.DebugIdentifyClear)
|
debug.Get("/iden/clear/:phone", handlers.DebugIdentifyClear)
|
||||||
|
debug.Get("/session/now", func(ctx *fiber.Ctx) error {
|
||||||
|
rs, err := q.Session.Where(q.Session.AccessTokenExpires.Gt(time.Now())).Find()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return ctx.JSON(rs)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +46,6 @@ func userRouter(api fiber.Router) {
|
|||||||
auth.Post("/token", auth2.Token)
|
auth.Post("/token", auth2.Token)
|
||||||
auth.Post("/revoke", auth2.Revoke)
|
auth.Post("/revoke", auth2.Revoke)
|
||||||
auth.Post("/introspect", auth2.Introspect)
|
auth.Post("/introspect", auth2.Introspect)
|
||||||
auth.Post("/verify/sms", handlers.SmsCode)
|
|
||||||
|
|
||||||
// 用户
|
// 用户
|
||||||
user := api.Group("/user")
|
user := api.Group("/user")
|
||||||
@@ -57,19 +67,18 @@ func userRouter(api fiber.Router) {
|
|||||||
resource.Post("/list/short", handlers.PageResourceShort)
|
resource.Post("/list/short", handlers.PageResourceShort)
|
||||||
resource.Post("/list/long", handlers.PageResourceLong)
|
resource.Post("/list/long", handlers.PageResourceLong)
|
||||||
resource.Post("/create", handlers.CreateResource)
|
resource.Post("/create", handlers.CreateResource)
|
||||||
resource.Post("/price", handlers.ResourcePrice)
|
|
||||||
resource.Post("/statistics/free", handlers.StatisticResourceFree)
|
resource.Post("/statistics/free", handlers.StatisticResourceFree)
|
||||||
resource.Post("/statistics/usage", handlers.StatisticResourceUsage)
|
resource.Post("/statistics/usage", handlers.StatisticResourceUsage)
|
||||||
|
|
||||||
// 批次
|
// 批次
|
||||||
batch := api.Group("/batch")
|
batch := api.Group("/batch")
|
||||||
batch.Post("/page", handlers.PageResourceBatch)
|
batch.Post("/page", handlers.PageBatch)
|
||||||
|
|
||||||
// 通道
|
// 通道
|
||||||
channel := api.Group("/channel")
|
channel := api.Group("/channel")
|
||||||
channel.Post("/list", handlers.ListChannels)
|
channel.Post("/list", handlers.ListChannel)
|
||||||
channel.Post("/create", handlers.CreateChannel)
|
channel.Post("/create", handlers.CreateChannel)
|
||||||
channel.Post("/remove", handlers.RemoveChannels)
|
|
||||||
|
|
||||||
// 交易
|
// 交易
|
||||||
trade := api.Group("/trade")
|
trade := api.Group("/trade")
|
||||||
@@ -91,7 +100,6 @@ func userRouter(api fiber.Router) {
|
|||||||
proxy.Post("/online", handlers.ProxyReportOnline)
|
proxy.Post("/online", handlers.ProxyReportOnline)
|
||||||
proxy.Post("/offline", handlers.ProxyReportOffline)
|
proxy.Post("/offline", handlers.ProxyReportOffline)
|
||||||
proxy.Post("/update", handlers.ProxyReportUpdate)
|
proxy.Post("/update", handlers.ProxyReportUpdate)
|
||||||
proxy.Post("/register/baidyin", handlers.ProxyRegisterBaiYin)
|
|
||||||
|
|
||||||
// 节点
|
// 节点
|
||||||
edge := api.Group("/edge")
|
edge := api.Group("/edge")
|
||||||
@@ -103,33 +111,112 @@ func userRouter(api fiber.Router) {
|
|||||||
inquiry.Post("/create", handlers.CreateInquiry)
|
inquiry.Post("/create", handlers.CreateInquiry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 客户端接口路由
|
||||||
|
func clientRouter(api fiber.Router) {
|
||||||
|
client := api
|
||||||
|
|
||||||
|
// 验证短信令牌
|
||||||
|
client.Post("/verify/sms", handlers.SmsCode)
|
||||||
|
|
||||||
|
// 套餐定价查询
|
||||||
|
resource := client.Group("/resource")
|
||||||
|
resource.Post("/price", handlers.ResourcePrice)
|
||||||
|
|
||||||
|
// 通道管理
|
||||||
|
channel := client.Group("/channel")
|
||||||
|
channel.Post("/remove", handlers.RemoveChannels)
|
||||||
|
|
||||||
|
// 代理网关注册
|
||||||
|
proxy := client.Group("/proxy")
|
||||||
|
proxy.Post("/register/baidyin", handlers.ProxyRegisterBaiYin)
|
||||||
|
}
|
||||||
|
|
||||||
// 管理员接口路由
|
// 管理员接口路由
|
||||||
func adminRouter(api fiber.Router) {
|
func adminRouter(api fiber.Router) {
|
||||||
api = api.Group("/admin")
|
api = api.Group("/admin")
|
||||||
|
|
||||||
|
// admin 管理员
|
||||||
|
var admin = api.Group("/admin")
|
||||||
|
admin.Post("/all", handlers.AllAdminByAdmin)
|
||||||
|
admin.Post("/page", handlers.PageAdminByAdmin)
|
||||||
|
admin.Post("/create", handlers.CreateAdmin)
|
||||||
|
admin.Post("/update", handlers.UpdateAdmin)
|
||||||
|
admin.Post("/remove", handlers.RemoveAdmin)
|
||||||
|
|
||||||
|
// admin-role 管理员角色
|
||||||
|
var adminRole = api.Group("/admin-role")
|
||||||
|
adminRole.Post("/list", handlers.AllAdminRoleByAdmin)
|
||||||
|
adminRole.Post("/page", handlers.PageAdminRoleByAdmin)
|
||||||
|
adminRole.Post("/create", handlers.CreateAdminRole)
|
||||||
|
adminRole.Post("/update", handlers.UpdateAdminRole)
|
||||||
|
adminRole.Post("/remove", handlers.RemoveAdminRole)
|
||||||
|
|
||||||
|
// permission 权限
|
||||||
|
var permission = api.Group("/permission")
|
||||||
|
permission.Post("/list", handlers.AllPermissionByAdmin)
|
||||||
|
permission.Post("/page", handlers.PagePermissionByAdmin)
|
||||||
|
|
||||||
// user 用户
|
// user 用户
|
||||||
var user = api.Group("/user")
|
var user = api.Group("/user")
|
||||||
user.Post("/page", handlers.PageUserByAdmin)
|
user.Post("/page", handlers.PageUserByAdmin)
|
||||||
|
user.Post("/get", handlers.GetUserByAdmin)
|
||||||
|
user.Post("/create", handlers.CreateUserByAdmin)
|
||||||
|
user.Post("/update", handlers.UpdateUserByAdmin)
|
||||||
|
user.Post("/remove", handlers.RemoveUserByAdmin)
|
||||||
|
|
||||||
user.Post("/bind", handlers.BindAdmin)
|
user.Post("/bind", handlers.BindAdmin)
|
||||||
|
user.Post("/update/balance", handlers.UpdateUserBalanceByAdmin)
|
||||||
|
|
||||||
// resource 套餐
|
// resource 套餐
|
||||||
var resource = api.Group("/resource")
|
var resource = api.Group("/resource")
|
||||||
resource.Post("/short/page", handlers.PageResourceShortByAdmin)
|
resource.Post("/short/page", handlers.PageResourceShortByAdmin)
|
||||||
resource.Post("/long/page", handlers.PageResourceLongByAdmin)
|
resource.Post("/long/page", handlers.PageResourceLongByAdmin)
|
||||||
|
resource.Post("/update", handlers.UpdateResourceByAdmin)
|
||||||
|
|
||||||
// batch 批次
|
// batch 批次
|
||||||
var usage = api.Group("batch")
|
var batch = api.Group("/batch")
|
||||||
usage.Post("/page", handlers.PageBatchByAdmin)
|
batch.Post("/page", handlers.PageBatchByAdmin)
|
||||||
|
|
||||||
// channel 通道
|
// channel 通道
|
||||||
var channel = api.Group("/channel")
|
var channel = api.Group("/channel")
|
||||||
channel.Post("/page", handlers.PageChannelsByAdmin)
|
channel.Post("/page", handlers.PageChannelByAdmin)
|
||||||
|
|
||||||
// trade 交易
|
// trade 交易
|
||||||
var trade = api.Group("trade")
|
var trade = api.Group("/trade")
|
||||||
trade.Post("/page", handlers.PageTradeByAdmin)
|
trade.Post("/page", handlers.PageTradeByAdmin)
|
||||||
|
|
||||||
// bill 账单
|
// bill 账单
|
||||||
var bill = api.Group("/bill")
|
var bill = api.Group("/bill")
|
||||||
bill.Post("/page", handlers.PageBillByAdmin)
|
bill.Post("/page", handlers.PageBillByAdmin)
|
||||||
|
|
||||||
|
// product 产品
|
||||||
|
var product = api.Group("/product")
|
||||||
|
product.Post("/all", handlers.AllProductByAdmin)
|
||||||
|
product.Post("/create", handlers.CreateProduct)
|
||||||
|
product.Post("/update", handlers.UpdateProduct)
|
||||||
|
product.Post("/remove", handlers.DeleteProduct)
|
||||||
|
|
||||||
|
product.Post("/sku/all", handlers.AllProductSkuByAdmin)
|
||||||
|
product.Post("/sku/page", handlers.PageProductSkuByAdmin)
|
||||||
|
product.Post("/sku/create", handlers.CreateProductSku)
|
||||||
|
product.Post("/sku/update", handlers.UpdateProductSku)
|
||||||
|
product.Post("/sku/remove", handlers.DeleteProductSku)
|
||||||
|
|
||||||
|
product.Post("/sku/update/discount/batch", handlers.BatchUpdateProductSkuDiscount)
|
||||||
|
|
||||||
|
// discount 折扣
|
||||||
|
var discount = api.Group("/discount")
|
||||||
|
discount.Post("/all", handlers.AllDiscountByAdmin)
|
||||||
|
discount.Post("/page", handlers.PageDiscountByAdmin)
|
||||||
|
discount.Post("/create", handlers.CreateDiscount)
|
||||||
|
discount.Post("/update", handlers.UpdateDiscount)
|
||||||
|
discount.Post("/remove", handlers.DeleteDiscount)
|
||||||
|
|
||||||
|
// coupon 优惠券
|
||||||
|
var coupon = api.Group("/coupon")
|
||||||
|
coupon.Post("/all", handlers.AllCouponByAdmin)
|
||||||
|
coupon.Post("/page", handlers.PageCouponByAdmin)
|
||||||
|
coupon.Post("/create", handlers.CreateCoupon)
|
||||||
|
coupon.Post("/update", handlers.UpdateCoupon)
|
||||||
|
coupon.Post("/remove", handlers.DeleteCoupon)
|
||||||
}
|
}
|
||||||
|
|||||||
159
web/services/admin.go
Normal file
159
web/services/admin.go
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/pkg/u"
|
||||||
|
"platform/web/core"
|
||||||
|
m "platform/web/models"
|
||||||
|
q "platform/web/queries"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Admin = &adminService{}
|
||||||
|
|
||||||
|
type adminService struct{}
|
||||||
|
|
||||||
|
func (s *adminService) PageAdmins(req core.PageReq) (result []*m.Admin, count int64, err error) {
|
||||||
|
return q.Admin.
|
||||||
|
Preload(q.Admin.Roles).
|
||||||
|
Omit(q.Admin.Password).
|
||||||
|
Order(q.Admin.CreatedAt.Desc()).
|
||||||
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *adminService) All() (result []*m.Admin, err error) {
|
||||||
|
return q.Admin.
|
||||||
|
Omit(q.Admin.Password).
|
||||||
|
Order(q.Admin.CreatedAt.Desc()).
|
||||||
|
Find()
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateAdmin struct {
|
||||||
|
Username string `json:"username" validate:"required,min=3,max=50"`
|
||||||
|
Password string `json:"password" validate:"required,min=6,max=50"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Avatar *string `json:"avatar"`
|
||||||
|
Phone *string `json:"phone"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
Status *m.AdminStatus `json:"status"`
|
||||||
|
Roles []int32 `json:"roles"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *adminService) CreateAdmin(create *CreateAdmin) error {
|
||||||
|
// 哈希密码
|
||||||
|
hash, err := bcrypt.GenerateFromPassword([]byte(create.Password), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("密码加密失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return q.Q.Transaction(func(tx *q.Query) error {
|
||||||
|
// 创建管理员
|
||||||
|
admin := &m.Admin{
|
||||||
|
Username: create.Username,
|
||||||
|
Password: string(hash),
|
||||||
|
Name: create.Name,
|
||||||
|
Avatar: create.Avatar,
|
||||||
|
Phone: create.Phone,
|
||||||
|
Email: create.Email,
|
||||||
|
Status: u.Else(create.Status, m.AdminStatusEnabled),
|
||||||
|
}
|
||||||
|
if err := tx.Admin.Create(admin); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关联角色
|
||||||
|
if len(create.Roles) > 0 {
|
||||||
|
links := make([]*m.LinkAdminRole, len(create.Roles))
|
||||||
|
for i, roleID := range create.Roles {
|
||||||
|
links[i] = &m.LinkAdminRole{
|
||||||
|
AdminID: admin.ID,
|
||||||
|
RoleID: roleID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := tx.LinkAdminRole.CreateInBatches(links, 1000); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateAdmin struct {
|
||||||
|
Id int32 `json:"id" validate:"required"`
|
||||||
|
Password *string `json:"password"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Avatar *string `json:"avatar"`
|
||||||
|
Phone *string `json:"phone"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
Status *m.AdminStatus `json:"status"`
|
||||||
|
Roles *[]int32 `json:"roles"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *adminService) UpdateAdmin(update *UpdateAdmin) error {
|
||||||
|
simples := make([]field.AssignExpr, 0)
|
||||||
|
|
||||||
|
if update.Password != nil {
|
||||||
|
hash, err := bcrypt.GenerateFromPassword([]byte(*update.Password), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("密码加密失败", err)
|
||||||
|
}
|
||||||
|
simples = append(simples, q.Admin.Password.Value(string(hash)))
|
||||||
|
}
|
||||||
|
if update.Name != nil {
|
||||||
|
simples = append(simples, q.Admin.Name.Value(*update.Name))
|
||||||
|
}
|
||||||
|
if update.Avatar != nil {
|
||||||
|
simples = append(simples, q.Admin.Avatar.Value(*update.Avatar))
|
||||||
|
}
|
||||||
|
if update.Phone != nil {
|
||||||
|
simples = append(simples, q.Admin.Phone.Value(*update.Phone))
|
||||||
|
}
|
||||||
|
if update.Email != nil {
|
||||||
|
simples = append(simples, q.Admin.Email.Value(*update.Email))
|
||||||
|
}
|
||||||
|
if update.Status != nil {
|
||||||
|
simples = append(simples, q.Admin.Status.Value(int(*update.Status)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return q.Q.Transaction(func(tx *q.Query) error {
|
||||||
|
// 更新管理员基本信息
|
||||||
|
if len(simples) > 0 {
|
||||||
|
_, err := tx.Admin.
|
||||||
|
Where(tx.Admin.ID.Eq(update.Id), tx.Admin.Username.Neq("admin")).
|
||||||
|
UpdateSimple(simples...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新角色关联
|
||||||
|
if update.Roles != nil {
|
||||||
|
roles := *update.Roles
|
||||||
|
if _, err := tx.LinkAdminRole.Where(tx.LinkAdminRole.AdminID.Eq(update.Id)).Delete(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(roles) > 0 {
|
||||||
|
links := make([]*m.LinkAdminRole, len(roles))
|
||||||
|
for i, roleID := range roles {
|
||||||
|
links[i] = &m.LinkAdminRole{
|
||||||
|
AdminID: update.Id,
|
||||||
|
RoleID: roleID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := tx.LinkAdminRole.CreateInBatches(links, 1000); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *adminService) RemoveAdmin(id int32) error {
|
||||||
|
_, err := q.Admin.Where(q.Admin.ID.Eq(id), q.Admin.Username.Neq("admin")).UpdateColumn(q.Admin.DeletedAt, time.Now())
|
||||||
|
return err
|
||||||
|
}
|
||||||
144
web/services/admin_role.go
Normal file
144
web/services/admin_role.go
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/pkg/u"
|
||||||
|
"platform/web/core"
|
||||||
|
g "platform/web/globals"
|
||||||
|
"platform/web/models"
|
||||||
|
m "platform/web/models"
|
||||||
|
q "platform/web/queries"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
)
|
||||||
|
|
||||||
|
var AdminRole = &adminRoleService{}
|
||||||
|
|
||||||
|
type adminRoleService struct{}
|
||||||
|
|
||||||
|
func (r *adminRoleService) ListRoles() (result []*m.AdminRole, err error) {
|
||||||
|
return q.AdminRole.
|
||||||
|
Order(q.AdminRole.Sort.Asc(), q.AdminRole.CreatedAt.Desc()).
|
||||||
|
Find()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *adminRoleService) PageRoles(req core.PageReq) (result []*m.AdminRole, count int64, err error) {
|
||||||
|
return q.AdminRole.
|
||||||
|
Preload(q.AdminRole.Permissions).
|
||||||
|
Order(q.AdminRole.Sort.Asc(), q.AdminRole.CreatedAt.Desc()).
|
||||||
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *adminRoleService) CreateAdminRole(create *CreateAdminRole) error {
|
||||||
|
return q.Q.Transaction(func(q *q.Query) error {
|
||||||
|
|
||||||
|
// 创建角色
|
||||||
|
role := &m.AdminRole{
|
||||||
|
Name: create.Name,
|
||||||
|
Description: create.Description,
|
||||||
|
Active: u.Else(create.Active, true),
|
||||||
|
Sort: u.Else(create.Sort, 0),
|
||||||
|
}
|
||||||
|
if err := q.AdminRole.Create(role); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 替换权限
|
||||||
|
permissions := make([]*models.LinkAdminRolePermission, 0, len(create.Permissions))
|
||||||
|
for _, permissionID := range create.Permissions {
|
||||||
|
permissions = append(permissions, &models.LinkAdminRolePermission{
|
||||||
|
RoleID: role.ID,
|
||||||
|
PermissionID: permissionID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(permissions) > 0 {
|
||||||
|
err := g.Redsync.WithLock(AdminRoleModifyLock, func() error {
|
||||||
|
return q.LinkAdminRolePermission.CreateInBatches(permissions, 1000)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateAdminRole struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description *string `json:"description"`
|
||||||
|
Active *bool `json:"active"`
|
||||||
|
Sort *int32 `json:"sort"`
|
||||||
|
Permissions []int32 `json:"permissions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *adminRoleService) UpdateAdminRole(update *UpdateAdminRole) error {
|
||||||
|
|
||||||
|
var simples = make([]field.AssignExpr, 0)
|
||||||
|
if update.Name != nil {
|
||||||
|
simples = append(simples, q.AdminRole.Name.Value(*update.Name))
|
||||||
|
}
|
||||||
|
if update.Description != nil {
|
||||||
|
simples = append(simples, q.AdminRole.Description.Value(*update.Description))
|
||||||
|
}
|
||||||
|
if update.Active != nil {
|
||||||
|
simples = append(simples, q.AdminRole.Active.Value(*update.Active))
|
||||||
|
}
|
||||||
|
if update.Sort != nil {
|
||||||
|
simples = append(simples, q.AdminRole.Sort.Value(*update.Sort))
|
||||||
|
}
|
||||||
|
|
||||||
|
err := q.Q.Transaction(func(q *q.Query) error {
|
||||||
|
|
||||||
|
// 修改角色
|
||||||
|
_, err := q.AdminRole.
|
||||||
|
Where(q.AdminRole.ID.Eq(update.Id)).
|
||||||
|
UpdateSimple(simples...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改角色关联权限
|
||||||
|
if update.Permissions != nil {
|
||||||
|
updatePermissions := *update.Permissions
|
||||||
|
permissions := make([]*models.LinkAdminRolePermission, len(updatePermissions))
|
||||||
|
for i, permissionID := range updatePermissions {
|
||||||
|
permissions[i] = &models.LinkAdminRolePermission{
|
||||||
|
RoleID: update.Id,
|
||||||
|
PermissionID: permissionID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = g.Redsync.WithLock(AdminRoleModifyLock, func() error {
|
||||||
|
if _, err := q.LinkAdminRolePermission.Where(q.LinkAdminRolePermission.RoleID.Eq(update.Id)).Delete(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = q.LinkAdminRolePermission.CreateInBatches(permissions, 1000); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateAdminRole struct {
|
||||||
|
Id int32 `json:"id"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Description *string `json:"description"`
|
||||||
|
Active *bool `json:"active"`
|
||||||
|
Sort *int32 `json:"sort"`
|
||||||
|
Permissions *[]int32 `json:"permissions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *adminRoleService) RemoveAdminRole(id int32) error {
|
||||||
|
_, err := q.AdminRole.Where(q.AdminRole.ID.Eq(id)).UpdateColumn(q.AdminRole.DeletedAt, time.Now())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var AdminRoleModifyLock = "platform:admin_role_permissions:modify"
|
||||||
@@ -2,42 +2,35 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
|
q "platform/web/queries"
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var Bill = &billService{}
|
var Bill = &billService{}
|
||||||
|
|
||||||
type billService struct{}
|
type billService struct{}
|
||||||
|
|
||||||
func (s *billService) GenNo() string {
|
func (s *billService) CreateForBalance(q *q.Query, uid, tradeId int32, detail *TradeDetail) error {
|
||||||
return ID.GenReadable("bil")
|
return q.Bill.Create(&m.Bill{
|
||||||
}
|
|
||||||
|
|
||||||
func newForRecharge(uid int32, billNo string, info string, amount decimal.Decimal, trade *m.Trade) *m.Bill {
|
|
||||||
return &m.Bill{
|
|
||||||
UserID: uid,
|
UserID: uid,
|
||||||
BillNo: billNo,
|
BillNo: ID.GenReadable("bil"),
|
||||||
TradeID: &trade.ID,
|
TradeID: &tradeId,
|
||||||
Type: m.BillTypeRecharge,
|
Type: m.BillTypeRecharge,
|
||||||
Info: &info,
|
Info: &detail.Subject,
|
||||||
Amount: amount,
|
Amount: detail.Amount,
|
||||||
}
|
Actual: detail.Actual,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func newForConsume(uid int32, billNo string, info string, amount decimal.Decimal, resource *m.Resource, trade ...*m.Trade) *m.Bill {
|
func (s *billService) CreateForResource(q *q.Query, uid, resourceId int32, tradeId *int32, detail *TradeDetail) error {
|
||||||
var bill = &m.Bill{
|
return q.Bill.Create(&m.Bill{
|
||||||
UserID: uid,
|
UserID: uid,
|
||||||
BillNo: billNo,
|
BillNo: ID.GenReadable("bil"),
|
||||||
ResourceID: &resource.ID,
|
ResourceID: &resourceId,
|
||||||
|
TradeID: tradeId,
|
||||||
|
CouponID: detail.CouponId,
|
||||||
Type: m.BillTypeConsume,
|
Type: m.BillTypeConsume,
|
||||||
Info: &info,
|
Info: &detail.Subject,
|
||||||
Amount: amount,
|
Amount: detail.Amount,
|
||||||
}
|
Actual: detail.Actual,
|
||||||
|
})
|
||||||
if len(trade) > 0 {
|
|
||||||
bill.TradeID = &trade[0].ID
|
|
||||||
}
|
|
||||||
|
|
||||||
return bill
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ func (s *channelBaiyinProvider) CreateChannels(source netip.Addr, resourceId int
|
|||||||
)
|
)
|
||||||
|
|
||||||
case isLongType:
|
case isLongType:
|
||||||
rs, err = q.ResourceLong.Debug().
|
rs, err = q.ResourceLong.
|
||||||
Where(
|
Where(
|
||||||
q.ResourceLong.ID.Eq(*resource.LongId),
|
q.ResourceLong.ID.Eq(*resource.LongId),
|
||||||
q.ResourceLong.Used.Eq(resource.Used),
|
q.ResourceLong.Used.Eq(resource.Used),
|
||||||
|
|||||||
139
web/services/coupon.go
Normal file
139
web/services/coupon.go
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"platform/web/core"
|
||||||
|
m "platform/web/models"
|
||||||
|
q "platform/web/queries"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Coupon = &couponService{}
|
||||||
|
|
||||||
|
type couponService struct{}
|
||||||
|
|
||||||
|
func (s *couponService) All() (result []*m.Coupon, err error) {
|
||||||
|
return q.Coupon.Order(q.Coupon.CreatedAt.Desc()).Find()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *couponService) Page(req *core.PageReq) (result []*m.Coupon, count int64, err error) {
|
||||||
|
return q.Coupon.Order(q.Coupon.CreatedAt.Desc()).FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *couponService) Create(data CreateCouponData) error {
|
||||||
|
return q.Coupon.Create(&m.Coupon{
|
||||||
|
UserID: data.UserID,
|
||||||
|
Code: data.Code,
|
||||||
|
Remark: data.Remark,
|
||||||
|
Amount: data.Amount,
|
||||||
|
MinAmount: data.MinAmount,
|
||||||
|
Status: m.CouponStatusUnused,
|
||||||
|
ExpireAt: data.ExpireAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateCouponData struct {
|
||||||
|
UserID *int32 `json:"user_id"`
|
||||||
|
Code string `json:"code" validate:"required"`
|
||||||
|
Remark *string `json:"remark"`
|
||||||
|
Amount decimal.Decimal `json:"amount" validate:"required"`
|
||||||
|
MinAmount decimal.Decimal `json:"min_amount"`
|
||||||
|
ExpireAt *time.Time `json:"expire_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *couponService) Update(data UpdateCouponData) error {
|
||||||
|
do := make([]field.AssignExpr, 0)
|
||||||
|
|
||||||
|
if data.UserID != nil {
|
||||||
|
do = append(do, q.Coupon.UserID.Value(*data.UserID))
|
||||||
|
}
|
||||||
|
if data.Code != nil {
|
||||||
|
do = append(do, q.Coupon.Code.Value(*data.Code))
|
||||||
|
}
|
||||||
|
if data.Remark != nil {
|
||||||
|
do = append(do, q.Coupon.Remark.Value(*data.Remark))
|
||||||
|
}
|
||||||
|
if data.Amount != nil {
|
||||||
|
do = append(do, q.Coupon.Amount.Value(*data.Amount))
|
||||||
|
}
|
||||||
|
if data.MinAmount != nil {
|
||||||
|
do = append(do, q.Coupon.MinAmount.Value(*data.MinAmount))
|
||||||
|
}
|
||||||
|
if data.Status != nil {
|
||||||
|
do = append(do, q.Coupon.Status.Value(int(*data.Status)))
|
||||||
|
}
|
||||||
|
if data.ExpireAt != nil {
|
||||||
|
do = append(do, q.Coupon.ExpireAt.Value(*data.ExpireAt))
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := q.Coupon.Where(q.Coupon.ID.Eq(data.ID)).UpdateSimple(do...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateCouponData struct {
|
||||||
|
ID int32 `json:"id" validate:"required"`
|
||||||
|
UserID *int32 `json:"user_id"`
|
||||||
|
Code *string `json:"code"`
|
||||||
|
Remark *string `json:"remark"`
|
||||||
|
Amount *decimal.Decimal `json:"amount"`
|
||||||
|
MinAmount *decimal.Decimal `json:"min_amount"`
|
||||||
|
Status *m.CouponStatus `json:"status"`
|
||||||
|
ExpireAt *time.Time `json:"expire_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *couponService) Delete(id int32) error {
|
||||||
|
_, err := q.Coupon.Where(q.Coupon.ID.Eq(id)).UpdateColumn(q.Coupon.DeletedAt, time.Now())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *couponService) GetCouponAvailableByCode(code string, amount decimal.Decimal, uid *int32) (*m.Coupon, error) {
|
||||||
|
// 获取优惠券
|
||||||
|
coupon, err := q.Coupon.Where(
|
||||||
|
q.Coupon.Code.Eq(code),
|
||||||
|
q.Coupon.Status.Eq(int(m.CouponStatusUnused)),
|
||||||
|
q.Coupon.
|
||||||
|
Where(q.Coupon.ExpireAt.Gt(time.Now())).
|
||||||
|
Or(q.Coupon.ExpireAt.IsNull()),
|
||||||
|
).Take()
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, core.NewBizErr("优惠券不存在或已失效")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, core.NewBizErr("获取优惠券数据失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查最小使用额度
|
||||||
|
if amount.Cmp(coupon.MinAmount) < 0 {
|
||||||
|
return nil, core.NewBizErr(fmt.Sprintf("使用此优惠券的最小额度为 %s", coupon.MinAmount))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查所属
|
||||||
|
if coupon.UserID != nil {
|
||||||
|
if uid == nil {
|
||||||
|
return nil, core.NewBizErr("检查优惠券所属用户失败")
|
||||||
|
}
|
||||||
|
if *coupon.UserID != *uid {
|
||||||
|
return nil, core.NewBizErr("优惠券不属于当前用户")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return coupon, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *couponService) UseCoupon(q *q.Query, id int32) error {
|
||||||
|
_, err := q.Coupon.
|
||||||
|
Where(
|
||||||
|
q.Coupon.ID.Eq(id),
|
||||||
|
q.Coupon.Status.Eq(int(m.CouponStatusUnused)),
|
||||||
|
q.Coupon.ExpireAt.Gt(time.Now()),
|
||||||
|
).
|
||||||
|
UpdateSimple(
|
||||||
|
q.Coupon.Status.Value(int(m.CouponStatusUsed)),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
19
web/services/permission.go
Normal file
19
web/services/permission.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/core"
|
||||||
|
m "platform/web/models"
|
||||||
|
q "platform/web/queries"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Permission = &permissionService{}
|
||||||
|
|
||||||
|
type permissionService struct{}
|
||||||
|
|
||||||
|
func (r *permissionService) ListPermissions() (result []*m.Permission, err error) {
|
||||||
|
return q.Permission.Order(q.Permission.Sort).Find()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *permissionService) PagePermissions(req core.PageReq) (result []*m.Permission, count int64, err error) {
|
||||||
|
return q.Permission.Order(q.Permission.Sort).FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
|
}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import q "platform/web/queries"
|
import (
|
||||||
|
"platform/web/core"
|
||||||
|
m "platform/web/models"
|
||||||
|
q "platform/web/queries"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
)
|
||||||
|
|
||||||
var Product = &productService{}
|
var Product = &productService{}
|
||||||
|
|
||||||
@@ -10,3 +17,70 @@ type productService struct{}
|
|||||||
func (s *productService) GetPrice(code string) {
|
func (s *productService) GetPrice(code string) {
|
||||||
q.ProductSku.Where(q.ProductSku.Code.Eq(code)).Find()
|
q.ProductSku.Where(q.ProductSku.Code.Eq(code)).Find()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取所有产品
|
||||||
|
func (s *productService) AllProducts() ([]*m.Product, error) {
|
||||||
|
return q.Product.
|
||||||
|
Order(q.Product.Sort.Asc(), q.Product.CreatedAt.Desc()).
|
||||||
|
Find()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增产品
|
||||||
|
func (s *productService) CreateProduct(create *CreateProductData) error {
|
||||||
|
return q.Product.Create(&m.Product{
|
||||||
|
Code: create.Code,
|
||||||
|
Name: create.Name,
|
||||||
|
Description: create.Description,
|
||||||
|
Sort: create.Sort,
|
||||||
|
Status: m.ProductStatus(create.Status),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateProductData struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description *string `json:"description"`
|
||||||
|
Sort int32 `json:"sort"`
|
||||||
|
Status int `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新产品
|
||||||
|
func (s *productService) UpdateProduct(update *UpdateProductData) error {
|
||||||
|
if update == nil {
|
||||||
|
return core.NewBizErr("更新数据不存在")
|
||||||
|
}
|
||||||
|
|
||||||
|
do := make([]field.AssignExpr, 0, 5)
|
||||||
|
if update.Code != nil {
|
||||||
|
do = append(do, q.Product.Code.Value(*update.Code))
|
||||||
|
}
|
||||||
|
if update.Name != nil {
|
||||||
|
do = append(do, q.Product.Name.Value(*update.Name))
|
||||||
|
}
|
||||||
|
if update.Description != nil {
|
||||||
|
do = append(do, q.Product.Description.Value(*update.Description))
|
||||||
|
}
|
||||||
|
if update.Sort != nil {
|
||||||
|
do = append(do, q.Product.Sort.Value(*update.Sort))
|
||||||
|
}
|
||||||
|
if update.Status != nil {
|
||||||
|
do = append(do, q.Product.Status.Value(*update.Status))
|
||||||
|
}
|
||||||
|
_, err := q.Product.Where(q.Product.ID.Eq(update.Id)).UpdateSimple(do...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateProductData struct {
|
||||||
|
Id int32 `json:"id"`
|
||||||
|
Code *string `json:"code"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Description *string `json:"description"`
|
||||||
|
Sort *int32 `json:"sort"`
|
||||||
|
Status *int `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除产品
|
||||||
|
func (s *productService) DeleteProduct(id int32) error {
|
||||||
|
_, err := q.Product.Where(q.Product.ID.Eq(id)).UpdateColumn(q.Product.DeletedAt, time.Now())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
59
web/services/product_discount.go
Normal file
59
web/services/product_discount.go
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/core"
|
||||||
|
m "platform/web/models"
|
||||||
|
q "platform/web/queries"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ProductDiscount = &productDiscountService{}
|
||||||
|
|
||||||
|
type productDiscountService struct{}
|
||||||
|
|
||||||
|
func (s *productDiscountService) All() (result []*m.ProductDiscount, err error) {
|
||||||
|
return q.ProductDiscount.Order(q.ProductDiscount.CreatedAt.Desc()).Find()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *productDiscountService) Page(req *core.PageReq) (result []*m.ProductDiscount, count int64, err error) {
|
||||||
|
return q.ProductDiscount.Order(q.ProductDiscount.CreatedAt.Desc()).FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *productDiscountService) Create(data CreateProductDiscountData) (err error) {
|
||||||
|
return q.ProductDiscount.Create(&m.ProductDiscount{
|
||||||
|
Name: data.Name,
|
||||||
|
Discount: data.Discount,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateProductDiscountData struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Discount int32 `json:"discount" validate:"min=0,max=100"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *productDiscountService) Update(data UpdateProductDiscountData) (err error) {
|
||||||
|
do := make([]field.AssignExpr, 0)
|
||||||
|
|
||||||
|
if data.Name != nil {
|
||||||
|
do = append(do, q.ProductDiscount.Name.Value(*data.Name))
|
||||||
|
}
|
||||||
|
if data.Discount != nil {
|
||||||
|
do = append(do, q.ProductDiscount.Discount.Value(*data.Discount))
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = q.ProductDiscount.Where(q.ProductDiscount.ID.Eq(data.ID)).UpdateSimple(do...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateProductDiscountData struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Discount *int32 `json:"discount" validate:"omitempty,min=0,max=100"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *productDiscountService) Delete(id int32) (err error) {
|
||||||
|
_, err = q.ProductDiscount.Where(q.ProductDiscount.ID.Eq(id)).UpdateColumn(q.ProductDiscount.DeletedAt, time.Now())
|
||||||
|
return
|
||||||
|
}
|
||||||
109
web/services/product_sku.go
Normal file
109
web/services/product_sku.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"platform/web/core"
|
||||||
|
m "platform/web/models"
|
||||||
|
q "platform/web/queries"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
"gorm.io/gen"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ProductSku = &productSkuService{}
|
||||||
|
|
||||||
|
type productSkuService struct{}
|
||||||
|
|
||||||
|
func (s *productSkuService) All(product_code string) (result []*m.ProductSku, err error) {
|
||||||
|
return q.ProductSku.
|
||||||
|
Joins(q.ProductSku.Product).
|
||||||
|
Where(q.Product.As("Product").Code.Eq(product_code)).
|
||||||
|
Select(q.ProductSku.ALL).
|
||||||
|
Order(q.ProductSku.CreatedAt.Desc()).
|
||||||
|
Find()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *productSkuService) Page(req *core.PageReq, productId *int32) (result []*m.ProductSku, count int64, err error) {
|
||||||
|
do := make([]gen.Condition, 0)
|
||||||
|
if productId != nil {
|
||||||
|
do = append(do, q.ProductSku.ProductID.Eq(*productId))
|
||||||
|
}
|
||||||
|
return q.ProductSku.
|
||||||
|
Joins(q.ProductSku.Discount).
|
||||||
|
Where(do...).
|
||||||
|
Order(q.ProductSku.CreatedAt.Desc()).
|
||||||
|
FindByPage(req.GetOffset(), req.GetLimit())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *productSkuService) Create(create CreateProductSkuData) (err error) {
|
||||||
|
price, err := decimal.NewFromString(create.Price)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewBizErr("产品价格的格式不正确", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return q.ProductSku.Create(&m.ProductSku{
|
||||||
|
ProductID: create.ProductID,
|
||||||
|
DiscountId: create.DiscountID,
|
||||||
|
Code: create.Code,
|
||||||
|
Name: create.Name,
|
||||||
|
Price: price,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateProductSkuData struct {
|
||||||
|
ProductID int32 `json:"product_id"`
|
||||||
|
DiscountID int32 `json:"discount_id"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Price string `json:"price"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *productSkuService) Update(update UpdateProductSkuData) (err error) {
|
||||||
|
do := make([]field.AssignExpr, 0)
|
||||||
|
|
||||||
|
if update.Price != nil {
|
||||||
|
price, err := decimal.NewFromString(*update.Price)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewBizErr("产品价格的格式不正确", err)
|
||||||
|
}
|
||||||
|
do = append(do, q.ProductSku.Price.Value(price))
|
||||||
|
}
|
||||||
|
if update.DiscountID != nil {
|
||||||
|
do = append(do, q.ProductSku.DiscountId.Value(*update.DiscountID))
|
||||||
|
}
|
||||||
|
if update.Code != nil {
|
||||||
|
do = append(do, q.ProductSku.Code.Value(*update.Code))
|
||||||
|
}
|
||||||
|
if update.Name != nil {
|
||||||
|
do = append(do, q.ProductSku.Name.Value(*update.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = q.ProductSku.Where(q.ProductSku.ID.Eq(update.ID)).UpdateSimple(do...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateProductSkuData struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
DiscountID *int32 `json:"discount_id"`
|
||||||
|
Code *string `json:"code"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Price *string `json:"price"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *productSkuService) Delete(id int32) (err error) {
|
||||||
|
_, err = q.ProductSku.Where(q.ProductSku.ID.Eq(id)).UpdateColumn(q.ProductSku.DeletedAt, time.Now())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *productSkuService) BatchUpdateDiscount(data BatchUpdateSkuDiscountData) (err error) {
|
||||||
|
_, err = q.ProductSku.Where(q.ProductSku.ProductID.Eq(data.ProductID)).UpdateSimple(
|
||||||
|
q.ProductSku.DiscountId.Value(data.DiscountID),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type BatchUpdateSkuDiscountData struct {
|
||||||
|
ProductID int32 `json:"product_id"`
|
||||||
|
DiscountID int32 `json:"discount_id"`
|
||||||
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"platform/pkg/u"
|
"platform/pkg/u"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
@@ -11,102 +9,62 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gen/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Resource = &resourceService{}
|
var Resource = &resourceService{}
|
||||||
|
|
||||||
type resourceService struct{}
|
type resourceService struct{}
|
||||||
|
|
||||||
func (s *resourceService) CreateResourceByBalance(uid int32, now time.Time, data *CreateResourceData) error {
|
// CreateResourceByBalance 通过余额购买套餐
|
||||||
|
func (s *resourceService) CreateResourceByBalance(user *m.User, data *CreateResourceData) error {
|
||||||
// 找到用户
|
now := time.Now()
|
||||||
user, err := q.User.
|
|
||||||
Where(q.User.ID.Eq(uid)).
|
|
||||||
Take()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取 sku
|
// 获取 sku
|
||||||
sku, err := s.GetSku(data)
|
detail, err := data.TradeDetail(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return core.NewServErr("获取产品支付信息失败", err)
|
||||||
}
|
|
||||||
|
|
||||||
// 检查余额
|
|
||||||
_, amount, err := s.GetPrice(sku, data.Count(), &uid)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
newBalance := user.Balance.Sub(amount)
|
|
||||||
if newBalance.IsNegative() {
|
|
||||||
return ErrBalanceNotEnough
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return q.Q.Transaction(func(q *q.Query) error {
|
return q.Q.Transaction(func(q *q.Query) error {
|
||||||
|
|
||||||
// 更新用户余额
|
// 更新用户余额
|
||||||
_, err = q.User.
|
if err := User.UpdateBalance(q, user, detail.Actual.Neg(), "余额购买产品", nil); err != nil {
|
||||||
Where(
|
|
||||||
q.User.ID.Eq(uid),
|
|
||||||
q.User.Balance.Eq(user.Balance),
|
|
||||||
).
|
|
||||||
UpdateSimple(q.User.Balance.Value(newBalance))
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("更新用户余额失败", err)
|
return core.NewServErr("更新用户余额失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存套餐
|
// 保存套餐
|
||||||
resource, err := createResource(q, uid, now, data)
|
resource, err := s.Create(q, user.ID, now, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return core.NewServErr("创建套餐失败", err)
|
return core.NewServErr("创建套餐失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成账单
|
// 生成账单
|
||||||
err = q.Bill.Create(newForConsume(uid, Bill.GenNo(), sku.Name, amount, resource))
|
err = Bill.CreateForResource(q, user.ID, resource.ID, nil, detail)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return core.NewServErr("生成账单失败", err)
|
return core.NewServErr("生成账单失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 核销优惠券
|
||||||
|
if detail.CouponId != nil {
|
||||||
|
err = Coupon.UseCoupon(q, *detail.CouponId)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("核销优惠券失败", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *resourceService) CreateResourceByTrade(uid int32, now time.Time, data *CreateResourceByTradeData, trade *m.Trade) error { // 检查交易
|
func (s *resourceService) Create(q *q.Query, uid int32, now time.Time, data *CreateResourceData) (*m.Resource, error) {
|
||||||
if trade == nil {
|
|
||||||
return core.NewBizErr("交易数据不能为空")
|
|
||||||
}
|
|
||||||
if trade.Status != m.TradeStatusSuccess {
|
|
||||||
return core.NewBizErr("交易状态不正确")
|
|
||||||
}
|
|
||||||
|
|
||||||
return q.Q.Transaction(func(q *q.Query) error {
|
|
||||||
|
|
||||||
// 保存套餐
|
|
||||||
resource, err := createResource(q, uid, now, data.Req)
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("创建套餐失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成账单
|
|
||||||
err = q.Bill.Create(newForConsume(uid, Bill.GenNo(), data.GetSubject(), data.GetAmount(), resource, trade))
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("生成账单失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func createResource(q *q.Query, uid int32, now time.Time, data *CreateResourceData) (*m.Resource, error) {
|
|
||||||
|
|
||||||
// 套餐基本信息
|
// 套餐基本信息
|
||||||
var resource = m.Resource{
|
var resource = m.Resource{
|
||||||
UserID: uid,
|
UserID: uid,
|
||||||
ResourceNo: u.P(ID.GenReadable("res")),
|
ResourceNo: u.P(ID.GenReadable("res")),
|
||||||
Active: true,
|
Active: true,
|
||||||
Type: data.Type,
|
Type: data.Type,
|
||||||
|
Code: data.Type.Code(),
|
||||||
}
|
}
|
||||||
switch data.Type {
|
switch data.Type {
|
||||||
|
|
||||||
@@ -120,6 +78,7 @@ func createResource(q *q.Query, uid int32, now time.Time, data *CreateResourceDa
|
|||||||
Live: short.Live,
|
Live: short.Live,
|
||||||
Type: short.Mode,
|
Type: short.Mode,
|
||||||
Quota: short.Quota,
|
Quota: short.Quota,
|
||||||
|
Code: data.Code(),
|
||||||
}
|
}
|
||||||
if short.Mode == m.ResourceModeTime {
|
if short.Mode == m.ResourceModeTime {
|
||||||
if short.Expire == nil {
|
if short.Expire == nil {
|
||||||
@@ -139,6 +98,7 @@ func createResource(q *q.Query, uid int32, now time.Time, data *CreateResourceDa
|
|||||||
Live: long.Live,
|
Live: long.Live,
|
||||||
Type: long.Mode,
|
Type: long.Mode,
|
||||||
Quota: long.Quota,
|
Quota: long.Quota,
|
||||||
|
Code: data.Code(),
|
||||||
}
|
}
|
||||||
if long.Mode == m.ResourceModeTime {
|
if long.Mode == m.ResourceModeTime {
|
||||||
if long.Expire == nil {
|
if long.Expire == nil {
|
||||||
@@ -159,50 +119,91 @@ func createResource(q *q.Query, uid int32, now time.Time, data *CreateResourceDa
|
|||||||
return &resource, nil
|
return &resource, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *resourceService) GetSku(data *CreateResourceData) (*m.ProductSku, error) {
|
func (s *resourceService) Update(data *UpdateResourceData) error {
|
||||||
sku, err := q.ProductSku.Where(q.ProductSku.Code.Eq(data.Code())).Take()
|
if data.Active == nil {
|
||||||
if err != nil {
|
return core.NewBizErr("更新套餐失败,active 不能为空")
|
||||||
return nil, core.NewServErr("产品不可用", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sku, nil
|
do := make([]field.AssignExpr, 0)
|
||||||
|
if data.Active != nil {
|
||||||
|
do = append(do, q.Resource.Active.Value(*data.Active))
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := q.Resource.
|
||||||
|
Where(q.Resource.ID.Eq(data.Id)).
|
||||||
|
UpdateSimple(do...)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("更新套餐失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *resourceService) GetPrice(sku *m.ProductSku, count int32, uid *int32) (decimal.Decimal, decimal.Decimal, error) {
|
type UpdateResourceData struct {
|
||||||
|
core.IdReq
|
||||||
|
Active *bool `json:"active"`
|
||||||
|
}
|
||||||
|
|
||||||
// 根据用户 id 查询特殊优惠
|
func (s *resourceService) CalcPrice(skuCode string, count int32, user *m.User, couponCode *string) (*m.ProductSku, *m.ProductDiscount, *m.Coupon, decimal.Decimal, decimal.Decimal, error) {
|
||||||
var uSku *m.ProductSkuUser
|
|
||||||
if uid != nil {
|
sku, err := q.ProductSku.
|
||||||
var err error
|
Joins(q.ProductSku.Discount).
|
||||||
uSku, err = q.ProductSkuUser.Where(
|
Where(q.ProductSku.Code.Eq(skuCode)).
|
||||||
q.ProductSkuUser.UserID.Eq(*uid),
|
Take()
|
||||||
q.ProductSkuUser.ProductSkuID.Eq(sku.ID),
|
if err != nil {
|
||||||
).Take()
|
return nil, nil, nil, decimal.Zero, decimal.Zero, core.NewServErr("产品不可用", err)
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
}
|
||||||
return decimal.Zero, decimal.Zero, core.NewServErr("客户特殊价查询失败", err)
|
|
||||||
|
// 原价
|
||||||
|
price := sku.Price
|
||||||
|
amount := price.Mul(decimal.NewFromInt32(count))
|
||||||
|
|
||||||
|
// 折扣价
|
||||||
|
discount := sku.Discount
|
||||||
|
if discount == nil {
|
||||||
|
return nil, nil, nil, decimal.Zero, decimal.Zero, core.NewServErr("价格查询失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
discountRate := discount.Rate()
|
||||||
|
if user != nil && user.DiscountID != nil { // 用户特殊优惠
|
||||||
|
uDiscount, err := q.ProductDiscount.Where(q.ProductDiscount.ID.Eq(*user.DiscountID)).Take()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, decimal.Zero, decimal.Zero, core.NewServErr("客户特殊价查询失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
uDiscountRate := uDiscount.Rate()
|
||||||
|
if uDiscountRate.Cmp(discountRate) > 0 {
|
||||||
|
discountRate = uDiscountRate
|
||||||
|
discount = uDiscount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
discounted := amount.Mul(discountRate)
|
||||||
|
|
||||||
// 返回计算价格
|
// 优惠价
|
||||||
price := sku.Price
|
uid := (*int32)(nil)
|
||||||
if uSku != nil && uSku.Price != nil {
|
if user != nil {
|
||||||
price = *uSku.Price
|
uid = &user.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
discount := sku.Discount
|
coupon := (*m.Coupon)(nil)
|
||||||
if uSku != nil && uSku.Discount != nil {
|
couponApplied := discounted.Copy()
|
||||||
discount = *uSku.Discount
|
if couponCode != nil {
|
||||||
|
var err error
|
||||||
|
coupon, err = Coupon.GetCouponAvailableByCode(*couponCode, discounted, uid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, decimal.Zero, decimal.Zero, err
|
||||||
|
}
|
||||||
|
couponApplied = discounted.Sub(coupon.Amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
before := price.Mul(decimal.NewFromInt32(count))
|
return sku, discount, coupon, discounted, couponApplied, nil
|
||||||
after := before.Mul(decimal.NewFromFloat32(discount))
|
|
||||||
return before, after, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateResourceData struct {
|
type CreateResourceData struct {
|
||||||
Type m.ResourceType `json:"type" validate:"required"`
|
Type m.ResourceType `json:"type" validate:"required"`
|
||||||
Short *CreateShortResourceData `json:"short,omitempty"`
|
Short *CreateShortResourceData `json:"short,omitempty"`
|
||||||
Long *CreateLongResourceData `json:"long,omitempty"`
|
Long *CreateLongResourceData `json:"long,omitempty"`
|
||||||
|
CouponCode *string `json:"coupon,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateShortResourceData struct {
|
type CreateShortResourceData struct {
|
||||||
@@ -225,101 +226,57 @@ type CreateLongResourceData struct {
|
|||||||
price *decimal.Decimal
|
price *decimal.Decimal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CreateResourceData) Count() int32 {
|
func (data *CreateResourceData) Count() int32 {
|
||||||
switch {
|
switch {
|
||||||
default:
|
default:
|
||||||
return 0
|
return 0
|
||||||
case c.Type == m.ResourceTypeShort && c.Short != nil:
|
case data.Type == m.ResourceTypeShort && data.Short != nil:
|
||||||
return c.Short.Quota
|
return data.Short.Quota
|
||||||
case c.Type == m.ResourceTypeLong && c.Long != nil:
|
case data.Type == m.ResourceTypeLong && data.Long != nil:
|
||||||
return c.Long.Quota
|
return data.Long.Quota
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CreateResourceData) Code() string {
|
func (data *CreateResourceData) Code() string {
|
||||||
switch {
|
switch {
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
case c.Type == m.ResourceTypeShort && c.Short != nil:
|
case data.Type == m.ResourceTypeShort && data.Short != nil:
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"mode=%s,live=%d,expire=%d",
|
"mode=%s,live=%d,expire=%d",
|
||||||
c.Short.Mode.Code(), c.Short.Live, u.Else(c.Short.Expire, 0),
|
data.Short.Mode.Code(), data.Short.Live, u.Else(data.Short.Expire, 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
case c.Type == m.ResourceTypeLong && c.Long != nil:
|
case data.Type == m.ResourceTypeLong && data.Long != nil:
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"mode=%s,live=%d,expire=%d",
|
"mode=%s,live=%d,expire=%d",
|
||||||
c.Long.Mode.Code(), c.Long.Live, u.Else(c.Long.Expire, 0),
|
data.Long.Mode.Code(), data.Long.Live, u.Else(data.Long.Expire, 0),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CreateResourceData) Serialize() (string, error) {
|
func (data *CreateResourceData) TradeDetail(user *m.User) (*TradeDetail, error) {
|
||||||
bytes, err := json.Marshal(c)
|
sku, discount, coupon, amount, actual, err := Resource.CalcPrice(data.Code(), data.Count(), user, data.CouponCode)
|
||||||
return string(bytes), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CreateResourceData) Deserialize(str string) error {
|
|
||||||
return json.Unmarshal([]byte(str), c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 交易后创建套餐
|
|
||||||
type ResourceOnTradeComplete struct{}
|
|
||||||
|
|
||||||
func (r ResourceOnTradeComplete) Check(t m.TradeType) (ProductInfo, bool) {
|
|
||||||
if t == m.TradeTypePurchase {
|
|
||||||
return &CreateResourceByTradeData{}, true
|
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r ResourceOnTradeComplete) OnTradeComplete(info ProductInfo, trade *m.Trade) error {
|
|
||||||
return Resource.CreateResourceByTrade(trade.UserID, time.Time(*trade.CompletedAt), info.(*CreateResourceByTradeData), trade)
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateResourceByTradeData struct {
|
|
||||||
Subject string `json:"subject"`
|
|
||||||
Amount decimal.Decimal `json:"amount"`
|
|
||||||
Req *CreateResourceData `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e CreateResourceByTradeData) GetType() m.TradeType {
|
|
||||||
return m.TradeTypePurchase
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e CreateResourceByTradeData) GetSubject() string {
|
|
||||||
return e.Subject
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e CreateResourceByTradeData) GetAmount() decimal.Decimal {
|
|
||||||
return e.Amount
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e CreateResourceByTradeData) Serialize() (string, error) {
|
|
||||||
bytes, err := json.Marshal(e)
|
|
||||||
return string(bytes), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *CreateResourceByTradeData) Deserialize(str string) error {
|
|
||||||
return json.Unmarshal([]byte(str), e)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCreateResourceByTradeData(req *CreateResourceData) (*CreateResourceByTradeData, error) {
|
|
||||||
sku, err := Resource.GetSku(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, amount, err := Resource.GetPrice(sku, req.Count(), nil)
|
var discountId *int32 = nil
|
||||||
if err != nil {
|
if discount != nil {
|
||||||
return nil, err
|
discountId = &discount.ID
|
||||||
}
|
}
|
||||||
|
var couponId *int32 = nil
|
||||||
return &CreateResourceByTradeData{
|
if coupon != nil {
|
||||||
Subject: sku.Name,
|
couponId = &coupon.ID
|
||||||
Amount: amount,
|
}
|
||||||
Req: req,
|
return &TradeDetail{
|
||||||
|
data,
|
||||||
|
m.TradeTypePurchase,
|
||||||
|
sku.Name,
|
||||||
|
amount, actual,
|
||||||
|
discountId, discount,
|
||||||
|
couponId, coupon,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/gob"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -23,88 +25,47 @@ import (
|
|||||||
"github.com/smartwalle/alipay/v3"
|
"github.com/smartwalle/alipay/v3"
|
||||||
"github.com/wechatpay-apiv3/wechatpay-go/services/partnerpayments/h5"
|
"github.com/wechatpay-apiv3/wechatpay-go/services/partnerpayments/h5"
|
||||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
|
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
gob.Register(&CreateResourceData{})
|
||||||
|
gob.Register(&UpdateBalanceData{})
|
||||||
|
}
|
||||||
|
|
||||||
var Trade = &tradeService{}
|
var Trade = &tradeService{}
|
||||||
|
|
||||||
type tradeService struct {
|
type tradeService struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建交易
|
// 创建交易
|
||||||
func (s *tradeService) CreateTrade(uid int32, now time.Time, payment *CreateTradeData, product ProductInfo) (*CreateTradeResult, error) {
|
func (s *tradeService) Create(user *m.User, tradeData *CreateTradeData, productData ProductData) (*CreateTradeResult, error) {
|
||||||
platform := payment.Platform
|
if user == nil {
|
||||||
method := payment.Method
|
return nil, core.NewBizErr("用户未登录")
|
||||||
tType := product.GetType()
|
|
||||||
expire := time.Now().Add(30 * time.Minute)
|
|
||||||
subject := product.GetSubject()
|
|
||||||
amount := product.GetAmount()
|
|
||||||
|
|
||||||
// 实际支付金额,只在创建真实订单时使用
|
|
||||||
amountReal := amount
|
|
||||||
if env.RunMode == env.RunModeDev {
|
|
||||||
amountReal = decimal.NewFromFloat(0.01)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 附加优惠券
|
detail, err := productData.TradeDetail(user)
|
||||||
if payment.CouponCode != nil {
|
if err != nil {
|
||||||
coupon, err := q.Coupon.
|
return nil, core.NewServErr("获取产品支付信息失败", err)
|
||||||
Where(
|
|
||||||
q.Coupon.Code.Eq(*payment.CouponCode),
|
|
||||||
q.Coupon.Status.Eq(int(m.CouponStatusUnused)),
|
|
||||||
).
|
|
||||||
Take()
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return nil, errors.New("优惠券不存在或已失效")
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
expireAt := time.Time(u.Z(coupon.ExpireAt))
|
|
||||||
if !expireAt.IsZero() && expireAt.Before(now) {
|
|
||||||
_, err = q.Coupon.
|
|
||||||
Where(q.Coupon.ID.Eq(coupon.ID)).
|
|
||||||
Update(q.Coupon.Status, m.CouponStatusExpired)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return nil, errors.New("优惠券已过期")
|
|
||||||
}
|
|
||||||
|
|
||||||
if amount.Cmp(coupon.MinAmount) < 0 {
|
|
||||||
return nil, errors.New("订单金额未达到使用优惠券的条件")
|
|
||||||
}
|
|
||||||
|
|
||||||
if coupon.UserID != nil {
|
|
||||||
switch *coupon.UserID {
|
|
||||||
// 指定用户的优惠券
|
|
||||||
case uid:
|
|
||||||
amount = amount.Sub(coupon.Amount)
|
|
||||||
if expireAt.IsZero() {
|
|
||||||
_, err = q.Coupon.
|
|
||||||
Where(q.Coupon.ID.Eq(coupon.ID)).
|
|
||||||
Update(q.Coupon.Status, int(m.CouponStatusUsed))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 该优惠券不属于当前用户
|
|
||||||
default:
|
|
||||||
return nil, errors.New("优惠券不属于当前用户")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 公开优惠券
|
|
||||||
amount = amount.Sub(coupon.Amount)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
platform := tradeData.Platform
|
||||||
|
method := tradeData.Method
|
||||||
|
expireIn := time.Duration(env.TradeExpire) * time.Second
|
||||||
|
expireAt := now.Add(expireIn)
|
||||||
|
|
||||||
// 生成订单号
|
// 生成订单号
|
||||||
tradeNo, err := ID.GenSerial()
|
tradeNo, err := ID.GenSerial()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, core.NewServErr("生成订单号失败", err)
|
return nil, core.NewServErr("生成订单号失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 实际支付金额,只在创建真实订单时使用
|
||||||
|
amountReal := detail.Actual
|
||||||
|
if env.RunMode == env.RunModeDev {
|
||||||
|
amountReal = decimal.NewFromFloat(0.01)
|
||||||
|
}
|
||||||
|
|
||||||
// 提交支付订单
|
// 提交支付订单
|
||||||
var paymentUrl string
|
var paymentUrl string
|
||||||
switch {
|
switch {
|
||||||
@@ -117,9 +78,9 @@ func (s *tradeService) CreateTrade(uid int32, now time.Time, payment *CreateTrad
|
|||||||
Trade: alipay.Trade{
|
Trade: alipay.Trade{
|
||||||
ProductCode: "FAST_INSTANT_TRADE_PAY",
|
ProductCode: "FAST_INSTANT_TRADE_PAY",
|
||||||
OutTradeNo: tradeNo,
|
OutTradeNo: tradeNo,
|
||||||
Subject: subject,
|
Subject: detail.Subject,
|
||||||
TotalAmount: amountReal.StringFixed(2),
|
TotalAmount: amountReal.StringFixed(2),
|
||||||
TimeExpire: expire.Format("2006-01-02 15:04:05"),
|
TimeExpire: expireAt.Format("2006-01-02 15:04:05"),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -133,8 +94,8 @@ func (s *tradeService) CreateTrade(uid int32, now time.Time, payment *CreateTrad
|
|||||||
Appid: &env.WechatPayAppId,
|
Appid: &env.WechatPayAppId,
|
||||||
Mchid: &env.WechatPayMchId,
|
Mchid: &env.WechatPayMchId,
|
||||||
OutTradeNo: &tradeNo,
|
OutTradeNo: &tradeNo,
|
||||||
Description: &subject,
|
Description: &detail.Subject,
|
||||||
TimeExpire: &expire,
|
TimeExpire: &expireAt,
|
||||||
NotifyUrl: &env.WechatPayCallbackUrl,
|
NotifyUrl: &env.WechatPayCallbackUrl,
|
||||||
Amount: &native.Amount{
|
Amount: &native.Amount{
|
||||||
Total: u.P(amountReal.Mul(decimal.NewFromInt(100)).Round(0).IntPart()),
|
Total: u.P(amountReal.Mul(decimal.NewFromInt(100)).Round(0).IntPart()),
|
||||||
@@ -151,8 +112,8 @@ func (s *tradeService) CreateTrade(uid int32, now time.Time, payment *CreateTrad
|
|||||||
SpAppid: &env.WechatPayAppId,
|
SpAppid: &env.WechatPayAppId,
|
||||||
SpMchid: &env.WechatPayMchId,
|
SpMchid: &env.WechatPayMchId,
|
||||||
OutTradeNo: &tradeNo,
|
OutTradeNo: &tradeNo,
|
||||||
Description: &subject,
|
Description: &detail.Subject,
|
||||||
TimeExpire: &expire,
|
TimeExpire: &expireAt,
|
||||||
NotifyUrl: &env.WechatPayCallbackUrl,
|
NotifyUrl: &env.WechatPayCallbackUrl,
|
||||||
Amount: &h5.Amount{
|
Amount: &h5.Amount{
|
||||||
Total: u.P(amountReal.Mul(decimal.NewFromInt(100)).Round(0).IntPart()),
|
Total: u.P(amountReal.Mul(decimal.NewFromInt(100)).Round(0).IntPart()),
|
||||||
@@ -174,18 +135,17 @@ func (s *tradeService) CreateTrade(uid int32, now time.Time, payment *CreateTrad
|
|||||||
payType = g.SftAlipay
|
payType = g.SftAlipay
|
||||||
case m.TradeMethodSftWechat:
|
case m.TradeMethodSftWechat:
|
||||||
payType = g.SftWeChat
|
payType = g.SftWeChat
|
||||||
default:
|
|
||||||
panic("unhandled default case")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := g.SFTPay.PaymentScanPay(&g.PaymentScanPayReq{
|
resp, err := g.SFTPay.PaymentScanPay(&g.PaymentScanPayReq{
|
||||||
MchOrderNo: tradeNo,
|
MchOrderNo: tradeNo,
|
||||||
Subject: subject,
|
Subject: detail.Subject,
|
||||||
Body: subject,
|
Body: detail.Subject,
|
||||||
Amount: amountReal.Mul(decimal.NewFromInt(100)).Round(0).IntPart(),
|
Amount: amountReal.Mul(decimal.NewFromInt(100)).Round(0).IntPart(),
|
||||||
PayType: payType,
|
PayType: payType,
|
||||||
Currency: "cny",
|
Currency: "cny",
|
||||||
ClientIp: "123.52.74.23",
|
ClientIp: "123.52.74.23",
|
||||||
OrderTimeout: u.P(expire.Format("2006-01-02 15:04:05")),
|
OrderTimeout: u.P(expireAt.Format("2006-01-02 15:04:05")),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -196,24 +156,24 @@ func (s *tradeService) CreateTrade(uid int32, now time.Time, payment *CreateTrad
|
|||||||
case
|
case
|
||||||
method == m.TradeMethodSftAlipay && platform == m.TradePlatformMobile,
|
method == m.TradeMethodSftAlipay && platform == m.TradePlatformMobile,
|
||||||
method == m.TradeMethodSftWechat && platform == m.TradePlatformMobile:
|
method == m.TradeMethodSftWechat && platform == m.TradePlatformMobile:
|
||||||
|
|
||||||
var payType g.SftPayType
|
var payType g.SftPayType
|
||||||
switch method {
|
switch method {
|
||||||
case m.TradeMethodSftAlipay:
|
case m.TradeMethodSftAlipay:
|
||||||
payType = g.SftAlipay
|
payType = g.SftAlipay
|
||||||
case m.TradeMethodSftWechat:
|
case m.TradeMethodSftWechat:
|
||||||
payType = g.SftWeChat
|
payType = g.SftWeChat
|
||||||
default:
|
|
||||||
panic("unhandled default case")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := g.SFTPay.PaymentH5Pay(&g.PaymentH5PayReq{
|
resp, err := g.SFTPay.PaymentH5Pay(&g.PaymentH5PayReq{
|
||||||
MchOrderNo: tradeNo,
|
MchOrderNo: tradeNo,
|
||||||
Subject: subject,
|
Subject: detail.Subject,
|
||||||
Body: subject,
|
Body: detail.Subject,
|
||||||
Amount: amountReal.Mul(decimal.NewFromInt(100)).Round(0).IntPart(),
|
Amount: amountReal.Mul(decimal.NewFromInt(100)).Round(0).IntPart(),
|
||||||
PayType: payType,
|
PayType: payType,
|
||||||
Currency: "cny",
|
Currency: "cny",
|
||||||
ClientIp: "123.52.74.23",
|
ClientIp: "123.52.74.23",
|
||||||
OrderTimeout: u.P(expire.Format("2006-01-02 15:04:05")),
|
OrderTimeout: u.P(expireAt.Format("2006-01-02 15:04:05")),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -228,11 +188,11 @@ func (s *tradeService) CreateTrade(uid int32, now time.Time, payment *CreateTrad
|
|||||||
|
|
||||||
// 保存订单
|
// 保存订单
|
||||||
err = q.Trade.Create(&m.Trade{
|
err = q.Trade.Create(&m.Trade{
|
||||||
UserID: uid,
|
UserID: user.ID,
|
||||||
InnerNo: tradeNo,
|
InnerNo: tradeNo,
|
||||||
Type: tType,
|
Type: detail.Type,
|
||||||
Subject: subject,
|
Subject: detail.Subject,
|
||||||
Amount: amount,
|
Amount: detail.Actual,
|
||||||
Method: method,
|
Method: method,
|
||||||
Platform: platform,
|
Platform: platform,
|
||||||
PaymentURL: &paymentUrl,
|
PaymentURL: &paymentUrl,
|
||||||
@@ -242,295 +202,240 @@ func (s *tradeService) CreateTrade(uid int32, now time.Time, payment *CreateTrad
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 缓存产品数据
|
// 缓存产品数据
|
||||||
serialized, err := product.Serialize()
|
w := bytes.Buffer{}
|
||||||
if err != nil {
|
gob.NewEncoder(&w).Encode(detail)
|
||||||
return nil, core.NewServErr("序列化产品信息失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = g.Redis.Set(
|
err = g.Redis.Set(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
tradeProductKey(tradeNo),
|
tradeProductKey(tradeNo),
|
||||||
serialized,
|
w.Bytes(),
|
||||||
time.Duration(env.TradeExpire+10)*time.Second,
|
expireIn,
|
||||||
).Err()
|
).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, core.NewServErr("保存购买信息失败", err)
|
return nil, core.NewServErr("保存购买信息失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交异步关闭事件
|
// 提交异步关闭事件
|
||||||
closeAt := now.Add(time.Duration(env.TradeExpire) * time.Second)
|
_, err = g.Asynq.Enqueue(e.NewCloseTradeTask(user.ID, tradeNo, method), asynq.ProcessAt(expireAt))
|
||||||
_, err = g.Asynq.Enqueue(e.NewCancelTrade(e.CompleteTradeData{
|
|
||||||
TradeNo: tradeNo,
|
|
||||||
Method: method,
|
|
||||||
}), asynq.ProcessAt(closeAt))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, core.NewServErr("提交异步关闭事件失败", err)
|
return nil, core.NewServErr("提交异步关闭事件失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &CreateTradeResult{
|
return &CreateTradeResult{
|
||||||
PaymentUrl: paymentUrl,
|
PayUrl: paymentUrl,
|
||||||
TradeNo: tradeNo,
|
TradeNo: tradeNo,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 完成交易
|
// 完成交易
|
||||||
func (s *tradeService) CompleteTrade(data *ModifyTradeData) error {
|
func (s *tradeService) CompleteTrade(user *m.User, ref *TradeRef) error {
|
||||||
return g.Redsync.WithLock(tradeLockKey(data.TradeNo), func() error {
|
|
||||||
|
|
||||||
// 检查订单状态
|
// 检查订单状态
|
||||||
result, err := s.CheckTrade(data)
|
result, err := s.CheckTrade(ref)
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("检查订单状态失败", err)
|
|
||||||
}
|
|
||||||
if result.Status != m.TradeStatusSuccess {
|
|
||||||
switch result.Status {
|
|
||||||
case m.TradeStatusPending:
|
|
||||||
return core.NewBizErr("订单未支付")
|
|
||||||
case m.TradeStatusCanceled:
|
|
||||||
return core.NewBizErr("订单已过期")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新交易状态
|
|
||||||
trade, err := completeTrade(&OnTradeCompletedData{
|
|
||||||
data.TradeNo,
|
|
||||||
result.TransId,
|
|
||||||
result.Success,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("处理交易失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理交易完成事件
|
|
||||||
err = afterTradeComplete(trade)
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("处理交易完成事件失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
func (s *tradeService) OnTradeCompleted(data *OnTradeCompletedData) error {
|
|
||||||
return g.Redsync.WithLock(tradeLockKey(data.TradeNo), func() error {
|
|
||||||
|
|
||||||
// 更新交易状态
|
|
||||||
trade, err := completeTrade(data)
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("处理交易失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理交易完成事件
|
|
||||||
err = afterTradeComplete(trade)
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("处理交易完成事件失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
func completeTrade(data *OnTradeCompletedData) (*m.Trade, error) {
|
|
||||||
var trade = new(m.Trade)
|
|
||||||
var err = q.Q.Transaction(func(tx *q.Query) error {
|
|
||||||
var tradeNo = data.TradeNo
|
|
||||||
var transId = data.TransId
|
|
||||||
var payment = data.Payment
|
|
||||||
var acquirer = data.Acquirer
|
|
||||||
var paidAt = data.Time
|
|
||||||
|
|
||||||
// 获取交易信息
|
|
||||||
var err error
|
|
||||||
trade, err = q.Trade.
|
|
||||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
|
||||||
Take()
|
|
||||||
if err != nil {
|
|
||||||
return core.NewBizErr("获取交易信息失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查交易状态
|
|
||||||
switch trade.Status {
|
|
||||||
case m.TradeStatusCanceled:
|
|
||||||
return core.NewBizErr("交易已取消")
|
|
||||||
case m.TradeStatusSuccess:
|
|
||||||
return nil // 跳过更新交易信息
|
|
||||||
case m.TradeStatusPending:
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新交易信息
|
|
||||||
trade.Status = m.TradeStatusSuccess
|
|
||||||
trade.OuterNo = &transId
|
|
||||||
trade.Payment = payment
|
|
||||||
trade.Acquirer = u.P(acquirer)
|
|
||||||
trade.CompletedAt = u.P(paidAt)
|
|
||||||
rs, err := q.Trade.
|
|
||||||
Where(q.Trade.InnerNo.Eq(tradeNo), q.Trade.Status.Eq(int(m.TradeStatusPending))).
|
|
||||||
Updates(trade)
|
|
||||||
if rs.RowsAffected == 0 {
|
|
||||||
return core.NewBizErr("交易状态已发生变化")
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("更新交易信息失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return core.NewServErr("检查订单状态失败", err)
|
||||||
} else {
|
}
|
||||||
return trade, err
|
if result.Status != m.TradeStatusSuccess {
|
||||||
|
switch result.Status {
|
||||||
|
case m.TradeStatusPending:
|
||||||
|
return core.NewBizErr("订单未支付")
|
||||||
|
case m.TradeStatusCanceled:
|
||||||
|
return core.NewBizErr("订单已过期")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
func afterTradeComplete(trade *m.Trade) error {
|
|
||||||
|
|
||||||
// 恢复购买信息
|
// 更新交易状态
|
||||||
productData, err := g.Redis.Get(context.Background(), tradeProductKey(trade.InnerNo)).Result()
|
err = s.OnCompleteTrade(user, ref.TradeNo, result.TransId, &result.Success)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("处理交易失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (s *tradeService) OnCompleteTrade(user *m.User, interNo string, outerNo string, result *TradeSuccessResult) error {
|
||||||
|
|
||||||
|
// 获取交易信息
|
||||||
|
trade, err := q.Trade.
|
||||||
|
Where(q.Trade.InnerNo.Eq(interNo)).
|
||||||
|
Take()
|
||||||
|
if err != nil {
|
||||||
|
return core.NewBizErr("获取交易信息失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查交易状态
|
||||||
|
switch trade.Status {
|
||||||
|
case m.TradeStatusCanceled:
|
||||||
|
return core.NewBizErr("交易已取消")
|
||||||
|
case m.TradeStatusSuccess:
|
||||||
|
return nil // 跳过更新交易信息
|
||||||
|
case m.TradeStatusPending:
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复购买信息;如果反序列化失败,检查开头 init 函数中是否注册了对应的 struct 类型
|
||||||
|
detailBytes, err := g.Redis.Get(context.Background(), tradeProductKey(interNo)).Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return core.NewServErr("恢复购买信息失败", err)
|
return core.NewServErr("恢复购买信息失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行资源创建
|
var detail TradeDetail
|
||||||
var ComplementEvents = []CompleteEvent{
|
r := bytes.NewReader(detailBytes)
|
||||||
ResourceOnTradeComplete{},
|
if err := gob.NewDecoder(r).Decode(&detail); err != nil {
|
||||||
UserOnTradeComplete{},
|
return core.NewServErr("解析购买信息失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, event := range ComplementEvents {
|
err = q.Q.Transaction(func(q *q.Query) error {
|
||||||
info, ok := event.Check(trade.Type)
|
// 更新交易信息
|
||||||
if !ok {
|
_, err := q.Trade.
|
||||||
continue
|
Where(
|
||||||
|
q.Trade.InnerNo.Eq(interNo),
|
||||||
|
q.Trade.Status.Eq(int(m.TradeStatusPending)),
|
||||||
|
).
|
||||||
|
UpdateSimple(
|
||||||
|
q.Trade.Status.Value(int(m.TradeStatusSuccess)),
|
||||||
|
q.Trade.OuterNo.Value(outerNo),
|
||||||
|
q.Trade.Payment.Value(result.Actual),
|
||||||
|
q.Trade.Acquirer.Value(int(result.Acquirer)),
|
||||||
|
q.Trade.CompletedAt.Value(result.Time),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("更新交易信息失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = info.Deserialize(productData)
|
switch trade.Type {
|
||||||
if err != nil {
|
case m.TradeTypeRecharge:
|
||||||
return core.NewServErr("反序列化购买信息失败", err)
|
// 更新用户余额
|
||||||
|
if err := User.UpdateBalance(q, user, detail.Actual, "充值余额", nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成账单
|
||||||
|
err = Bill.CreateForBalance(q, user.ID, trade.ID, &detail)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("生成账单失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
case m.TradeTypePurchase:
|
||||||
|
data, ok := detail.Product.(*CreateResourceData)
|
||||||
|
if !ok {
|
||||||
|
return core.NewServErr("购买信息解析失败", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存套餐
|
||||||
|
resource, err := Resource.Create(q, user.ID, result.Time, data)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("创建套餐失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成账单
|
||||||
|
err = Bill.CreateForResource(q, user.ID, resource.ID, &trade.ID, &detail)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("生成账单失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 核销优惠券
|
||||||
|
if detail.CouponId != nil {
|
||||||
|
err = Coupon.UseCoupon(q, *detail.CouponId)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("核销优惠券失败", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = event.OnTradeComplete(info, trade)
|
return nil
|
||||||
if err != nil {
|
})
|
||||||
return core.NewServErr("处理交易完成事件失败", err)
|
if err != nil {
|
||||||
}
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取消交易
|
// 取消交易
|
||||||
func (s *tradeService) CancelTrade(data *ModifyTradeData, now time.Time) error {
|
func (s *tradeService) CancelTrade(ref *TradeRef) error {
|
||||||
tradeNo := data.TradeNo
|
now := time.Now()
|
||||||
method := data.Method
|
|
||||||
|
|
||||||
return g.Redsync.WithLock(tradeLockKey(tradeNo), func() error {
|
switch ref.Method {
|
||||||
switch method {
|
case m.TradeMethodAlipay:
|
||||||
|
resp, err := g.Alipay.TradeCancel(context.Background(), alipay.TradeCancel{
|
||||||
case m.TradeMethodAlipay:
|
OutTradeNo: ref.TradeNo,
|
||||||
resp, err := g.Alipay.TradeCancel(context.Background(), alipay.TradeCancel{
|
})
|
||||||
OutTradeNo: tradeNo,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("上游取消交易失败", err)
|
|
||||||
}
|
|
||||||
if resp.Code != alipay.CodeSuccess {
|
|
||||||
slog.Error("支付宝交易取消失败", "code", resp.Code, "sub_code", resp.SubCode, "msg", resp.Msg)
|
|
||||||
return errors.New("上游取消交易失败")
|
|
||||||
}
|
|
||||||
|
|
||||||
case m.TradeMethodWechat:
|
|
||||||
resp, err := g.WechatPay.Native.CloseOrder(context.Background(), native.CloseOrderRequest{
|
|
||||||
Mchid: &env.WechatPayMchId,
|
|
||||||
OutTradeNo: &tradeNo,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("上游取消交易失败", err)
|
|
||||||
}
|
|
||||||
if resp.Response.StatusCode != http.StatusNoContent {
|
|
||||||
body, err := io.ReadAll(resp.Response.Body)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("读取微信交易取消响应失败", "error", err)
|
|
||||||
return core.NewServErr("上游取消交易失败", err)
|
|
||||||
}
|
|
||||||
slog.Error("微信交易取消失败", "code", resp.Response.StatusCode, "body", string(body))
|
|
||||||
return errors.New("上游取消交易失败")
|
|
||||||
}
|
|
||||||
|
|
||||||
case m.TradeMethodSft, m.TradeMethodSftAlipay, m.TradeMethodSftWechat:
|
|
||||||
_, err := g.SFTPay.OrderClose(&g.OrderCloseReq{
|
|
||||||
MchOrderNo: &tradeNo,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
slog.Debug(fmt.Sprintf("订单无需关闭: %s", err.Error()))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return ErrTransactionNotSupported
|
|
||||||
}
|
|
||||||
|
|
||||||
err := cancelTrade(tradeNo, now)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return core.NewServErr("上游取消交易失败", err)
|
||||||
|
}
|
||||||
|
if resp.Code != alipay.CodeSuccess {
|
||||||
|
slog.Error("支付宝交易取消失败", "code", resp.Code, "sub_code", resp.SubCode, "msg", resp.Msg)
|
||||||
|
return errors.New("上游取消交易失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
case m.TradeMethodWechat:
|
||||||
})
|
resp, err := g.WechatPay.Native.CloseOrder(context.Background(), native.CloseOrderRequest{
|
||||||
}
|
Mchid: &env.WechatPayMchId,
|
||||||
func (s *tradeService) OnTradeCanceled(tradeNo string, now time.Time) error {
|
OutTradeNo: &ref.TradeNo,
|
||||||
err := g.Redsync.WithLock(tradeLockKey(tradeNo), func() error {
|
})
|
||||||
return cancelTrade(tradeNo, now)
|
if err != nil {
|
||||||
})
|
return core.NewServErr("上游取消交易失败", err)
|
||||||
if err != nil {
|
}
|
||||||
return core.NewServErr("处理交易取消失败", err)
|
if resp.Response.StatusCode != http.StatusNoContent {
|
||||||
|
body, err := io.ReadAll(resp.Response.Body)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("读取微信交易取消响应失败", "error", err)
|
||||||
|
return core.NewServErr("上游取消交易失败", err)
|
||||||
|
}
|
||||||
|
slog.Error("微信交易取消失败", "code", resp.Response.StatusCode, "body", string(body))
|
||||||
|
return errors.New("上游取消交易失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
case m.TradeMethodSft, m.TradeMethodSftAlipay, m.TradeMethodSftWechat:
|
||||||
|
_, err := g.SFTPay.OrderClose(&g.OrderCloseReq{
|
||||||
|
MchOrderNo: &ref.TradeNo,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
slog.Debug(fmt.Sprintf("订单无需关闭: %s", err.Error()))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ErrTransactionNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err := s.OnCancelTrade(ref.TradeNo, now)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func cancelTrade(tradeNo string, now time.Time) error {
|
func (s *tradeService) OnCancelTrade(tradeNo string, now time.Time) error {
|
||||||
return q.Q.Transaction(func(q *q.Query) error {
|
_, err := q.Trade.
|
||||||
// 获取交易信息
|
Where(
|
||||||
var status m.TradeStatus
|
q.Trade.InnerNo.Eq(tradeNo),
|
||||||
err := q.Trade.
|
q.Trade.Status.Eq(int(m.TradeStatusPending)),
|
||||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
).
|
||||||
Select(q.Trade.Status).
|
UpdateSimple(
|
||||||
Scan(&status)
|
q.Trade.Status.Value(int(m.TradeStatusCanceled)),
|
||||||
if err != nil {
|
q.Trade.CanceledAt.Value(now),
|
||||||
return core.NewBizErr("获取交易信息失败", err)
|
)
|
||||||
}
|
if err != nil {
|
||||||
|
return core.NewServErr("更新交易状态失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
// 检查交易状态
|
return nil
|
||||||
switch status {
|
|
||||||
case m.TradeStatusCanceled:
|
|
||||||
return core.NewBizErr("交易已取消")
|
|
||||||
case m.TradeStatusSuccess:
|
|
||||||
return core.NewBizErr("交易已完成")
|
|
||||||
case m.TradeStatusPending:
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新交易状态
|
|
||||||
_, err = q.Trade.
|
|
||||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
|
||||||
UpdateSimple(
|
|
||||||
q.Trade.Status.Value(int(m.TradeStatusCanceled)),
|
|
||||||
q.Trade.CanceledAt.Value(now),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("更新交易状态失败", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 交易退款
|
// 交易退款
|
||||||
func (s *tradeService) RefundTrade(data *ModifyTradeData) error {
|
func (s *tradeService) RefundTrade(ref *TradeRef) error {
|
||||||
panic("todo")
|
panic("todo")
|
||||||
}
|
}
|
||||||
func (s *tradeService) OnTradeRefunded(q *q.Query, tradeNo string, now time.Time) error {
|
func (s *tradeService) OnRefundTrade(q *q.Query, tradeNo string, now time.Time) error {
|
||||||
panic("todo")
|
panic("todo")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查交易状态
|
// 检查交易状态
|
||||||
func (s *tradeService) CheckTrade(data *ModifyTradeData) (*CheckTradeResult, error) {
|
func (s *tradeService) CheckTrade(ref *TradeRef) (*CheckTradeResult, error) {
|
||||||
var tradeNo = data.TradeNo
|
var tradeNo = ref.TradeNo
|
||||||
var method = data.Method
|
var method = ref.Method
|
||||||
|
|
||||||
// 检查交易号是否存在
|
// 检查交易号是否存在
|
||||||
var result = new(CheckTradeResult)
|
var result CheckTradeResult
|
||||||
switch method {
|
switch method {
|
||||||
|
|
||||||
// 支付宝
|
// 支付宝
|
||||||
@@ -560,9 +465,8 @@ func (s *tradeService) CheckTrade(data *ModifyTradeData) (*CheckTradeResult, err
|
|||||||
|
|
||||||
case alipay.TradeStatusSuccess, alipay.TradeStatusFinished:
|
case alipay.TradeStatusSuccess, alipay.TradeStatusFinished:
|
||||||
result.Status = m.TradeStatusSuccess
|
result.Status = m.TradeStatusSuccess
|
||||||
result.Success = &TradeSuccessResult{}
|
|
||||||
result.Success.Acquirer = m.TradeAcquirerAlipay
|
result.Success.Acquirer = m.TradeAcquirerAlipay
|
||||||
result.Success.Payment, err = decimal.NewFromString(resp.TotalAmount)
|
result.Success.Actual, err = decimal.NewFromString(resp.ReceiptAmount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -606,9 +510,8 @@ func (s *tradeService) CheckTrade(data *ModifyTradeData) (*CheckTradeResult, err
|
|||||||
|
|
||||||
case "SUCCESS", "REFUND":
|
case "SUCCESS", "REFUND":
|
||||||
result.Status = m.TradeStatusSuccess
|
result.Status = m.TradeStatusSuccess
|
||||||
result.Success = &TradeSuccessResult{}
|
|
||||||
result.Success.Acquirer = m.TradeAcquirerWechat
|
result.Success.Acquirer = m.TradeAcquirerWechat
|
||||||
result.Success.Payment = decimal.NewFromInt(*resp.Amount.PayerTotal).Div(decimal.NewFromInt(100))
|
result.Success.Actual = decimal.NewFromInt(*resp.Amount.PayerTotal).Div(decimal.NewFromInt(100))
|
||||||
result.Success.Time, err = time.Parse(time.RFC3339, *resp.SuccessTime)
|
result.Success.Time, err = time.Parse(time.RFC3339, *resp.SuccessTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -626,12 +529,12 @@ func (s *tradeService) CheckTrade(data *ModifyTradeData) (*CheckTradeResult, err
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 填充返回值
|
||||||
if resp.PayOrderId == nil {
|
if resp.PayOrderId == nil {
|
||||||
return nil, errors.New("商福通交易号不存在")
|
return nil, errors.New("商福通交易号不存在")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 填充返回值
|
|
||||||
result.TransId = *resp.PayOrderId
|
result.TransId = *resp.PayOrderId
|
||||||
|
|
||||||
switch resp.State {
|
switch resp.State {
|
||||||
|
|
||||||
case g.SftInit, g.SftTradeAwait, g.SftTradeFail:
|
case g.SftInit, g.SftTradeAwait, g.SftTradeFail:
|
||||||
@@ -642,7 +545,6 @@ func (s *tradeService) CheckTrade(data *ModifyTradeData) (*CheckTradeResult, err
|
|||||||
|
|
||||||
case g.SftTradeSuccess, g.SftTradeRefund, g.SftRefundIng:
|
case g.SftTradeSuccess, g.SftTradeRefund, g.SftRefundIng:
|
||||||
result.Status = m.TradeStatusSuccess
|
result.Status = m.TradeStatusSuccess
|
||||||
result.Success = &TradeSuccessResult{}
|
|
||||||
switch resp.PayType {
|
switch resp.PayType {
|
||||||
case "WECHAT":
|
case "WECHAT":
|
||||||
result.Success.Acquirer = m.TradeAcquirerWechat
|
result.Success.Acquirer = m.TradeAcquirerWechat
|
||||||
@@ -651,7 +553,7 @@ func (s *tradeService) CheckTrade(data *ModifyTradeData) (*CheckTradeResult, err
|
|||||||
case "UNIONPAY":
|
case "UNIONPAY":
|
||||||
result.Success.Acquirer = m.TradeAcquirerUnionPay
|
result.Success.Acquirer = m.TradeAcquirerUnionPay
|
||||||
}
|
}
|
||||||
result.Success.Payment = decimal.NewFromInt(resp.Amount).Div(decimal.NewFromInt(100))
|
result.Success.Actual = decimal.NewFromInt(resp.Amount).Div(decimal.NewFromInt(100))
|
||||||
result.Success.Time, err = time.Parse("2006-01-02 15:04:05", *resp.PayTime)
|
result.Success.Time, err = time.Parse("2006-01-02 15:04:05", *resp.PayTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -663,7 +565,7 @@ func (s *tradeService) CheckTrade(data *ModifyTradeData) (*CheckTradeResult, err
|
|||||||
return nil, ErrTransactionNotSupported
|
return nil, ErrTransactionNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func tradeProductKey(no string) string {
|
func tradeProductKey(no string) string {
|
||||||
@@ -675,17 +577,16 @@ func tradeLockKey(no string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CreateTradeData struct {
|
type CreateTradeData struct {
|
||||||
Platform m.TradePlatform `json:"platform" validate:"required"`
|
Platform m.TradePlatform `json:"platform" validate:"required"`
|
||||||
Method m.TradeMethod `json:"method" validate:"required"`
|
Method m.TradeMethod `json:"method" validate:"required"`
|
||||||
CouponCode *string `json:"coupon_code"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateTradeResult struct {
|
type CreateTradeResult struct {
|
||||||
TradeNo string
|
PayUrl string `json:"pay_url"`
|
||||||
PaymentUrl string
|
TradeNo string `json:"trade_no"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModifyTradeData struct {
|
type TradeRef struct {
|
||||||
TradeNo string `json:"trade_no" query:"trade_no" validate:"required"`
|
TradeNo string `json:"trade_no" query:"trade_no" validate:"required"`
|
||||||
Method m.TradeMethod `json:"method" validate:"required"`
|
Method m.TradeMethod `json:"method" validate:"required"`
|
||||||
}
|
}
|
||||||
@@ -693,12 +594,12 @@ type ModifyTradeData struct {
|
|||||||
type CheckTradeResult struct {
|
type CheckTradeResult struct {
|
||||||
TransId string
|
TransId string
|
||||||
Status m.TradeStatus
|
Status m.TradeStatus
|
||||||
Success *TradeSuccessResult
|
Success TradeSuccessResult
|
||||||
}
|
}
|
||||||
|
|
||||||
type TradeSuccessResult struct {
|
type TradeSuccessResult struct {
|
||||||
Acquirer m.TradeAcquirer
|
Acquirer m.TradeAcquirer
|
||||||
Payment decimal.Decimal
|
Actual decimal.Decimal
|
||||||
Time time.Time
|
Time time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -708,17 +609,20 @@ type OnTradeCompletedData struct {
|
|||||||
*TradeSuccessResult
|
*TradeSuccessResult
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductInfo interface {
|
type ProductData interface {
|
||||||
GetType() m.TradeType
|
TradeDetail(user *m.User) (*TradeDetail, error)
|
||||||
GetSubject() string
|
|
||||||
GetAmount() decimal.Decimal
|
|
||||||
Serialize() (string, error)
|
|
||||||
Deserialize(str string) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompleteEvent interface {
|
type TradeDetail struct {
|
||||||
Check(t m.TradeType) (ProductInfo, bool)
|
Product ProductData `json:"product"`
|
||||||
OnTradeComplete(info ProductInfo, trade *m.Trade) error
|
Type m.TradeType `json:"type"`
|
||||||
|
Subject string `json:"subject"`
|
||||||
|
Amount decimal.Decimal `json:"amount"`
|
||||||
|
Actual decimal.Decimal `json:"actual"`
|
||||||
|
DiscountId *int32 `json:"discount_id,omitempty"`
|
||||||
|
Discount *m.ProductDiscount `json:"-"` // 不应缓存
|
||||||
|
CouponId *int32 `json:"coupon_id,omitempty"`
|
||||||
|
Coupon *m.Coupon `json:"-"` // 不应缓存
|
||||||
}
|
}
|
||||||
|
|
||||||
type TradeErr string
|
type TradeErr string
|
||||||
|
|||||||
@@ -1,66 +1,80 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"platform/pkg/u"
|
||||||
"platform/web/core"
|
"platform/web/core"
|
||||||
g "platform/web/globals"
|
|
||||||
m "platform/web/models"
|
m "platform/web/models"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var User = &userService{}
|
var User = &userService{}
|
||||||
|
|
||||||
type userService struct{}
|
type userService struct{}
|
||||||
|
|
||||||
func (s *userService) UpdateBalanceByTrade(uid int32, info *RechargeProductInfo, trade *m.Trade) (err error) {
|
func (s *userService) Get(q *q.Query, uid int32) (*m.User, error) {
|
||||||
err = g.Redsync.WithLock(userBalanceKey(uid), func() error {
|
|
||||||
return q.Q.Transaction(func(q *q.Query) error {
|
|
||||||
|
|
||||||
err = updateBalance(q, uid, info)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成账单
|
|
||||||
subject := info.GetSubject()
|
|
||||||
amount := info.GetAmount()
|
|
||||||
err = q.Bill.Create(newForRecharge(uid, Bill.GenNo(), subject, amount, trade))
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("生成账单失败", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return core.NewServErr("更新用户余额失败")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func updateBalance(q *q.Query, uid int32, info *RechargeProductInfo) error {
|
|
||||||
user, err := q.User.
|
user, err := q.User.
|
||||||
Where(q.User.ID.Eq(uid)).Take()
|
Where(q.User.ID.Eq(uid)).Take()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return core.NewServErr("查询用户失败", err)
|
return nil, core.NewServErr("查询用户失败", err)
|
||||||
|
}
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *userService) UpdateBalanceByAdmin(user *m.User, newBalance decimal.Decimal, adminId *int32) error {
|
||||||
|
if user == nil {
|
||||||
|
return core.NewServErr("用户不存在")
|
||||||
}
|
}
|
||||||
|
|
||||||
amount := info.GetAmount()
|
amount := newBalance.Sub(user.Balance)
|
||||||
|
if amount.IsZero() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return q.Q.Transaction(func(q *q.Query) error {
|
||||||
|
return s.UpdateBalance(q, user, amount, "管理员修改余额", adminId)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *userService) UpdateBalance(q *q.Query, user *m.User, amount decimal.Decimal, remark string, adminId *int32) error {
|
||||||
balance := user.Balance.Add(amount)
|
balance := user.Balance.Add(amount)
|
||||||
if balance.IsNegative() {
|
if balance.IsNegative() {
|
||||||
return core.NewServErr("用户余额不足")
|
return core.NewServErr("用户余额不足")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = q.User.
|
// 更新余额
|
||||||
Where(q.User.ID.Eq(user.ID)).
|
_, err := q.User.
|
||||||
UpdateSimple(q.User.Balance.Value(balance))
|
Where(
|
||||||
|
q.User.ID.Eq(user.ID),
|
||||||
|
q.User.Balance.Eq(user.Balance),
|
||||||
|
).
|
||||||
|
UpdateSimple(
|
||||||
|
q.User.Balance.Value(balance),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return core.NewServErr("更新用户余额失败", err)
|
return core.NewServErr("更新用户余额失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增动账记录
|
||||||
|
err = q.BalanceActivity.Create(&m.BalanceActivity{
|
||||||
|
UserID: user.ID,
|
||||||
|
AdminID: adminId,
|
||||||
|
Amount: amount.StringFixed(2),
|
||||||
|
BalancePrev: user.Balance.StringFixed(2),
|
||||||
|
BalanceCurr: balance.StringFixed(2),
|
||||||
|
Remark: &remark,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("新增动账记录失败", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,40 +82,154 @@ func userBalanceKey(uid int32) string {
|
|||||||
return fmt.Sprintf("user:%d:balance", uid)
|
return fmt.Sprintf("user:%d:balance", uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
type RechargeProductInfo struct {
|
type UpdateBalanceData struct {
|
||||||
Amount int `json:"amount"`
|
Amount int `json:"amount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RechargeProductInfo) GetType() m.TradeType {
|
func (data *UpdateBalanceData) TradeDetail(user *m.User) (*TradeDetail, error) {
|
||||||
return m.TradeTypeRecharge
|
amount := decimal.NewFromInt(int64(data.Amount)).Div(decimal.NewFromInt(100))
|
||||||
|
return &TradeDetail{
|
||||||
|
data,
|
||||||
|
m.TradeTypeRecharge,
|
||||||
|
fmt.Sprintf("账户充值 - %s元", amount.StringFixed(2)),
|
||||||
|
amount, amount,
|
||||||
|
nil, nil,
|
||||||
|
nil, nil,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RechargeProductInfo) GetSubject() string {
|
// CreateByAdmin 管理员创建用户的数据
|
||||||
return fmt.Sprintf("账户充值 - %s元", r.GetAmount().StringFixed(2))
|
func (s *userService) CreateByAdmin(data CreateUserByAdminData) error {
|
||||||
}
|
var hashedPwd *string
|
||||||
|
if data.Password != nil {
|
||||||
func (r *RechargeProductInfo) GetAmount() decimal.Decimal {
|
hash, err := bcrypt.GenerateFromPassword([]byte(*data.Password), bcrypt.DefaultCost)
|
||||||
return decimal.NewFromInt(int64(r.Amount)).Div(decimal.NewFromInt(100))
|
if err != nil {
|
||||||
}
|
return core.NewServErr("密码加密失败", err)
|
||||||
|
}
|
||||||
func (r *RechargeProductInfo) Serialize() (string, error) {
|
hashedPwd = u.P(string(hash))
|
||||||
bytes, err := json.Marshal(r)
|
|
||||||
return string(bytes), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RechargeProductInfo) Deserialize(str string) error {
|
|
||||||
return json.Unmarshal([]byte(str), r)
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserOnTradeComplete struct{}
|
|
||||||
|
|
||||||
func (u UserOnTradeComplete) Check(t m.TradeType) (ProductInfo, bool) {
|
|
||||||
if t == m.TradeTypeRecharge {
|
|
||||||
return &RechargeProductInfo{}, true
|
|
||||||
}
|
}
|
||||||
return nil, false
|
|
||||||
|
source := m.UserSourceAdd
|
||||||
|
err := q.User.Create(&m.User{
|
||||||
|
Phone: data.Phone,
|
||||||
|
AdminID: data.AdminID,
|
||||||
|
DiscountID: data.DiscountID,
|
||||||
|
Username: data.Username,
|
||||||
|
Email: data.Email,
|
||||||
|
Password: hashedPwd,
|
||||||
|
Source: &source,
|
||||||
|
Name: data.Name,
|
||||||
|
Avatar: data.Avatar,
|
||||||
|
Status: u.Else(data.Status, m.UserStatusEnabled),
|
||||||
|
ContactQQ: data.ContactQQ,
|
||||||
|
ContactWechat: data.ContactWechat,
|
||||||
|
})
|
||||||
|
if errors.Is(err, gorm.ErrDuplicatedKey) {
|
||||||
|
return core.NewBizErr("账号已存在,请检查手机号/用户名/邮箱是否重复")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u UserOnTradeComplete) OnTradeComplete(info ProductInfo, trade *m.Trade) error {
|
type CreateUserByAdminData struct {
|
||||||
return User.UpdateBalanceByTrade(trade.UserID, info.(*RechargeProductInfo), trade)
|
Phone string `json:"phone" validate:"required"`
|
||||||
|
AdminID *int32 `json:"admin_id"`
|
||||||
|
DiscountID *int32 `json:"discount_id"`
|
||||||
|
Username *string `json:"username"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
Password *string `json:"password"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Avatar *string `json:"avatar"`
|
||||||
|
Status *m.UserStatus `json:"status"`
|
||||||
|
ContactQQ *string `json:"contact_qq"`
|
||||||
|
ContactWechat *string `json:"contact_wechat"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateByAdmin 管理员更新用户的数据
|
||||||
|
func (s *userService) UpdateByAdmin(data UpdateUserByAdminData) error {
|
||||||
|
do := make([]field.AssignExpr, 0)
|
||||||
|
|
||||||
|
if data.Phone != nil {
|
||||||
|
do = append(do, q.User.Phone.Value(*data.Phone))
|
||||||
|
}
|
||||||
|
if data.AdminID != nil {
|
||||||
|
do = append(do, q.User.AdminID.Value(*data.AdminID))
|
||||||
|
}
|
||||||
|
if data.DiscountID != nil {
|
||||||
|
do = append(do, q.User.DiscountID.Value(*data.DiscountID))
|
||||||
|
}
|
||||||
|
if data.Username != nil {
|
||||||
|
do = append(do, q.User.Username.Value(*data.Username))
|
||||||
|
}
|
||||||
|
if data.Email != nil {
|
||||||
|
do = append(do, q.User.Email.Value(*data.Email))
|
||||||
|
}
|
||||||
|
if data.Password != nil {
|
||||||
|
hash, err := bcrypt.GenerateFromPassword([]byte(*data.Password), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewServErr("密码加密失败", err)
|
||||||
|
}
|
||||||
|
do = append(do, q.User.Password.Value(string(hash)))
|
||||||
|
}
|
||||||
|
if data.Name != nil {
|
||||||
|
do = append(do, q.User.Name.Value(*data.Name))
|
||||||
|
}
|
||||||
|
if data.Avatar != nil {
|
||||||
|
do = append(do, q.User.Avatar.Value(*data.Avatar))
|
||||||
|
}
|
||||||
|
if data.Status != nil {
|
||||||
|
do = append(do, q.User.Status.Value(int(*data.Status)))
|
||||||
|
}
|
||||||
|
if data.IDType != nil {
|
||||||
|
do = append(do, q.User.IDType.Value(int(*data.IDType)))
|
||||||
|
}
|
||||||
|
if data.IDNo != nil {
|
||||||
|
do = append(do, q.User.IDNo.Value(*data.IDNo))
|
||||||
|
}
|
||||||
|
if data.IDToken != nil {
|
||||||
|
do = append(do, q.User.IDToken.Value(*data.IDToken))
|
||||||
|
}
|
||||||
|
if data.ContactQQ != nil {
|
||||||
|
do = append(do, q.User.ContactQQ.Value(*data.ContactQQ))
|
||||||
|
}
|
||||||
|
if data.ContactWechat != nil {
|
||||||
|
do = append(do, q.User.ContactWechat.Value(*data.ContactWechat))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(do) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := q.User.Where(q.User.ID.Eq(data.ID)).UpdateSimple(do...)
|
||||||
|
if errors.Is(err, gorm.ErrDuplicatedKey) {
|
||||||
|
return core.NewBizErr("账号已存在,请检查手机号/用户名/邮箱是否重复")
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateUserByAdminData struct {
|
||||||
|
ID int32 `json:"id" validate:"required"`
|
||||||
|
Phone *string `json:"phone"`
|
||||||
|
AdminID *int32 `json:"admin_id"`
|
||||||
|
DiscountID *int32 `json:"discount_id"`
|
||||||
|
Username *string `json:"username"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
Password *string `json:"password"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Avatar *string `json:"avatar"`
|
||||||
|
Status *m.UserStatus `json:"status"`
|
||||||
|
IDType *m.UserIDType `json:"id_type"`
|
||||||
|
IDNo *string `json:"id_no"`
|
||||||
|
IDToken *string `json:"id_token"`
|
||||||
|
ContactQQ *string `json:"contact_qq"`
|
||||||
|
ContactWechat *string `json:"contact_wechat"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *userService) RemoveByAdmin(id int32) error {
|
||||||
|
_, err := q.User.Where(q.User.ID.Eq(id)).UpdateColumn(q.User.DeletedAt, time.Now())
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,29 +6,34 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"platform/web/events"
|
"platform/web/events"
|
||||||
|
q "platform/web/queries"
|
||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hibiken/asynq"
|
"github.com/hibiken/asynq"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleCompleteTrade(_ context.Context, task *asynq.Task) (err error) {
|
func HandleCompleteTrade(_ context.Context, task *asynq.Task) error {
|
||||||
event := new(events.CompleteTradeData)
|
var event events.CloseTradeData
|
||||||
err = json.Unmarshal(task.Payload(), event)
|
if err := json.Unmarshal(task.Payload(), &event); err != nil {
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("解析任务参数失败: %w", err)
|
return fmt.Errorf("解析任务参数失败: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data := &s.ModifyTradeData{
|
data := s.TradeRef{
|
||||||
TradeNo: event.TradeNo,
|
TradeNo: event.TradeNo,
|
||||||
Method: event.Method,
|
Method: event.Method,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Trade.CompleteTrade(data)
|
// 尝试完成交易
|
||||||
|
user, err := s.User.Get(q.Q, event.UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return fmt.Errorf("获取用户失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.Trade.CompleteTrade(user, &data); err != nil {
|
||||||
slog.Debug("完成交易失败[异步结束订单]", "err", err)
|
slog.Debug("完成交易失败[异步结束订单]", "err", err)
|
||||||
err = s.Trade.CancelTrade(data, time.Now())
|
|
||||||
if err != nil {
|
// 交易无法完成,关闭交易
|
||||||
|
if err := s.Trade.CancelTrade(&data); err != nil {
|
||||||
return fmt.Errorf("取消交易失败[异步结束订单]: %w", err)
|
return fmt.Errorf("取消交易失败[异步结束订单]: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ func RunTask(ctx context.Context) error {
|
|||||||
|
|
||||||
var mux = asynq.NewServeMux()
|
var mux = asynq.NewServeMux()
|
||||||
mux.HandleFunc(events.RemoveChannel, tasks.HandleRemoveChannel)
|
mux.HandleFunc(events.RemoveChannel, tasks.HandleRemoveChannel)
|
||||||
mux.HandleFunc(events.CompleteTrade, tasks.HandleCompleteTrade)
|
mux.HandleFunc(events.CloseTrade, tasks.HandleCompleteTrade)
|
||||||
|
|
||||||
// 停止服务
|
// 停止服务
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
Reference in New Issue
Block a user