diff --git a/pkg/u/u.go b/pkg/u/u.go index 7b77672..d83269d 100644 --- a/pkg/u/u.go +++ b/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:] +} diff --git a/scripts/sql/fill.sql b/scripts/sql/fill.sql index 1b7031b..d40d495 100644 --- a/scripts/sql/fill.sql +++ b/scripts/sql/fill.sql @@ -15,88 +15,92 @@ insert into admin (username, password, name, lock) values ('admin', '', '超级 -- region 产品 -- ==================== -insert into product (code, name, description) values ('short', '短效动态', '短效动态'); -insert into product (code, name, description) values ('long', '长效动态', '长效动态'); -insert into product (code, name, description) values ('static', '长效静态', '长效静态'); +delete from 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 套餐 -- ==================== -insert into product_sku (product_id, code, name, price, price_min) values - ((select id from product where code = 'short' and deleted_at is null), 'mode=quota&live=3&expire=0', '短效动态包量 3 分钟', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=quota&live=5&expire=0', '短效动态包量 5 分钟', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=quota&live=10&expire=0', '短效动态包量 10 分钟', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=quota&live=15&expire=0', '短效动态包量 15 分钟', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=quota&live=30&expire=0', '短效动态包量 30 分钟', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=7', '短效动态包时 3 分钟 7 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=7', '短效动态包时 5 分钟 7 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=7', '短效动态包时 10 分钟 7 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=7', '短效动态包时 15 分钟 7 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=7', '短效动态包时 30 分钟 7 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=15', '短效动态包时 3 分钟 15 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=15', '短效动态包时 5 分钟 15 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=15', '短效动态包时 10 分钟 15 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=15', '短效动态包时 15 分钟 15 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=15', '短效动态包时 30 分钟 15 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=30', '短效动态包时 3 分钟 30 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=30', '短效动态包时 5 分钟 30 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=30', '短效动态包时 10 分钟 30 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=30', '短效动态包时 15 分钟 30 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=30', '短效动态包时 30 分钟 30 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=90', '短效动态包时 3 分钟 90 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=90', '短效动态包时 5 分钟 90 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=90', '短效动态包时 10 分钟 90 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=90', '短效动态包时 15 分钟 90 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=90', '短效动态包时 30 分钟 90 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=180', '短效动态包时 3 分钟 180 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=180', '短效动态包时 5 分钟 180 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=180', '短效动态包时 10 分钟 180 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=180', '短效动态包时 15 分钟 180 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=180', '短效动态包时 30 分钟 180 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=3&expire=365', '短效动态包时 3 分钟 365 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=5&expire=365', '短效动态包时 5 分钟 365 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=10&expire=365', '短效动态包时 10 分钟 365 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=15&expire=365', '短效动态包时 15 分钟 365 天', 10.00, 10.00), - ((select id from product where code = 'short' and deleted_at is null), 'mode=time&live=30&expire=365', '短效动态包时 30 分钟 365 天', 10.00, 10.00) +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) values - ((select id from product where code = 'long' and deleted_at is null), 'mode=quota&live=60&expire=0', '长效动态包量 1 小时', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=quota&live=240&expire=0', '长效动态包量 4 小时', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=quota&live=480&expire=0', '长效动态包量 8 小时', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=quota&live=720&expire=0', '长效动态包量 12 小时', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=quota&live=1440&expire=0', '长效动态包量 24 小时', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=7', '长效动态包时 1 小时 7 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=7', '长效动态包时 4 小时 7 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=7', '长效动态包时 8 小时 7 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=7', '长效动态包时 12 小时 7 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=7', '长效动态包时 24 小时 7 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=15', '长效动态包时 1 小时 15 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=15', '长效动态包时 4 小时 15 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=15', '长效动态包时 8 小时 15 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=15', '长效动态包时 12 小时 15 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=15', '长效动态包时 24 小时 15 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=30', '长效动态包时 1 小时 30 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=30', '长效动态包时 4 小时 30 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=30', '长效动态包时 8 小时 30 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=30', '长效动态包时 12 小时 30 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=30', '长效动态包时 24 小时 30 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=90', '长效动态包时 1 小时 90 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=90', '长效动态包时 4 小时 90 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=90', '长效动态包时 8 小时 90 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=90', '长效动态包时 12 小时 90 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=90', '长效动态包时 24 小时 90 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=180', '长效动态包时 1 小时 180 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=180', '长效动态包时 4 小时 180 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=180', '长效动态包时 8 小时 180 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=180', '长效动态包时 12 小时 180 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=180','长效动态包时 24 小时 180 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=60&expire=365', '长效动态包时 1 小时 365 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=240&expire=365', '长效动态包时 4 小时 365 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=480&expire=365', '长效动态包时 8 小时 365 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=720&expire=365', '长效动态包时 12 小时 365 天', 10.00, 10.00), - ((select id from product where code = 'long' and deleted_at is null), 'mode=time&live=1440&expire=365','长效动态包时 24 小时 365 天', 10.00, 10.00) +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) ; -- ==================== diff --git a/scripts/sql/init.sql b/scripts/sql/init.sql index b5f65c9..2cc01d0 100644 --- a/scripts/sql/init.sql +++ b/scripts/sql/init.sql @@ -761,6 +761,7 @@ create table product_sku ( 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 @@ -778,6 +779,7 @@ comment on column product_sku.code is 'SKU 代码:格式为 key=value,key=valu comment on column product_sku.name is 'SKU 可读名称'; 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 '删除时间'; diff --git a/scripts/sql/update.sql b/scripts/sql/update.sql new file mode 100644 index 0000000..b4aef69 --- /dev/null +++ b/scripts/sql/update.sql @@ -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; diff --git a/web/auth/account.go b/web/auth/account.go index a79707e..889cf53 100644 --- a/web/auth/account.go +++ b/web/auth/account.go @@ -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) } diff --git a/web/auth/endpoints.go b/web/auth/endpoints.go index 99c1656..b75dbfe 100644 --- a/web/auth/endpoints.go +++ b/web/auth/endpoints.go @@ -537,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 { @@ -579,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"` diff --git a/web/core/model.go b/web/core/model.go index 3f1fbfb..c1723a2 100644 --- a/web/core/model.go +++ b/web/core/model.go @@ -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"` } diff --git a/web/handlers/product.go b/web/handlers/product.go index 135fae2..78c11cf 100644 --- a/web/handlers/product.go +++ b/web/handlers/product.go @@ -35,11 +35,6 @@ type AllProductsByAdminReq struct { } func AllProduct(c *fiber.Ctx) error { - _, err := auth.GetAuthCtx(c).PermitUser() - if err != nil { - return err - } - infos, err := s.Product.AllProductSaleInfos() if err != nil { return err diff --git a/web/handlers/resource.go b/web/handlers/resource.go index c26e41b..6cc86f2 100644 --- a/web/handlers/resource.go +++ b/web/handlers/resource.go @@ -817,11 +817,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"` } diff --git a/web/handlers/user.go b/web/handlers/user.go index e96cb9c..aa52e94 100644 --- a/web/handlers/user.go +++ b/web/handlers/user.go @@ -12,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" ) @@ -305,14 +306,26 @@ 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("用户名或邮箱已被占用") } @@ -325,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"` } // 更新账号信息 @@ -379,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 } @@ -411,7 +422,6 @@ func UpdatePassword(c *fiber.Ctx) error { } type UpdatePasswordReq struct { - Phone string `json:"phone"` Code string `json:"code"` Password string `json:"password"` } diff --git a/web/handlers/verifier.go b/web/handlers/verifier.go index 1e5ae16..1b28260 100644 --- a/web/handlers/verifier.go +++ b/web/handlers/verifier.go @@ -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") diff --git a/web/models/product.go b/web/models/product.go index 7c91f2c..cece21c 100644 --- a/web/models/product.go +++ b/web/models/product.go @@ -13,7 +13,7 @@ type Product struct { Sort int32 `json:"sort" gorm:"column:sort"` // 排序 Status ProductStatus `json:"status" gorm:"column:status"` // 产品状态:0-禁用,1-正常 - Skus []ProductSku `json:"skus"` + Skus []*ProductSku `json:"skus,omitempty" gorm:"foreignKey:ProductID"` // 产品包含的SKU列表 } // ProductStatus 产品状态枚举 diff --git a/web/models/product_sku.go b/web/models/product_sku.go index f346f3e..4697af9 100644 --- a/web/models/product_sku.go +++ b/web/models/product_sku.go @@ -16,6 +16,7 @@ type ProductSku struct { 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"` diff --git a/web/queries/product_sku.gen.go b/web/queries/product_sku.gen.go index 5229fb1..4fe34a9 100644 --- a/web/queries/product_sku.gen.go +++ b/web/queries/product_sku.gen.go @@ -38,6 +38,7 @@ func newProductSku(db *gorm.DB, opts ...gen.DOOption) productSku { _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{}), @@ -91,6 +92,7 @@ type productSku struct { Price field.Field PriceMin field.Field Status field.Int32 + Sort field.Int32 Product productSkuBelongsToProduct Discount productSkuBelongsToDiscount @@ -121,6 +123,7 @@ func (p *productSku) updateTableName(table string) *productSku { 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() @@ -137,7 +140,7 @@ func (p *productSku) GetFieldByName(fieldName string) (field.OrderExpr, bool) { } func (p *productSku) fillFieldMap() { - p.fieldMap = make(map[string]field.Expr, 13) + 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 @@ -149,6 +152,7 @@ func (p *productSku) fillFieldMap() { p.fieldMap["price"] = p.Price p.fieldMap["price_min"] = p.PriceMin p.fieldMap["status"] = p.Status + p.fieldMap["sort"] = p.Sort } diff --git a/web/routes.go b/web/routes.go index 87eafc1..c9c3f36 100644 --- a/web/routes.go +++ b/web/routes.go @@ -113,6 +113,10 @@ func userRouter(api fiber.Router) { // 产品 product := api.Group("/product") product.Post("/list", handlers.AllProduct) + + // 认证 + verify := api.Group("/verify") + verify.Post("/sms/password", handlers.SendSmsCodeForPassword) } // 客户端接口路由 @@ -120,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") diff --git a/web/services/bill.go b/web/services/bill.go index 61882bc..196c25b 100644 --- a/web/services/bill.go +++ b/web/services/bill.go @@ -16,7 +16,7 @@ func (s *billService) CreateForBalance(q *q.Query, uid, tradeId int32, detail *T TradeID: &tradeId, Type: m.BillTypeRecharge, Info: &detail.Subject, - Amount: detail.Amount, + Amount: detail.Discounted, Actual: detail.Actual, } @@ -37,7 +37,7 @@ func (s *billService) CreateForResource(q *q.Query, uid, resourceId int32, trade CouponUserID: detail.CouponUserId, Type: m.BillTypeConsume, Info: &detail.Subject, - Amount: detail.Amount, + Amount: detail.Discounted, Actual: detail.Actual, } diff --git a/web/services/channel.go b/web/services/channel.go index 2862abb..a6a3148 100644 --- a/web/services/channel.go +++ b/web/services/channel.go @@ -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 diff --git a/web/services/product.go b/web/services/product.go index 5be77f1..ced33b9 100644 --- a/web/services/product.go +++ b/web/services/product.go @@ -21,24 +21,58 @@ func (s *productService) AllProducts() ([]*m.Product, error) { } func (s *productService) AllProductSaleInfos() ([]*m.Product, error) { - return q.Product. - Joins(q.Product.Skus). + 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.Code, + q.ProductSku.ProductID, q.ProductSku.Name, + q.ProductSku.Code, q.ProductSku.Price, ). Where( - q.Product.Status.Eq(int(m.ProxyStatusOnline)), - q.ProductSku.Status.Eq(int32(m.ProductStatusEnabled)), + 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 } // 新增产品 diff --git a/web/services/product_sku.go b/web/services/product_sku.go index 2f7bfe7..b7fb587 100644 --- a/web/services/product_sku.go +++ b/web/services/product_sku.go @@ -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() } @@ -32,7 +32,7 @@ func (s *productSkuService) Page(req *core.PageReq, productId *int32) (result [] return q.ProductSku. Joins(q.ProductSku.Discount, q.ProductSku.Product). Where(do...). - Order(q.ProductSku.ID). + Order(q.ProductSku.Sort). FindByPage(req.GetOffset(), req.GetLimit()) } diff --git a/web/services/resource.go b/web/services/resource.go index 04a9d5b..966b449 100644 --- a/web/services/resource.go +++ b/web/services/resource.go @@ -144,31 +144,31 @@ type UpdateResourceData struct { Active *bool `json:"active"` } -func (s *resourceService) CalcPrice(skuCode string, count int32, user *m.User, cuid *int32) (*m.ProductSku, *m.ProductDiscount, *m.CouponUser, 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), q.ProductSku.Status.Eq(int32(m.SkuStatusEnabled))). Take() if err != nil { - return nil, nil, nil, decimal.Zero, decimal.Zero, core.NewServErr(fmt.Sprintf("产品不可用 %s", skuCode), 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() @@ -186,20 +186,20 @@ func (s *resourceService) CalcPrice(skuCode string, count int32, user *m.User, c var err error 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.Coupon.Amount) } // 约束到最低价格 - if discounted.Cmp(sku.PriceMin) < 0 { - discounted = sku.PriceMin.Copy() + if discounted.Cmp(amountMin) < 0 { + discounted = amountMin.Copy() } - if couponApplied.Cmp(sku.PriceMin) < 0 { - couponApplied = sku.PriceMin.Copy() + if couponApplied.Cmp(amountMin) < 0 { + couponApplied = amountMin.Copy() } - return sku, discount, coupon, discounted, couponApplied, nil + return sku, discount, coupon, amount, discounted, couponApplied, nil } type CreateResourceData struct { @@ -260,7 +260,7 @@ func (data *CreateResourceData) Code() string { } func (data *CreateResourceData) TradeDetail(user *m.User) (*TradeDetail, error) { - sku, discount, coupon, amount, actual, err := Resource.CalcPrice(data.Code(), data.Count(), user, data.CouponId) + sku, discount, coupon, amount, discounted, actual, err := Resource.CalcPrice(data.Code(), data.Count(), user, data.CouponId) if err != nil { return nil, err } @@ -277,7 +277,7 @@ func (data *CreateResourceData) TradeDetail(user *m.User) (*TradeDetail, error) data, m.TradeTypePurchase, sku.Name, - amount, actual, + amount, discounted, actual, discountId, couponUserId, }, nil } diff --git a/web/services/trade.go b/web/services/trade.go index 9885d2d..2c04dfa 100644 --- a/web/services/trade.go +++ b/web/services/trade.go @@ -619,6 +619,7 @@ type TradeDetail struct { 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"` diff --git a/web/services/user.go b/web/services/user.go index 69532fd..b452f47 100644 --- a/web/services/user.go +++ b/web/services/user.go @@ -93,7 +93,7 @@ func (data *UpdateBalanceData) TradeDetail(user *m.User) (*TradeDetail, error) { data, m.TradeTypeRecharge, fmt.Sprintf("账户充值 - %s元", amount.StringFixed(2)), - amount, amount, + amount, amount, amount, nil, nil, }, nil } diff --git a/web/services/verifier.go b/web/services/verifier.go index 840bba2..a1a1da4 100644 --- a/web/services/verifier.go +++ b/web/services/verifier.go @@ -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 服务异常