Compare commits
12 Commits
v1.3.0
...
fd475d3e63
| Author | SHA1 | Date | |
|---|---|---|---|
| fd475d3e63 | |||
| 9b3546b45f | |||
| b8c8c7d7b1 | |||
| 58b8849d8d | |||
| 46d326638b | |||
| cfbe751af7 | |||
| 624a5ff2c0 | |||
| 7d7b979b66 | |||
| 3040b10eed | |||
| 3fb3a8026f | |||
| fccb83c0e5 | |||
| c684523cb8 |
57
.env.example
Normal file
57
.env.example
Normal file
@@ -0,0 +1,57 @@
|
||||
# 应用配置
|
||||
RUN_MODE=development
|
||||
DEBUG_HTTP_DUMP=false
|
||||
|
||||
# 数据库配置
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=5432
|
||||
DB_NAME=app
|
||||
DB_USERNAME=dev
|
||||
DB_PASSWORD=dev
|
||||
|
||||
# redis 配置
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PORT=6379
|
||||
|
||||
# otel 配置
|
||||
OTEL_HOST=127.0.0.1
|
||||
OTEL_PORT=4317
|
||||
|
||||
# 白银节点
|
||||
BAIYIN_CLOUD_URL=
|
||||
BAIYIN_TOKEN_URL=
|
||||
|
||||
# 京东实名
|
||||
IDEN_ACCESS_KEY=
|
||||
IDEN_SECRET_KEY=
|
||||
IDEN_CALLBACK_URL=
|
||||
|
||||
# 支付宝(暂时弃用,但是需要配置)
|
||||
ALIPAY_APP_ID=
|
||||
ALIPAY_APP_PRIVATE_KEY=
|
||||
ALIPAY_PUBLIC_KEY=
|
||||
ALIPAY_API_CERT=
|
||||
|
||||
# 微信支付(暂时弃用,但是需要配置)
|
||||
WECHATPAY_APP_ID=
|
||||
WECHATPAY_MCH_ID=
|
||||
WECHATPAY_MCH_PRIVATE_KEY_SERIAL=
|
||||
WECHATPAY_MCH_PRIVATE_KEY=
|
||||
WECHATPAY_PUBLIC_KEY_ID=
|
||||
WECHATPAY_PUBLIC_KEY=
|
||||
WECHATPAY_API_CERT=
|
||||
WECHATPAY_CALLBACK_URL=
|
||||
|
||||
# 阿里云
|
||||
ALIYUN_ACCESS_KEY=
|
||||
ALIYUN_ACCESS_KEY_SECRET=
|
||||
ALIYUN_SMS_SIGNATURE=
|
||||
ALIYUN_SMS_TEMPLATE_LOGIN=
|
||||
|
||||
# 商福通
|
||||
SFTPAY_ENABLE=
|
||||
SFTPAY_APP_ID=
|
||||
SFTPAY_ROUTE_ID=
|
||||
SFTPAY_APP_PRIVATE_KEY=
|
||||
SFTPAY_PUBLIC_KEY=
|
||||
SFTPAY_RETURN_URL=
|
||||
@@ -19,7 +19,7 @@ WORKDIR /app
|
||||
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||
RUN apk add --no-cache ca-certificates tzdata
|
||||
|
||||
COPY --from=builder /build/bin/platform_linux_amd64 /app/platform
|
||||
|
||||
@@ -66,6 +66,7 @@ func main() {
|
||||
m.Inquiry{},
|
||||
m.ProductDiscount{},
|
||||
m.BalanceActivity{},
|
||||
m.CouponUser{},
|
||||
)
|
||||
g.Execute()
|
||||
}
|
||||
|
||||
2
pkg/env/env.go
vendored
2
pkg/env/env.go
vendored
@@ -24,7 +24,6 @@ var (
|
||||
SessionAccessExpire = 60 * 60 * 2 // 访问令牌过期时间,单位秒。默认 2 小时
|
||||
SessionRefreshExpire = 60 * 60 * 24 * 7 // 刷新令牌过期时间,单位秒。默认 7 天
|
||||
DebugHttpDump = false // 是否打印请求和响应的原始数据
|
||||
DebugExternalChange = true // 是否实际执行外部非幂等接口调用,在开发调试时可以关闭,避免对外部数据产生影响
|
||||
|
||||
DbHost = "localhost"
|
||||
DbPort = "5432"
|
||||
@@ -106,7 +105,6 @@ func Init() {
|
||||
errs = append(errs, parse(&SessionAccessExpire, "SESSION_ACCESS_EXPIRE", true, nil))
|
||||
errs = append(errs, parse(&SessionRefreshExpire, "SESSION_REFRESH_EXPIRE", true, nil))
|
||||
errs = append(errs, parse(&DebugHttpDump, "DEBUG_HTTP_DUMP", true, nil))
|
||||
errs = append(errs, parse(&DebugExternalChange, "DEBUG_EXTERNAL_CHANGE", true, nil))
|
||||
|
||||
errs = append(errs, parse(&DbHost, "DB_HOST", true, nil))
|
||||
errs = append(errs, parse(&DbPort, "DB_PORT", true, nil))
|
||||
|
||||
30
pkg/u/u.go
30
pkg/u/u.go
@@ -53,6 +53,18 @@ func X[T comparable](v T) *T {
|
||||
return &v
|
||||
}
|
||||
|
||||
// N 零值视为 nil
|
||||
func N[T comparable](v *T) *T {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
var zero T
|
||||
if *v == zero {
|
||||
return nil
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// ====================
|
||||
// 数组
|
||||
// ====================
|
||||
@@ -110,3 +122,21 @@ func CombineErrors(errs []error) error {
|
||||
}
|
||||
return combinedErr
|
||||
}
|
||||
|
||||
// ====================
|
||||
// 业务
|
||||
// ====================
|
||||
|
||||
func MaskPhone(phone string) string {
|
||||
if len(phone) < 11 {
|
||||
return phone
|
||||
}
|
||||
return phone[:3] + "****" + phone[7:]
|
||||
}
|
||||
|
||||
func MaskIdNo(idNo string) string {
|
||||
if len(idNo) < 18 {
|
||||
return idNo
|
||||
}
|
||||
return idNo[:3] + "*********" + idNo[14:]
|
||||
}
|
||||
|
||||
@@ -1,21 +1,269 @@
|
||||
-- ====================
|
||||
-- region 填充数据
|
||||
-- region 客户端
|
||||
-- ====================
|
||||
|
||||
insert into client (type, spec, name, client_id, client_secret, redirect_uri) values (1, 3, 'web', 'web', '$2a$10$Ss12mXQgpYyo1CKIZ3URouDm.Lc2KcYJzsvEK2PTIXlv6fHQht45a', '');
|
||||
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', '长效静态', '长效静态');
|
||||
-- ====================
|
||||
-- region 管理员
|
||||
-- ====================
|
||||
|
||||
insert into admin (username, password, name, lock) values ('admin', '', '超级管理员', true);
|
||||
|
||||
-- ====================
|
||||
-- region 产品
|
||||
-- ====================
|
||||
|
||||
delete from product where true;
|
||||
|
||||
insert into product (code, name, description, sort) values ('short', '短效动态', '短效动态', 1);
|
||||
insert into product (code, name, description, sort) values ('long', '长效动态', '长效动态', 2);
|
||||
insert into product (code, name, description, sort) values ('static', '长效静态', '长效静态', 3);
|
||||
|
||||
-- ====================
|
||||
-- region 套餐
|
||||
-- ====================
|
||||
|
||||
delete from product_sku where true;
|
||||
|
||||
insert into product_sku (product_id, code, name, price, price_min, sort) values
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=quota&live=3&expire=0', '短效动态包量 3 分钟', 10.00, 10.00, 1),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=quota&live=5&expire=0', '短效动态包量 5 分钟', 10.00, 10.00, 2),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=quota&live=10&expire=0', '短效动态包量 10 分钟', 10.00, 10.00, 3),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=quota&live=15&expire=0', '短效动态包量 15 分钟', 10.00, 10.00, 4),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=quota&live=30&expire=0', '短效动态包量 30 分钟', 10.00, 10.00, 5),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=7', '短效动态包时 3 分钟 7 天', 10.00, 10.00, 6),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=7', '短效动态包时 5 分钟 7 天', 10.00, 10.00, 7),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=7', '短效动态包时 10 分钟 7 天', 10.00, 10.00, 8),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=7', '短效动态包时 15 分钟 7 天', 10.00, 10.00, 9),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=7', '短效动态包时 30 分钟 7 天', 10.00, 10.00, 10),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=15', '短效动态包时 3 分钟 15 天', 10.00, 10.00, 11),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=15', '短效动态包时 5 分钟 15 天', 10.00, 10.00, 12),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=15', '短效动态包时 10 分钟 15 天', 10.00, 10.00, 13),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=15', '短效动态包时 15 分钟 15 天', 10.00, 10.00, 14),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=15', '短效动态包时 30 分钟 15 天', 10.00, 10.00, 15),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=30', '短效动态包时 3 分钟 30 天', 10.00, 10.00, 16),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=30', '短效动态包时 5 分钟 30 天', 10.00, 10.00, 17),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=30', '短效动态包时 10 分钟 30 天', 10.00, 10.00, 18),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=30', '短效动态包时 15 分钟 30 天', 10.00, 10.00, 19),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=30', '短效动态包时 30 分钟 30 天', 10.00, 10.00, 20),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=90', '短效动态包时 3 分钟 90 天', 10.00, 10.00, 21),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=90', '短效动态包时 5 分钟 90 天', 10.00, 10.00, 22),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=90', '短效动态包时 10 分钟 90 天', 10.00, 10.00, 23),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=90', '短效动态包时 15 分钟 90 天', 10.00, 10.00, 24),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=90', '短效动态包时 30 分钟 90 天', 10.00, 10.00, 25),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=180', '短效动态包时 3 分钟 180 天', 10.00, 10.00, 26),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=180', '短效动态包时 5 分钟 180 天', 10.00, 10.00, 27),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=180', '短效动态包时 10 分钟 180 天', 10.00, 10.00, 28),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=180', '短效动态包时 15 分钟 180 天', 10.00, 10.00, 29),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=180', '短效动态包时 30 分钟 180 天', 10.00, 10.00, 30),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=365', '短效动态包时 3 分钟 365 天', 10.00, 10.00, 31),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=365', '短效动态包时 5 分钟 365 天', 10.00, 10.00, 32),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=365', '短效动态包时 10 分钟 365 天', 10.00, 10.00, 33),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=365', '短效动态包时 15 分钟 365 天', 10.00, 10.00, 34),
|
||||
((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=365', '短效动态包时 30 分钟 365 天', 10.00, 10.00, 35)
|
||||
;
|
||||
|
||||
insert into product_sku (product_id, code, name, price, price_min, sort) values
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=quota&live=60&expire=0', '长效动态包量 1 小时', 10.00, 10.00, 1),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=quota&live=240&expire=0', '长效动态包量 4 小时', 10.00, 10.00, 2),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=quota&live=480&expire=0', '长效动态包量 8 小时', 10.00, 10.00, 3),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=quota&live=720&expire=0', '长效动态包量 12 小时', 10.00, 10.00, 4),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=quota&live=1440&expire=0', '长效动态包量 24 小时', 10.00, 10.00, 5),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=7', '长效动态包时 1 小时 7 天', 10.00, 10.00, 6),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=7', '长效动态包时 4 小时 7 天', 10.00, 10.00, 7),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=7', '长效动态包时 8 小时 7 天', 10.00, 10.00, 8),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=7', '长效动态包时 12 小时 7 天', 10.00, 10.00, 9),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=7', '长效动态包时 24 小时 7 天', 10.00, 10.00, 10),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=15', '长效动态包时 1 小时 15 天', 10.00, 10.00, 11),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=15', '长效动态包时 4 小时 15 天', 10.00, 10.00, 12),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=15', '长效动态包时 8 小时 15 天', 10.00, 10.00, 13),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=15', '长效动态包时 12 小时 15 天', 10.00, 10.00, 14),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=15', '长效动态包时 24 小时 15 天', 10.00, 10.00, 15),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=30', '长效动态包时 1 小时 30 天', 10.00, 10.00, 16),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=30', '长效动态包时 4 小时 30 天', 10.00, 10.00, 17),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=30', '长效动态包时 8 小时 30 天', 10.00, 10.00, 18),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=30', '长效动态包时 12 小时 30 天', 10.00, 10.00, 19),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=30', '长效动态包时 24 小时 30 天', 10.00, 10.00, 20),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=90', '长效动态包时 1 小时 90 天', 10.00, 10.00, 21),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=90', '长效动态包时 4 小时 90 天', 10.00, 10.00, 22),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=90', '长效动态包时 8 小时 90 天', 10.00, 10.00, 23),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=90', '长效动态包时 12 小时 90 天', 10.00, 10.00, 24),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=90', '长效动态包时 24 小时 90 天', 10.00, 10.00, 25),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=180', '长效动态包时 1 小时 180 天', 10.00, 10.00, 26),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=180', '长效动态包时 4 小时 180 天', 10.00, 10.00, 27),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=180', '长效动态包时 8 小时 180 天', 10.00, 10.00, 28),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=180', '长效动态包时 12 小时 180 天', 10.00, 10.00, 29),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=180','长效动态包时 24 小时 180 天', 10.00, 10.00, 30),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=365', '长效动态包时 1 小时 365 天', 10.00, 10.00, 31),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=365', '长效动态包时 4 小时 365 天', 10.00, 10.00, 32),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=365', '长效动态包时 8 小时 365 天', 10.00, 10.00, 33),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=365', '长效动态包时 12 小时 365 天', 10.00, 10.00, 34),
|
||||
((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=365','长效动态包时 24 小时 365 天', 10.00, 10.00, 35)
|
||||
;
|
||||
|
||||
-- ====================
|
||||
-- region 权限
|
||||
-- ====================
|
||||
|
||||
delete from permission where true;
|
||||
insert into permission
|
||||
(name, description)
|
||||
values
|
||||
('permission:read', '读取权限列表'),
|
||||
('permission:write', '写入权限'),
|
||||
('admin-role:read', '读取管理员角色列表'),
|
||||
('admin-role:write', '写入管理员角色')
|
||||
;
|
||||
|
||||
-- --------------------------
|
||||
-- level 1
|
||||
-- --------------------------
|
||||
insert into permission (name, description, sort) values
|
||||
('permission', '权限', 1),
|
||||
('admin_role', '管理员角色', 2),
|
||||
('admin', '管理员', 3),
|
||||
('product', '产品', 4),
|
||||
('product_sku', '产品套餐', 5),
|
||||
('discount', '折扣', 6),
|
||||
('resource', '用户套餐', 7),
|
||||
('user', '用户', 8),
|
||||
('coupon', '优惠券', 9),
|
||||
('batch', '批次', 10),
|
||||
('channel', 'IP', 11),
|
||||
('trade', '交易', 12),
|
||||
('bill', '账单', 13),
|
||||
('balance_activity', '余额变动', 14);
|
||||
|
||||
-- --------------------------
|
||||
-- level 2
|
||||
-- --------------------------
|
||||
|
||||
-- permission 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'permission' and deleted_at is null), 'permission:read', '读取权限列表', 1),
|
||||
((select id from permission where name = 'permission' and deleted_at is null), 'permission:write', '写入权限', 2);
|
||||
|
||||
-- admin_role 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'admin_role' and deleted_at is null), 'admin_role:read', '读取管理员角色列表', 1),
|
||||
((select id from permission where name = 'admin_role' and deleted_at is null), 'admin_role:write', '写入管理员角色', 2);
|
||||
|
||||
-- admin 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'admin' and deleted_at is null), 'admin:read', '读取管理员列表', 1),
|
||||
((select id from permission where name = 'admin' and deleted_at is null), 'admin:write', '写入管理员', 2);
|
||||
|
||||
-- product 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'product' and deleted_at is null), 'product:read', '读取产品列表', 1),
|
||||
((select id from permission where name = 'product' and deleted_at is null), 'product:write', '写入产品', 2);
|
||||
|
||||
-- product_sku 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'product_sku' and deleted_at is null), 'product_sku:read', '读取产品套餐列表', 1),
|
||||
((select id from permission where name = 'product_sku' and deleted_at is null), 'product_sku:write', '写入产品套餐', 2);
|
||||
|
||||
-- discount 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'discount' and deleted_at is null), 'discount:read', '读取折扣列表', 1),
|
||||
((select id from permission where name = 'discount' and deleted_at is null), 'discount:write', '写入折扣', 2);
|
||||
|
||||
-- resource 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'resource' and deleted_at is null), 'resource:read', '读取用户套餐列表', 1),
|
||||
((select id from permission where name = 'resource' and deleted_at is null), 'resource:write', '写入用户套餐', 2),
|
||||
((select id from permission where name = 'resource' and deleted_at is null), 'resource:short', '短效动态套餐', 3),
|
||||
((select id from permission where name = 'resource' and deleted_at is null), 'resource:long', '长效动态套餐', 4);
|
||||
|
||||
-- user 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'user' and deleted_at is null), 'user:read', '读取用户列表', 1),
|
||||
((select id from permission where name = 'user' and deleted_at is null), 'user:write', '写入用户', 2);
|
||||
|
||||
-- coupon 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'coupon' and deleted_at is null), 'coupon:read', '读取优惠券列表', 1),
|
||||
((select id from permission where name = 'coupon' and deleted_at is null), 'coupon:write', '写入优惠券', 2);
|
||||
|
||||
-- batch 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'batch' and deleted_at is null), 'batch:read', '读取批次列表', 1),
|
||||
((select id from permission where name = 'batch' and deleted_at is null), 'batch:write', '写入批次', 2);
|
||||
|
||||
-- channel 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'channel' and deleted_at is null), 'channel:read', '读取 IP 列表', 1),
|
||||
((select id from permission where name = 'channel' and deleted_at is null), 'channel:write', '写入 IP', 2);
|
||||
|
||||
-- trade 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'trade' and deleted_at is null), 'trade:read', '读取交易列表', 1),
|
||||
((select id from permission where name = 'trade' and deleted_at is null), 'trade:write', '写入交易', 2);
|
||||
|
||||
-- bill 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'bill' and deleted_at is null), 'bill:read', '读取账单列表', 1),
|
||||
((select id from permission where name = 'bill' and deleted_at is null), 'bill:write', '写入账单', 2);
|
||||
|
||||
-- balance_activity 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'balance_activity' and deleted_at is null), 'balance_activity:read', '读取余额变动列表', 1);
|
||||
|
||||
-- --------------------------
|
||||
-- level 3
|
||||
-- --------------------------
|
||||
|
||||
-- product_sku:write 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'product_sku:write' and deleted_at is null), 'product_sku:write:status', '更改产品套餐状态', 1);
|
||||
|
||||
-- resource:short 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'resource:short' and deleted_at is null), 'resource:short:read', '读取用户短效动态套餐列表', 1);
|
||||
|
||||
-- resource:long 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'resource:long' and deleted_at is null), 'resource:long:read', '读取用户长效动态套餐列表', 1);
|
||||
|
||||
-- user:read 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'user:read' and deleted_at is null), 'user:read:one', '读取单个用户', 1),
|
||||
((select id from permission where name = 'user:read' and deleted_at is null), 'user:read:not_bind', '读取未绑定管理员的用户列表', 2);
|
||||
|
||||
-- user:write 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'user:write' and deleted_at is null), 'user:write:balance', '写入用户余额', 1),
|
||||
((select id from permission where name = 'user:write' and deleted_at is null), 'user:write:bind', '用户认领', 2);
|
||||
|
||||
-- batch:read 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'batch:read' and deleted_at is null), 'batch:read:of_user', '读取指定用户的批次列表', 1);
|
||||
|
||||
-- channel:read 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'channel:read' and deleted_at is null), 'channel:read:of_user', '读取指定用户的 IP 列表', 1);
|
||||
|
||||
-- trade:read 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'trade:read' and deleted_at is null), 'trade:read:of_user', '读取指定用户的交易列表', 1);
|
||||
|
||||
-- bill:read 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'bill:read' and deleted_at is null), 'bill:read:of_user', '读取指定用户的账单列表', 1);
|
||||
|
||||
-- balance_activity:read 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'balance_activity:read' and deleted_at is null), 'balance_activity:read:of_user', '读取指定用户的余额变动列表', 1);
|
||||
|
||||
-- --------------------------
|
||||
-- level 4
|
||||
-- --------------------------
|
||||
|
||||
-- user:write:balance 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'user:write:balance' and deleted_at is null), 'user:write:balance:inc', '增加用户余额', 1),
|
||||
((select id from permission where name = 'user:write:balance' and deleted_at is null), 'user:write:balance:dec', '减少用户余额', 2);
|
||||
|
||||
-- resource:short:read 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'resource:short:read' and deleted_at is null), 'resource:short:read:of_user', '读取指定用户的短效动态套餐列表', 1);
|
||||
|
||||
-- resource:long:read 子权限
|
||||
insert into permission (parent_id, name, description, sort) values
|
||||
((select id from permission where name = 'resource:long:read' and deleted_at is null), 'resource:long:read:of_user', '读取指定用户的长效动态套餐列表', 1);
|
||||
|
||||
-- endregion
|
||||
|
||||
@@ -196,6 +196,7 @@ create table admin (
|
||||
last_login timestamptz,
|
||||
last_login_ip inet,
|
||||
last_login_ua text,
|
||||
lock bool not null default false,
|
||||
created_at timestamptz default current_timestamp,
|
||||
updated_at timestamptz default current_timestamp,
|
||||
deleted_at timestamptz
|
||||
@@ -217,6 +218,7 @@ comment on column admin.status is '状态:0-禁用,1-正常';
|
||||
comment on column admin.last_login is '最后登录时间';
|
||||
comment on column admin.last_login_ip is '最后登录地址';
|
||||
comment on column admin.last_login_ua is '最后登录代理';
|
||||
comment on column admin.lock is '是否锁定编辑';
|
||||
comment on column admin.created_at is '创建时间';
|
||||
comment on column admin.updated_at is '更新时间';
|
||||
comment on column admin.deleted_at is '删除时间';
|
||||
@@ -757,6 +759,9 @@ create table product_sku (
|
||||
code text not null unique,
|
||||
name text not null,
|
||||
price decimal not null,
|
||||
price_min decimal not null,
|
||||
status int not null default 1,
|
||||
sort int not null default 0,
|
||||
created_at timestamptz default current_timestamp,
|
||||
updated_at timestamptz default current_timestamp,
|
||||
deleted_at timestamptz
|
||||
@@ -772,7 +777,9 @@ 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.name is 'SKU 可读名称';
|
||||
comment on column product_sku.price is '定价';
|
||||
comment on column product_sku.price_min is '最低价格';
|
||||
comment on column product_sku.status is 'SKU状态:0-禁用,1-正常';
|
||||
comment on column product_sku.sort is '排序';
|
||||
comment on column product_sku.created_at is '创建时间';
|
||||
comment on column product_sku.updated_at is '更新时间';
|
||||
comment on column product_sku.deleted_at is '删除时间';
|
||||
@@ -984,7 +991,7 @@ create table bill (
|
||||
trade_id int,
|
||||
resource_id int,
|
||||
refund_id int,
|
||||
coupon_id int,
|
||||
coupon_user_id int,
|
||||
bill_no text not null,
|
||||
info text,
|
||||
type int not null,
|
||||
@@ -999,7 +1006,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_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_coupon_id on bill (coupon_id) where deleted_at is null;
|
||||
create index idx_bill_coupon_id on bill (coupon_user_id) where deleted_at is null;
|
||||
create index idx_bill_created_at on bill (created_at) where deleted_at is null;
|
||||
|
||||
-- bill表字段注释
|
||||
@@ -1009,6 +1016,7 @@ comment on column bill.user_id is '用户ID';
|
||||
comment on column bill.trade_id is '订单ID';
|
||||
comment on column bill.resource_id is '套餐ID';
|
||||
comment on column bill.refund_id is '退款ID';
|
||||
comment on column bill.coupon_user_id is '优惠券发放ID';
|
||||
comment on column bill.bill_no is '易读账单号';
|
||||
comment on column bill.info is '产品可读信息';
|
||||
comment on column bill.type is '账单类型:1-消费,2-退款,3-充值';
|
||||
@@ -1051,36 +1059,59 @@ comment on column balance_activity.created_at is '创建时间';
|
||||
-- coupon 优惠券
|
||||
drop table if exists coupon cascade;
|
||||
create table coupon (
|
||||
id int generated by default as identity primary key,
|
||||
user_id int,
|
||||
code text not null,
|
||||
remark text,
|
||||
amount decimal(12, 2) not null default 0,
|
||||
min_amount decimal(12, 2) not null default 0,
|
||||
status int not null default 0,
|
||||
expire_at timestamptz,
|
||||
created_at timestamptz default current_timestamp,
|
||||
updated_at timestamptz default current_timestamp,
|
||||
deleted_at timestamptz
|
||||
id int generated by default as identity primary key,
|
||||
name text not null,
|
||||
amount decimal(12, 2) not null default 0,
|
||||
min_amount decimal(12, 2) not null default 0,
|
||||
count int not null default 0,
|
||||
status int not null default 1,
|
||||
expire_type int not null default 0,
|
||||
expire_at timestamptz,
|
||||
expire_in int,
|
||||
created_at timestamptz default current_timestamp,
|
||||
updated_at timestamptz default current_timestamp,
|
||||
deleted_at timestamptz
|
||||
);
|
||||
create index idx_coupon_user_id on coupon (user_id) where deleted_at is null;
|
||||
create index idx_coupon_code on coupon (code) where deleted_at is null;
|
||||
create index idx_coupon_created_at on coupon (created_at) where deleted_at is null;
|
||||
|
||||
-- coupon表字段注释
|
||||
comment on table coupon is '优惠券表';
|
||||
comment on column coupon.id is '优惠券ID';
|
||||
comment on column coupon.user_id is '用户ID';
|
||||
comment on column coupon.code is '优惠券代码';
|
||||
comment on column coupon.remark is '优惠券备注';
|
||||
comment on column coupon.name is '优惠券名称';
|
||||
comment on column coupon.amount is '优惠券金额';
|
||||
comment on column coupon.min_amount is '最低消费金额';
|
||||
comment on column coupon.status is '优惠券状态:0-未使用,1-已使用,2-已过期';
|
||||
comment on column coupon.expire_at is '过期时间';
|
||||
comment on column coupon.count is '优惠券数量';
|
||||
comment on column coupon.status is '优惠券状态:0-禁用,1-正常';
|
||||
comment on column coupon.expire_type is '过期类型:0-不过期,1-固定日期,2-相对日期(从发放时间算起)';
|
||||
comment on column coupon.expire_at is '过期时间,固定日期必填';
|
||||
comment on column coupon.expire_in is '过期时长(天),相对日期必填';
|
||||
comment on column coupon.created_at is '创建时间';
|
||||
comment on column coupon.updated_at is '更新时间';
|
||||
comment on column coupon.deleted_at is '删除时间';
|
||||
|
||||
-- coupon_user 优惠券发放
|
||||
drop table if exists coupon_user cascade;
|
||||
create table coupon_user (
|
||||
id int generated by default as identity primary key,
|
||||
coupon_id int not null,
|
||||
user_id int not null,
|
||||
status int not null default 0,
|
||||
expire_at timestamptz,
|
||||
used_at timestamptz,
|
||||
created_at timestamptz default current_timestamp
|
||||
);
|
||||
create index idx_coupon_user_coupon_id on coupon_user (coupon_id);
|
||||
create index idx_coupon_user_user_id on coupon_user (user_id);
|
||||
|
||||
-- coupon_user表字段注释
|
||||
comment on table coupon_user is '优惠券发放表';
|
||||
comment on column coupon_user.id is '记录ID';
|
||||
comment on column coupon_user.coupon_id is '优惠券ID';
|
||||
comment on column coupon_user.user_id is '用户ID';
|
||||
comment on column coupon_user.status is '使用状态:0-未使用,1-已使用';
|
||||
comment on column coupon_user.expire_at is '过期时间';
|
||||
comment on column coupon_user.used_at is '使用时间';
|
||||
comment on column coupon_user.created_at is '创建时间';
|
||||
|
||||
-- endregion
|
||||
|
||||
-- ====================
|
||||
@@ -1185,11 +1216,13 @@ alter table bill
|
||||
alter table bill
|
||||
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;
|
||||
add constraint fk_bill_coupon_id foreign key (coupon_user_id) references coupon_user (id) on delete set null;
|
||||
|
||||
-- coupon表外键
|
||||
alter table coupon
|
||||
add constraint fk_coupon_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||||
-- coupon_user表外键
|
||||
alter table coupon_user
|
||||
add constraint fk_coupon_user_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||||
alter table coupon_user
|
||||
add constraint fk_coupon_user_coupon_id foreign key (coupon_id) references coupon (id) on delete cascade;
|
||||
|
||||
-- product_sku表外键
|
||||
alter table product_sku
|
||||
|
||||
81
scripts/sql/update.sql
Normal file
81
scripts/sql/update.sql
Normal file
@@ -0,0 +1,81 @@
|
||||
-- ====================
|
||||
-- region 套餐更新
|
||||
-- ====================
|
||||
|
||||
-- --------------------------
|
||||
-- 短效动态
|
||||
-- --------------------------
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包量 3 分钟', price = 10.00, price_min = 10.00, sort = 1 where code = 'mode=quota&live=3&expire=0' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包量 5 分钟', price = 10.00, price_min = 10.00, sort = 2 where code = 'mode=quota&live=5&expire=0' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包量 10 分钟', price = 10.00, price_min = 10.00, sort = 3 where code = 'mode=quota&live=10&expire=0' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包量 15 分钟', price = 10.00, price_min = 10.00, sort = 4 where code = 'mode=quota&live=15&expire=0' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包量 30 分钟', price = 10.00, price_min = 10.00, sort = 5 where code = 'mode=quota&live=30&expire=0' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 3 分钟 7 天', price = 10.00, price_min = 10.00, sort = 6 where code = 'mode=time&live=3&expire=7' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 5 分钟 7 天', price = 10.00, price_min = 10.00, sort = 7 where code = 'mode=time&live=5&expire=7' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 10 分钟 7 天', price = 10.00, price_min = 10.00, sort = 8 where code = 'mode=time&live=10&expire=7' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 15 分钟 7 天', price = 10.00, price_min = 10.00, sort = 9 where code = 'mode=time&live=15&expire=7' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 30 分钟 7 天', price = 10.00, price_min = 10.00, sort = 10 where code = 'mode=time&live=30&expire=7' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 3 分钟 15 天', price = 10.00, price_min = 10.00, sort = 11 where code = 'mode=time&live=3&expire=15' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 5 分钟 15 天', price = 10.00, price_min = 10.00, sort = 12 where code = 'mode=time&live=5&expire=15' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 10 分钟 15 天', price = 10.00, price_min = 10.00, sort = 13 where code = 'mode=time&live=10&expire=15' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 15 分钟 15 天', price = 10.00, price_min = 10.00, sort = 14 where code = 'mode=time&live=15&expire=15' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 30 分钟 15 天', price = 10.00, price_min = 10.00, sort = 15 where code = 'mode=time&live=30&expire=15' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 3 分钟 30 天', price = 10.00, price_min = 10.00, sort = 16 where code = 'mode=time&live=3&expire=30' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 5 分钟 30 天', price = 10.00, price_min = 10.00, sort = 17 where code = 'mode=time&live=5&expire=30' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 10 分钟 30 天', price = 10.00, price_min = 10.00, sort = 18 where code = 'mode=time&live=10&expire=30' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 15 分钟 30 天', price = 10.00, price_min = 10.00, sort = 19 where code = 'mode=time&live=15&expire=30' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 30 分钟 30 天', price = 10.00, price_min = 10.00, sort = 20 where code = 'mode=time&live=30&expire=30' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 3 分钟 90 天', price = 10.00, price_min = 10.00, sort = 21 where code = 'mode=time&live=3&expire=90' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 5 分钟 90 天', price = 10.00, price_min = 10.00, sort = 22 where code = 'mode=time&live=5&expire=90' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 10 分钟 90 天', price = 10.00, price_min = 10.00, sort = 23 where code = 'mode=time&live=10&expire=90' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 15 分钟 90 天', price = 10.00, price_min = 10.00, sort = 24 where code = 'mode=time&live=15&expire=90' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 30 分钟 90 天', price = 10.00, price_min = 10.00, sort = 25 where code = 'mode=time&live=30&expire=90' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 3 分钟 180 天', price = 10.00, price_min = 10.00, sort = 26 where code = 'mode=time&live=3&expire=180' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 5 分钟 180 天', price = 10.00, price_min = 10.00, sort = 27 where code = 'mode=time&live=5&expire=180' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 10 分钟 180 天', price = 10.00, price_min = 10.00, sort = 28 where code = 'mode=time&live=10&expire=180' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 15 分钟 180 天', price = 10.00, price_min = 10.00, sort = 29 where code = 'mode=time&live=15&expire=180' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 30 分钟 180 天', price = 10.00, price_min = 10.00, sort = 30 where code = 'mode=time&live=30&expire=180' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 3 分钟 365 天', price = 10.00, price_min = 10.00, sort = 31 where code = 'mode=time&live=3&expire=365' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 5 分钟 365 天', price = 10.00, price_min = 10.00, sort = 32 where code = 'mode=time&live=5&expire=365' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 10 分钟 365 天', price = 10.00, price_min = 10.00, sort = 33 where code = 'mode=time&live=10&expire=365' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 15 分钟 365 天', price = 10.00, price_min = 10.00, sort = 34 where code = 'mode=time&live=15&expire=365' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'short' and deleted_at is null), name = '短效动态包时 30 分钟 365 天', price = 10.00, price_min = 10.00, sort = 35 where code = 'mode=time&live=30&expire=365' and deleted_at is null;
|
||||
|
||||
-- --------------------------
|
||||
-- 长效动态
|
||||
-- --------------------------
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包量 1 小时', price = 10.00, price_min = 10.00, sort = 1 where code = 'mode=quota&live=60&expire=0' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包量 4 小时', price = 10.00, price_min = 10.00, sort = 2 where code = 'mode=quota&live=240&expire=0' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包量 8 小时', price = 10.00, price_min = 10.00, sort = 3 where code = 'mode=quota&live=480&expire=0' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包量 12 小时', price = 10.00, price_min = 10.00, sort = 4 where code = 'mode=quota&live=720&expire=0' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包量 24 小时', price = 10.00, price_min = 10.00, sort = 5 where code = 'mode=quota&live=1440&expire=0' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 1 小时 7 天', price = 10.00, price_min = 10.00, sort = 6 where code = 'mode=time&live=60&expire=7' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 4 小时 7 天', price = 10.00, price_min = 10.00, sort = 7 where code = 'mode=time&live=240&expire=7' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 8 小时 7 天', price = 10.00, price_min = 10.00, sort = 8 where code = 'mode=time&live=480&expire=7' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 12 小时 7 天', price = 10.00, price_min = 10.00, sort = 9 where code = 'mode=time&live=720&expire=7' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 24 小时 7 天', price = 10.00, price_min = 10.00, sort = 10 where code = 'mode=time&live=1440&expire=7' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 1 小时 15 天', price = 10.00, price_min = 10.00, sort = 11 where code = 'mode=time&live=60&expire=15' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 4 小时 15 天', price = 10.00, price_min = 10.00, sort = 12 where code = 'mode=time&live=240&expire=15' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 8 小时 15 天', price = 10.00, price_min = 10.00, sort = 13 where code = 'mode=time&live=480&expire=15' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 12 小时 15 天', price = 10.00, price_min = 10.00, sort = 14 where code = 'mode=time&live=720&expire=15' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 24 小时 15 天', price = 10.00, price_min = 10.00, sort = 15 where code = 'mode=time&live=1440&expire=15' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 1 小时 30 天', price = 10.00, price_min = 10.00, sort = 16 where code = 'mode=time&live=60&expire=30' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 4 小时 30 天', price = 10.00, price_min = 10.00, sort = 17 where code = 'mode=time&live=240&expire=30' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 8 小时 30 天', price = 10.00, price_min = 10.00, sort = 18 where code = 'mode=time&live=480&expire=30' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 12 小时 30 天', price = 10.00, price_min = 10.00, sort = 19 where code = 'mode=time&live=720&expire=30' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 24 小时 30 天', price = 10.00, price_min = 10.00, sort = 20 where code = 'mode=time&live=1440&expire=30' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 1 小时 90 天', price = 10.00, price_min = 10.00, sort = 21 where code = 'mode=time&live=60&expire=90' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 4 小时 90 天', price = 10.00, price_min = 10.00, sort = 22 where code = 'mode=time&live=240&expire=90' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 8 小时 90 天', price = 10.00, price_min = 10.00, sort = 23 where code = 'mode=time&live=480&expire=90' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 12 小时 90 天', price = 10.00, price_min = 10.00, sort = 24 where code = 'mode=time&live=720&expire=90' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 24 小时 90 天', price = 10.00, price_min = 10.00, sort = 25 where code = 'mode=time&live=1440&expire=90' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 1 小时 180 天', price = 10.00, price_min = 10.00, sort = 26 where code = 'mode=time&live=60&expire=180' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 4 小时 180 天', price = 10.00, price_min = 10.00, sort = 27 where code = 'mode=time&live=240&expire=180' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 8 小时 180 天', price = 10.00, price_min = 10.00, sort = 28 where code = 'mode=time&live=480&expire=180' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 12 小时 180 天', price = 10.00, price_min = 10.00, sort = 29 where code = 'mode=time&live=720&expire=180' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 24 小时 180 天', price = 10.00, price_min = 10.00, sort = 30 where code = 'mode=time&live=1440&expire=180' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 1 小时 365 天', price = 10.00, price_min = 10.00, sort = 31 where code = 'mode=time&live=60&expire=365' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 4 小时 365 天', price = 10.00, price_min = 10.00, sort = 32 where code = 'mode=time&live=240&expire=365' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 8 小时 365 天', price = 10.00, price_min = 10.00, sort = 33 where code = 'mode=time&live=480&expire=365' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 12 小时 365 天', price = 10.00, price_min = 10.00, sort = 34 where code = 'mode=time&live=720&expire=365' and deleted_at is null;
|
||||
update product_sku set product_id = (select id from product where code = 'long' and deleted_at is null), name = '长效动态包时 24 小时 365 天', price = 10.00, price_min = 10.00, sort = 35 where code = 'mode=time&live=1440&expire=365' and deleted_at is null;
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"platform/pkg/u"
|
||||
"platform/web/core"
|
||||
m "platform/web/models"
|
||||
q "platform/web/queries"
|
||||
@@ -50,9 +49,8 @@ func authUser(loginType PwdLoginType, username, password string) (user *m.User,
|
||||
}
|
||||
if user == nil {
|
||||
user = &m.User{
|
||||
Phone: username,
|
||||
Username: u.P(username),
|
||||
Status: m.UserStatusEnabled,
|
||||
Phone: username,
|
||||
Status: m.UserStatusEnabled,
|
||||
}
|
||||
}
|
||||
case PwdLoginByEmail:
|
||||
@@ -79,7 +77,7 @@ func authUser(loginType PwdLoginType, username, password string) (user *m.User,
|
||||
|
||||
func authUserBySms(tx *q.Query, username, code string) (*m.User, error) {
|
||||
// 验证验证码
|
||||
err := s.Verifier.VerifySms(context.Background(), username, code)
|
||||
err := s.Verifier.VerifySms(context.Background(), username, code, s.VerifierSmsPurposeLogin)
|
||||
if err != nil {
|
||||
return nil, core.NewBizErr("短信认证失败", err)
|
||||
}
|
||||
@@ -169,6 +167,9 @@ func adminScopes(admin *m.Admin) ([]string, error) {
|
||||
|
||||
scopeNames := make([]string, 0, len(scopes))
|
||||
for _, scope := range scopes {
|
||||
if scope.Name == "" {
|
||||
continue
|
||||
}
|
||||
scopeNames = append(scopeNames, scope.Name)
|
||||
}
|
||||
return scopeNames, nil
|
||||
|
||||
@@ -356,6 +356,11 @@ func authPassword(c *fiber.Ctx, auth *AuthCtx, req *TokenReq, now time.Time) (*m
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 非锁定管理员,不允许为空权限
|
||||
if !admin.Lock && (len(scopes) == 0) {
|
||||
return nil, ErrAuthorizeInvalidScope // 没有配置权限
|
||||
}
|
||||
|
||||
// 更新管理员登录时间
|
||||
admin.LastLogin = u.P(time.Now())
|
||||
admin.LastLoginIP = ip
|
||||
@@ -532,10 +537,10 @@ func introspectUser(ctx *fiber.Ctx, authCtx *AuthCtx) error {
|
||||
|
||||
// 掩码敏感信息
|
||||
if profile.Phone != "" {
|
||||
profile.Phone = maskPhone(profile.Phone)
|
||||
profile.Phone = u.MaskPhone(profile.Phone)
|
||||
}
|
||||
if profile.IDNo != nil && *profile.IDNo != "" {
|
||||
profile.IDNo = u.P(maskIdNo(*profile.IDNo))
|
||||
profile.IDNo = u.P(u.MaskIdNo(*profile.IDNo))
|
||||
}
|
||||
|
||||
return ctx.JSON(struct {
|
||||
@@ -574,20 +579,6 @@ func introspectAdmin(ctx *fiber.Ctx, authCtx *AuthCtx) error {
|
||||
}{profile, list})
|
||||
}
|
||||
|
||||
func maskPhone(phone string) string {
|
||||
if len(phone) < 11 {
|
||||
return phone
|
||||
}
|
||||
return phone[:3] + "****" + phone[7:]
|
||||
}
|
||||
|
||||
func maskIdNo(idNo string) string {
|
||||
if len(idNo) < 18 {
|
||||
return idNo
|
||||
}
|
||||
return idNo[:3] + "*********" + idNo[14:]
|
||||
}
|
||||
|
||||
type CodeContext struct {
|
||||
UserID int32 `json:"user_id"`
|
||||
ClientID int32 `json:"client_id"`
|
||||
|
||||
@@ -12,9 +12,9 @@ type IModel interface {
|
||||
}
|
||||
|
||||
type Model struct {
|
||||
ID int32 `json:"id" gorm:"column:id;primaryKey"`
|
||||
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"`
|
||||
ID int32 `json:"id,omitzero" gorm:"column:id;primaryKey"`
|
||||
CreatedAt time.Time `json:"created_at,omitzero" gorm:"column:created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at,omitzero" gorm:"column:updated_at"`
|
||||
DeletedAt gorm.DeletedAt `json:"-" gorm:"column:deleted_at"`
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@ const (
|
||||
ScopeProductRead = string("product:read") // 读取产品列表
|
||||
ScopeProductWrite = string("product:write") // 写入产品
|
||||
|
||||
ScopeProductSku = string("product_sku") // 产品套餐
|
||||
ScopeProductSkuRead = string("product_sku:read") // 读取产品套餐列表
|
||||
ScopeProductSkuWrite = string("product_sku:write") // 写入产品套餐
|
||||
ScopeProductSku = string("product_sku") // 产品套餐
|
||||
ScopeProductSkuRead = string("product_sku:read") // 读取产品套餐列表
|
||||
ScopeProductSkuWrite = string("product_sku:write") // 写入产品套餐
|
||||
ScopeProductSkuWriteStatus = string("product_sku:write:status") // 更改产品套餐状态
|
||||
|
||||
ScopeDiscount = string("discount") // 折扣
|
||||
ScopeDiscountRead = string("discount:read") // 读取折扣列表
|
||||
@@ -29,30 +30,50 @@ const (
|
||||
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") // 用户认领
|
||||
ScopeResourceShort = string("resource:short") // 短效动态套餐
|
||||
ScopeResourceShortRead = string("resource:short:read") // 读取用户短效动态套餐列表
|
||||
ScopeResourceShortReadOfUser = string("resource:short:read:of_user") // 读取指定用户的短效动态套餐列表
|
||||
|
||||
ScopeResourceLong = string("resource:long") // 长效动态套餐
|
||||
ScopeResourceLongRead = string("resource:long:read") // 读取用户长效动态套餐列表
|
||||
ScopeResourceLongReadOfUser = string("resource:long:read:of_user") // 读取指定用户的长效动态套餐列表
|
||||
|
||||
ScopeUser = string("user") // 用户
|
||||
ScopeUserRead = string("user:read") // 读取用户列表
|
||||
ScopeUserReadOne = string("user:read:one") // 读取单个用户
|
||||
ScopeUserReadNotBind = string("user:read:not_bind") // 读取未绑定管理员的用户列表
|
||||
ScopeUserWrite = string("user:write") // 写入用户
|
||||
ScopeUserWriteBalance = string("user:write:balance") // 写入用户余额
|
||||
ScopeUserWriteBalanceInc = string("user:write:balance:inc") // 增加用户余额
|
||||
ScopeUserWriteBalanceDec = string("user:write:balance:dec") // 减少用户余额
|
||||
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") // 写入批次
|
||||
ScopeBatch = string("batch") // 批次
|
||||
ScopeBatchRead = string("batch:read") // 读取批次列表
|
||||
ScopeBatchReadOfUser = string("batch:read:of_user") // 读取指定用户的批次列表
|
||||
ScopeBatchWrite = string("batch:write") // 写入批次
|
||||
|
||||
ScopeChannel = string("channel") // IP
|
||||
ScopeChannelRead = string("channel:read") // 读取 IP 列表
|
||||
ScopeChannelWrite = string("channel:write") // 写入 IP
|
||||
ScopeChannel = string("channel") // IP
|
||||
ScopeChannelRead = string("channel:read") // 读取 IP 列表
|
||||
ScopeChannelReadOfUser = string("channel:read:of_user") // 读取指定用户的 IP 列表
|
||||
ScopeChannelWrite = string("channel:write") // 写入 IP
|
||||
|
||||
ScopeTrade = string("trade") // 交易
|
||||
ScopeTradeRead = string("trade:read") // 读取交易列表
|
||||
ScopeTradeWrite = string("trade:write") // 写入交易
|
||||
ScopeTrade = string("trade") // 交易
|
||||
ScopeTradeRead = string("trade:read") // 读取交易列表
|
||||
ScopeTradeReadOfUser = string("trade:read:of_user") // 读取指定用户的交易列表
|
||||
ScopeTradeWrite = string("trade:write") // 写入交易
|
||||
ScopeTradeWriteComplete = string("trade:write:complete") // 完成交易
|
||||
|
||||
ScopeBill = string("bill") // 账单
|
||||
ScopeBillRead = string("bill:read") // 读取账单列表
|
||||
ScopeBillWrite = string("bill:write") // 写入账单
|
||||
ScopeBill = string("bill") // 账单
|
||||
ScopeBillRead = string("bill:read") // 读取账单列表
|
||||
ScopeBillReadOfUser = string("bill:read:of_user") // 读取指定用户的账单列表
|
||||
ScopeBillWrite = string("bill:write") // 写入账单
|
||||
|
||||
ScopeBalanceActivity = string("balance_activity") // 余额变动
|
||||
ScopeBalanceActivityRead = string("balance_activity:read") // 读取余额变动列表
|
||||
ScopeBalanceActivityReadOfUser = string("balance_activity:read:of_user") // 读取指定用户的余额变动列表
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ func PageAdminByAdmin(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
list, total, err := s.Admin.PageAdmins(req.PageReq)
|
||||
list, total, err := s.Admin.Page(req.PageReq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -62,7 +62,7 @@ func CreateAdmin(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Admin.CreateAdmin(&req); err != nil {
|
||||
if err := s.Admin.Create(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func UpdateAdmin(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Admin.UpdateAdmin(&req); err != nil {
|
||||
if err := s.Admin.Update(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ func RemoveAdmin(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Admin.RemoveAdmin(req.Id); err != nil {
|
||||
if err := s.Admin.Remove(req.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
137
web/handlers/balance_activity.go
Normal file
137
web/handlers/balance_activity.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"platform/pkg/u"
|
||||
"platform/web/auth"
|
||||
"platform/web/core"
|
||||
g "platform/web/globals"
|
||||
q "platform/web/queries"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// PageBalanceActivityByAdmin 分页查询所有余额变动记录
|
||||
func PageBalanceActivityByAdmin(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeBalanceActivityRead)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析请求参数
|
||||
req := new(PageBalanceActivityByAdminReq)
|
||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 构造查询条件
|
||||
do := q.BalanceActivity.Where()
|
||||
if req.UserPhone != nil {
|
||||
do = do.Where(q.User.As("User").Phone.Eq(*req.UserPhone))
|
||||
}
|
||||
if req.BillNo != nil {
|
||||
do = do.Where(q.Bill.As("Bill").BillNo.Eq(*req.BillNo))
|
||||
}
|
||||
if req.CreatedAtStart != nil {
|
||||
t := u.DateHead(*req.CreatedAtStart)
|
||||
do = do.Where(q.BalanceActivity.CreatedAt.Gte(t))
|
||||
}
|
||||
if req.CreatedAtEnd != nil {
|
||||
t := u.DateTail(*req.CreatedAtEnd)
|
||||
do = do.Where(q.BalanceActivity.CreatedAt.Lte(t))
|
||||
}
|
||||
|
||||
// 查询余额变动列表
|
||||
list, total, err := q.BalanceActivity.Debug().
|
||||
Joins(q.BalanceActivity.User, q.BalanceActivity.Admin, q.BalanceActivity.Bill).
|
||||
Select(
|
||||
q.BalanceActivity.ALL,
|
||||
q.User.As("User").Phone.As("User__phone"),
|
||||
q.User.As("User").Name.As("User__name"),
|
||||
q.Admin.As("Admin").Name.As("Admin__name"),
|
||||
q.Bill.As("Bill").BillNo.As("Bill__bill_no"),
|
||||
).
|
||||
Where(do).
|
||||
Order(q.BalanceActivity.CreatedAt.Desc()).
|
||||
FindByPage(req.GetOffset(), req.GetLimit())
|
||||
if err != nil {
|
||||
return core.NewBizErr("获取数据失败", err)
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
return c.JSON(core.PageResp{
|
||||
List: list,
|
||||
Total: int(total),
|
||||
Page: req.GetPage(),
|
||||
Size: req.GetSize(),
|
||||
})
|
||||
}
|
||||
|
||||
type PageBalanceActivityByAdminReq struct {
|
||||
core.PageReq
|
||||
UserPhone *string `json:"user_phone,omitempty"`
|
||||
BillNo *string `json:"bill_no,omitempty"`
|
||||
CreatedAtStart *time.Time `json:"created_at_start,omitempty"`
|
||||
CreatedAtEnd *time.Time `json:"created_at_end,omitempty"`
|
||||
}
|
||||
|
||||
// PageBalanceActivityOfUserByAdmin 分页查询指定用户的余额变动记录
|
||||
func PageBalanceActivityOfUserByAdmin(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeBalanceActivityReadOfUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析请求参数
|
||||
req := new(PageBalanceActivityOfUserByAdminReq)
|
||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 构造查询条件
|
||||
do := q.BalanceActivity.Where(q.BalanceActivity.UserID.Eq(req.UserID))
|
||||
if req.BillNo != nil {
|
||||
do = do.Where(q.Bill.As("Bill").BillNo.Eq(*req.BillNo))
|
||||
}
|
||||
if req.CreatedAtStart != nil {
|
||||
t := u.DateHead(*req.CreatedAtStart)
|
||||
do = do.Where(q.BalanceActivity.CreatedAt.Gte(t))
|
||||
}
|
||||
if req.CreatedAtEnd != nil {
|
||||
t := u.DateTail(*req.CreatedAtEnd)
|
||||
do = do.Where(q.BalanceActivity.CreatedAt.Lte(t))
|
||||
}
|
||||
|
||||
// 查询余额变动列表
|
||||
list, total, err := q.BalanceActivity.
|
||||
Joins(q.BalanceActivity.Admin, q.BalanceActivity.Bill).
|
||||
Select(
|
||||
q.BalanceActivity.ALL,
|
||||
q.Admin.As("Admin").Name.As("Admin__name"),
|
||||
q.Bill.As("Bill").BillNo.As("Bill__bill_no"),
|
||||
).
|
||||
Where(do).
|
||||
Order(q.BalanceActivity.CreatedAt.Desc()).
|
||||
FindByPage(req.GetOffset(), req.GetLimit())
|
||||
if err != nil {
|
||||
return core.NewBizErr("获取数据失败", err)
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
return c.JSON(core.PageResp{
|
||||
List: list,
|
||||
Total: int(total),
|
||||
Page: req.GetPage(),
|
||||
Size: req.GetSize(),
|
||||
})
|
||||
}
|
||||
|
||||
type PageBalanceActivityOfUserByAdminReq struct {
|
||||
core.PageReq
|
||||
UserID int32 `json:"user_id" validate:"required"`
|
||||
BillNo *string `json:"bill_no,omitempty"`
|
||||
CreatedAtStart *time.Time `json:"created_at_start,omitempty"`
|
||||
CreatedAtEnd *time.Time `json:"created_at_end,omitempty"`
|
||||
}
|
||||
@@ -71,10 +71,10 @@ func PageBatchByAdmin(c *fiber.Ctx) error {
|
||||
|
||||
do := q.LogsUserUsage.Where()
|
||||
if req.UserPhone != nil {
|
||||
do = do.Where(q.User.Phone.Eq(*req.UserPhone))
|
||||
do = do.Where(q.User.As("User").Phone.Eq(*req.UserPhone))
|
||||
}
|
||||
if req.ResourceNo != nil {
|
||||
do = do.Where(q.Resource.ResourceNo.Eq(*req.ResourceNo))
|
||||
do = do.Where(q.Resource.As("Resource").ResourceNo.Eq(*req.ResourceNo))
|
||||
}
|
||||
if req.BatchNo != nil {
|
||||
do = do.Where(q.LogsUserUsage.BatchNo.Eq(*req.BatchNo))
|
||||
@@ -128,3 +128,75 @@ type PageBatchByAdminReq struct {
|
||||
CreatedAtStart *time.Time `json:"created_at_start"`
|
||||
CreatedAtEnd *time.Time `json:"created_at_end"`
|
||||
}
|
||||
|
||||
// PageBatchOfUserByAdmin 分页查询指定用户的提取记录
|
||||
func PageBatchOfUserByAdmin(ctx *fiber.Ctx) error {
|
||||
_, err := auth.GetAuthCtx(ctx).PermitAdmin(core.ScopeBatchReadOfUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req PageBatchOfUserByAdminReq
|
||||
if err = g.Validator.ParseBody(ctx, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
do := q.LogsUserUsage.Where(q.LogsUserUsage.UserID.Eq(req.UserID))
|
||||
if req.ResourceNo != nil {
|
||||
do = do.Where(q.Resource.As("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 {
|
||||
t := u.DateHead(*req.CreatedAtStart)
|
||||
do = do.Where(q.LogsUserUsage.Time.Gte(t))
|
||||
}
|
||||
if req.CreatedAtEnd != nil {
|
||||
t := u.DateTail(*req.CreatedAtEnd)
|
||||
do = do.Where(q.LogsUserUsage.Time.Lte(t))
|
||||
}
|
||||
|
||||
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())
|
||||
if err != nil {
|
||||
return ctx.JSON(core.NewBizErr("获取数据失败", err))
|
||||
}
|
||||
|
||||
return ctx.JSON(c.PageResp{
|
||||
List: list,
|
||||
Total: int(total),
|
||||
Page: req.GetPage(),
|
||||
Size: req.GetSize(),
|
||||
})
|
||||
}
|
||||
|
||||
type PageBatchOfUserByAdminReq struct {
|
||||
c.PageReq
|
||||
UserID int32 `json:"user_id" validate:"required"`
|
||||
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"`
|
||||
}
|
||||
|
||||
@@ -101,6 +101,90 @@ type PageBillByAdminReq struct {
|
||||
SkuCode *string `json:"sku_code,omitempty"`
|
||||
}
|
||||
|
||||
// PageBillOfUserByAdmin 分页查询指定用户账单
|
||||
func PageBillOfUserByAdmin(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeBillReadOfUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析请求参数
|
||||
req := new(PageBillOfUserByAdminReq)
|
||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 构造查询条件
|
||||
do := q.Bill.Where(q.Bill.UserID.Eq(req.UserID))
|
||||
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.
|
||||
Joins(
|
||||
q.Bill.Resource,
|
||||
q.Bill.Trade,
|
||||
q.Bill.Resource.Short,
|
||||
q.Bill.Resource.Long,
|
||||
).
|
||||
Select(
|
||||
q.Bill.ALL,
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
return c.JSON(core.PageResp{
|
||||
List: list,
|
||||
Total: int(total),
|
||||
Page: req.GetPage(),
|
||||
Size: req.GetSize(),
|
||||
})
|
||||
}
|
||||
|
||||
type PageBillOfUserByAdminReq struct {
|
||||
core.PageReq
|
||||
UserID int32 `json:"user_id" validate:"required"`
|
||||
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 获取账单列表
|
||||
func ListBill(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
|
||||
@@ -271,3 +271,76 @@ func RemoveChannels(c *fiber.Ctx) error {
|
||||
type RemoveChannelsReq struct {
|
||||
Batch string `json:"batch" validate:"required"`
|
||||
}
|
||||
|
||||
// PageChannelOfUserByAdmin 分页查询指定用户的通道
|
||||
func PageChannelOfUserByAdmin(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeChannelReadOfUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析请求参数
|
||||
var req PageChannelOfUserByAdminReq
|
||||
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 构建查询条件
|
||||
do := q.Channel.Where(q.Channel.UserID.Eq(req.UserID))
|
||||
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.ExpiredAtStart != nil {
|
||||
t := u.DateHead(*req.ExpiredAtStart)
|
||||
do = do.Where(q.Channel.ExpiredAt.Gte(t))
|
||||
}
|
||||
if req.ExpiredAtEnd != nil {
|
||||
t := u.DateHead(*req.ExpiredAtEnd)
|
||||
do = do.Where(q.Channel.ExpiredAt.Lte(t))
|
||||
}
|
||||
|
||||
// 查询通道列表
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
return c.JSON(core.PageResp{
|
||||
List: list,
|
||||
Total: int(total),
|
||||
Page: req.GetPage(),
|
||||
Size: req.GetSize(),
|
||||
})
|
||||
}
|
||||
|
||||
type PageChannelOfUserByAdminReq struct {
|
||||
core.PageReq
|
||||
UserID int32 `json:"user_id" validate:"required"`
|
||||
ResourceNo *string `json:"resource_no"`
|
||||
BatchNo *string `json:"batch_no"`
|
||||
ProxyHost *string `json:"proxy_host"`
|
||||
ProxyPort *uint16 `json:"proxy_port"`
|
||||
ExpiredAtStart *time.Time `json:"expired_at_start"`
|
||||
ExpiredAtEnd *time.Time `json:"expired_at_end"`
|
||||
}
|
||||
|
||||
@@ -34,6 +34,15 @@ func AllProductByAdmin(c *fiber.Ctx) error {
|
||||
type AllProductsByAdminReq struct {
|
||||
}
|
||||
|
||||
func AllProduct(c *fiber.Ctx) error {
|
||||
infos, err := s.Product.AllProductSaleInfos()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(infos)
|
||||
}
|
||||
|
||||
func CreateProduct(c *fiber.Ctx) error {
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductWrite)
|
||||
if err != nil {
|
||||
@@ -181,6 +190,32 @@ func UpdateProductSku(c *fiber.Ctx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdateProductStatusSku(c *fiber.Ctx) error {
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type Params struct {
|
||||
ID int32 `json:"id"`
|
||||
Status int32 `json:"status"`
|
||||
}
|
||||
var req Params
|
||||
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.ProductSku.Update(s.UpdateProductSkuData{
|
||||
ID: req.ID,
|
||||
Status: &req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func BatchUpdateProductSkuDiscount(c *fiber.Ctx) error {
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite)
|
||||
if err != nil {
|
||||
|
||||
@@ -209,7 +209,7 @@ type PageResourceLongReq struct {
|
||||
|
||||
// PageResourceShortByAdmin 分页查询全部短效套餐
|
||||
func PageResourceShortByAdmin(c *fiber.Ctx) error {
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeResourceRead)
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeResourceShortRead)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -303,7 +303,7 @@ type PageResourceShortByAdminReq struct {
|
||||
|
||||
// PageResourceLongByAdmin 分页查询全部长效套餐
|
||||
func PageResourceLongByAdmin(c *fiber.Ctx) error {
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeResourceRead)
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeResourceLongRead)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -393,6 +393,148 @@ type PageResourceLongByAdminReq struct {
|
||||
Expired *bool `json:"expired" form:"expired"`
|
||||
}
|
||||
|
||||
// PageResourceShortOfUserByAdmin 分页查询指定用户的短效套餐
|
||||
func PageResourceShortOfUserByAdmin(c *fiber.Ctx) error {
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeResourceShortReadOfUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req PageResourceShortOfUserByAdminReq
|
||||
if err = g.Validator.ParseBody(c, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
do := q.Resource.Where(q.Resource.UserID.Eq(req.UserID))
|
||||
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 {
|
||||
t := u.DateHead(*req.CreatedAtStart)
|
||||
do = do.Where(q.Resource.CreatedAt.Gte(t))
|
||||
}
|
||||
if req.CreatedAtEnd != nil {
|
||||
t := u.DateTail(*req.CreatedAtEnd)
|
||||
do = do.Where(q.Resource.CreatedAt.Lte(t))
|
||||
}
|
||||
|
||||
list, total, err := q.Resource.
|
||||
Joins(q.Resource.User, q.Resource.Short, q.Resource.Short.Sku).
|
||||
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())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(core.PageResp{
|
||||
List: list,
|
||||
Total: int(total),
|
||||
Page: req.GetPage(),
|
||||
Size: req.GetSize(),
|
||||
})
|
||||
}
|
||||
|
||||
type PageResourceShortOfUserByAdminReq struct {
|
||||
core.PageReq
|
||||
UserID int32 `json:"user_id" validate:"required"`
|
||||
ResourceNo *string `json:"resource_no"`
|
||||
Active *bool `json:"active"`
|
||||
Mode *int `json:"mode"`
|
||||
CreatedAtStart *time.Time `json:"created_at_start"`
|
||||
CreatedAtEnd *time.Time `json:"created_at_end"`
|
||||
}
|
||||
|
||||
// PageResourceLongOfUserByAdmin 分页查询指定用户的长效套餐
|
||||
func PageResourceLongOfUserByAdmin(c *fiber.Ctx) error {
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeResourceLongReadOfUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req PageResourceLongOfUserByAdminReq
|
||||
if err = g.Validator.ParseBody(c, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
do := q.Resource.Where(q.Resource.UserID.Eq(req.UserID))
|
||||
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 {
|
||||
t := u.DateHead(*req.CreatedAtStart)
|
||||
do = do.Where(q.Resource.CreatedAt.Gte(t))
|
||||
}
|
||||
if req.CreatedAtEnd != nil {
|
||||
t := u.DateTail(*req.CreatedAtEnd)
|
||||
do = do.Where(q.Resource.CreatedAt.Lte(t))
|
||||
}
|
||||
|
||||
list, total, err := q.Resource.
|
||||
Joins(q.Resource.User, q.Resource.Long, q.Resource.Long.Sku).
|
||||
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())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(core.PageResp{
|
||||
List: list,
|
||||
Total: int(total),
|
||||
Page: req.GetPage(),
|
||||
Size: req.GetSize(),
|
||||
})
|
||||
}
|
||||
|
||||
type PageResourceLongOfUserByAdminReq struct {
|
||||
core.PageReq
|
||||
UserID int32 `json:"user_id" validate:"required"`
|
||||
ResourceNo *string `json:"resource_no"`
|
||||
Active *bool `json:"active"`
|
||||
Mode *int `json:"mode"`
|
||||
CreatedAtStart *time.Time `json:"created_at_start"`
|
||||
CreatedAtEnd *time.Time `json:"created_at_end"`
|
||||
}
|
||||
|
||||
// AllActiveResource 所有可用套餐
|
||||
func AllActiveResource(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
@@ -449,9 +591,6 @@ func AllActiveResource(c *fiber.Ctx) error {
|
||||
return c.JSON(resources)
|
||||
}
|
||||
|
||||
type AllResourceReq struct {
|
||||
}
|
||||
|
||||
func UpdateResourceByAdmin(c *fiber.Ctx) error {
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeResourceWrite)
|
||||
if err != nil {
|
||||
@@ -658,10 +797,7 @@ type CreateResourceReq struct {
|
||||
// ResourcePrice 套餐价格
|
||||
func ResourcePrice(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
_, err := auth.GetAuthCtx(c).PermitSecretClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ac := auth.GetAuthCtx(c)
|
||||
|
||||
// 解析请求参数
|
||||
var req = new(CreateResourceReq)
|
||||
@@ -670,16 +806,7 @@ func ResourcePrice(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
// 获取套餐价格
|
||||
// sku, err := s.Resource.GetSku(req.CreateResourceData.Code())
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// _, amount, discounted, couponApplied, err := s.Resource.GetPrice(sku, req.Count(), nil, nil)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
detail, err := req.TradeDetail(nil)
|
||||
detail, err := req.TradeDetail(ac.User)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -687,11 +814,13 @@ func ResourcePrice(c *fiber.Ctx) error {
|
||||
// 计算折扣
|
||||
return c.JSON(ResourcePriceResp{
|
||||
Price: detail.Amount.StringFixed(2),
|
||||
Discounted: detail.Actual.StringFixed(2),
|
||||
Discounted: detail.Discounted.StringFixed(2),
|
||||
Actual: detail.Actual.StringFixed(2),
|
||||
})
|
||||
}
|
||||
|
||||
type ResourcePriceResp struct {
|
||||
Price string `json:"price"`
|
||||
Discounted string `json:"discounted_price"`
|
||||
Discounted string `json:"discounted"`
|
||||
Actual string `json:"actual"`
|
||||
}
|
||||
|
||||
@@ -97,6 +97,84 @@ type PageTradeByAdminReq struct {
|
||||
CreatedAtEnd *time.Time `json:"created_at_end,omitempty"`
|
||||
}
|
||||
|
||||
// PageTradeOfUserByAdmin 分页查询指定用户的订单
|
||||
func PageTradeOfUserByAdmin(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeTradeReadOfUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析请求参数
|
||||
req := new(PageTradeOfUserByAdminReq)
|
||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 构建查询语句
|
||||
do := q.Trade.Where(q.Trade.UserID.Eq(req.UserID))
|
||||
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.
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
return c.JSON(core.PageResp{
|
||||
List: list,
|
||||
Total: int(total),
|
||||
Page: req.GetPage(),
|
||||
Size: req.GetSize(),
|
||||
})
|
||||
}
|
||||
|
||||
type PageTradeOfUserByAdminReq struct {
|
||||
core.PageReq
|
||||
UserID int32 `json:"user_id" validate:"required"`
|
||||
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 {
|
||||
// 检查权限
|
||||
@@ -143,6 +221,8 @@ type TradeCreateReq struct {
|
||||
Recharge *s.UpdateBalanceData `json:"recharge,omitempty"`
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
|
||||
// 完成订单
|
||||
func TradeComplete(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
@@ -152,13 +232,13 @@ func TradeComplete(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
// 解析请求参数
|
||||
req := new(TradeCompleteReq)
|
||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||
var req s.TradeRef
|
||||
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查订单状态
|
||||
err = s.Trade.CompleteTrade(authCtx.User, &req.TradeRef)
|
||||
err = s.Trade.CompleteTrade(authCtx.User, &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -166,10 +246,40 @@ func TradeComplete(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusNoContent)
|
||||
}
|
||||
|
||||
type TradeCompleteReq struct {
|
||||
s.TradeRef
|
||||
// 管理员完成订单
|
||||
func TradeCompleteByAdmin(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeTradeWriteComplete)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析请求参数
|
||||
var req struct {
|
||||
s.TradeRef
|
||||
UserID int32 `json:"user_id" validate:"required"`
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// 完成订单
|
||||
err = s.Trade.CompleteTrade(user, &req.TradeRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.SendStatus(fiber.StatusNoContent)
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
|
||||
// 取消订单
|
||||
func TradeCancel(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
@@ -198,6 +308,8 @@ type TradeCancelReq struct {
|
||||
s.TradeRef
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
|
||||
// 检查订单
|
||||
func TradeCheck(c *fiber.Ctx) error {
|
||||
// 检查权限:sse 接口暂时不检查权限
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"platform/web/auth"
|
||||
"platform/web/core"
|
||||
g "platform/web/globals"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/shopspring/decimal"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -67,7 +69,7 @@ func PageUserByAdmin(c *fiber.Ctx) error {
|
||||
// 查询用户列表
|
||||
users, total, err := q.User.
|
||||
Preload(q.User.Admin, q.User.Discount).
|
||||
Omit(q.User.Password).
|
||||
Omit(q.User.Password, q.Admin.Password).
|
||||
Where(do).
|
||||
Order(q.User.CreatedAt.Desc()).
|
||||
FindByPage(req.GetOffset(), req.GetLimit())
|
||||
@@ -76,6 +78,12 @@ func PageUserByAdmin(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
|
||||
if user.IDNo != nil && len(*user.IDNo) == 18 {
|
||||
var str = *user.IDNo
|
||||
*user.IDNo = str[:6] + "****" + str[len(str)-2:]
|
||||
}
|
||||
|
||||
if user.Admin != nil {
|
||||
user.Admin = &m.Admin{
|
||||
Name: user.Admin.Name,
|
||||
@@ -133,7 +141,7 @@ func GetUserByAdmin(c *fiber.Ctx) error {
|
||||
// 查询用户
|
||||
user, err := q.User.
|
||||
Preload(q.User.Admin, q.User.Discount).
|
||||
Omit(q.User.Password).
|
||||
Omit(q.User.Password, q.Admin.Password).
|
||||
Where(do).
|
||||
Order(q.User.CreatedAt.Desc()).
|
||||
First()
|
||||
@@ -298,14 +306,29 @@ func UpdateUser(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
// 更新用户信息
|
||||
do := make([]field.AssignExpr, 0)
|
||||
if req.Username != nil && *req.Username != "" {
|
||||
do = append(do, q.User.Username.Value(*req.Username))
|
||||
}
|
||||
if req.Email != nil {
|
||||
if *req.Email == "" {
|
||||
do = append(do, q.User.Email.Null())
|
||||
} else {
|
||||
do = append(do, q.User.Email.Value(*req.Email))
|
||||
}
|
||||
}
|
||||
if req.ContactQQ != nil {
|
||||
do = append(do, q.User.ContactQQ.Value(*req.ContactQQ))
|
||||
}
|
||||
if req.ContactWechat != nil {
|
||||
do = append(do, q.User.ContactWechat.Value(*req.ContactWechat))
|
||||
}
|
||||
_, err = q.User.
|
||||
Where(q.User.ID.Eq(authCtx.User.ID)).
|
||||
Updates(m.User{
|
||||
Username: &req.Username,
|
||||
Email: &req.Email,
|
||||
ContactQQ: &req.ContactQQ,
|
||||
ContactWechat: &req.ContactWechat,
|
||||
})
|
||||
UpdateSimple(do...)
|
||||
if errors.Is(err, gorm.ErrDuplicatedKey) {
|
||||
return core.NewBizErr("用户名或邮箱已被占用")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -315,10 +338,10 @@ func UpdateUser(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
type UpdateUserReq struct {
|
||||
Username string `json:"username" validate:"omitempty,min=3,max=20"`
|
||||
Email string `json:"email" validate:"omitempty,email"`
|
||||
ContactQQ string `json:"contact_qq" validate:"omitempty,qq"`
|
||||
ContactWechat string `json:"contact_wechat" validate:"omitempty,wechat"`
|
||||
Username *string `json:"username" validate:"omitempty,min=3,max=20"`
|
||||
Email *string `json:"email" validate:"omitempty,email"`
|
||||
ContactQQ *string `json:"contact_qq" validate:"omitempty,qq"`
|
||||
ContactWechat *string `json:"contact_wechat" validate:"omitempty,wechat"`
|
||||
}
|
||||
|
||||
// 更新账号信息
|
||||
@@ -369,16 +392,14 @@ func UpdatePassword(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// 验证手机号
|
||||
if req.Phone != authCtx.User.Phone {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "手机号码不正确")
|
||||
}
|
||||
|
||||
// 验证手机令牌
|
||||
if req.Code == "" {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "手机号码和验证码不能为空")
|
||||
return fiber.NewError(fiber.StatusBadRequest, "验证码不能为空")
|
||||
}
|
||||
err = s.Verifier.VerifySms(c.Context(), authCtx.User.Phone, req.Code, s.VerifierSmsPurposePassword)
|
||||
if errors.Is(err, s.ErrVerifierServiceInvalid) {
|
||||
return core.NewBizErr(s.ErrVerifierServiceInvalid.Error())
|
||||
}
|
||||
err = s.Verifier.VerifySms(c.Context(), req.Phone, req.Code)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -401,7 +422,121 @@ func UpdatePassword(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
type UpdatePasswordReq struct {
|
||||
Phone string `json:"phone"`
|
||||
Code string `json:"code"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// PageUserNotBindByAdmin 分页获取未绑定管理员的用户
|
||||
func PageUserNotBindByAdmin(c *fiber.Ctx) error {
|
||||
// 检查权限
|
||||
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserReadNotBind)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析请求参数
|
||||
req := new(PageUserNotBindByAdminReq)
|
||||
if err := g.Validator.ParseBody(c, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 构建查询条件(强制过滤未绑定管理员的用户)
|
||||
do := q.User.Where(q.User.AdminID.IsNull())
|
||||
if req.Phone != nil {
|
||||
do = do.Where(q.User.Phone.Eq(*req.Phone))
|
||||
}
|
||||
|
||||
// 查询用户列表
|
||||
users, total, err := q.User.
|
||||
Omit(q.User.Password, q.User.IDNo).
|
||||
Where(do).
|
||||
Order(q.User.CreatedAt.Desc()).
|
||||
FindByPage(req.GetOffset(), req.GetLimit())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
return c.JSON(core.PageResp{
|
||||
Total: int(total),
|
||||
Page: req.GetPage(),
|
||||
Size: req.GetSize(),
|
||||
List: users,
|
||||
})
|
||||
}
|
||||
|
||||
type PageUserNotBindByAdminReq struct {
|
||||
core.PageReq
|
||||
Phone *string `json:"phone,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateUserBalanceIncByAdmin 管理员增加用户余额
|
||||
func UpdateUserBalanceIncByAdmin(c *fiber.Ctx) error {
|
||||
authCtx, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWriteBalance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req UpdateUserBalanceChangeByAdminData
|
||||
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
amount, err := decimal.NewFromString(req.Amount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !amount.IsPositive() {
|
||||
return core.NewBizErr("金额必须为正数")
|
||||
}
|
||||
|
||||
user, err := s.User.Get(q.Q, req.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newBalance := user.Balance.Add(amount)
|
||||
if err := s.User.UpdateBalanceByAdmin(user, newBalance, &authCtx.Admin.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(nil)
|
||||
}
|
||||
|
||||
// UpdateUserBalanceDecByAdmin 管理员减少用户余额
|
||||
func UpdateUserBalanceDecByAdmin(c *fiber.Ctx) error {
|
||||
authCtx, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeUserWriteBalance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req UpdateUserBalanceChangeByAdminData
|
||||
if err := g.Validator.ParseBody(c, &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
amount, err := decimal.NewFromString(req.Amount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !amount.IsPositive() {
|
||||
return core.NewBizErr("金额必须为正数")
|
||||
}
|
||||
|
||||
user, err := s.User.Get(q.Q, req.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newBalance := user.Balance.Sub(amount)
|
||||
if err := s.User.UpdateBalanceByAdmin(user, newBalance, &authCtx.Admin.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(nil)
|
||||
}
|
||||
|
||||
type UpdateUserBalanceChangeByAdminData struct {
|
||||
UserID int32 `json:"user_id" validate:"required"`
|
||||
Amount string `json:"amount" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"platform/pkg/env"
|
||||
"platform/web/auth"
|
||||
"platform/web/services"
|
||||
s "platform/web/services"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
@@ -13,12 +14,11 @@ import (
|
||||
)
|
||||
|
||||
type VerifierReq struct {
|
||||
Purpose services.VerifierSmsPurpose `json:"purpose"`
|
||||
Phone string `json:"phone"`
|
||||
Purpose s.VerifierSmsPurpose `json:"purpose"`
|
||||
Phone string `json:"phone"`
|
||||
}
|
||||
|
||||
func SmsCode(c *fiber.Ctx) error {
|
||||
|
||||
func SendSmsCode(c *fiber.Ctx) error {
|
||||
_, err := auth.GetAuthCtx(c).PermitOfficialClient()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -38,9 +38,9 @@ func SmsCode(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
// 发送身份验证码
|
||||
err = services.Verifier.SendSms(c.Context(), req.Phone, req.Purpose)
|
||||
err = s.Verifier.SendSms(c.Context(), req.Phone, req.Purpose)
|
||||
if err != nil {
|
||||
var sErr services.VerifierServiceSendLimitErr
|
||||
var sErr s.VerifierServiceSendLimitErr
|
||||
if errors.As(err, &sErr) {
|
||||
return fiber.NewError(fiber.StatusTooManyRequests, strconv.Itoa(int(sErr)))
|
||||
}
|
||||
@@ -51,6 +51,23 @@ func SmsCode(c *fiber.Ctx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func SendSmsCodeForPassword(c *fiber.Ctx) error {
|
||||
ac, err := auth.GetAuthCtx(c).PermitUser()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Verifier.SendSms(c.Context(), ac.User.Phone, s.VerifierSmsPurposePassword); err != nil {
|
||||
var sErr s.VerifierServiceSendLimitErr
|
||||
if errors.As(err, &sErr) {
|
||||
return fiber.NewError(fiber.StatusTooManyRequests, strconv.Itoa(int(sErr)))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func DebugGetSmsCode(c *fiber.Ctx) error {
|
||||
if env.RunMode != env.RunModeDev {
|
||||
return fiber.NewError(fiber.StatusForbidden, "not allowed")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"platform/pkg/env"
|
||||
"platform/pkg/u"
|
||||
"platform/web/auth"
|
||||
@@ -92,7 +93,7 @@ func CreateWhitelist(c *fiber.Ctx) error {
|
||||
|
||||
ip, err := secureAddr(req.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
return core.NewBizErr("IP 地址无效", err)
|
||||
}
|
||||
|
||||
// 创建白名单
|
||||
@@ -132,7 +133,7 @@ func UpdateWhitelist(c *fiber.Ctx) error {
|
||||
|
||||
ip, err := secureAddr(req.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
return core.NewBizErr("IP 地址无效", err)
|
||||
}
|
||||
|
||||
// 更新白名单
|
||||
@@ -201,7 +202,7 @@ func secureAddr(str string) (*orm.Inet, error) {
|
||||
return nil, err
|
||||
}
|
||||
if !ip.IsGlobalUnicast() && env.RunMode != env.RunModeDev {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "IP 地址不可用")
|
||||
return nil, errors.New("IP 地址不可用")
|
||||
}
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
type Admin struct {
|
||||
core.Model
|
||||
Username string `json:"username" gorm:"column:username"` // 用户名
|
||||
Password string `json:"password" gorm:"column:password"` // 密码
|
||||
Password string `json:"-" gorm:"column:password"` // 密码
|
||||
Name *string `json:"name,omitempty" gorm:"column:name"` // 真实姓名
|
||||
Avatar *string `json:"avatar,omitempty" gorm:"column:avatar"` // 头像URL
|
||||
Phone *string `json:"phone,omitempty" gorm:"column:phone"` // 手机号码
|
||||
@@ -20,6 +20,7 @@ type Admin struct {
|
||||
LastLogin *time.Time `json:"last_login,omitempty" gorm:"column:last_login"` // 最后登录时间
|
||||
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"` // 最后登录代理
|
||||
Lock bool `json:"lock" gorm:"column:lock"` // 是否锁定编辑
|
||||
|
||||
Roles []*AdminRole `json:"roles" gorm:"many2many:link_admin_role"`
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ type BalanceActivity struct {
|
||||
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"`
|
||||
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
Bill *Bill `json:"bill,omitempty" gorm:"foreignKey:BillID"`
|
||||
Admin *Admin `json:"admin,omitempty" gorm:"foreignKey:AdminID"`
|
||||
}
|
||||
|
||||
@@ -9,21 +9,22 @@ import (
|
||||
// Bill 账单表
|
||||
type Bill struct {
|
||||
core.Model
|
||||
UserID int32 `json:"user_id" gorm:"column:user_id"` // 用户ID
|
||||
TradeID *int32 `json:"trade_id,omitempty" gorm:"column:trade_id"` // 订单ID
|
||||
ResourceID *int32 `json:"resource_id,omitempty" gorm:"column:resource_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"` // 易读账单号
|
||||
Info *string `json:"info,omitempty" gorm:"column:info"` // 产品可读信息
|
||||
Type BillType `json:"type" gorm:"column:type"` // 账单类型:1-消费,2-退款,3-充值
|
||||
Amount decimal.Decimal `json:"amount" gorm:"column:amount"` // 应付金额
|
||||
Actual decimal.Decimal `json:"actual" gorm:"column:actual"` // 实付金额
|
||||
UserID int32 `json:"user_id" gorm:"column:user_id"` // 用户ID
|
||||
TradeID *int32 `json:"trade_id,omitempty" gorm:"column:trade_id"` // 订单ID
|
||||
ResourceID *int32 `json:"resource_id,omitempty" gorm:"column:resource_id"` // 套餐ID
|
||||
RefundID *int32 `json:"refund_id,omitempty" gorm:"column:refund_id"` // 退款ID
|
||||
CouponUserID *int32 `json:"coupon_user_id,omitempty" gorm:"column:coupon_user_id"` // 优惠券发放ID
|
||||
BillNo string `json:"bill_no" gorm:"column:bill_no"` // 易读账单号
|
||||
Info *string `json:"info,omitempty" gorm:"column:info"` // 产品可读信息
|
||||
Type BillType `json:"type" gorm:"column:type"` // 账单类型:1-消费,2-退款,3-充值
|
||||
Amount decimal.Decimal `json:"amount" gorm:"column:amount"` // 应付金额
|
||||
Actual decimal.Decimal `json:"actual" gorm:"column:actual"` // 实付金额
|
||||
|
||||
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
Trade *Trade `json:"trade,omitempty" gorm:"foreignKey:TradeID"`
|
||||
Resource *Resource `json:"resource,omitempty" gorm:"foreignKey:ResourceID"`
|
||||
Refund *Refund `json:"refund,omitempty" gorm:"foreignKey:RefundID"`
|
||||
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
Trade *Trade `json:"trade,omitempty" gorm:"foreignKey:TradeID"`
|
||||
Resource *Resource `json:"resource,omitempty" gorm:"foreignKey:ResourceID"`
|
||||
Refund *Refund `json:"refund,omitempty" gorm:"foreignKey:RefundID"`
|
||||
CouponUser *CouponUser `json:"coupon,omitempty" gorm:"foreignKey:CouponUserID"`
|
||||
}
|
||||
|
||||
// BillType 账单类型枚举
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
type Client struct {
|
||||
core.Model
|
||||
ClientID string `json:"client_id" gorm:"column:client_id"` // OAuth2客户端标识符
|
||||
ClientSecret string `json:"client_secret" gorm:"column:client_secret"` // OAuth2客户端密钥
|
||||
ClientSecret string `json:"-" gorm:"column:client_secret"` // OAuth2客户端密钥
|
||||
RedirectURI *string `json:"redirect_uri,omitempty" gorm:"column:redirect_uri"` // OAuth2 重定向URI
|
||||
Spec ClientSpec `json:"spec" gorm:"column:spec"` // 安全规范:1-native,2-browser,3-web,4-api
|
||||
Name string `json:"name" gorm:"column:name"` // 名称
|
||||
|
||||
@@ -10,20 +10,29 @@ import (
|
||||
// Coupon 优惠券表
|
||||
type Coupon struct {
|
||||
core.Model
|
||||
UserID *int32 `json:"user_id,omitempty" gorm:"column:user_id"` // 用户ID
|
||||
Code string `json:"code" gorm:"column:code"` // 优惠券代码
|
||||
Remark *string `json:"remark,omitempty" gorm:"column:remark"` // 优惠券备注
|
||||
Amount decimal.Decimal `json:"amount" gorm:"column:amount"` // 优惠券金额
|
||||
MinAmount decimal.Decimal `json:"min_amount" gorm:"column:min_amount"` // 最低消费金额
|
||||
Status CouponStatus `json:"status" gorm:"column:status"` // 优惠券状态:0-未使用,1-已使用,2-已过期
|
||||
ExpireAt *time.Time `json:"expire_at,omitempty" gorm:"column:expire_at"` // 过期时间
|
||||
Name string `json:"name" gorm:"column:name"` // 优惠券名称
|
||||
Amount decimal.Decimal `json:"amount" gorm:"column:amount"` // 优惠券金额
|
||||
MinAmount decimal.Decimal `json:"min_amount" gorm:"column:min_amount"` // 最低消费金额
|
||||
Count int32 `json:"count" gorm:"column:count"` // 优惠券数量
|
||||
Status CouponStatus `json:"status" gorm:"column:status"` // 优惠券状态:0-禁用,1-正常
|
||||
ExpireType CouponExpireType `json:"expire_type" gorm:"column:expire_type"` // 过期类型:0-不过期,1-固定日期,2-相对日期(从发放时间算起)
|
||||
ExpireAt *time.Time `json:"expire_at,omitempty" gorm:"column:expire_at"` // 过期时间,固定日期必填
|
||||
ExpireIn *int `json:"expire_in,omitempty" gorm:"column:expire_in"` // 过期时长(天),相对日期必填
|
||||
}
|
||||
|
||||
// CouponStatus 优惠券状态枚举
|
||||
// CouponStatus 优惠券使用状态枚举
|
||||
type CouponStatus int
|
||||
|
||||
const (
|
||||
CouponStatusUnused CouponStatus = 0 // 未使用
|
||||
CouponStatusUsed CouponStatus = 1 // 已使用
|
||||
CouponStatusExpired CouponStatus = 2 // 已过期
|
||||
CouponStatusDisabled CouponStatus = 0 // 禁用
|
||||
CouponStatusEnabled CouponStatus = 1 // 正常
|
||||
)
|
||||
|
||||
// CouponExpireType 优惠券过期类型枚举
|
||||
type CouponExpireType int
|
||||
|
||||
const (
|
||||
CouponExpireTypeNever CouponExpireType = 0 // 不过期
|
||||
CouponExpireTypeFixed CouponExpireType = 1 // 固定日期
|
||||
CouponExpireTypeRelative CouponExpireType = 2 // 相对日期
|
||||
)
|
||||
|
||||
25
web/models/coupon_user.go
Normal file
25
web/models/coupon_user.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// CouponUser 优惠券发放表
|
||||
type CouponUser struct {
|
||||
ID int32 `json:"id" gorm:"column:id;primaryKey"` // 记录ID
|
||||
CouponID int32 `json:"coupon_id" gorm:"column:coupon_id"` // 优惠券ID
|
||||
UserID int32 `json:"user_id" gorm:"column:user_id"` // 用户ID
|
||||
Status CouponStatus `json:"status" gorm:"column:status"` // 使用状态:0-未使用,1-已使用
|
||||
ExpireAt *time.Time `json:"expire_at,omitempty" gorm:"column:expire_at"` // 过期时间
|
||||
UsedAt *time.Time `json:"used_at,omitempty" gorm:"column:used_at"` // 使用时间
|
||||
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` // 创建时间
|
||||
|
||||
Coupon *Coupon `json:"coupon,omitempty" gorm:"foreignKey:CouponID"`
|
||||
User *User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
}
|
||||
|
||||
// CouponUserStatus 优惠券发放状态枚举
|
||||
type CouponUserStatus int
|
||||
|
||||
const (
|
||||
CouponUserStatusUnused CouponUserStatus = 0 // 未使用
|
||||
CouponUserStatusUsed CouponUserStatus = 1 // 已使用
|
||||
)
|
||||
@@ -12,6 +12,8 @@ type Product struct {
|
||||
Description *string `json:"description,omitempty" gorm:"column:description"` // 产品描述
|
||||
Sort int32 `json:"sort" gorm:"column:sort"` // 排序
|
||||
Status ProductStatus `json:"status" gorm:"column:status"` // 产品状态:0-禁用,1-正常
|
||||
|
||||
Skus []*ProductSku `json:"skus,omitempty" gorm:"foreignKey:ProductID"` // 产品包含的SKU列表
|
||||
}
|
||||
|
||||
// ProductStatus 产品状态枚举
|
||||
|
||||
@@ -14,7 +14,18 @@ type ProductSku struct {
|
||||
Code string `json:"code" gorm:"column:code"` // SSKU 代码:格式为 key=value,key=value,...,其中,key:value 是 SKU 的属性,多个属性用逗号分隔
|
||||
Name string `json:"name" gorm:"column:name"` // SKU 可读名称
|
||||
Price decimal.Decimal `json:"price" gorm:"column:price"` // 定价
|
||||
PriceMin decimal.Decimal `json:"price_min" gorm:"column:price_min"` // 最低价格
|
||||
Status SkuStatus `json:"status" gorm:"column:status"` // SKU 状态:0-禁用,1-正常
|
||||
Sort int32 `json:"sort" gorm:"column:sort"` // 排序
|
||||
|
||||
Product *Product `json:"product,omitempty" gorm:"foreignKey:ProductID"`
|
||||
Discount *ProductDiscount `json:"discount,omitempty" gorm:"foreignKey:DiscountId"`
|
||||
}
|
||||
|
||||
// SkuStatus SKU 状态
|
||||
type SkuStatus int32
|
||||
|
||||
const (
|
||||
SkuStatusDisabled SkuStatus = 0 // 禁用
|
||||
SkuStatusEnabled SkuStatus = 1 // 正常
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ type User struct {
|
||||
Phone string `json:"phone" gorm:"column:phone"` // 手机号码
|
||||
Username *string `json:"username,omitempty" gorm:"column:username"` // 用户名
|
||||
Email *string `json:"email,omitempty" gorm:"column:email"` // 邮箱
|
||||
Password *string `json:"password,omitempty" gorm:"column:password"` // 用户密码
|
||||
Password *string `json:"-" gorm:"column:password"` // 用户密码
|
||||
Source *UserSource `json:"source,omitempty" gorm:"column:source"` // 用户来源:0-官网注册,1-管理员添加,2-代理商注册,3-代理商添加
|
||||
Name *string `json:"name,omitempty" gorm:"column:name"` // 真实姓名
|
||||
Avatar *string `json:"avatar,omitempty" gorm:"column:avatar"` // 头像URL
|
||||
|
||||
@@ -41,6 +41,7 @@ func newAdmin(db *gorm.DB, opts ...gen.DOOption) admin {
|
||||
_admin.LastLogin = field.NewTime(tableName, "last_login")
|
||||
_admin.LastLoginIP = field.NewField(tableName, "last_login_ip")
|
||||
_admin.LastLoginUA = field.NewString(tableName, "last_login_ua")
|
||||
_admin.Lock = field.NewBool(tableName, "lock")
|
||||
_admin.Roles = adminManyToManyRoles{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
@@ -91,6 +92,7 @@ type admin struct {
|
||||
LastLogin field.Time
|
||||
LastLoginIP field.Field
|
||||
LastLoginUA field.String
|
||||
Lock field.Bool
|
||||
Roles adminManyToManyRoles
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
@@ -122,6 +124,7 @@ func (a *admin) updateTableName(table string) *admin {
|
||||
a.LastLogin = field.NewTime(table, "last_login")
|
||||
a.LastLoginIP = field.NewField(table, "last_login_ip")
|
||||
a.LastLoginUA = field.NewString(table, "last_login_ua")
|
||||
a.Lock = field.NewBool(table, "lock")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
@@ -138,7 +141,7 @@ func (a *admin) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (a *admin) fillFieldMap() {
|
||||
a.fieldMap = make(map[string]field.Expr, 15)
|
||||
a.fieldMap = make(map[string]field.Expr, 16)
|
||||
a.fieldMap["id"] = a.ID
|
||||
a.fieldMap["created_at"] = a.CreatedAt
|
||||
a.fieldMap["updated_at"] = a.UpdatedAt
|
||||
@@ -153,6 +156,7 @@ func (a *admin) fillFieldMap() {
|
||||
a.fieldMap["last_login"] = a.LastLogin
|
||||
a.fieldMap["last_login_ip"] = a.LastLoginIP
|
||||
a.fieldMap["last_login_ua"] = a.LastLoginUA
|
||||
a.fieldMap["lock"] = a.Lock
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -36,10 +36,10 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
_balanceActivity.BalanceCurr = field.NewString(tableName, "balance_curr")
|
||||
_balanceActivity.Remark = field.NewString(tableName, "remark")
|
||||
_balanceActivity.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_balanceActivity.Admin = balanceActivityHasOneAdmin{
|
||||
_balanceActivity.User = balanceActivityBelongsToUser{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Admin", "models.User"),
|
||||
RelationField: field.NewRelation("User", "models.User"),
|
||||
Admin: struct {
|
||||
field.RelationField
|
||||
Roles struct {
|
||||
@@ -55,7 +55,7 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
}
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Admin.Admin", "models.Admin"),
|
||||
RelationField: field.NewRelation("User.Admin", "models.Admin"),
|
||||
Roles: struct {
|
||||
field.RelationField
|
||||
Permissions struct {
|
||||
@@ -68,7 +68,7 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
}
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Admin.Admin.Roles", "models.AdminRole"),
|
||||
RelationField: field.NewRelation("User.Admin.Roles", "models.AdminRole"),
|
||||
Permissions: struct {
|
||||
field.RelationField
|
||||
Parent struct {
|
||||
@@ -78,16 +78,16 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Admin.Admin.Roles.Permissions", "models.Permission"),
|
||||
RelationField: field.NewRelation("User.Admin.Roles.Permissions", "models.Permission"),
|
||||
Parent: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Admin.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Parent", "models.Permission"),
|
||||
},
|
||||
Children: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Admin.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||
RelationField: field.NewRelation("User.Admin.Roles.Permissions.Children", "models.Permission"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -95,7 +95,7 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Admin.Discount", "models.ProductDiscount"),
|
||||
RelationField: field.NewRelation("User.Discount", "models.ProductDiscount"),
|
||||
},
|
||||
Roles: struct {
|
||||
field.RelationField
|
||||
@@ -103,21 +103,15 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Admin.Roles", "models.UserRole"),
|
||||
RelationField: field.NewRelation("User.Roles", "models.UserRole"),
|
||||
Permissions: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Admin.Roles.Permissions", "models.Permission"),
|
||||
RelationField: field.NewRelation("User.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{}),
|
||||
|
||||
@@ -151,6 +145,9 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -179,6 +176,9 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -190,6 +190,9 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -198,8 +201,16 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
RelationField: field.NewRelation("Bill.Resource.Short.Sku", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Bill.Resource.Short.Sku.Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Bill.Resource.Short.Sku.Product.Skus", "models.ProductSku"),
|
||||
},
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
@@ -232,6 +243,33 @@ func newBalanceActivity(db *gorm.DB, opts ...gen.DOOption) balanceActivity {
|
||||
}{
|
||||
RelationField: field.NewRelation("Bill.Refund", "models.Refund"),
|
||||
},
|
||||
CouponUser: struct {
|
||||
field.RelationField
|
||||
Coupon struct {
|
||||
field.RelationField
|
||||
}
|
||||
User struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Bill.CouponUser", "models.CouponUser"),
|
||||
Coupon: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Bill.CouponUser.Coupon", "models.Coupon"),
|
||||
},
|
||||
User: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Bill.CouponUser.User", "models.User"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_balanceActivity.Admin = balanceActivityBelongsToAdmin{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Admin", "models.Admin"),
|
||||
}
|
||||
|
||||
_balanceActivity.fillFieldMap()
|
||||
@@ -252,12 +290,12 @@ type balanceActivity struct {
|
||||
BalanceCurr field.String
|
||||
Remark field.String
|
||||
CreatedAt field.Time
|
||||
Admin balanceActivityHasOneAdmin
|
||||
|
||||
User balanceActivityBelongsToUser
|
||||
User balanceActivityBelongsToUser
|
||||
|
||||
Bill balanceActivityBelongsToBill
|
||||
|
||||
Admin balanceActivityBelongsToAdmin
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
@@ -313,24 +351,24 @@ func (b *balanceActivity) fillFieldMap() {
|
||||
|
||||
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
|
||||
b.Admin.db = db.Session(&gorm.Session{Initialized: true})
|
||||
b.Admin.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{})
|
||||
b.Admin.db = db.Session(&gorm.Session{})
|
||||
return b
|
||||
}
|
||||
|
||||
type balanceActivityHasOneAdmin struct {
|
||||
type balanceActivityBelongsToUser struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
@@ -361,87 +399,6 @@ type balanceActivityHasOneAdmin struct {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -542,6 +499,9 @@ type balanceActivityBelongsToBill struct {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -561,6 +521,15 @@ type balanceActivityBelongsToBill struct {
|
||||
Refund struct {
|
||||
field.RelationField
|
||||
}
|
||||
CouponUser struct {
|
||||
field.RelationField
|
||||
Coupon struct {
|
||||
field.RelationField
|
||||
}
|
||||
User struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToBill) Where(conds ...field.Expr) *balanceActivityBelongsToBill {
|
||||
@@ -638,6 +607,87 @@ func (a balanceActivityBelongsToBillTx) Unscoped() *balanceActivityBelongsToBill
|
||||
return &a
|
||||
}
|
||||
|
||||
type balanceActivityBelongsToAdmin struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToAdmin) Where(conds ...field.Expr) *balanceActivityBelongsToAdmin {
|
||||
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 balanceActivityBelongsToAdmin) WithContext(ctx context.Context) *balanceActivityBelongsToAdmin {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToAdmin) Session(session *gorm.Session) *balanceActivityBelongsToAdmin {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToAdmin) Model(m *models.BalanceActivity) *balanceActivityBelongsToAdminTx {
|
||||
return &balanceActivityBelongsToAdminTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToAdmin) Unscoped() *balanceActivityBelongsToAdmin {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type balanceActivityBelongsToAdminTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a balanceActivityBelongsToAdminTx) Find() (result *models.Admin, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToAdminTx) Append(values ...*models.Admin) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToAdminTx) Replace(values ...*models.Admin) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToAdminTx) Delete(values ...*models.Admin) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToAdminTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToAdminTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a balanceActivityBelongsToAdminTx) Unscoped() *balanceActivityBelongsToAdminTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type balanceActivityDo struct{ gen.DO }
|
||||
|
||||
func (b balanceActivityDo) Debug() *balanceActivityDo {
|
||||
|
||||
@@ -35,7 +35,7 @@ func newBill(db *gorm.DB, opts ...gen.DOOption) bill {
|
||||
_bill.TradeID = field.NewInt32(tableName, "trade_id")
|
||||
_bill.ResourceID = field.NewInt32(tableName, "resource_id")
|
||||
_bill.RefundID = field.NewInt32(tableName, "refund_id")
|
||||
_bill.CouponID = field.NewInt32(tableName, "coupon_id")
|
||||
_bill.CouponUserID = field.NewInt32(tableName, "coupon_user_id")
|
||||
_bill.BillNo = field.NewString(tableName, "bill_no")
|
||||
_bill.Info = field.NewString(tableName, "info")
|
||||
_bill.Type = field.NewInt(tableName, "type")
|
||||
@@ -143,6 +143,9 @@ func newBill(db *gorm.DB, opts ...gen.DOOption) bill {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -154,6 +157,9 @@ func newBill(db *gorm.DB, opts ...gen.DOOption) bill {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -162,8 +168,16 @@ func newBill(db *gorm.DB, opts ...gen.DOOption) bill {
|
||||
RelationField: field.NewRelation("Resource.Short.Sku", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Resource.Short.Sku.Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Resource.Short.Sku.Product.Skus", "models.ProductSku"),
|
||||
},
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
@@ -198,6 +212,22 @@ func newBill(db *gorm.DB, opts ...gen.DOOption) bill {
|
||||
RelationField: field.NewRelation("Refund", "models.Refund"),
|
||||
}
|
||||
|
||||
_bill.CouponUser = billBelongsToCouponUser{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("CouponUser", "models.CouponUser"),
|
||||
Coupon: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("CouponUser.Coupon", "models.Coupon"),
|
||||
},
|
||||
User: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("CouponUser.User", "models.User"),
|
||||
},
|
||||
}
|
||||
|
||||
_bill.fillFieldMap()
|
||||
|
||||
return _bill
|
||||
@@ -206,22 +236,22 @@ func newBill(db *gorm.DB, opts ...gen.DOOption) bill {
|
||||
type bill struct {
|
||||
billDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int32
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
DeletedAt field.Field
|
||||
UserID field.Int32
|
||||
TradeID field.Int32
|
||||
ResourceID field.Int32
|
||||
RefundID field.Int32
|
||||
CouponID field.Int32
|
||||
BillNo field.String
|
||||
Info field.String
|
||||
Type field.Int
|
||||
Amount field.Field
|
||||
Actual field.Field
|
||||
User billBelongsToUser
|
||||
ALL field.Asterisk
|
||||
ID field.Int32
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
DeletedAt field.Field
|
||||
UserID field.Int32
|
||||
TradeID field.Int32
|
||||
ResourceID field.Int32
|
||||
RefundID field.Int32
|
||||
CouponUserID field.Int32
|
||||
BillNo field.String
|
||||
Info field.String
|
||||
Type field.Int
|
||||
Amount field.Field
|
||||
Actual field.Field
|
||||
User billBelongsToUser
|
||||
|
||||
Trade billBelongsToTrade
|
||||
|
||||
@@ -229,6 +259,8 @@ type bill struct {
|
||||
|
||||
Refund billBelongsToRefund
|
||||
|
||||
CouponUser billBelongsToCouponUser
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
@@ -252,7 +284,7 @@ func (b *bill) updateTableName(table string) *bill {
|
||||
b.TradeID = field.NewInt32(table, "trade_id")
|
||||
b.ResourceID = field.NewInt32(table, "resource_id")
|
||||
b.RefundID = field.NewInt32(table, "refund_id")
|
||||
b.CouponID = field.NewInt32(table, "coupon_id")
|
||||
b.CouponUserID = field.NewInt32(table, "coupon_user_id")
|
||||
b.BillNo = field.NewString(table, "bill_no")
|
||||
b.Info = field.NewString(table, "info")
|
||||
b.Type = field.NewInt(table, "type")
|
||||
@@ -274,7 +306,7 @@ func (b *bill) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (b *bill) fillFieldMap() {
|
||||
b.fieldMap = make(map[string]field.Expr, 18)
|
||||
b.fieldMap = make(map[string]field.Expr, 19)
|
||||
b.fieldMap["id"] = b.ID
|
||||
b.fieldMap["created_at"] = b.CreatedAt
|
||||
b.fieldMap["updated_at"] = b.UpdatedAt
|
||||
@@ -283,7 +315,7 @@ func (b *bill) fillFieldMap() {
|
||||
b.fieldMap["trade_id"] = b.TradeID
|
||||
b.fieldMap["resource_id"] = b.ResourceID
|
||||
b.fieldMap["refund_id"] = b.RefundID
|
||||
b.fieldMap["coupon_id"] = b.CouponID
|
||||
b.fieldMap["coupon_user_id"] = b.CouponUserID
|
||||
b.fieldMap["bill_no"] = b.BillNo
|
||||
b.fieldMap["info"] = b.Info
|
||||
b.fieldMap["type"] = b.Type
|
||||
@@ -302,6 +334,8 @@ func (b bill) clone(db *gorm.DB) bill {
|
||||
b.Resource.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
b.Refund.db = db.Session(&gorm.Session{Initialized: true})
|
||||
b.Refund.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
b.CouponUser.db = db.Session(&gorm.Session{Initialized: true})
|
||||
b.CouponUser.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -311,6 +345,7 @@ func (b bill) replaceDB(db *gorm.DB) bill {
|
||||
b.Trade.db = db.Session(&gorm.Session{})
|
||||
b.Resource.db = db.Session(&gorm.Session{})
|
||||
b.Refund.db = db.Session(&gorm.Session{})
|
||||
b.CouponUser.db = db.Session(&gorm.Session{})
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -519,6 +554,9 @@ type billBelongsToResource struct {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -692,6 +730,94 @@ func (a billBelongsToRefundTx) Unscoped() *billBelongsToRefundTx {
|
||||
return &a
|
||||
}
|
||||
|
||||
type billBelongsToCouponUser struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
|
||||
Coupon struct {
|
||||
field.RelationField
|
||||
}
|
||||
User struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
|
||||
func (a billBelongsToCouponUser) Where(conds ...field.Expr) *billBelongsToCouponUser {
|
||||
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 billBelongsToCouponUser) WithContext(ctx context.Context) *billBelongsToCouponUser {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a billBelongsToCouponUser) Session(session *gorm.Session) *billBelongsToCouponUser {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a billBelongsToCouponUser) Model(m *models.Bill) *billBelongsToCouponUserTx {
|
||||
return &billBelongsToCouponUserTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a billBelongsToCouponUser) Unscoped() *billBelongsToCouponUser {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type billBelongsToCouponUserTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a billBelongsToCouponUserTx) Find() (result *models.CouponUser, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a billBelongsToCouponUserTx) Append(values ...*models.CouponUser) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a billBelongsToCouponUserTx) Replace(values ...*models.CouponUser) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a billBelongsToCouponUserTx) Delete(values ...*models.CouponUser) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a billBelongsToCouponUserTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a billBelongsToCouponUserTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a billBelongsToCouponUserTx) Unscoped() *billBelongsToCouponUserTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type billDo struct{ gen.DO }
|
||||
|
||||
func (b billDo) Debug() *billDo {
|
||||
|
||||
@@ -138,6 +138,9 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -149,6 +152,9 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -157,8 +163,16 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel {
|
||||
RelationField: field.NewRelation("Resource.Short.Sku", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Resource.Short.Sku.Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Resource.Short.Sku.Product.Skus", "models.ProductSku"),
|
||||
},
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
@@ -490,6 +504,9 @@ type channelBelongsToResource struct {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
|
||||
@@ -31,13 +31,14 @@ func newCoupon(db *gorm.DB, opts ...gen.DOOption) coupon {
|
||||
_coupon.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_coupon.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||
_coupon.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||
_coupon.UserID = field.NewInt32(tableName, "user_id")
|
||||
_coupon.Code = field.NewString(tableName, "code")
|
||||
_coupon.Remark = field.NewString(tableName, "remark")
|
||||
_coupon.Name = field.NewString(tableName, "name")
|
||||
_coupon.Amount = field.NewField(tableName, "amount")
|
||||
_coupon.MinAmount = field.NewField(tableName, "min_amount")
|
||||
_coupon.Count_ = field.NewInt32(tableName, "count")
|
||||
_coupon.Status = field.NewInt(tableName, "status")
|
||||
_coupon.ExpireType = field.NewInt(tableName, "expire_type")
|
||||
_coupon.ExpireAt = field.NewTime(tableName, "expire_at")
|
||||
_coupon.ExpireIn = field.NewInt(tableName, "expire_in")
|
||||
|
||||
_coupon.fillFieldMap()
|
||||
|
||||
@@ -47,18 +48,19 @@ func newCoupon(db *gorm.DB, opts ...gen.DOOption) coupon {
|
||||
type coupon struct {
|
||||
couponDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int32
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
DeletedAt field.Field
|
||||
UserID field.Int32
|
||||
Code field.String
|
||||
Remark field.String
|
||||
Amount field.Field
|
||||
MinAmount field.Field
|
||||
Status field.Int
|
||||
ExpireAt field.Time
|
||||
ALL field.Asterisk
|
||||
ID field.Int32
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
DeletedAt field.Field
|
||||
Name field.String
|
||||
Amount field.Field
|
||||
MinAmount field.Field
|
||||
Count_ field.Int32
|
||||
Status field.Int
|
||||
ExpireType field.Int
|
||||
ExpireAt field.Time
|
||||
ExpireIn field.Int
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@@ -79,13 +81,14 @@ func (c *coupon) updateTableName(table string) *coupon {
|
||||
c.CreatedAt = field.NewTime(table, "created_at")
|
||||
c.UpdatedAt = field.NewTime(table, "updated_at")
|
||||
c.DeletedAt = field.NewField(table, "deleted_at")
|
||||
c.UserID = field.NewInt32(table, "user_id")
|
||||
c.Code = field.NewString(table, "code")
|
||||
c.Remark = field.NewString(table, "remark")
|
||||
c.Name = field.NewString(table, "name")
|
||||
c.Amount = field.NewField(table, "amount")
|
||||
c.MinAmount = field.NewField(table, "min_amount")
|
||||
c.Count_ = field.NewInt32(table, "count")
|
||||
c.Status = field.NewInt(table, "status")
|
||||
c.ExpireType = field.NewInt(table, "expire_type")
|
||||
c.ExpireAt = field.NewTime(table, "expire_at")
|
||||
c.ExpireIn = field.NewInt(table, "expire_in")
|
||||
|
||||
c.fillFieldMap()
|
||||
|
||||
@@ -102,18 +105,19 @@ func (c *coupon) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (c *coupon) fillFieldMap() {
|
||||
c.fieldMap = make(map[string]field.Expr, 11)
|
||||
c.fieldMap = make(map[string]field.Expr, 12)
|
||||
c.fieldMap["id"] = c.ID
|
||||
c.fieldMap["created_at"] = c.CreatedAt
|
||||
c.fieldMap["updated_at"] = c.UpdatedAt
|
||||
c.fieldMap["deleted_at"] = c.DeletedAt
|
||||
c.fieldMap["user_id"] = c.UserID
|
||||
c.fieldMap["code"] = c.Code
|
||||
c.fieldMap["remark"] = c.Remark
|
||||
c.fieldMap["name"] = c.Name
|
||||
c.fieldMap["amount"] = c.Amount
|
||||
c.fieldMap["min_amount"] = c.MinAmount
|
||||
c.fieldMap["count"] = c.Count_
|
||||
c.fieldMap["status"] = c.Status
|
||||
c.fieldMap["expire_type"] = c.ExpireType
|
||||
c.fieldMap["expire_at"] = c.ExpireAt
|
||||
c.fieldMap["expire_in"] = c.ExpireIn
|
||||
}
|
||||
|
||||
func (c coupon) clone(db *gorm.DB) coupon {
|
||||
|
||||
621
web/queries/coupon_user.gen.go
Normal file
621
web/queries/coupon_user.gen.go
Normal file
@@ -0,0 +1,621 @@
|
||||
// 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 newCouponUser(db *gorm.DB, opts ...gen.DOOption) couponUser {
|
||||
_couponUser := couponUser{}
|
||||
|
||||
_couponUser.couponUserDo.UseDB(db, opts...)
|
||||
_couponUser.couponUserDo.UseModel(&models.CouponUser{})
|
||||
|
||||
tableName := _couponUser.couponUserDo.TableName()
|
||||
_couponUser.ALL = field.NewAsterisk(tableName)
|
||||
_couponUser.ID = field.NewInt32(tableName, "id")
|
||||
_couponUser.CouponID = field.NewInt32(tableName, "coupon_id")
|
||||
_couponUser.UserID = field.NewInt32(tableName, "user_id")
|
||||
_couponUser.Status = field.NewInt(tableName, "status")
|
||||
_couponUser.ExpireAt = field.NewTime(tableName, "expire_at")
|
||||
_couponUser.UsedAt = field.NewTime(tableName, "used_at")
|
||||
_couponUser.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_couponUser.Coupon = couponUserBelongsToCoupon{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Coupon", "models.Coupon"),
|
||||
}
|
||||
|
||||
_couponUser.User = couponUserBelongsToUser{
|
||||
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"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_couponUser.fillFieldMap()
|
||||
|
||||
return _couponUser
|
||||
}
|
||||
|
||||
type couponUser struct {
|
||||
couponUserDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int32
|
||||
CouponID field.Int32
|
||||
UserID field.Int32
|
||||
Status field.Int
|
||||
ExpireAt field.Time
|
||||
UsedAt field.Time
|
||||
CreatedAt field.Time
|
||||
Coupon couponUserBelongsToCoupon
|
||||
|
||||
User couponUserBelongsToUser
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (c couponUser) Table(newTableName string) *couponUser {
|
||||
c.couponUserDo.UseTable(newTableName)
|
||||
return c.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (c couponUser) As(alias string) *couponUser {
|
||||
c.couponUserDo.DO = *(c.couponUserDo.As(alias).(*gen.DO))
|
||||
return c.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (c *couponUser) updateTableName(table string) *couponUser {
|
||||
c.ALL = field.NewAsterisk(table)
|
||||
c.ID = field.NewInt32(table, "id")
|
||||
c.CouponID = field.NewInt32(table, "coupon_id")
|
||||
c.UserID = field.NewInt32(table, "user_id")
|
||||
c.Status = field.NewInt(table, "status")
|
||||
c.ExpireAt = field.NewTime(table, "expire_at")
|
||||
c.UsedAt = field.NewTime(table, "used_at")
|
||||
c.CreatedAt = field.NewTime(table, "created_at")
|
||||
|
||||
c.fillFieldMap()
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *couponUser) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := c.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (c *couponUser) fillFieldMap() {
|
||||
c.fieldMap = make(map[string]field.Expr, 9)
|
||||
c.fieldMap["id"] = c.ID
|
||||
c.fieldMap["coupon_id"] = c.CouponID
|
||||
c.fieldMap["user_id"] = c.UserID
|
||||
c.fieldMap["status"] = c.Status
|
||||
c.fieldMap["expire_at"] = c.ExpireAt
|
||||
c.fieldMap["used_at"] = c.UsedAt
|
||||
c.fieldMap["created_at"] = c.CreatedAt
|
||||
|
||||
}
|
||||
|
||||
func (c couponUser) clone(db *gorm.DB) couponUser {
|
||||
c.couponUserDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
c.Coupon.db = db.Session(&gorm.Session{Initialized: true})
|
||||
c.Coupon.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
c.User.db = db.Session(&gorm.Session{Initialized: true})
|
||||
c.User.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
return c
|
||||
}
|
||||
|
||||
func (c couponUser) replaceDB(db *gorm.DB) couponUser {
|
||||
c.couponUserDo.ReplaceDB(db)
|
||||
c.Coupon.db = db.Session(&gorm.Session{})
|
||||
c.User.db = db.Session(&gorm.Session{})
|
||||
return c
|
||||
}
|
||||
|
||||
type couponUserBelongsToCoupon struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToCoupon) Where(conds ...field.Expr) *couponUserBelongsToCoupon {
|
||||
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 couponUserBelongsToCoupon) WithContext(ctx context.Context) *couponUserBelongsToCoupon {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToCoupon) Session(session *gorm.Session) *couponUserBelongsToCoupon {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToCoupon) Model(m *models.CouponUser) *couponUserBelongsToCouponTx {
|
||||
return &couponUserBelongsToCouponTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToCoupon) Unscoped() *couponUserBelongsToCoupon {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type couponUserBelongsToCouponTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a couponUserBelongsToCouponTx) Find() (result *models.Coupon, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToCouponTx) Append(values ...*models.Coupon) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToCouponTx) Replace(values ...*models.Coupon) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToCouponTx) Delete(values ...*models.Coupon) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToCouponTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToCouponTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToCouponTx) Unscoped() *couponUserBelongsToCouponTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type couponUserBelongsToUser 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 couponUserBelongsToUser) Where(conds ...field.Expr) *couponUserBelongsToUser {
|
||||
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 couponUserBelongsToUser) WithContext(ctx context.Context) *couponUserBelongsToUser {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToUser) Session(session *gorm.Session) *couponUserBelongsToUser {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToUser) Model(m *models.CouponUser) *couponUserBelongsToUserTx {
|
||||
return &couponUserBelongsToUserTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToUser) Unscoped() *couponUserBelongsToUser {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type couponUserBelongsToUserTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a couponUserBelongsToUserTx) Find() (result *models.User, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToUserTx) 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 couponUserBelongsToUserTx) 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 couponUserBelongsToUserTx) 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 couponUserBelongsToUserTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToUserTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a couponUserBelongsToUserTx) Unscoped() *couponUserBelongsToUserTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type couponUserDo struct{ gen.DO }
|
||||
|
||||
func (c couponUserDo) Debug() *couponUserDo {
|
||||
return c.withDO(c.DO.Debug())
|
||||
}
|
||||
|
||||
func (c couponUserDo) WithContext(ctx context.Context) *couponUserDo {
|
||||
return c.withDO(c.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (c couponUserDo) ReadDB() *couponUserDo {
|
||||
return c.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (c couponUserDo) WriteDB() *couponUserDo {
|
||||
return c.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (c couponUserDo) Session(config *gorm.Session) *couponUserDo {
|
||||
return c.withDO(c.DO.Session(config))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Clauses(conds ...clause.Expression) *couponUserDo {
|
||||
return c.withDO(c.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Returning(value interface{}, columns ...string) *couponUserDo {
|
||||
return c.withDO(c.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Not(conds ...gen.Condition) *couponUserDo {
|
||||
return c.withDO(c.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Or(conds ...gen.Condition) *couponUserDo {
|
||||
return c.withDO(c.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Select(conds ...field.Expr) *couponUserDo {
|
||||
return c.withDO(c.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Where(conds ...gen.Condition) *couponUserDo {
|
||||
return c.withDO(c.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Order(conds ...field.Expr) *couponUserDo {
|
||||
return c.withDO(c.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Distinct(cols ...field.Expr) *couponUserDo {
|
||||
return c.withDO(c.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Omit(cols ...field.Expr) *couponUserDo {
|
||||
return c.withDO(c.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Join(table schema.Tabler, on ...field.Expr) *couponUserDo {
|
||||
return c.withDO(c.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) LeftJoin(table schema.Tabler, on ...field.Expr) *couponUserDo {
|
||||
return c.withDO(c.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) RightJoin(table schema.Tabler, on ...field.Expr) *couponUserDo {
|
||||
return c.withDO(c.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Group(cols ...field.Expr) *couponUserDo {
|
||||
return c.withDO(c.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Having(conds ...gen.Condition) *couponUserDo {
|
||||
return c.withDO(c.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Limit(limit int) *couponUserDo {
|
||||
return c.withDO(c.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Offset(offset int) *couponUserDo {
|
||||
return c.withDO(c.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *couponUserDo {
|
||||
return c.withDO(c.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Unscoped() *couponUserDo {
|
||||
return c.withDO(c.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (c couponUserDo) Create(values ...*models.CouponUser) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Create(values)
|
||||
}
|
||||
|
||||
func (c couponUserDo) CreateInBatches(values []*models.CouponUser, batchSize int) error {
|
||||
return c.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 (c couponUserDo) Save(values ...*models.CouponUser) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Save(values)
|
||||
}
|
||||
|
||||
func (c couponUserDo) First() (*models.CouponUser, error) {
|
||||
if result, err := c.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.CouponUser), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c couponUserDo) Take() (*models.CouponUser, error) {
|
||||
if result, err := c.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.CouponUser), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c couponUserDo) Last() (*models.CouponUser, error) {
|
||||
if result, err := c.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.CouponUser), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c couponUserDo) Find() ([]*models.CouponUser, error) {
|
||||
result, err := c.DO.Find()
|
||||
return result.([]*models.CouponUser), err
|
||||
}
|
||||
|
||||
func (c couponUserDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.CouponUser, err error) {
|
||||
buf := make([]*models.CouponUser, 0, batchSize)
|
||||
err = c.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 (c couponUserDo) FindInBatches(result *[]*models.CouponUser, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return c.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (c couponUserDo) Attrs(attrs ...field.AssignExpr) *couponUserDo {
|
||||
return c.withDO(c.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Assign(attrs ...field.AssignExpr) *couponUserDo {
|
||||
return c.withDO(c.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (c couponUserDo) Joins(fields ...field.RelationField) *couponUserDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Joins(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c couponUserDo) Preload(fields ...field.RelationField) *couponUserDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Preload(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c couponUserDo) FirstOrInit() (*models.CouponUser, error) {
|
||||
if result, err := c.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.CouponUser), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c couponUserDo) FirstOrCreate() (*models.CouponUser, error) {
|
||||
if result, err := c.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.CouponUser), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c couponUserDo) FindByPage(offset int, limit int) (result []*models.CouponUser, count int64, err error) {
|
||||
result, err = c.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 = c.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (c couponUserDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = c.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = c.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c couponUserDo) Scan(result interface{}) (err error) {
|
||||
return c.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (c couponUserDo) Delete(models ...*models.CouponUser) (result gen.ResultInfo, err error) {
|
||||
return c.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (c *couponUserDo) withDO(do gen.Dao) *couponUserDo {
|
||||
c.DO = *do.(*gen.DO)
|
||||
return c
|
||||
}
|
||||
@@ -25,6 +25,7 @@ var (
|
||||
Channel *channel
|
||||
Client *client
|
||||
Coupon *coupon
|
||||
CouponUser *couponUser
|
||||
Edge *edge
|
||||
Inquiry *inquiry
|
||||
LinkAdminRole *linkAdminRole
|
||||
@@ -63,6 +64,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
||||
Channel = &Q.Channel
|
||||
Client = &Q.Client
|
||||
Coupon = &Q.Coupon
|
||||
CouponUser = &Q.CouponUser
|
||||
Edge = &Q.Edge
|
||||
Inquiry = &Q.Inquiry
|
||||
LinkAdminRole = &Q.LinkAdminRole
|
||||
@@ -102,6 +104,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
||||
Channel: newChannel(db, opts...),
|
||||
Client: newClient(db, opts...),
|
||||
Coupon: newCoupon(db, opts...),
|
||||
CouponUser: newCouponUser(db, opts...),
|
||||
Edge: newEdge(db, opts...),
|
||||
Inquiry: newInquiry(db, opts...),
|
||||
LinkAdminRole: newLinkAdminRole(db, opts...),
|
||||
@@ -142,6 +145,7 @@ type Query struct {
|
||||
Channel channel
|
||||
Client client
|
||||
Coupon coupon
|
||||
CouponUser couponUser
|
||||
Edge edge
|
||||
Inquiry inquiry
|
||||
LinkAdminRole linkAdminRole
|
||||
@@ -183,6 +187,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
|
||||
Channel: q.Channel.clone(db),
|
||||
Client: q.Client.clone(db),
|
||||
Coupon: q.Coupon.clone(db),
|
||||
CouponUser: q.CouponUser.clone(db),
|
||||
Edge: q.Edge.clone(db),
|
||||
Inquiry: q.Inquiry.clone(db),
|
||||
LinkAdminRole: q.LinkAdminRole.clone(db),
|
||||
@@ -231,6 +236,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
||||
Channel: q.Channel.replaceDB(db),
|
||||
Client: q.Client.replaceDB(db),
|
||||
Coupon: q.Coupon.replaceDB(db),
|
||||
CouponUser: q.CouponUser.replaceDB(db),
|
||||
Edge: q.Edge.replaceDB(db),
|
||||
Inquiry: q.Inquiry.replaceDB(db),
|
||||
LinkAdminRole: q.LinkAdminRole.replaceDB(db),
|
||||
@@ -269,6 +275,7 @@ type queryCtx struct {
|
||||
Channel *channelDo
|
||||
Client *clientDo
|
||||
Coupon *couponDo
|
||||
CouponUser *couponUserDo
|
||||
Edge *edgeDo
|
||||
Inquiry *inquiryDo
|
||||
LinkAdminRole *linkAdminRoleDo
|
||||
@@ -307,6 +314,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
||||
Channel: q.Channel.WithContext(ctx),
|
||||
Client: q.Client.WithContext(ctx),
|
||||
Coupon: q.Coupon.WithContext(ctx),
|
||||
CouponUser: q.CouponUser.WithContext(ctx),
|
||||
Edge: q.Edge.WithContext(ctx),
|
||||
Inquiry: q.Inquiry.WithContext(ctx),
|
||||
LinkAdminRole: q.LinkAdminRole.WithContext(ctx),
|
||||
|
||||
@@ -128,6 +128,9 @@ func newLogsUserUsage(db *gorm.DB, opts ...gen.DOOption) logsUserUsage {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -139,6 +142,9 @@ func newLogsUserUsage(db *gorm.DB, opts ...gen.DOOption) logsUserUsage {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -147,8 +153,16 @@ func newLogsUserUsage(db *gorm.DB, opts ...gen.DOOption) logsUserUsage {
|
||||
RelationField: field.NewRelation("Resource.Short.Sku", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Resource.Short.Sku.Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Resource.Short.Sku.Product.Skus", "models.ProductSku"),
|
||||
},
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
@@ -391,6 +405,9 @@ type logsUserUsageBelongsToResource struct {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
|
||||
@@ -36,6 +36,29 @@ func newProduct(db *gorm.DB, opts ...gen.DOOption) product {
|
||||
_product.Description = field.NewString(tableName, "description")
|
||||
_product.Sort = field.NewInt32(tableName, "sort")
|
||||
_product.Status = field.NewInt(tableName, "status")
|
||||
_product.Skus = productHasManySkus{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Skus", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Skus.Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Skus.Product.Skus", "models.ProductSku"),
|
||||
},
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Skus.Discount", "models.ProductDiscount"),
|
||||
},
|
||||
}
|
||||
|
||||
_product.fillFieldMap()
|
||||
|
||||
@@ -55,6 +78,7 @@ type product struct {
|
||||
Description field.String
|
||||
Sort field.Int32
|
||||
Status field.Int
|
||||
Skus productHasManySkus
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@@ -96,7 +120,7 @@ func (p *product) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (p *product) fillFieldMap() {
|
||||
p.fieldMap = make(map[string]field.Expr, 9)
|
||||
p.fieldMap = make(map[string]field.Expr, 10)
|
||||
p.fieldMap["id"] = p.ID
|
||||
p.fieldMap["created_at"] = p.CreatedAt
|
||||
p.fieldMap["updated_at"] = p.UpdatedAt
|
||||
@@ -106,18 +130,113 @@ func (p *product) fillFieldMap() {
|
||||
p.fieldMap["description"] = p.Description
|
||||
p.fieldMap["sort"] = p.Sort
|
||||
p.fieldMap["status"] = p.Status
|
||||
|
||||
}
|
||||
|
||||
func (p product) clone(db *gorm.DB) product {
|
||||
p.productDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
p.Skus.db = db.Session(&gorm.Session{Initialized: true})
|
||||
p.Skus.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
return p
|
||||
}
|
||||
|
||||
func (p product) replaceDB(db *gorm.DB) product {
|
||||
p.productDo.ReplaceDB(db)
|
||||
p.Skus.db = db.Session(&gorm.Session{})
|
||||
return p
|
||||
}
|
||||
|
||||
type productHasManySkus struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
|
||||
func (a productHasManySkus) Where(conds ...field.Expr) *productHasManySkus {
|
||||
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 productHasManySkus) WithContext(ctx context.Context) *productHasManySkus {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a productHasManySkus) Session(session *gorm.Session) *productHasManySkus {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a productHasManySkus) Model(m *models.Product) *productHasManySkusTx {
|
||||
return &productHasManySkusTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a productHasManySkus) Unscoped() *productHasManySkus {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type productHasManySkusTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a productHasManySkusTx) Find() (result []*models.ProductSku, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a productHasManySkusTx) 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 productHasManySkusTx) 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 productHasManySkusTx) 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 productHasManySkusTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a productHasManySkusTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a productHasManySkusTx) Unscoped() *productHasManySkusTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type productDo struct{ gen.DO }
|
||||
|
||||
func (p productDo) Debug() *productDo {
|
||||
|
||||
@@ -36,10 +36,34 @@ func newProductSku(db *gorm.DB, opts ...gen.DOOption) productSku {
|
||||
_productSku.Code = field.NewString(tableName, "code")
|
||||
_productSku.Name = field.NewString(tableName, "name")
|
||||
_productSku.Price = field.NewField(tableName, "price")
|
||||
_productSku.PriceMin = field.NewField(tableName, "price_min")
|
||||
_productSku.Status = field.NewInt32(tableName, "status")
|
||||
_productSku.Sort = field.NewInt32(tableName, "sort")
|
||||
_productSku.Product = productSkuBelongsToProduct{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Product.Skus", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Product.Skus.Product", "models.Product"),
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Product.Skus.Discount", "models.ProductDiscount"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_productSku.Discount = productSkuBelongsToDiscount{
|
||||
@@ -66,6 +90,9 @@ type productSku struct {
|
||||
Code field.String
|
||||
Name field.String
|
||||
Price field.Field
|
||||
PriceMin field.Field
|
||||
Status field.Int32
|
||||
Sort field.Int32
|
||||
Product productSkuBelongsToProduct
|
||||
|
||||
Discount productSkuBelongsToDiscount
|
||||
@@ -94,6 +121,9 @@ func (p *productSku) updateTableName(table string) *productSku {
|
||||
p.Code = field.NewString(table, "code")
|
||||
p.Name = field.NewString(table, "name")
|
||||
p.Price = field.NewField(table, "price")
|
||||
p.PriceMin = field.NewField(table, "price_min")
|
||||
p.Status = field.NewInt32(table, "status")
|
||||
p.Sort = field.NewInt32(table, "sort")
|
||||
|
||||
p.fillFieldMap()
|
||||
|
||||
@@ -110,7 +140,7 @@ func (p *productSku) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (p *productSku) fillFieldMap() {
|
||||
p.fieldMap = make(map[string]field.Expr, 11)
|
||||
p.fieldMap = make(map[string]field.Expr, 14)
|
||||
p.fieldMap["id"] = p.ID
|
||||
p.fieldMap["created_at"] = p.CreatedAt
|
||||
p.fieldMap["updated_at"] = p.UpdatedAt
|
||||
@@ -120,6 +150,9 @@ func (p *productSku) fillFieldMap() {
|
||||
p.fieldMap["code"] = p.Code
|
||||
p.fieldMap["name"] = p.Name
|
||||
p.fieldMap["price"] = p.Price
|
||||
p.fieldMap["price_min"] = p.PriceMin
|
||||
p.fieldMap["status"] = p.Status
|
||||
p.fieldMap["sort"] = p.Sort
|
||||
|
||||
}
|
||||
|
||||
@@ -143,6 +176,16 @@ type productSkuBelongsToProduct struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a productSkuBelongsToProduct) Where(conds ...field.Expr) *productSkuBelongsToProduct {
|
||||
|
||||
@@ -115,8 +115,16 @@ func newProductSkuUser(db *gorm.DB, opts ...gen.DOOption) productSkuUser {
|
||||
RelationField: field.NewRelation("ProductSku", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("ProductSku.Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("ProductSku.Product.Skus", "models.ProductSku"),
|
||||
},
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
@@ -331,6 +339,9 @@ type productSkuUserBelongsToProductSku struct {
|
||||
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
|
||||
@@ -153,6 +153,9 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -181,6 +184,9 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -192,6 +198,9 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -200,8 +209,16 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy {
|
||||
RelationField: field.NewRelation("Channels.Resource.Short.Sku", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Channels.Resource.Short.Sku.Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Channels.Resource.Short.Sku.Product.Skus", "models.ProductSku"),
|
||||
},
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
@@ -387,6 +404,9 @@ type proxyHasManyChannels struct {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
|
||||
@@ -44,6 +44,9 @@ func newResource(db *gorm.DB, opts ...gen.DOOption) resource {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
@@ -52,8 +55,16 @@ func newResource(db *gorm.DB, opts ...gen.DOOption) resource {
|
||||
RelationField: field.NewRelation("Short.Sku", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Short.Sku.Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Short.Sku.Product.Skus", "models.ProductSku"),
|
||||
},
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
@@ -266,6 +277,9 @@ type resourceHasOneShort struct {
|
||||
field.RelationField
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
|
||||
@@ -43,8 +43,16 @@ func newResourceLong(db *gorm.DB, opts ...gen.DOOption) resourceLong {
|
||||
RelationField: field.NewRelation("Sku", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Sku.Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Sku.Product.Skus", "models.ProductSku"),
|
||||
},
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
@@ -149,6 +157,9 @@ type resourceLongHasOneSku struct {
|
||||
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
|
||||
@@ -43,8 +43,16 @@ func newResourceShort(db *gorm.DB, opts ...gen.DOOption) resourceShort {
|
||||
RelationField: field.NewRelation("Sku", "models.ProductSku"),
|
||||
Product: struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Sku.Product", "models.Product"),
|
||||
Skus: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Sku.Product.Skus", "models.ProductSku"),
|
||||
},
|
||||
},
|
||||
Discount: struct {
|
||||
field.RelationField
|
||||
@@ -149,6 +157,9 @@ type resourceShortHasOneSku struct {
|
||||
|
||||
Product struct {
|
||||
field.RelationField
|
||||
Skus struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
Discount struct {
|
||||
field.RelationField
|
||||
|
||||
@@ -109,6 +109,14 @@ func userRouter(api fiber.Router) {
|
||||
// 前台
|
||||
inquiry := api.Group("/inquiry")
|
||||
inquiry.Post("/create", handlers.CreateInquiry)
|
||||
|
||||
// 产品
|
||||
product := api.Group("/product")
|
||||
product.Post("/list", handlers.AllProduct)
|
||||
|
||||
// 认证
|
||||
verify := api.Group("/verify")
|
||||
verify.Post("/sms/password", handlers.SendSmsCodeForPassword)
|
||||
}
|
||||
|
||||
// 客户端接口路由
|
||||
@@ -116,7 +124,7 @@ func clientRouter(api fiber.Router) {
|
||||
client := api
|
||||
|
||||
// 验证短信令牌
|
||||
client.Post("/verify/sms", handlers.SmsCode)
|
||||
client.Post("/verify/sms", handlers.SendSmsCode)
|
||||
|
||||
// 套餐定价查询
|
||||
resource := client.Group("/resource")
|
||||
@@ -159,35 +167,50 @@ func adminRouter(api fiber.Router) {
|
||||
// user 用户
|
||||
var user = api.Group("/user")
|
||||
user.Post("/page", handlers.PageUserByAdmin)
|
||||
user.Post("/page/not-bind", handlers.PageUserNotBindByAdmin)
|
||||
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("/update/bind", handlers.BindAdmin)
|
||||
user.Post("/update/balance", handlers.UpdateUserBalanceByAdmin)
|
||||
user.Post("/update/balance-inc", handlers.UpdateUserBalanceIncByAdmin)
|
||||
user.Post("/update/balance-dec", handlers.UpdateUserBalanceDecByAdmin)
|
||||
|
||||
// resource 套餐
|
||||
var resource = api.Group("/resource")
|
||||
resource.Post("/short/page", handlers.PageResourceShortByAdmin)
|
||||
resource.Post("/short/page/of-user", handlers.PageResourceShortOfUserByAdmin)
|
||||
resource.Post("/long/page", handlers.PageResourceLongByAdmin)
|
||||
resource.Post("/long/page/of-user", handlers.PageResourceLongOfUserByAdmin)
|
||||
resource.Post("/update", handlers.UpdateResourceByAdmin)
|
||||
|
||||
// batch 批次
|
||||
var batch = api.Group("/batch")
|
||||
batch.Post("/page", handlers.PageBatchByAdmin)
|
||||
batch.Post("/page/of-user", handlers.PageBatchOfUserByAdmin)
|
||||
|
||||
// channel 通道
|
||||
var channel = api.Group("/channel")
|
||||
channel.Post("/page", handlers.PageChannelByAdmin)
|
||||
channel.Post("/page/of-user", handlers.PageChannelOfUserByAdmin)
|
||||
|
||||
// trade 交易
|
||||
var trade = api.Group("/trade")
|
||||
trade.Post("/page", handlers.PageTradeByAdmin)
|
||||
trade.Post("/page/of-user", handlers.PageTradeOfUserByAdmin)
|
||||
trade.Post("/complete", handlers.TradeCompleteByAdmin)
|
||||
|
||||
// bill 账单
|
||||
var bill = api.Group("/bill")
|
||||
bill.Post("/page", handlers.PageBillByAdmin)
|
||||
bill.Post("/page/of-user", handlers.PageBillOfUserByAdmin)
|
||||
|
||||
// balance-activity 余额变动
|
||||
var balanceActivity = api.Group("/balance-activity")
|
||||
balanceActivity.Post("/page", handlers.PageBalanceActivityByAdmin)
|
||||
balanceActivity.Post("/page/of-user", handlers.PageBalanceActivityOfUserByAdmin)
|
||||
|
||||
// product 产品
|
||||
var product = api.Group("/product")
|
||||
@@ -200,6 +223,7 @@ func adminRouter(api fiber.Router) {
|
||||
product.Post("/sku/page", handlers.PageProductSkuByAdmin)
|
||||
product.Post("/sku/create", handlers.CreateProductSku)
|
||||
product.Post("/sku/update", handlers.UpdateProductSku)
|
||||
product.Post("/sku/update/status", handlers.UpdateProductStatusSku)
|
||||
product.Post("/sku/remove", handlers.DeleteProductSku)
|
||||
|
||||
product.Post("/sku/update/discount/batch", handlers.BatchUpdateProductSkuDiscount)
|
||||
|
||||
@@ -15,7 +15,7 @@ var Admin = &adminService{}
|
||||
|
||||
type adminService struct{}
|
||||
|
||||
func (s *adminService) PageAdmins(req core.PageReq) (result []*m.Admin, count int64, err error) {
|
||||
func (s *adminService) Page(req core.PageReq) (result []*m.Admin, count int64, err error) {
|
||||
return q.Admin.
|
||||
Preload(q.Admin.Roles).
|
||||
Omit(q.Admin.Password).
|
||||
@@ -30,25 +30,14 @@ func (s *adminService) All() (result []*m.Admin, err error) {
|
||||
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 {
|
||||
func (s *adminService) Create(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 {
|
||||
return q.Q.Transaction(func(q *q.Query) error {
|
||||
// 创建管理员
|
||||
admin := &m.Admin{
|
||||
Username: create.Username,
|
||||
@@ -59,7 +48,7 @@ func (s *adminService) CreateAdmin(create *CreateAdmin) error {
|
||||
Email: create.Email,
|
||||
Status: u.Else(create.Status, m.AdminStatusEnabled),
|
||||
}
|
||||
if err := tx.Admin.Create(admin); err != nil {
|
||||
if err := q.Admin.Create(admin); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -72,7 +61,7 @@ func (s *adminService) CreateAdmin(create *CreateAdmin) error {
|
||||
RoleID: roleID,
|
||||
}
|
||||
}
|
||||
if err := tx.LinkAdminRole.CreateInBatches(links, 1000); err != nil {
|
||||
if err := q.LinkAdminRole.CreateInBatches(links, 1000); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -81,18 +70,18 @@ func (s *adminService) CreateAdmin(create *CreateAdmin) error {
|
||||
})
|
||||
}
|
||||
|
||||
type UpdateAdmin struct {
|
||||
Id int32 `json:"id" validate:"required"`
|
||||
Password *string `json:"password"`
|
||||
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"`
|
||||
Roles []int32 `json:"roles"`
|
||||
}
|
||||
|
||||
func (s *adminService) UpdateAdmin(update *UpdateAdmin) error {
|
||||
func (s *adminService) Update(update *UpdateAdmin) error {
|
||||
simples := make([]field.AssignExpr, 0)
|
||||
|
||||
if update.Password != nil {
|
||||
@@ -118,11 +107,14 @@ func (s *adminService) UpdateAdmin(update *UpdateAdmin) error {
|
||||
simples = append(simples, q.Admin.Status.Value(int(*update.Status)))
|
||||
}
|
||||
|
||||
return q.Q.Transaction(func(tx *q.Query) error {
|
||||
return q.Q.Transaction(func(q *q.Query) error {
|
||||
// 更新管理员基本信息
|
||||
if len(simples) > 0 {
|
||||
_, err := tx.Admin.
|
||||
Where(tx.Admin.ID.Eq(update.Id), tx.Admin.Username.Neq("admin")).
|
||||
_, err := q.Admin.
|
||||
Where(
|
||||
q.Admin.ID.Eq(update.Id),
|
||||
q.Admin.Lock.Is(false),
|
||||
).
|
||||
UpdateSimple(simples...)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -132,7 +124,7 @@ func (s *adminService) UpdateAdmin(update *UpdateAdmin) error {
|
||||
// 更新角色关联
|
||||
if update.Roles != nil {
|
||||
roles := *update.Roles
|
||||
if _, err := tx.LinkAdminRole.Where(tx.LinkAdminRole.AdminID.Eq(update.Id)).Delete(); err != nil {
|
||||
if _, err := q.LinkAdminRole.Where(q.LinkAdminRole.AdminID.Eq(update.Id)).Delete(); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(roles) > 0 {
|
||||
@@ -143,7 +135,7 @@ func (s *adminService) UpdateAdmin(update *UpdateAdmin) error {
|
||||
RoleID: roleID,
|
||||
}
|
||||
}
|
||||
if err := tx.LinkAdminRole.CreateInBatches(links, 1000); err != nil {
|
||||
if err := q.LinkAdminRole.CreateInBatches(links, 1000); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -153,7 +145,23 @@ func (s *adminService) UpdateAdmin(update *UpdateAdmin) error {
|
||||
})
|
||||
}
|
||||
|
||||
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())
|
||||
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) Remove(id int32) error {
|
||||
_, err := q.Admin.
|
||||
Where(
|
||||
q.Admin.ID.Eq(id),
|
||||
q.Admin.Lock.Is(false),
|
||||
).
|
||||
UpdateColumn(q.Admin.DeletedAt, time.Now())
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -9,28 +9,42 @@ var Bill = &billService{}
|
||||
|
||||
type billService struct{}
|
||||
|
||||
func (s *billService) CreateForBalance(q *q.Query, uid, tradeId int32, detail *TradeDetail) error {
|
||||
return q.Bill.Create(&m.Bill{
|
||||
func (s *billService) CreateForBalance(q *q.Query, uid, tradeId int32, detail *TradeDetail) (*m.Bill, error) {
|
||||
bill := &m.Bill{
|
||||
UserID: uid,
|
||||
BillNo: ID.GenReadable("bil"),
|
||||
TradeID: &tradeId,
|
||||
Type: m.BillTypeRecharge,
|
||||
Info: &detail.Subject,
|
||||
Amount: detail.Amount,
|
||||
Amount: detail.Discounted,
|
||||
Actual: detail.Actual,
|
||||
})
|
||||
}
|
||||
|
||||
err := q.Bill.Create(bill)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bill, nil
|
||||
}
|
||||
|
||||
func (s *billService) CreateForResource(q *q.Query, uid, resourceId int32, tradeId *int32, detail *TradeDetail) error {
|
||||
return q.Bill.Create(&m.Bill{
|
||||
UserID: uid,
|
||||
BillNo: ID.GenReadable("bil"),
|
||||
ResourceID: &resourceId,
|
||||
TradeID: tradeId,
|
||||
CouponID: detail.CouponId,
|
||||
Type: m.BillTypeConsume,
|
||||
Info: &detail.Subject,
|
||||
Amount: detail.Amount,
|
||||
Actual: detail.Actual,
|
||||
})
|
||||
func (s *billService) CreateForResource(q *q.Query, uid, resourceId int32, tradeId *int32, detail *TradeDetail) (*m.Bill, error) {
|
||||
bill := &m.Bill{
|
||||
UserID: uid,
|
||||
BillNo: ID.GenReadable("bil"),
|
||||
ResourceID: &resourceId,
|
||||
TradeID: tradeId,
|
||||
CouponUserID: detail.CouponUserId,
|
||||
Type: m.BillTypeConsume,
|
||||
Info: &detail.Subject,
|
||||
Amount: detail.Discounted,
|
||||
Actual: detail.Actual,
|
||||
}
|
||||
|
||||
err := q.Bill.Create(bill)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bill, nil
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ func findResource(resourceId int32, now time.Time) (*ResourceView, error) {
|
||||
var sub = resource.Short
|
||||
info.ShortId = &sub.ID
|
||||
info.ExpireAt = sub.ExpireAt
|
||||
info.Live = time.Duration(sub.Live) * time.Second
|
||||
info.Live = time.Duration(sub.Live) * time.Minute
|
||||
info.Mode = sub.Type
|
||||
info.Quota = sub.Quota
|
||||
info.Used = sub.Used
|
||||
|
||||
@@ -229,7 +229,7 @@ func (s *channelBaiyinProvider) CreateChannels(source netip.Addr, resourceId int
|
||||
// 提交配置
|
||||
secret := strings.Split(u.Z(proxy.Secret), ":")
|
||||
gateway := g.NewGateway(proxy.IP.String(), secret[0], secret[1])
|
||||
if env.DebugExternalChange {
|
||||
if env.RunMode == env.RunModeProd {
|
||||
|
||||
// 连接节点到网关
|
||||
err = g.Cloud.CloudConnect(&g.CloudConnectReq{
|
||||
@@ -292,7 +292,8 @@ func (s *channelBaiyinProvider) RemoveChannels(batch string) error {
|
||||
}
|
||||
|
||||
// 提交配置
|
||||
if env.DebugExternalChange {
|
||||
if env.RunMode == env.RunModeProd {
|
||||
|
||||
// 断开节点连接
|
||||
g.Cloud.CloudDisconnect(&g.CloudDisconnectReq{
|
||||
Uuid: proxy.Mac,
|
||||
|
||||
@@ -3,6 +3,7 @@ package services
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"platform/pkg/u"
|
||||
"platform/web/core"
|
||||
m "platform/web/models"
|
||||
q "platform/web/queries"
|
||||
@@ -27,36 +28,32 @@ func (s *couponService) Page(req *core.PageReq) (result []*m.Coupon, count int64
|
||||
|
||||
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,
|
||||
Name: data.Name,
|
||||
Amount: data.Amount,
|
||||
MinAmount: data.MinAmount,
|
||||
Count: int32(u.Else(data.Count, 1)),
|
||||
Status: u.Else(data.Status, m.CouponStatusEnabled),
|
||||
ExpireType: u.Else(data.ExpireType, m.CouponExpireTypeNever),
|
||||
ExpireAt: data.ExpireAt,
|
||||
ExpireIn: data.ExpireIn,
|
||||
})
|
||||
}
|
||||
|
||||
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"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Amount decimal.Decimal `json:"amount" validate:"required"`
|
||||
MinAmount decimal.Decimal `json:"min_amount"`
|
||||
Count *int `json:"count"`
|
||||
Status *m.CouponStatus `json:"status"`
|
||||
ExpireType *m.CouponExpireType `json:"expire_type"`
|
||||
ExpireAt *time.Time `json:"expire_at"`
|
||||
ExpireIn *int `json:"expire_in"`
|
||||
}
|
||||
|
||||
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.Name != nil {
|
||||
do = append(do, q.Coupon.Name.Value(*data.Name))
|
||||
}
|
||||
if data.Amount != nil {
|
||||
do = append(do, q.Coupon.Amount.Value(*data.Amount))
|
||||
@@ -64,26 +61,36 @@ func (s *couponService) Update(data UpdateCouponData) error {
|
||||
if data.MinAmount != nil {
|
||||
do = append(do, q.Coupon.MinAmount.Value(*data.MinAmount))
|
||||
}
|
||||
if data.Count != nil {
|
||||
do = append(do, q.Coupon.Count_.Value(int32(*data.Count)))
|
||||
}
|
||||
if data.Status != nil {
|
||||
do = append(do, q.Coupon.Status.Value(int(*data.Status)))
|
||||
}
|
||||
if data.ExpireType != nil {
|
||||
do = append(do, q.Coupon.ExpireType.Value(int(*data.ExpireType)))
|
||||
}
|
||||
if data.ExpireAt != nil {
|
||||
do = append(do, q.Coupon.ExpireAt.Value(*data.ExpireAt))
|
||||
}
|
||||
if data.ExpireIn != nil {
|
||||
do = append(do, q.Coupon.ExpireIn.Value(*data.ExpireIn))
|
||||
}
|
||||
|
||||
_, 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"`
|
||||
ID int32 `json:"id" validate:"required"`
|
||||
Name *string `json:"name"`
|
||||
Amount *decimal.Decimal `json:"amount"`
|
||||
MinAmount *decimal.Decimal `json:"min_amount"`
|
||||
Count *int `json:"count"`
|
||||
Status *m.CouponStatus `json:"status"`
|
||||
ExpireType *m.CouponExpireType `json:"expire_type"`
|
||||
ExpireAt *time.Time `json:"expire_at"`
|
||||
ExpireIn *int `json:"expire_in"`
|
||||
}
|
||||
|
||||
func (s *couponService) Delete(id int32) error {
|
||||
@@ -91,14 +98,14 @@ func (s *couponService) Delete(id int32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *couponService) GetCouponAvailableByCode(code string, amount decimal.Decimal, uid *int32) (*m.Coupon, error) {
|
||||
// GetUserCoupon 获取用户的指定优惠券
|
||||
func (s *couponService) GetUserCoupon(uid int32, cuid int32, amount decimal.Decimal) (*m.CouponUser, 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()),
|
||||
assigned, err := q.CouponUser.Joins(q.CouponUser.Coupon).Where(
|
||||
q.CouponUser.ID.Eq(cuid),
|
||||
q.CouponUser.UserID.Eq(uid),
|
||||
q.CouponUser.Status.Eq(int(m.CouponUserStatusUnused)),
|
||||
q.CouponUser.ExpireAt.Gt(time.Now()),
|
||||
).Take()
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, core.NewBizErr("优惠券不存在或已失效")
|
||||
@@ -108,32 +115,22 @@ func (s *couponService) GetCouponAvailableByCode(code string, amount decimal.Dec
|
||||
}
|
||||
|
||||
// 检查最小使用额度
|
||||
if amount.Cmp(coupon.MinAmount) < 0 {
|
||||
return nil, core.NewBizErr(fmt.Sprintf("使用此优惠券的最小额度为 %s", coupon.MinAmount))
|
||||
if amount.Cmp(assigned.Coupon.MinAmount) < 0 {
|
||||
return nil, core.NewBizErr(fmt.Sprintf("使用此优惠券的最小额度为 %s", assigned.Coupon.MinAmount))
|
||||
}
|
||||
|
||||
// 检查所属
|
||||
if coupon.UserID != nil {
|
||||
if uid == nil {
|
||||
return nil, core.NewBizErr("检查优惠券所属用户失败")
|
||||
}
|
||||
if *coupon.UserID != *uid {
|
||||
return nil, core.NewBizErr("优惠券不属于当前用户")
|
||||
}
|
||||
}
|
||||
|
||||
return coupon, nil
|
||||
return assigned, nil
|
||||
}
|
||||
|
||||
func (s *couponService) UseCoupon(q *q.Query, id int32) error {
|
||||
_, err := q.Coupon.
|
||||
func (s *couponService) UseCoupon(q *q.Query, cuid int32) error {
|
||||
_, err := q.CouponUser.
|
||||
Where(
|
||||
q.Coupon.ID.Eq(id),
|
||||
q.Coupon.Status.Eq(int(m.CouponStatusUnused)),
|
||||
q.Coupon.ExpireAt.Gt(time.Now()),
|
||||
q.CouponUser.ID.Eq(cuid),
|
||||
q.CouponUser.Status.Eq(int(m.CouponUserStatusUnused)),
|
||||
).
|
||||
UpdateSimple(
|
||||
q.Coupon.Status.Value(int(m.CouponStatusUsed)),
|
||||
q.CouponUser.Status.Value(int(m.CouponUserStatusUsed)),
|
||||
q.CouponUser.UsedAt.Value(time.Now()),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -13,11 +13,6 @@ var Product = &productService{}
|
||||
|
||||
type productService struct{}
|
||||
|
||||
// 获取产品价格
|
||||
func (s *productService) GetPrice(code string) {
|
||||
q.ProductSku.Where(q.ProductSku.Code.Eq(code)).Find()
|
||||
}
|
||||
|
||||
// 获取所有产品
|
||||
func (s *productService) AllProducts() ([]*m.Product, error) {
|
||||
return q.Product.
|
||||
@@ -25,6 +20,61 @@ func (s *productService) AllProducts() ([]*m.Product, error) {
|
||||
Find()
|
||||
}
|
||||
|
||||
func (s *productService) AllProductSaleInfos() ([]*m.Product, error) {
|
||||
products, err := q.Product.
|
||||
Select(
|
||||
q.Product.ID,
|
||||
q.Product.Code,
|
||||
q.Product.Name,
|
||||
q.Product.Description,
|
||||
q.Product.Sort,
|
||||
).
|
||||
Where(
|
||||
q.Product.Status.Eq(int(m.ProductStatusEnabled)),
|
||||
).
|
||||
Order(q.Product.Sort).
|
||||
Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pids := make([]int32, len(products))
|
||||
for i, p := range products {
|
||||
pids[i] = p.ID
|
||||
}
|
||||
|
||||
skus, err := q.ProductSku.
|
||||
Select(
|
||||
q.ProductSku.ID,
|
||||
q.ProductSku.ProductID,
|
||||
q.ProductSku.Name,
|
||||
q.ProductSku.Code,
|
||||
q.ProductSku.Price,
|
||||
).
|
||||
Where(
|
||||
q.ProductSku.ProductID.In(pids...),
|
||||
q.ProductSku.Status.Eq(int32(m.SkuStatusEnabled)),
|
||||
).
|
||||
Order(q.ProductSku.Sort).
|
||||
Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pmap := make(map[int32]*m.Product, len(products))
|
||||
for _, p := range products {
|
||||
pmap[p.ID] = p
|
||||
p.Skus = make([]*m.ProductSku, 0)
|
||||
}
|
||||
for _, s := range skus {
|
||||
if p, ok := pmap[s.ProductID]; ok {
|
||||
p.Skus = append(p.Skus, s)
|
||||
}
|
||||
}
|
||||
|
||||
return products, nil
|
||||
}
|
||||
|
||||
// 新增产品
|
||||
func (s *productService) CreateProduct(create *CreateProductData) error {
|
||||
return q.Product.Create(&m.Product{
|
||||
|
||||
@@ -20,7 +20,7 @@ func (s *productSkuService) All(product_code string) (result []*m.ProductSku, er
|
||||
Joins(q.ProductSku.Product).
|
||||
Where(q.Product.As("Product").Code.Eq(product_code)).
|
||||
Select(q.ProductSku.ALL).
|
||||
Order(q.ProductSku.CreatedAt.Desc()).
|
||||
Order(q.ProductSku.Sort).
|
||||
Find()
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ func (s *productSkuService) Page(req *core.PageReq, productId *int32) (result []
|
||||
do = append(do, q.ProductSku.ProductID.Eq(*productId))
|
||||
}
|
||||
return q.ProductSku.
|
||||
Joins(q.ProductSku.Discount).
|
||||
Joins(q.ProductSku.Discount, q.ProductSku.Product).
|
||||
Where(do...).
|
||||
Order(q.ProductSku.CreatedAt.Desc()).
|
||||
Order(q.ProductSku.Sort).
|
||||
FindByPage(req.GetOffset(), req.GetLimit())
|
||||
}
|
||||
|
||||
@@ -42,12 +42,18 @@ func (s *productSkuService) Create(create CreateProductSkuData) (err error) {
|
||||
return core.NewBizErr("产品价格的格式不正确", err)
|
||||
}
|
||||
|
||||
priceMin, err := decimal.NewFromString(create.PriceMin)
|
||||
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,
|
||||
PriceMin: priceMin,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -57,6 +63,7 @@ type CreateProductSkuData struct {
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
Price string `json:"price"`
|
||||
PriceMin string `json:"price_min"`
|
||||
}
|
||||
|
||||
func (s *productSkuService) Update(update UpdateProductSkuData) (err error) {
|
||||
@@ -69,6 +76,13 @@ func (s *productSkuService) Update(update UpdateProductSkuData) (err error) {
|
||||
}
|
||||
do = append(do, q.ProductSku.Price.Value(price))
|
||||
}
|
||||
if update.PriceMin != "" {
|
||||
priceMin, err := decimal.NewFromString(update.PriceMin)
|
||||
if err != nil {
|
||||
return core.NewBizErr("产品最低价格的格式不正确", err)
|
||||
}
|
||||
do = append(do, q.ProductSku.PriceMin.Value(priceMin))
|
||||
}
|
||||
if update.DiscountID != nil {
|
||||
do = append(do, q.ProductSku.DiscountId.Value(*update.DiscountID))
|
||||
}
|
||||
@@ -78,6 +92,9 @@ func (s *productSkuService) Update(update UpdateProductSkuData) (err error) {
|
||||
if update.Name != nil {
|
||||
do = append(do, q.ProductSku.Name.Value(*update.Name))
|
||||
}
|
||||
if update.Status != nil {
|
||||
do = append(do, q.ProductSku.Status.Value(*update.Status))
|
||||
}
|
||||
|
||||
_, err = q.ProductSku.Where(q.ProductSku.ID.Eq(update.ID)).UpdateSimple(do...)
|
||||
return err
|
||||
@@ -89,6 +106,8 @@ type UpdateProductSkuData struct {
|
||||
Code *string `json:"code"`
|
||||
Name *string `json:"name"`
|
||||
Price *string `json:"price"`
|
||||
PriceMin string `json:"price_min"`
|
||||
Status *int32 `json:"status"`
|
||||
}
|
||||
|
||||
func (s *productSkuService) Delete(id int32) (err error) {
|
||||
|
||||
@@ -28,11 +28,6 @@ func (s *resourceService) CreateResourceByBalance(user *m.User, data *CreateReso
|
||||
|
||||
return q.Q.Transaction(func(q *q.Query) error {
|
||||
|
||||
// 更新用户余额
|
||||
if err := User.UpdateBalance(q, user, detail.Actual.Neg(), "余额购买产品", nil); err != nil {
|
||||
return core.NewServErr("更新用户余额失败", err)
|
||||
}
|
||||
|
||||
// 保存套餐
|
||||
resource, err := s.Create(q, user.ID, now, data)
|
||||
if err != nil {
|
||||
@@ -40,14 +35,19 @@ func (s *resourceService) CreateResourceByBalance(user *m.User, data *CreateReso
|
||||
}
|
||||
|
||||
// 生成账单
|
||||
err = Bill.CreateForResource(q, user.ID, resource.ID, nil, detail)
|
||||
bill, err := Bill.CreateForResource(q, user.ID, resource.ID, nil, detail)
|
||||
if err != nil {
|
||||
return core.NewServErr("生成账单失败", err)
|
||||
}
|
||||
|
||||
// 更新用户余额
|
||||
if err := User.UpdateBalance(q, user, detail.Actual.Neg(), "余额购买产品", nil, &bill.ID); err != nil {
|
||||
return core.NewServErr("更新用户余额失败", err)
|
||||
}
|
||||
|
||||
// 核销优惠券
|
||||
if detail.CouponId != nil {
|
||||
err = Coupon.UseCoupon(q, *detail.CouponId)
|
||||
if detail.CouponUserId != nil {
|
||||
err = Coupon.UseCoupon(q, *detail.CouponUserId)
|
||||
if err != nil {
|
||||
return core.NewServErr("核销优惠券失败", err)
|
||||
}
|
||||
@@ -144,35 +144,35 @@ type UpdateResourceData struct {
|
||||
Active *bool `json:"active"`
|
||||
}
|
||||
|
||||
func (s *resourceService) CalcPrice(skuCode string, count int32, user *m.User, couponCode *string) (*m.ProductSku, *m.ProductDiscount, *m.Coupon, decimal.Decimal, decimal.Decimal, error) {
|
||||
func (s *resourceService) CalcPrice(skuCode string, count int32, user *m.User, cuid *int32) (*m.ProductSku, *m.ProductDiscount, *m.CouponUser, decimal.Decimal, decimal.Decimal, decimal.Decimal, error) {
|
||||
|
||||
sku, err := q.ProductSku.
|
||||
Joins(q.ProductSku.Discount).
|
||||
Where(q.ProductSku.Code.Eq(skuCode)).
|
||||
Where(q.ProductSku.Code.Eq(skuCode), q.ProductSku.Status.Eq(int32(m.SkuStatusEnabled))).
|
||||
Take()
|
||||
if err != nil {
|
||||
return nil, nil, nil, decimal.Zero, decimal.Zero, core.NewServErr("产品不可用", err)
|
||||
return nil, nil, nil, decimal.Zero, decimal.Zero, decimal.Zero, core.NewServErr(fmt.Sprintf("产品不可用 %s", skuCode), err)
|
||||
}
|
||||
|
||||
// 原价
|
||||
price := sku.Price
|
||||
amount := price.Mul(decimal.NewFromInt32(count))
|
||||
amountMin := sku.PriceMin.Mul(decimal.NewFromInt32(count))
|
||||
amount := sku.Price.Mul(decimal.NewFromInt32(count))
|
||||
|
||||
// 折扣价
|
||||
discount := sku.Discount
|
||||
if discount == nil {
|
||||
return nil, nil, nil, decimal.Zero, decimal.Zero, core.NewServErr("价格查询失败", err)
|
||||
return nil, nil, nil, decimal.Zero, 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)
|
||||
return nil, nil, nil, decimal.Zero, decimal.Zero, decimal.Zero, core.NewServErr("客户特殊价查询失败", err)
|
||||
}
|
||||
|
||||
uDiscountRate := uDiscount.Rate()
|
||||
if uDiscountRate.Cmp(discountRate) > 0 {
|
||||
if uDiscountRate.Cmp(discountRate) < 0 {
|
||||
discountRate = uDiscountRate
|
||||
discount = uDiscount
|
||||
}
|
||||
@@ -180,30 +180,33 @@ func (s *resourceService) CalcPrice(skuCode string, count int32, user *m.User, c
|
||||
discounted := amount.Mul(discountRate)
|
||||
|
||||
// 优惠价
|
||||
uid := (*int32)(nil)
|
||||
if user != nil {
|
||||
uid = &user.ID
|
||||
}
|
||||
|
||||
coupon := (*m.Coupon)(nil)
|
||||
coupon := (*m.CouponUser)(nil)
|
||||
couponApplied := discounted.Copy()
|
||||
if couponCode != nil {
|
||||
if user != nil && cuid != nil {
|
||||
var err error
|
||||
coupon, err = Coupon.GetCouponAvailableByCode(*couponCode, discounted, uid)
|
||||
coupon, err = Coupon.GetUserCoupon(user.ID, *cuid, discounted)
|
||||
if err != nil {
|
||||
return nil, nil, nil, decimal.Zero, decimal.Zero, err
|
||||
return nil, nil, nil, decimal.Zero, decimal.Zero, decimal.Zero, err
|
||||
}
|
||||
couponApplied = discounted.Sub(coupon.Amount)
|
||||
couponApplied = discounted.Sub(coupon.Coupon.Amount)
|
||||
}
|
||||
|
||||
return sku, discount, coupon, discounted, couponApplied, nil
|
||||
// 约束到最低价格
|
||||
if discounted.Cmp(amountMin) < 0 {
|
||||
discounted = amountMin.Copy()
|
||||
}
|
||||
if couponApplied.Cmp(amountMin) < 0 {
|
||||
couponApplied = amountMin.Copy()
|
||||
}
|
||||
|
||||
return sku, discount, coupon, amount, discounted, couponApplied, nil
|
||||
}
|
||||
|
||||
type CreateResourceData struct {
|
||||
Type m.ResourceType `json:"type" validate:"required"`
|
||||
Short *CreateShortResourceData `json:"short,omitempty"`
|
||||
Long *CreateLongResourceData `json:"long,omitempty"`
|
||||
CouponCode *string `json:"coupon,omitempty"`
|
||||
Type m.ResourceType `json:"type" validate:"required"`
|
||||
Short *CreateShortResourceData `json:"short,omitempty"`
|
||||
Long *CreateLongResourceData `json:"long,omitempty"`
|
||||
CouponId *int32 `json:"coupon,omitempty"`
|
||||
}
|
||||
|
||||
type CreateShortResourceData struct {
|
||||
@@ -244,20 +247,20 @@ func (data *CreateResourceData) Code() string {
|
||||
|
||||
case data.Type == m.ResourceTypeShort && data.Short != nil:
|
||||
return fmt.Sprintf(
|
||||
"mode=%s,live=%d,expire=%d",
|
||||
"mode=%s&live=%d&expire=%d",
|
||||
data.Short.Mode.Code(), data.Short.Live, u.Else(data.Short.Expire, 0),
|
||||
)
|
||||
|
||||
case data.Type == m.ResourceTypeLong && data.Long != nil:
|
||||
return fmt.Sprintf(
|
||||
"mode=%s,live=%d,expire=%d",
|
||||
"mode=%s&live=%d&expire=%d",
|
||||
data.Long.Mode.Code(), data.Long.Live, u.Else(data.Long.Expire, 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (data *CreateResourceData) TradeDetail(user *m.User) (*TradeDetail, error) {
|
||||
sku, discount, coupon, amount, actual, err := Resource.CalcPrice(data.Code(), data.Count(), user, data.CouponCode)
|
||||
sku, discount, coupon, amount, discounted, actual, err := Resource.CalcPrice(data.Code(), data.Count(), user, data.CouponId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -266,17 +269,16 @@ func (data *CreateResourceData) TradeDetail(user *m.User) (*TradeDetail, error)
|
||||
if discount != nil {
|
||||
discountId = &discount.ID
|
||||
}
|
||||
var couponId *int32 = nil
|
||||
var couponUserId *int32 = nil
|
||||
if coupon != nil {
|
||||
couponId = &coupon.ID
|
||||
couponUserId = &coupon.ID
|
||||
}
|
||||
return &TradeDetail{
|
||||
data,
|
||||
m.TradeTypePurchase,
|
||||
sku.Name,
|
||||
amount, actual,
|
||||
discountId, discount,
|
||||
couponId, coupon,
|
||||
amount, discounted, actual,
|
||||
discountId, couponUserId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -302,17 +302,18 @@ func (s *tradeService) OnCompleteTrade(user *m.User, interNo string, outerNo str
|
||||
|
||||
switch trade.Type {
|
||||
case m.TradeTypeRecharge:
|
||||
// 更新用户余额
|
||||
if err := User.UpdateBalance(q, user, detail.Actual, "充值余额", nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 生成账单
|
||||
err = Bill.CreateForBalance(q, user.ID, trade.ID, &detail)
|
||||
bill, err := Bill.CreateForBalance(q, user.ID, trade.ID, &detail)
|
||||
if err != nil {
|
||||
return core.NewServErr("生成账单失败", err)
|
||||
}
|
||||
|
||||
// 更新用户余额
|
||||
if err := User.UpdateBalance(q, user, detail.Actual, "充值余额", nil, &bill.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case m.TradeTypePurchase:
|
||||
data, ok := detail.Product.(*CreateResourceData)
|
||||
if !ok {
|
||||
@@ -326,14 +327,14 @@ func (s *tradeService) OnCompleteTrade(user *m.User, interNo string, outerNo str
|
||||
}
|
||||
|
||||
// 生成账单
|
||||
err = Bill.CreateForResource(q, user.ID, resource.ID, &trade.ID, &detail)
|
||||
_, 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 detail.CouponUserId != nil {
|
||||
err = Coupon.UseCoupon(q, *detail.CouponUserId)
|
||||
if err != nil {
|
||||
return core.NewServErr("核销优惠券失败", err)
|
||||
}
|
||||
@@ -614,15 +615,14 @@ type ProductData interface {
|
||||
}
|
||||
|
||||
type TradeDetail struct {
|
||||
Product ProductData `json:"product"`
|
||||
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:"-"` // 不应缓存
|
||||
Product ProductData `json:"product"`
|
||||
Type m.TradeType `json:"type"`
|
||||
Subject string `json:"subject"`
|
||||
Amount decimal.Decimal `json:"amount"`
|
||||
Discounted decimal.Decimal `json:"discounted"`
|
||||
Actual decimal.Decimal `json:"actual"`
|
||||
DiscountId *int32 `json:"discount_id,omitempty"`
|
||||
CouponUserId *int32 `json:"coupon_id,omitempty"`
|
||||
}
|
||||
|
||||
type TradeErr string
|
||||
|
||||
@@ -39,11 +39,11 @@ func (s *userService) UpdateBalanceByAdmin(user *m.User, newBalance decimal.Deci
|
||||
}
|
||||
|
||||
return q.Q.Transaction(func(q *q.Query) error {
|
||||
return s.UpdateBalance(q, user, amount, "管理员修改余额", adminId)
|
||||
return s.UpdateBalance(q, user, amount, "管理员修改余额", adminId, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *userService) UpdateBalance(q *q.Query, user *m.User, amount decimal.Decimal, remark string, adminId *int32) error {
|
||||
func (s *userService) UpdateBalance(q *q.Query, user *m.User, amount decimal.Decimal, remark string, adminId *int32, billId *int32) error {
|
||||
balance := user.Balance.Add(amount)
|
||||
if balance.IsNegative() {
|
||||
return core.NewServErr("用户余额不足")
|
||||
@@ -66,6 +66,7 @@ func (s *userService) UpdateBalance(q *q.Query, user *m.User, amount decimal.Dec
|
||||
err = q.BalanceActivity.Create(&m.BalanceActivity{
|
||||
UserID: user.ID,
|
||||
AdminID: adminId,
|
||||
BillID: billId,
|
||||
Amount: amount.StringFixed(2),
|
||||
BalancePrev: user.Balance.StringFixed(2),
|
||||
BalanceCurr: balance.StringFixed(2),
|
||||
@@ -92,8 +93,7 @@ func (data *UpdateBalanceData) TradeDetail(user *m.User) (*TradeDetail, error) {
|
||||
data,
|
||||
m.TradeTypeRecharge,
|
||||
fmt.Sprintf("账户充值 - %s元", amount.StringFixed(2)),
|
||||
amount, amount,
|
||||
nil, nil,
|
||||
amount, amount, amount,
|
||||
nil, nil,
|
||||
}, nil
|
||||
}
|
||||
@@ -118,7 +118,6 @@ func (s *userService) CreateByAdmin(data CreateUserByAdminData) error {
|
||||
Email: data.Email,
|
||||
Password: hashedPwd,
|
||||
Source: &source,
|
||||
Name: data.Name,
|
||||
Avatar: data.Avatar,
|
||||
Status: u.Else(data.Status, m.UserStatusEnabled),
|
||||
ContactQQ: data.ContactQQ,
|
||||
@@ -141,7 +140,6 @@ type CreateUserByAdminData struct {
|
||||
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"`
|
||||
|
||||
@@ -55,7 +55,7 @@ func (s *verifierService) SendSms(ctx context.Context, phone string, purpose Ver
|
||||
code := rand.Intn(900000) + 100000 // 6-digit code between 100000-999999
|
||||
|
||||
// 发送短信验证码
|
||||
if env.DebugExternalChange {
|
||||
if env.RunMode == env.RunModeProd {
|
||||
params, err := json.Marshal(map[string]string{
|
||||
"code": strconv.Itoa(code),
|
||||
})
|
||||
@@ -89,8 +89,8 @@ func (s *verifierService) SendSms(ctx context.Context, phone string, purpose Ver
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *verifierService) VerifySms(ctx context.Context, phone, code string) error {
|
||||
key := smsKey(phone, VerifierSmsPurposeLogin)
|
||||
func (s *verifierService) VerifySms(ctx context.Context, phone, code string, purpose VerifierSmsPurpose) error {
|
||||
key := smsKey(phone, purpose)
|
||||
keyLock := key + ":lock"
|
||||
|
||||
err := g.Redis.Watch(ctx, func(tx *redis.Tx) error {
|
||||
@@ -146,7 +146,8 @@ func smsKey(phone string, purpose VerifierSmsPurpose) string {
|
||||
type VerifierSmsPurpose int
|
||||
|
||||
const (
|
||||
VerifierSmsPurposeLogin VerifierSmsPurpose = iota // 登录
|
||||
VerifierSmsPurposeLogin VerifierSmsPurpose = iota // 登录
|
||||
VerifierSmsPurposePassword // 修改密码
|
||||
)
|
||||
|
||||
// region 服务异常
|
||||
|
||||
Reference in New Issue
Block a user