diff --git a/scripts/sql/init.sql b/scripts/sql/init.sql index cc9eaba..3ff4ca3 100644 --- a/scripts/sql/init.sql +++ b/scripts/sql/init.sql @@ -7,7 +7,7 @@ drop table if exists logs_request cascade; create table logs_request ( id serial primary key, - identity int, + identity int not null, visitor int, ip varchar(45) not null, ua varchar(255), @@ -15,12 +15,14 @@ create table logs_request ( method varchar(10) not null, path varchar(255) not null, - latency varchar(255), status int not null, - error varchar(255), + error text, - time timestamp default current_timestamp + time timestamp not null, + latency varchar(255) not null ); +create index logs_request_identity_index on logs_request (identity); +create index logs_request_visitor_index on logs_request (visitor); -- logs_access表字段注释 comment on table logs_request is '访问日志表'; @@ -31,10 +33,83 @@ comment on column logs_request.ip is 'IP地址'; comment on column logs_request.ua is '用户代理'; comment on column logs_request.method is '请求方法'; comment on column logs_request.path is '请求路径'; -comment on column logs_request.latency is '请求延迟'; comment on column logs_request.status is '响应状态码'; comment on column logs_request.error is '错误信息'; comment on column logs_request.time is '请求时间'; +comment on column logs_request.latency is '请求延迟'; + +-- logs_login + +drop table if exists logs_login cascade; +create table logs_login ( + id serial primary key, + ip varchar(45) not null, + ua varchar(255) not null, + grant_type varchar(255) not null, + password_grant_type varchar(255) not null, + success bool not null, + user_id int, + time timestamp not null +); +create index logs_login_user_id_index on logs_login (user_id); + +-- logs_login表字段注释 +comment on table logs_login is '登录日志表'; +comment on column logs_login.id is '登录日志ID'; +comment on column logs_login.user_id is '用户ID'; +comment on column logs_login.ip is 'IP地址'; +comment on column logs_login.ua is '用户代理'; +comment on column logs_login.grant_type is '授权类型:authorization_code-授权码模式,client_credentials-客户端凭证模式,refresh_token-刷新令牌模式,password-密码模式'; +comment on column logs_login.password_grant_type is '密码模式子授权类型:password-账号密码,phone_code-手机验证码,email_code-邮箱验证码'; +comment on column logs_login.success is '登录是否成功'; +comment on column logs_login.time is '登录时间'; + +-- logs_user_usage +drop table if exists logs_user_usage cascade; +create table logs_user_usage ( + id serial primary key, + user_id int not null, + resource_id int not null, + count int not null, + prov varchar(255), + city varchar(255), + isp varchar(255), + ip varchar(45) not null, + time timestamp not null +); +create index logs_user_usage_user_id_index on logs_user_usage (user_id); +create index logs_user_usage_resource_id_index on logs_user_usage (resource_id); + +-- logs_user_usage表字段注释 +comment on table logs_user_usage is '用户使用日志表'; +comment on column logs_user_usage.id is '日志ID'; +comment on column logs_user_usage.user_id is '用户ID'; +comment on column logs_user_usage.resource_id is '套餐ID'; +comment on column logs_user_usage.count is '数量'; +comment on column logs_user_usage.prov is '省份'; +comment on column logs_user_usage.city is '城市'; +comment on column logs_user_usage.isp is '运营商'; +comment on column logs_user_usage.ip is 'IP地址'; +comment on column logs_user_usage.time is '提取时间'; + +-- logs_user_bandwidth +drop table if exists logs_user_bandwidth cascade; +create table logs_user_bandwidth ( + id serial primary key, + user_id int not null, + bandwidth int not null, + time timestamp not null +); +create index logs_user_bandwidth_user_id_index on logs_user_bandwidth (user_id); + +-- logs_user_bandwidth表字段注释 +comment on table logs_user_bandwidth is '用户带宽日志表'; +comment on column logs_user_bandwidth.id is '日志ID'; +comment on column logs_user_bandwidth.user_id is '用户ID'; +comment on column logs_user_bandwidth.bandwidth is '带宽使用量(KB)'; +comment on column logs_user_bandwidth.time is '记录时间'; + +-- logs_user_bandwidth -- endregion @@ -806,7 +881,7 @@ create table trade ( payment decimal(12, 2) not null default 0, method int not null, platform int not null, - acquirer int , + acquirer int, status int not null default 0, pay_url text, paid_at timestamp, diff --git a/web/auth/authorize.go b/web/auth/authorize.go index eb97056..45adf46 100644 --- a/web/auth/authorize.go +++ b/web/auth/authorize.go @@ -12,9 +12,9 @@ const ( type PasswordGrantType string const ( - GrantPasswordSecret = PasswordGrantType("password") // 密码模式 - GrantPasswordPhone = PasswordGrantType("phone_code") // 手机号模式 - GrantPasswordEmail = PasswordGrantType("email_code") // 邮箱模式 + GrantPasswordSecret = PasswordGrantType("password") // 账号密码 + GrantPasswordPhone = PasswordGrantType("phone_code") // 手机验证码 + GrantPasswordEmail = PasswordGrantType("email_code") // 邮箱验证码 ) func Token(grant GrantType) error { diff --git a/web/handlers/channel.go b/web/handlers/channel.go index b193e5e..9dd9986 100644 --- a/web/handlers/channel.go +++ b/web/handlers/channel.go @@ -154,6 +154,7 @@ func CreateChannel(c *fiber.Ctx) error { // 创建通道 result, err := s.Channel.CreateChannel( + c, authContext.Payload.Id, req.ResourceId, req.Protocol, diff --git a/web/handlers/resource.go b/web/handlers/resource.go index 4b5b65d..9d58197 100644 --- a/web/handlers/resource.go +++ b/web/handlers/resource.go @@ -1,6 +1,7 @@ package handlers import ( + "gorm.io/gen/field" "platform/pkg/u" "platform/web/auth" "platform/web/core" @@ -14,8 +15,6 @@ import ( "github.com/gofiber/fiber/v2" ) -// region 查询套餐 - type ListResourceShortReq struct { core.PageReq ResourceNo *string `json:"resource_no"` @@ -236,9 +235,175 @@ func AllActiveResource(c *fiber.Ctx) error { return c.JSON(resources) } -// endregion +type StatisticPersonalResp struct { + Short StatisticShort `json:"short"` + Long StatisticLong `json:"long"` +} -// region 创建套餐 +type StatisticShort struct { + ResourceCount int + ResourceQuotaSum int + ResourceDailyFreeSum int +} + +type StatisticLong struct { + ResourceCount int + ResourceQuotaSum int + ResourceDailyFreeSum int +} + +func StatisticResourceFree(c *fiber.Ctx) error { + // 检查权限 + session, err := auth.NewProtect(c).Payload(auth.PayloadUser).Do() + if err != nil { + return err + } + + // 统计套餐剩余数量 + resources, err := q.Resource. + Preload( + q.Resource.Short, + q.Resource.Long, + ). + Where( + q.Resource.UserID.Eq(session.Payload.Id), + q.Resource.Active.Is(true), + ). + Select(q.Resource.ID). + Find() + if err != nil { + return err + } + + var shortCount, shortQuotaSum, shortDailyFreeSum int + var longCount, longQuotaSum, longDailyFreeSum int + for _, resource := range resources { + switch { + + // 短效包量 + case resource2.Type(resource.Type) == resource2.TypeShort && resource2.Mode(resource.Short.Type) == resource2.ModeCount: + if u.Z(resource.Short.Quota) > resource.Short.Used { + shortCount++ + shortQuotaSum += int(u.Z(resource.Short.Quota) - resource.Short.Used) + } + + // 长效包量 + case resource2.Type(resource.Type) == resource2.TypeLong && resource2.Mode(resource.Long.Type) == resource2.ModeCount: + if u.Z(resource.Long.Quota) > resource.Long.Used { + longCount++ + longQuotaSum += int(u.Z(resource.Long.Quota) - resource.Long.Used) + } + + // 短效包时 + case resource2.Type(resource.Type) == resource2.TypeShort && resource2.Mode(resource.Short.Type) == resource2.ModeTime: + if time.Time(*resource.Short.Expire).After(time.Now()) { + if time.Time(*resource.Short.DailyLast) != u.Today() { + shortCount++ + shortDailyFreeSum += int(resource.Short.DailyLimit) + } else if resource.Short.DailyLimit > resource.Short.DailyUsed { + shortCount++ + shortDailyFreeSum += int(resource.Short.DailyLimit - resource.Short.DailyUsed) + } + } + + // 长效包时 + case resource2.Type(resource.Type) == resource2.TypeLong && resource2.Mode(resource.Long.Type) == resource2.ModeTime: + if time.Time(*resource.Long.Expire).After(time.Now()) { + if time.Time(*resource.Long.DailyLast) != u.Today() { + longCount++ + longDailyFreeSum += int(resource.Long.DailyLimit) + } else if resource.Long.DailyLimit > resource.Long.DailyUsed { + longCount++ + longDailyFreeSum += int(resource.Long.DailyLimit - resource.Long.DailyUsed) + } + } + } + } + + return c.JSON(StatisticPersonalResp{ + Short: StatisticShort{ + ResourceCount: shortCount, + ResourceQuotaSum: shortQuotaSum, + ResourceDailyFreeSum: shortDailyFreeSum, + }, + Long: StatisticLong{ + ResourceCount: longCount, + ResourceQuotaSum: longQuotaSum, + ResourceDailyFreeSum: longDailyFreeSum, + }, + }) +} + +type StatisticResourceUsageReq struct { + ResourceNo *string `json:"resource_no"` + TimeAfter *time.Time `json:"time_after"` + TimeBefore *time.Time `json:"time_before"` +} + +type StatisticResourceUsageResp []struct { + Date time.Time `json:"date"` + Count int `json:"count"` +} + +func StatisticResourceUsage(c *fiber.Ctx) error { + // 检查权限 + session, err := auth.NewProtect(c).Payload(auth.PayloadUser).Do() + if err != nil { + return err + } + + // 解析请求参数 + var req = new(StatisticResourceUsageReq) + if err := g.Validator.Validate(c, req); err != nil { + return err + } + + // 统计套餐提取数量 + do := q.LogsUserUsage.Where() + if req.ResourceNo != nil && *req.ResourceNo != "" { + var resourceID int32 + err := q.Resource. + Where( + q.Resource.UserID.Eq(session.Payload.Id), + q.Resource.ResourceNo.Eq(*req.ResourceNo), + ). + Select(q.Resource.ID). + Scan(&resourceID) + if err != nil { + return err + } + do.Where(q.LogsUserUsage.ResourceID.Eq(resourceID)) + } + if req.TimeAfter != nil { + do.Where(q.LogsUserUsage.Time.Gte(orm.LocalDateTime(*req.TimeAfter))) + } + if req.TimeBefore != nil { + do.Where(q.LogsUserUsage.Time.Lte(orm.LocalDateTime(*req.TimeBefore))) + } + + var data = new(StatisticResourceUsageResp) + err = q.LogsUserUsage. + Select( + q.LogsUserUsage.Count_.Sum().As("count"), + field.NewField("", "date_trunc('day', time)").As("date"), + ). + Where( + q.LogsUserUsage.UserID.Eq(session.Payload.Id), + do, + ). + Group( + field.NewField("", "date_trunc('day', time)"), + ). + Order( + field.NewField("", "date").Desc(), + ). + Scan(&data) + if err != nil { + return err + } + + return c.JSON(data) +} type CreateResourceReq struct { s.CreateResourceData @@ -330,8 +495,6 @@ func CompleteCreateResource(c *fiber.Ctx) error { return nil } -// endregion - func ResourcePrice(c *fiber.Ctx) error { // 检查权限 _, err := auth.NewProtect(c).Payload(auth.PayloadInternalServer).Do() diff --git a/web/models/logs_login.gen.go b/web/models/logs_login.gen.go new file mode 100644 index 0000000..9711081 --- /dev/null +++ b/web/models/logs_login.gen.go @@ -0,0 +1,26 @@ +// 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 models + +import "platform/web/globals/orm" + +const TableNameLogsLogin = "logs_login" + +// LogsLogin mapped from table +type LogsLogin struct { + ID int32 `gorm:"column:id;type:integer;primaryKey;autoIncrement:true;comment:登录日志ID" json:"id"` // 登录日志ID + IP string `gorm:"column:ip;type:character varying(45);not null;comment:IP地址" json:"ip"` // IP地址 + Ua string `gorm:"column:ua;type:character varying(255);not null;comment:用户代理" json:"ua"` // 用户代理 + GrantType string `gorm:"column:grant_type;type:character varying(255);not null;comment:授权类型:authorization_code-授权码模式,client_credentials-客户端凭证模式,refresh_token-刷新令牌模式,password-密码模式" json:"grant_type"` // 授权类型:authorization_code-授权码模式,client_credentials-客户端凭证模式,refresh_token-刷新令牌模式,password-密码模式 + PasswordGrantType string `gorm:"column:password_grant_type;type:character varying(255);not null;comment:密码模式子授权类型:password-账号密码,phone_code-手机验证码,email_code-邮箱验证码" json:"password_grant_type"` // 密码模式子授权类型:password-账号密码,phone_code-手机验证码,email_code-邮箱验证码 + Success bool `gorm:"column:success;type:boolean;not null;comment:登录是否成功" json:"success"` // 登录是否成功 + Time orm.LocalDateTime `gorm:"column:time;type:timestamp without time zone;not null;comment:登录时间" json:"time"` // 登录时间 + UserID *int32 `gorm:"column:user_id;type:integer;comment:用户ID" json:"user_id"` // 用户ID +} + +// TableName LogsLogin's table name +func (*LogsLogin) TableName() string { + return TableNameLogsLogin +} diff --git a/web/models/logs_request.gen.go b/web/models/logs_request.gen.go index 6b4e437..73add45 100644 --- a/web/models/logs_request.gen.go +++ b/web/models/logs_request.gen.go @@ -10,17 +10,17 @@ const TableNameLogsRequest = "logs_request" // LogsRequest mapped from table type LogsRequest struct { - ID int32 `gorm:"column:id;type:integer;primaryKey;autoIncrement:true;comment:访问日志ID" json:"id"` // 访问日志ID - Identity *int32 `gorm:"column:identity;type:integer;comment:访客身份:0-游客,1-用户,2-管理员,3-公共服务,4-安全服务,5-内部服务" json:"identity"` // 访客身份:0-游客,1-用户,2-管理员,3-公共服务,4-安全服务,5-内部服务 - Visitor *int32 `gorm:"column:visitor;type:integer;comment:访客ID" json:"visitor"` // 访客ID - IP string `gorm:"column:ip;type:character varying(45);not null;comment:IP地址" json:"ip"` // IP地址 - Ua *string `gorm:"column:ua;type:character varying(255);comment:用户代理" json:"ua"` // 用户代理 - Method string `gorm:"column:method;type:character varying(10);not null;comment:请求方法" json:"method"` // 请求方法 - Path string `gorm:"column:path;type:character varying(255);not null;comment:请求路径" json:"path"` // 请求路径 - Latency *string `gorm:"column:latency;type:character varying(255);comment:请求延迟" json:"latency"` // 请求延迟 - Status int32 `gorm:"column:status;type:integer;not null;comment:响应状态码" json:"status"` // 响应状态码 - Error *string `gorm:"column:error;type:character varying(255);comment:错误信息" json:"error"` // 错误信息 - Time *orm.LocalDateTime `gorm:"column:time;type:timestamp without time zone;default:CURRENT_TIMESTAMP;comment:请求时间" json:"time"` // 请求时间 + ID int32 `gorm:"column:id;type:integer;primaryKey;autoIncrement:true;comment:访问日志ID" json:"id"` // 访问日志ID + Identity int32 `gorm:"column:identity;type:integer;not null;comment:访客身份:0-游客,1-用户,2-管理员,3-公共服务,4-安全服务,5-内部服务" json:"identity"` // 访客身份:0-游客,1-用户,2-管理员,3-公共服务,4-安全服务,5-内部服务 + Visitor *int32 `gorm:"column:visitor;type:integer;comment:访客ID" json:"visitor"` // 访客ID + IP string `gorm:"column:ip;type:character varying(45);not null;comment:IP地址" json:"ip"` // IP地址 + Ua *string `gorm:"column:ua;type:character varying(255);comment:用户代理" json:"ua"` // 用户代理 + Method string `gorm:"column:method;type:character varying(10);not null;comment:请求方法" json:"method"` // 请求方法 + Path string `gorm:"column:path;type:character varying(255);not null;comment:请求路径" json:"path"` // 请求路径 + Latency string `gorm:"column:latency;type:character varying(255);not null;comment:请求延迟" json:"latency"` // 请求延迟 + Status int32 `gorm:"column:status;type:integer;not null;comment:响应状态码" json:"status"` // 响应状态码 + Error *string `gorm:"column:error;type:text;comment:错误信息" json:"error"` // 错误信息 + Time orm.LocalDateTime `gorm:"column:time;type:timestamp without time zone;not null;comment:请求时间" json:"time"` // 请求时间 } // TableName LogsRequest's table name diff --git a/web/models/logs_user_bandwidth.gen.go b/web/models/logs_user_bandwidth.gen.go new file mode 100644 index 0000000..f4e4c94 --- /dev/null +++ b/web/models/logs_user_bandwidth.gen.go @@ -0,0 +1,22 @@ +// 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 models + +import "platform/web/globals/orm" + +const TableNameLogsUserBandwidth = "logs_user_bandwidth" + +// LogsUserBandwidth mapped from table +type LogsUserBandwidth struct { + ID int32 `gorm:"column:id;type:integer;primaryKey;autoIncrement:true;comment:日志ID" json:"id"` // 日志ID + UserID int32 `gorm:"column:user_id;type:integer;not null;comment:用户ID" json:"user_id"` // 用户ID + Bandwidth int32 `gorm:"column:bandwidth;type:integer;not null;comment:带宽使用量(KB)" json:"bandwidth"` // 带宽使用量(KB) + Time orm.LocalDateTime `gorm:"column:time;type:timestamp without time zone;not null;comment:记录时间" json:"time"` // 记录时间 +} + +// TableName LogsUserBandwidth's table name +func (*LogsUserBandwidth) TableName() string { + return TableNameLogsUserBandwidth +} diff --git a/web/models/logs_user_usage.gen.go b/web/models/logs_user_usage.gen.go new file mode 100644 index 0000000..8ab6f05 --- /dev/null +++ b/web/models/logs_user_usage.gen.go @@ -0,0 +1,27 @@ +// 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 models + +import "platform/web/globals/orm" + +const TableNameLogsUserUsage = "logs_user_usage" + +// LogsUserUsage mapped from table +type LogsUserUsage struct { + ID int32 `gorm:"column:id;type:integer;primaryKey;autoIncrement:true;comment:日志ID" json:"id"` // 日志ID + UserID int32 `gorm:"column:user_id;type:integer;not null;comment:用户ID" json:"user_id"` // 用户ID + ResourceID int32 `gorm:"column:resource_id;type:integer;not null;comment:套餐ID" json:"resource_id"` // 套餐ID + Count_ int32 `gorm:"column:count;type:integer;not null;comment:数量" json:"count"` // 数量 + Prov *string `gorm:"column:prov;type:character varying(255);comment:省份" json:"prov"` // 省份 + City *string `gorm:"column:city;type:character varying(255);comment:城市" json:"city"` // 城市 + Isp *string `gorm:"column:isp;type:character varying(255);comment:运营商" json:"isp"` // 运营商 + IP string `gorm:"column:ip;type:character varying(45);not null;comment:IP地址" json:"ip"` // IP地址 + Time orm.LocalDateTime `gorm:"column:time;type:timestamp without time zone;not null;comment:提取时间" json:"time"` // 提取时间 +} + +// TableName LogsUserUsage's table name +func (*LogsUserUsage) TableName() string { + return TableNameLogsUserUsage +} diff --git a/web/models/trade.gen.go b/web/models/trade.gen.go index 3ecc5b9..8281607 100644 --- a/web/models/trade.gen.go +++ b/web/models/trade.gen.go @@ -32,7 +32,7 @@ type Trade struct { CreatedAt *orm.LocalDateTime `gorm:"column:created_at;type:timestamp without time zone;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间 UpdatedAt *orm.LocalDateTime `gorm:"column:updated_at;type:timestamp without time zone;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间 DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp without time zone;comment:删除时间" json:"deleted_at"` // 删除时间 - Acquirer int32 `gorm:"column:acquirer;type:integer;not null;comment:收单机构:1-支付宝,2-微信,3-银联" json:"acquirer"` // 收单机构:1-支付宝,2-微信,3-银联 + Acquirer *int32 `gorm:"column:acquirer;type:integer;comment:收单机构:1-支付宝,2-微信,3-银联" json:"acquirer"` // 收单机构:1-支付宝,2-微信,3-银联 Platform int32 `gorm:"column:platform;type:integer;not null;comment:支付平台:1-电脑网站,2-手机网站" json:"platform"` // 支付平台:1-电脑网站,2-手机网站 } diff --git a/web/queries/gen.go b/web/queries/gen.go index 66f46c3..f7d459d 100644 --- a/web/queries/gen.go +++ b/web/queries/gen.go @@ -28,7 +28,10 @@ var ( ClientPermissionLink *clientPermissionLink Coupon *coupon Edge *edge + LogsLogin *logsLogin LogsRequest *logsRequest + LogsUserBandwidth *logsUserBandwidth + LogsUserUsage *logsUserUsage Permission *permission Product *product Proxy *proxy @@ -58,7 +61,10 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) { ClientPermissionLink = &Q.ClientPermissionLink Coupon = &Q.Coupon Edge = &Q.Edge + LogsLogin = &Q.LogsLogin LogsRequest = &Q.LogsRequest + LogsUserBandwidth = &Q.LogsUserBandwidth + LogsUserUsage = &Q.LogsUserUsage Permission = &Q.Permission Product = &Q.Product Proxy = &Q.Proxy @@ -89,7 +95,10 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query { ClientPermissionLink: newClientPermissionLink(db, opts...), Coupon: newCoupon(db, opts...), Edge: newEdge(db, opts...), + LogsLogin: newLogsLogin(db, opts...), LogsRequest: newLogsRequest(db, opts...), + LogsUserBandwidth: newLogsUserBandwidth(db, opts...), + LogsUserUsage: newLogsUserUsage(db, opts...), Permission: newPermission(db, opts...), Product: newProduct(db, opts...), Proxy: newProxy(db, opts...), @@ -121,7 +130,10 @@ type Query struct { ClientPermissionLink clientPermissionLink Coupon coupon Edge edge + LogsLogin logsLogin LogsRequest logsRequest + LogsUserBandwidth logsUserBandwidth + LogsUserUsage logsUserUsage Permission permission Product product Proxy proxy @@ -154,7 +166,10 @@ func (q *Query) clone(db *gorm.DB) *Query { ClientPermissionLink: q.ClientPermissionLink.clone(db), Coupon: q.Coupon.clone(db), Edge: q.Edge.clone(db), + LogsLogin: q.LogsLogin.clone(db), LogsRequest: q.LogsRequest.clone(db), + LogsUserBandwidth: q.LogsUserBandwidth.clone(db), + LogsUserUsage: q.LogsUserUsage.clone(db), Permission: q.Permission.clone(db), Product: q.Product.clone(db), Proxy: q.Proxy.clone(db), @@ -194,7 +209,10 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query { ClientPermissionLink: q.ClientPermissionLink.replaceDB(db), Coupon: q.Coupon.replaceDB(db), Edge: q.Edge.replaceDB(db), + LogsLogin: q.LogsLogin.replaceDB(db), LogsRequest: q.LogsRequest.replaceDB(db), + LogsUserBandwidth: q.LogsUserBandwidth.replaceDB(db), + LogsUserUsage: q.LogsUserUsage.replaceDB(db), Permission: q.Permission.replaceDB(db), Product: q.Product.replaceDB(db), Proxy: q.Proxy.replaceDB(db), @@ -224,7 +242,10 @@ type queryCtx struct { ClientPermissionLink *clientPermissionLinkDo Coupon *couponDo Edge *edgeDo + LogsLogin *logsLoginDo LogsRequest *logsRequestDo + LogsUserBandwidth *logsUserBandwidthDo + LogsUserUsage *logsUserUsageDo Permission *permissionDo Product *productDo Proxy *proxyDo @@ -254,7 +275,10 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx { ClientPermissionLink: q.ClientPermissionLink.WithContext(ctx), Coupon: q.Coupon.WithContext(ctx), Edge: q.Edge.WithContext(ctx), + LogsLogin: q.LogsLogin.WithContext(ctx), LogsRequest: q.LogsRequest.WithContext(ctx), + LogsUserBandwidth: q.LogsUserBandwidth.WithContext(ctx), + LogsUserUsage: q.LogsUserUsage.WithContext(ctx), Permission: q.Permission.WithContext(ctx), Product: q.Product.WithContext(ctx), Proxy: q.Proxy.WithContext(ctx), diff --git a/web/queries/logs_login.gen.go b/web/queries/logs_login.gen.go new file mode 100644 index 0000000..f6a2bcd --- /dev/null +++ b/web/queries/logs_login.gen.go @@ -0,0 +1,347 @@ +// 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 newLogsLogin(db *gorm.DB, opts ...gen.DOOption) logsLogin { + _logsLogin := logsLogin{} + + _logsLogin.logsLoginDo.UseDB(db, opts...) + _logsLogin.logsLoginDo.UseModel(&models.LogsLogin{}) + + tableName := _logsLogin.logsLoginDo.TableName() + _logsLogin.ALL = field.NewAsterisk(tableName) + _logsLogin.ID = field.NewInt32(tableName, "id") + _logsLogin.IP = field.NewString(tableName, "ip") + _logsLogin.Ua = field.NewString(tableName, "ua") + _logsLogin.GrantType = field.NewString(tableName, "grant_type") + _logsLogin.PasswordGrantType = field.NewString(tableName, "password_grant_type") + _logsLogin.Success = field.NewBool(tableName, "success") + _logsLogin.Time = field.NewField(tableName, "time") + _logsLogin.UserID = field.NewInt32(tableName, "user_id") + + _logsLogin.fillFieldMap() + + return _logsLogin +} + +type logsLogin struct { + logsLoginDo + + ALL field.Asterisk + ID field.Int32 // 登录日志ID + IP field.String // IP地址 + Ua field.String // 用户代理 + GrantType field.String // 授权类型:authorization_code-授权码模式,client_credentials-客户端凭证模式,refresh_token-刷新令牌模式,password-密码模式 + PasswordGrantType field.String // 密码模式子授权类型:password-账号密码,phone_code-手机验证码,email_code-邮箱验证码 + Success field.Bool // 登录是否成功 + Time field.Field // 登录时间 + UserID field.Int32 // 用户ID + + fieldMap map[string]field.Expr +} + +func (l logsLogin) Table(newTableName string) *logsLogin { + l.logsLoginDo.UseTable(newTableName) + return l.updateTableName(newTableName) +} + +func (l logsLogin) As(alias string) *logsLogin { + l.logsLoginDo.DO = *(l.logsLoginDo.As(alias).(*gen.DO)) + return l.updateTableName(alias) +} + +func (l *logsLogin) updateTableName(table string) *logsLogin { + l.ALL = field.NewAsterisk(table) + l.ID = field.NewInt32(table, "id") + l.IP = field.NewString(table, "ip") + l.Ua = field.NewString(table, "ua") + l.GrantType = field.NewString(table, "grant_type") + l.PasswordGrantType = field.NewString(table, "password_grant_type") + l.Success = field.NewBool(table, "success") + l.Time = field.NewField(table, "time") + l.UserID = field.NewInt32(table, "user_id") + + l.fillFieldMap() + + return l +} + +func (l *logsLogin) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := l.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (l *logsLogin) fillFieldMap() { + l.fieldMap = make(map[string]field.Expr, 8) + l.fieldMap["id"] = l.ID + l.fieldMap["ip"] = l.IP + l.fieldMap["ua"] = l.Ua + l.fieldMap["grant_type"] = l.GrantType + l.fieldMap["password_grant_type"] = l.PasswordGrantType + l.fieldMap["success"] = l.Success + l.fieldMap["time"] = l.Time + l.fieldMap["user_id"] = l.UserID +} + +func (l logsLogin) clone(db *gorm.DB) logsLogin { + l.logsLoginDo.ReplaceConnPool(db.Statement.ConnPool) + return l +} + +func (l logsLogin) replaceDB(db *gorm.DB) logsLogin { + l.logsLoginDo.ReplaceDB(db) + return l +} + +type logsLoginDo struct{ gen.DO } + +func (l logsLoginDo) Debug() *logsLoginDo { + return l.withDO(l.DO.Debug()) +} + +func (l logsLoginDo) WithContext(ctx context.Context) *logsLoginDo { + return l.withDO(l.DO.WithContext(ctx)) +} + +func (l logsLoginDo) ReadDB() *logsLoginDo { + return l.Clauses(dbresolver.Read) +} + +func (l logsLoginDo) WriteDB() *logsLoginDo { + return l.Clauses(dbresolver.Write) +} + +func (l logsLoginDo) Session(config *gorm.Session) *logsLoginDo { + return l.withDO(l.DO.Session(config)) +} + +func (l logsLoginDo) Clauses(conds ...clause.Expression) *logsLoginDo { + return l.withDO(l.DO.Clauses(conds...)) +} + +func (l logsLoginDo) Returning(value interface{}, columns ...string) *logsLoginDo { + return l.withDO(l.DO.Returning(value, columns...)) +} + +func (l logsLoginDo) Not(conds ...gen.Condition) *logsLoginDo { + return l.withDO(l.DO.Not(conds...)) +} + +func (l logsLoginDo) Or(conds ...gen.Condition) *logsLoginDo { + return l.withDO(l.DO.Or(conds...)) +} + +func (l logsLoginDo) Select(conds ...field.Expr) *logsLoginDo { + return l.withDO(l.DO.Select(conds...)) +} + +func (l logsLoginDo) Where(conds ...gen.Condition) *logsLoginDo { + return l.withDO(l.DO.Where(conds...)) +} + +func (l logsLoginDo) Order(conds ...field.Expr) *logsLoginDo { + return l.withDO(l.DO.Order(conds...)) +} + +func (l logsLoginDo) Distinct(cols ...field.Expr) *logsLoginDo { + return l.withDO(l.DO.Distinct(cols...)) +} + +func (l logsLoginDo) Omit(cols ...field.Expr) *logsLoginDo { + return l.withDO(l.DO.Omit(cols...)) +} + +func (l logsLoginDo) Join(table schema.Tabler, on ...field.Expr) *logsLoginDo { + return l.withDO(l.DO.Join(table, on...)) +} + +func (l logsLoginDo) LeftJoin(table schema.Tabler, on ...field.Expr) *logsLoginDo { + return l.withDO(l.DO.LeftJoin(table, on...)) +} + +func (l logsLoginDo) RightJoin(table schema.Tabler, on ...field.Expr) *logsLoginDo { + return l.withDO(l.DO.RightJoin(table, on...)) +} + +func (l logsLoginDo) Group(cols ...field.Expr) *logsLoginDo { + return l.withDO(l.DO.Group(cols...)) +} + +func (l logsLoginDo) Having(conds ...gen.Condition) *logsLoginDo { + return l.withDO(l.DO.Having(conds...)) +} + +func (l logsLoginDo) Limit(limit int) *logsLoginDo { + return l.withDO(l.DO.Limit(limit)) +} + +func (l logsLoginDo) Offset(offset int) *logsLoginDo { + return l.withDO(l.DO.Offset(offset)) +} + +func (l logsLoginDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *logsLoginDo { + return l.withDO(l.DO.Scopes(funcs...)) +} + +func (l logsLoginDo) Unscoped() *logsLoginDo { + return l.withDO(l.DO.Unscoped()) +} + +func (l logsLoginDo) Create(values ...*models.LogsLogin) error { + if len(values) == 0 { + return nil + } + return l.DO.Create(values) +} + +func (l logsLoginDo) CreateInBatches(values []*models.LogsLogin, batchSize int) error { + return l.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 (l logsLoginDo) Save(values ...*models.LogsLogin) error { + if len(values) == 0 { + return nil + } + return l.DO.Save(values) +} + +func (l logsLoginDo) First() (*models.LogsLogin, error) { + if result, err := l.DO.First(); err != nil { + return nil, err + } else { + return result.(*models.LogsLogin), nil + } +} + +func (l logsLoginDo) Take() (*models.LogsLogin, error) { + if result, err := l.DO.Take(); err != nil { + return nil, err + } else { + return result.(*models.LogsLogin), nil + } +} + +func (l logsLoginDo) Last() (*models.LogsLogin, error) { + if result, err := l.DO.Last(); err != nil { + return nil, err + } else { + return result.(*models.LogsLogin), nil + } +} + +func (l logsLoginDo) Find() ([]*models.LogsLogin, error) { + result, err := l.DO.Find() + return result.([]*models.LogsLogin), err +} + +func (l logsLoginDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.LogsLogin, err error) { + buf := make([]*models.LogsLogin, 0, batchSize) + err = l.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 (l logsLoginDo) FindInBatches(result *[]*models.LogsLogin, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return l.DO.FindInBatches(result, batchSize, fc) +} + +func (l logsLoginDo) Attrs(attrs ...field.AssignExpr) *logsLoginDo { + return l.withDO(l.DO.Attrs(attrs...)) +} + +func (l logsLoginDo) Assign(attrs ...field.AssignExpr) *logsLoginDo { + return l.withDO(l.DO.Assign(attrs...)) +} + +func (l logsLoginDo) Joins(fields ...field.RelationField) *logsLoginDo { + for _, _f := range fields { + l = *l.withDO(l.DO.Joins(_f)) + } + return &l +} + +func (l logsLoginDo) Preload(fields ...field.RelationField) *logsLoginDo { + for _, _f := range fields { + l = *l.withDO(l.DO.Preload(_f)) + } + return &l +} + +func (l logsLoginDo) FirstOrInit() (*models.LogsLogin, error) { + if result, err := l.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*models.LogsLogin), nil + } +} + +func (l logsLoginDo) FirstOrCreate() (*models.LogsLogin, error) { + if result, err := l.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*models.LogsLogin), nil + } +} + +func (l logsLoginDo) FindByPage(offset int, limit int) (result []*models.LogsLogin, count int64, err error) { + result, err = l.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 = l.Offset(-1).Limit(-1).Count() + return +} + +func (l logsLoginDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = l.Count() + if err != nil { + return + } + + err = l.Offset(offset).Limit(limit).Scan(result) + return +} + +func (l logsLoginDo) Scan(result interface{}) (err error) { + return l.DO.Scan(result) +} + +func (l logsLoginDo) Delete(models ...*models.LogsLogin) (result gen.ResultInfo, err error) { + return l.DO.Delete(models) +} + +func (l *logsLoginDo) withDO(do gen.Dao) *logsLoginDo { + l.DO = *do.(*gen.DO) + return l +} diff --git a/web/queries/logs_user_bandwidth.gen.go b/web/queries/logs_user_bandwidth.gen.go new file mode 100644 index 0000000..878a45f --- /dev/null +++ b/web/queries/logs_user_bandwidth.gen.go @@ -0,0 +1,331 @@ +// 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 newLogsUserBandwidth(db *gorm.DB, opts ...gen.DOOption) logsUserBandwidth { + _logsUserBandwidth := logsUserBandwidth{} + + _logsUserBandwidth.logsUserBandwidthDo.UseDB(db, opts...) + _logsUserBandwidth.logsUserBandwidthDo.UseModel(&models.LogsUserBandwidth{}) + + tableName := _logsUserBandwidth.logsUserBandwidthDo.TableName() + _logsUserBandwidth.ALL = field.NewAsterisk(tableName) + _logsUserBandwidth.ID = field.NewInt32(tableName, "id") + _logsUserBandwidth.UserID = field.NewInt32(tableName, "user_id") + _logsUserBandwidth.Bandwidth = field.NewInt32(tableName, "bandwidth") + _logsUserBandwidth.Time = field.NewField(tableName, "time") + + _logsUserBandwidth.fillFieldMap() + + return _logsUserBandwidth +} + +type logsUserBandwidth struct { + logsUserBandwidthDo + + ALL field.Asterisk + ID field.Int32 // 日志ID + UserID field.Int32 // 用户ID + Bandwidth field.Int32 // 带宽使用量(KB) + Time field.Field // 记录时间 + + fieldMap map[string]field.Expr +} + +func (l logsUserBandwidth) Table(newTableName string) *logsUserBandwidth { + l.logsUserBandwidthDo.UseTable(newTableName) + return l.updateTableName(newTableName) +} + +func (l logsUserBandwidth) As(alias string) *logsUserBandwidth { + l.logsUserBandwidthDo.DO = *(l.logsUserBandwidthDo.As(alias).(*gen.DO)) + return l.updateTableName(alias) +} + +func (l *logsUserBandwidth) updateTableName(table string) *logsUserBandwidth { + l.ALL = field.NewAsterisk(table) + l.ID = field.NewInt32(table, "id") + l.UserID = field.NewInt32(table, "user_id") + l.Bandwidth = field.NewInt32(table, "bandwidth") + l.Time = field.NewField(table, "time") + + l.fillFieldMap() + + return l +} + +func (l *logsUserBandwidth) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := l.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (l *logsUserBandwidth) fillFieldMap() { + l.fieldMap = make(map[string]field.Expr, 4) + l.fieldMap["id"] = l.ID + l.fieldMap["user_id"] = l.UserID + l.fieldMap["bandwidth"] = l.Bandwidth + l.fieldMap["time"] = l.Time +} + +func (l logsUserBandwidth) clone(db *gorm.DB) logsUserBandwidth { + l.logsUserBandwidthDo.ReplaceConnPool(db.Statement.ConnPool) + return l +} + +func (l logsUserBandwidth) replaceDB(db *gorm.DB) logsUserBandwidth { + l.logsUserBandwidthDo.ReplaceDB(db) + return l +} + +type logsUserBandwidthDo struct{ gen.DO } + +func (l logsUserBandwidthDo) Debug() *logsUserBandwidthDo { + return l.withDO(l.DO.Debug()) +} + +func (l logsUserBandwidthDo) WithContext(ctx context.Context) *logsUserBandwidthDo { + return l.withDO(l.DO.WithContext(ctx)) +} + +func (l logsUserBandwidthDo) ReadDB() *logsUserBandwidthDo { + return l.Clauses(dbresolver.Read) +} + +func (l logsUserBandwidthDo) WriteDB() *logsUserBandwidthDo { + return l.Clauses(dbresolver.Write) +} + +func (l logsUserBandwidthDo) Session(config *gorm.Session) *logsUserBandwidthDo { + return l.withDO(l.DO.Session(config)) +} + +func (l logsUserBandwidthDo) Clauses(conds ...clause.Expression) *logsUserBandwidthDo { + return l.withDO(l.DO.Clauses(conds...)) +} + +func (l logsUserBandwidthDo) Returning(value interface{}, columns ...string) *logsUserBandwidthDo { + return l.withDO(l.DO.Returning(value, columns...)) +} + +func (l logsUserBandwidthDo) Not(conds ...gen.Condition) *logsUserBandwidthDo { + return l.withDO(l.DO.Not(conds...)) +} + +func (l logsUserBandwidthDo) Or(conds ...gen.Condition) *logsUserBandwidthDo { + return l.withDO(l.DO.Or(conds...)) +} + +func (l logsUserBandwidthDo) Select(conds ...field.Expr) *logsUserBandwidthDo { + return l.withDO(l.DO.Select(conds...)) +} + +func (l logsUserBandwidthDo) Where(conds ...gen.Condition) *logsUserBandwidthDo { + return l.withDO(l.DO.Where(conds...)) +} + +func (l logsUserBandwidthDo) Order(conds ...field.Expr) *logsUserBandwidthDo { + return l.withDO(l.DO.Order(conds...)) +} + +func (l logsUserBandwidthDo) Distinct(cols ...field.Expr) *logsUserBandwidthDo { + return l.withDO(l.DO.Distinct(cols...)) +} + +func (l logsUserBandwidthDo) Omit(cols ...field.Expr) *logsUserBandwidthDo { + return l.withDO(l.DO.Omit(cols...)) +} + +func (l logsUserBandwidthDo) Join(table schema.Tabler, on ...field.Expr) *logsUserBandwidthDo { + return l.withDO(l.DO.Join(table, on...)) +} + +func (l logsUserBandwidthDo) LeftJoin(table schema.Tabler, on ...field.Expr) *logsUserBandwidthDo { + return l.withDO(l.DO.LeftJoin(table, on...)) +} + +func (l logsUserBandwidthDo) RightJoin(table schema.Tabler, on ...field.Expr) *logsUserBandwidthDo { + return l.withDO(l.DO.RightJoin(table, on...)) +} + +func (l logsUserBandwidthDo) Group(cols ...field.Expr) *logsUserBandwidthDo { + return l.withDO(l.DO.Group(cols...)) +} + +func (l logsUserBandwidthDo) Having(conds ...gen.Condition) *logsUserBandwidthDo { + return l.withDO(l.DO.Having(conds...)) +} + +func (l logsUserBandwidthDo) Limit(limit int) *logsUserBandwidthDo { + return l.withDO(l.DO.Limit(limit)) +} + +func (l logsUserBandwidthDo) Offset(offset int) *logsUserBandwidthDo { + return l.withDO(l.DO.Offset(offset)) +} + +func (l logsUserBandwidthDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *logsUserBandwidthDo { + return l.withDO(l.DO.Scopes(funcs...)) +} + +func (l logsUserBandwidthDo) Unscoped() *logsUserBandwidthDo { + return l.withDO(l.DO.Unscoped()) +} + +func (l logsUserBandwidthDo) Create(values ...*models.LogsUserBandwidth) error { + if len(values) == 0 { + return nil + } + return l.DO.Create(values) +} + +func (l logsUserBandwidthDo) CreateInBatches(values []*models.LogsUserBandwidth, batchSize int) error { + return l.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 (l logsUserBandwidthDo) Save(values ...*models.LogsUserBandwidth) error { + if len(values) == 0 { + return nil + } + return l.DO.Save(values) +} + +func (l logsUserBandwidthDo) First() (*models.LogsUserBandwidth, error) { + if result, err := l.DO.First(); err != nil { + return nil, err + } else { + return result.(*models.LogsUserBandwidth), nil + } +} + +func (l logsUserBandwidthDo) Take() (*models.LogsUserBandwidth, error) { + if result, err := l.DO.Take(); err != nil { + return nil, err + } else { + return result.(*models.LogsUserBandwidth), nil + } +} + +func (l logsUserBandwidthDo) Last() (*models.LogsUserBandwidth, error) { + if result, err := l.DO.Last(); err != nil { + return nil, err + } else { + return result.(*models.LogsUserBandwidth), nil + } +} + +func (l logsUserBandwidthDo) Find() ([]*models.LogsUserBandwidth, error) { + result, err := l.DO.Find() + return result.([]*models.LogsUserBandwidth), err +} + +func (l logsUserBandwidthDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.LogsUserBandwidth, err error) { + buf := make([]*models.LogsUserBandwidth, 0, batchSize) + err = l.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 (l logsUserBandwidthDo) FindInBatches(result *[]*models.LogsUserBandwidth, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return l.DO.FindInBatches(result, batchSize, fc) +} + +func (l logsUserBandwidthDo) Attrs(attrs ...field.AssignExpr) *logsUserBandwidthDo { + return l.withDO(l.DO.Attrs(attrs...)) +} + +func (l logsUserBandwidthDo) Assign(attrs ...field.AssignExpr) *logsUserBandwidthDo { + return l.withDO(l.DO.Assign(attrs...)) +} + +func (l logsUserBandwidthDo) Joins(fields ...field.RelationField) *logsUserBandwidthDo { + for _, _f := range fields { + l = *l.withDO(l.DO.Joins(_f)) + } + return &l +} + +func (l logsUserBandwidthDo) Preload(fields ...field.RelationField) *logsUserBandwidthDo { + for _, _f := range fields { + l = *l.withDO(l.DO.Preload(_f)) + } + return &l +} + +func (l logsUserBandwidthDo) FirstOrInit() (*models.LogsUserBandwidth, error) { + if result, err := l.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*models.LogsUserBandwidth), nil + } +} + +func (l logsUserBandwidthDo) FirstOrCreate() (*models.LogsUserBandwidth, error) { + if result, err := l.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*models.LogsUserBandwidth), nil + } +} + +func (l logsUserBandwidthDo) FindByPage(offset int, limit int) (result []*models.LogsUserBandwidth, count int64, err error) { + result, err = l.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 = l.Offset(-1).Limit(-1).Count() + return +} + +func (l logsUserBandwidthDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = l.Count() + if err != nil { + return + } + + err = l.Offset(offset).Limit(limit).Scan(result) + return +} + +func (l logsUserBandwidthDo) Scan(result interface{}) (err error) { + return l.DO.Scan(result) +} + +func (l logsUserBandwidthDo) Delete(models ...*models.LogsUserBandwidth) (result gen.ResultInfo, err error) { + return l.DO.Delete(models) +} + +func (l *logsUserBandwidthDo) withDO(do gen.Dao) *logsUserBandwidthDo { + l.DO = *do.(*gen.DO) + return l +} diff --git a/web/queries/logs_user_usage.gen.go b/web/queries/logs_user_usage.gen.go new file mode 100644 index 0000000..ecf762f --- /dev/null +++ b/web/queries/logs_user_usage.gen.go @@ -0,0 +1,351 @@ +// 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 newLogsUserUsage(db *gorm.DB, opts ...gen.DOOption) logsUserUsage { + _logsUserUsage := logsUserUsage{} + + _logsUserUsage.logsUserUsageDo.UseDB(db, opts...) + _logsUserUsage.logsUserUsageDo.UseModel(&models.LogsUserUsage{}) + + tableName := _logsUserUsage.logsUserUsageDo.TableName() + _logsUserUsage.ALL = field.NewAsterisk(tableName) + _logsUserUsage.ID = field.NewInt32(tableName, "id") + _logsUserUsage.UserID = field.NewInt32(tableName, "user_id") + _logsUserUsage.ResourceID = field.NewInt32(tableName, "resource_id") + _logsUserUsage.Count_ = field.NewInt32(tableName, "count") + _logsUserUsage.Prov = field.NewString(tableName, "prov") + _logsUserUsage.City = field.NewString(tableName, "city") + _logsUserUsage.Isp = field.NewString(tableName, "isp") + _logsUserUsage.IP = field.NewString(tableName, "ip") + _logsUserUsage.Time = field.NewField(tableName, "time") + + _logsUserUsage.fillFieldMap() + + return _logsUserUsage +} + +type logsUserUsage struct { + logsUserUsageDo + + ALL field.Asterisk + ID field.Int32 // 日志ID + UserID field.Int32 // 用户ID + ResourceID field.Int32 // 套餐ID + Count_ field.Int32 // 数量 + Prov field.String // 省份 + City field.String // 城市 + Isp field.String // 运营商 + IP field.String // IP地址 + Time field.Field // 提取时间 + + fieldMap map[string]field.Expr +} + +func (l logsUserUsage) Table(newTableName string) *logsUserUsage { + l.logsUserUsageDo.UseTable(newTableName) + return l.updateTableName(newTableName) +} + +func (l logsUserUsage) As(alias string) *logsUserUsage { + l.logsUserUsageDo.DO = *(l.logsUserUsageDo.As(alias).(*gen.DO)) + return l.updateTableName(alias) +} + +func (l *logsUserUsage) updateTableName(table string) *logsUserUsage { + l.ALL = field.NewAsterisk(table) + l.ID = field.NewInt32(table, "id") + l.UserID = field.NewInt32(table, "user_id") + l.ResourceID = field.NewInt32(table, "resource_id") + l.Count_ = field.NewInt32(table, "count") + l.Prov = field.NewString(table, "prov") + l.City = field.NewString(table, "city") + l.Isp = field.NewString(table, "isp") + l.IP = field.NewString(table, "ip") + l.Time = field.NewField(table, "time") + + l.fillFieldMap() + + return l +} + +func (l *logsUserUsage) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := l.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (l *logsUserUsage) fillFieldMap() { + l.fieldMap = make(map[string]field.Expr, 9) + l.fieldMap["id"] = l.ID + l.fieldMap["user_id"] = l.UserID + l.fieldMap["resource_id"] = l.ResourceID + l.fieldMap["count"] = l.Count_ + l.fieldMap["prov"] = l.Prov + l.fieldMap["city"] = l.City + l.fieldMap["isp"] = l.Isp + l.fieldMap["ip"] = l.IP + l.fieldMap["time"] = l.Time +} + +func (l logsUserUsage) clone(db *gorm.DB) logsUserUsage { + l.logsUserUsageDo.ReplaceConnPool(db.Statement.ConnPool) + return l +} + +func (l logsUserUsage) replaceDB(db *gorm.DB) logsUserUsage { + l.logsUserUsageDo.ReplaceDB(db) + return l +} + +type logsUserUsageDo struct{ gen.DO } + +func (l logsUserUsageDo) Debug() *logsUserUsageDo { + return l.withDO(l.DO.Debug()) +} + +func (l logsUserUsageDo) WithContext(ctx context.Context) *logsUserUsageDo { + return l.withDO(l.DO.WithContext(ctx)) +} + +func (l logsUserUsageDo) ReadDB() *logsUserUsageDo { + return l.Clauses(dbresolver.Read) +} + +func (l logsUserUsageDo) WriteDB() *logsUserUsageDo { + return l.Clauses(dbresolver.Write) +} + +func (l logsUserUsageDo) Session(config *gorm.Session) *logsUserUsageDo { + return l.withDO(l.DO.Session(config)) +} + +func (l logsUserUsageDo) Clauses(conds ...clause.Expression) *logsUserUsageDo { + return l.withDO(l.DO.Clauses(conds...)) +} + +func (l logsUserUsageDo) Returning(value interface{}, columns ...string) *logsUserUsageDo { + return l.withDO(l.DO.Returning(value, columns...)) +} + +func (l logsUserUsageDo) Not(conds ...gen.Condition) *logsUserUsageDo { + return l.withDO(l.DO.Not(conds...)) +} + +func (l logsUserUsageDo) Or(conds ...gen.Condition) *logsUserUsageDo { + return l.withDO(l.DO.Or(conds...)) +} + +func (l logsUserUsageDo) Select(conds ...field.Expr) *logsUserUsageDo { + return l.withDO(l.DO.Select(conds...)) +} + +func (l logsUserUsageDo) Where(conds ...gen.Condition) *logsUserUsageDo { + return l.withDO(l.DO.Where(conds...)) +} + +func (l logsUserUsageDo) Order(conds ...field.Expr) *logsUserUsageDo { + return l.withDO(l.DO.Order(conds...)) +} + +func (l logsUserUsageDo) Distinct(cols ...field.Expr) *logsUserUsageDo { + return l.withDO(l.DO.Distinct(cols...)) +} + +func (l logsUserUsageDo) Omit(cols ...field.Expr) *logsUserUsageDo { + return l.withDO(l.DO.Omit(cols...)) +} + +func (l logsUserUsageDo) Join(table schema.Tabler, on ...field.Expr) *logsUserUsageDo { + return l.withDO(l.DO.Join(table, on...)) +} + +func (l logsUserUsageDo) LeftJoin(table schema.Tabler, on ...field.Expr) *logsUserUsageDo { + return l.withDO(l.DO.LeftJoin(table, on...)) +} + +func (l logsUserUsageDo) RightJoin(table schema.Tabler, on ...field.Expr) *logsUserUsageDo { + return l.withDO(l.DO.RightJoin(table, on...)) +} + +func (l logsUserUsageDo) Group(cols ...field.Expr) *logsUserUsageDo { + return l.withDO(l.DO.Group(cols...)) +} + +func (l logsUserUsageDo) Having(conds ...gen.Condition) *logsUserUsageDo { + return l.withDO(l.DO.Having(conds...)) +} + +func (l logsUserUsageDo) Limit(limit int) *logsUserUsageDo { + return l.withDO(l.DO.Limit(limit)) +} + +func (l logsUserUsageDo) Offset(offset int) *logsUserUsageDo { + return l.withDO(l.DO.Offset(offset)) +} + +func (l logsUserUsageDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *logsUserUsageDo { + return l.withDO(l.DO.Scopes(funcs...)) +} + +func (l logsUserUsageDo) Unscoped() *logsUserUsageDo { + return l.withDO(l.DO.Unscoped()) +} + +func (l logsUserUsageDo) Create(values ...*models.LogsUserUsage) error { + if len(values) == 0 { + return nil + } + return l.DO.Create(values) +} + +func (l logsUserUsageDo) CreateInBatches(values []*models.LogsUserUsage, batchSize int) error { + return l.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 (l logsUserUsageDo) Save(values ...*models.LogsUserUsage) error { + if len(values) == 0 { + return nil + } + return l.DO.Save(values) +} + +func (l logsUserUsageDo) First() (*models.LogsUserUsage, error) { + if result, err := l.DO.First(); err != nil { + return nil, err + } else { + return result.(*models.LogsUserUsage), nil + } +} + +func (l logsUserUsageDo) Take() (*models.LogsUserUsage, error) { + if result, err := l.DO.Take(); err != nil { + return nil, err + } else { + return result.(*models.LogsUserUsage), nil + } +} + +func (l logsUserUsageDo) Last() (*models.LogsUserUsage, error) { + if result, err := l.DO.Last(); err != nil { + return nil, err + } else { + return result.(*models.LogsUserUsage), nil + } +} + +func (l logsUserUsageDo) Find() ([]*models.LogsUserUsage, error) { + result, err := l.DO.Find() + return result.([]*models.LogsUserUsage), err +} + +func (l logsUserUsageDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.LogsUserUsage, err error) { + buf := make([]*models.LogsUserUsage, 0, batchSize) + err = l.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 (l logsUserUsageDo) FindInBatches(result *[]*models.LogsUserUsage, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return l.DO.FindInBatches(result, batchSize, fc) +} + +func (l logsUserUsageDo) Attrs(attrs ...field.AssignExpr) *logsUserUsageDo { + return l.withDO(l.DO.Attrs(attrs...)) +} + +func (l logsUserUsageDo) Assign(attrs ...field.AssignExpr) *logsUserUsageDo { + return l.withDO(l.DO.Assign(attrs...)) +} + +func (l logsUserUsageDo) Joins(fields ...field.RelationField) *logsUserUsageDo { + for _, _f := range fields { + l = *l.withDO(l.DO.Joins(_f)) + } + return &l +} + +func (l logsUserUsageDo) Preload(fields ...field.RelationField) *logsUserUsageDo { + for _, _f := range fields { + l = *l.withDO(l.DO.Preload(_f)) + } + return &l +} + +func (l logsUserUsageDo) FirstOrInit() (*models.LogsUserUsage, error) { + if result, err := l.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*models.LogsUserUsage), nil + } +} + +func (l logsUserUsageDo) FirstOrCreate() (*models.LogsUserUsage, error) { + if result, err := l.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*models.LogsUserUsage), nil + } +} + +func (l logsUserUsageDo) FindByPage(offset int, limit int) (result []*models.LogsUserUsage, count int64, err error) { + result, err = l.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 = l.Offset(-1).Limit(-1).Count() + return +} + +func (l logsUserUsageDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = l.Count() + if err != nil { + return + } + + err = l.Offset(offset).Limit(limit).Scan(result) + return +} + +func (l logsUserUsageDo) Scan(result interface{}) (err error) { + return l.DO.Scan(result) +} + +func (l logsUserUsageDo) Delete(models ...*models.LogsUserUsage) (result gen.ResultInfo, err error) { + return l.DO.Delete(models) +} + +func (l *logsUserUsageDo) withDO(do gen.Dao) *logsUserUsageDo { + l.DO = *do.(*gen.DO) + return l +} diff --git a/web/router.go b/web/router.go index 1663d94..247a18f 100644 --- a/web/router.go +++ b/web/router.go @@ -36,9 +36,11 @@ func ApplyRouters(app *fiber.App) { // 套餐 resource := api.Group("/resource") + resource.Post("/all", handlers.AllActiveResource) resource.Post("/list/short", handlers.ListResourceShort) resource.Post("/list/long", handlers.ListResourceLong) - resource.Post("/all", handlers.AllActiveResource) + resource.Post("/statistics/free", handlers.StatisticResourceFree) + resource.Post("/statistics/usage", handlers.StatisticResourceUsage) resource.Post("/create", handlers.CreateResource) resource.Post("/create/prepare", handlers.PrepareCreateResource) resource.Post("/create/complete", handlers.CompleteCreateResource) diff --git a/web/services/channel.go b/web/services/channel.go index 57692f3..8b9e658 100644 --- a/web/services/channel.go +++ b/web/services/channel.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "fmt" + "github.com/gofiber/fiber/v2" "log/slog" "math" "math/rand/v2" @@ -217,6 +218,7 @@ func removeShortChannelExternal(proxies []*m.Proxy, channels []*m.Channel) error // region 创建通道 func (s *channelService) CreateChannel( + c *fiber.Ctx, userId int32, resourceId int32, protocol channel2.Protocol, @@ -301,6 +303,18 @@ func (s *channelService) CreateChannel( return nil, core.NewBizErr("提交异步删除通道任务失败", err) } + // 记录通道创建日志 + slog.Info("创建通道", + slog.Int("user_id", int(userId)), + slog.Int("resource_id", int(resourceId)), + slog.Int("count", count), + slog.String("prov", filter.Prov), + slog.String("city", filter.City), + slog.String("isp", filter.Isp), + slog.String("ip", c.IP()), + slog.Time("time", now), + ) + return channels, nil } diff --git a/web/services/trade.go b/web/services/trade.go index ed9639b..8c5fd06 100644 --- a/web/services/trade.go +++ b/web/services/trade.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" "github.com/shopspring/decimal" - wecahtpay_core "github.com/wechatpay-apiv3/wechatpay-go/core" + wecahtpaycore "github.com/wechatpay-apiv3/wechatpay-go/core" "io" "log/slog" "net/http" @@ -272,7 +272,7 @@ func (s *tradeService) OnTradeCreated(q *q.Query, data *OnTradeCreateData) (*m.T trade.Status = int32(trade2.StatusSuccess) trade.OuterNo = &transId trade.Payment = payment - trade.Acquirer = int32(acquirer) + trade.Acquirer = u.P(int32(acquirer)) trade.PaidAt = u.P(orm.LocalDateTime(paidAt)) trade.PayURL = u.P("") _, err = q.Trade. @@ -401,7 +401,7 @@ func (s *tradeService) VerifyTrade(data *TradeVerifyData) (*TradeSuccessResult, Mchid: &env.WechatPayMchId, }) if err != nil { - var apiErr *wecahtpay_core.APIError + var apiErr *wecahtpaycore.APIError if errors.As(err, &apiErr) { if apiErr.Code == "ORDER_NOT_EXIST" { return nil, ErrTransactionNotPaid diff --git a/web/web.go b/web/web.go index f05e819..550068a 100644 --- a/web/web.go +++ b/web/web.go @@ -150,17 +150,15 @@ func newLogger() fiber.Handler { var errStr = strings.TrimSpace(logVars[5]) var item = &m.LogsRequest{ - IP: ip, - Ua: u.P(ua), - Method: method, - Path: path, - Latency: &latency, - Status: int32(status), - Error: &errStr, - Time: u.P(orm.LocalDateTime(reqTime)), - } - if authType != auth.PayloadNone { - item.Identity = u.P(int32(authType)) + Identity: int32(authType), + IP: ip, + Ua: u.P(ua), + Method: method, + Path: path, + Latency: latency, + Status: int32(status), + Error: &errStr, + Time: orm.LocalDateTime(reqTime), } if authID != 0 { item.Visitor = u.P(int32(authID))