feat(用户): 添加用户余额日志分页查询功能

修复AnyTLSUri端口使用错误问题
添加订阅列表排序功能
更新.gitignore移除日志文件忽略
完善流量通知模板变量
This commit is contained in:
shanshanzhong 2025-08-27 08:15:31 -07:00
parent 41423ca666
commit b16ac2cb9b
13 changed files with 23 additions and 10 deletions

2
.gitignore vendored
View File

@ -3,10 +3,8 @@
*-dev.yaml *-dev.yaml
*.local.yaml *.local.yaml
/test/ /test/
*.log
.DS_Store .DS_Store
*_test_config.go *_test_config.go
*.log*
/build/ /build/
*.p8 *.p8
*.crt *.crt

View File

@ -4,6 +4,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/perfect-panel/server/internal/logic/public/user" "github.com/perfect-panel/server/internal/logic/public/user"
"github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/result" "github.com/perfect-panel/server/pkg/result"
) )
@ -11,8 +12,15 @@ import (
func QueryUserBalanceLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { func QueryUserBalanceLogHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
var req types.QueryUserBalanceLogListRequest
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)
return
}
l := user.NewQueryUserBalanceLogLogic(c.Request.Context(), svcCtx) l := user.NewQueryUserBalanceLogLogic(c.Request.Context(), svcCtx)
resp, err := l.QueryUserBalanceLog() resp, err := l.QueryUserBalanceLog(&req)
result.HttpResult(c, resp, err) result.HttpResult(c, resp, err)
} }
} }

View File

@ -31,7 +31,7 @@ func NewQueryUserBalanceLogLogic(ctx context.Context, svcCtx *svc.ServiceContext
} }
} }
func (l *QueryUserBalanceLogLogic) QueryUserBalanceLog() (resp *types.QueryUserBalanceLogListResponse, err error) { func (l *QueryUserBalanceLogLogic) QueryUserBalanceLog(req *types.QueryUserBalanceLogListRequest) (resp *types.QueryUserBalanceLogListResponse, err error) {
u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User) u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User)
if !ok { if !ok {
logger.Error("current user is not found in context") logger.Error("current user is not found in context")
@ -41,7 +41,7 @@ func (l *QueryUserBalanceLogLogic) QueryUserBalanceLog() (resp *types.QueryUserB
var total int64 var total int64
// Query User Balance Log // Query User Balance Log
err = l.svcCtx.UserModel.Transaction(l.ctx, func(db *gorm.DB) error { err = l.svcCtx.UserModel.Transaction(l.ctx, func(db *gorm.DB) error {
return db.Model(&user.BalanceLog{}).Order("created_at DESC").Where("user_id = ?", u.Id).Count(&total).Find(&data).Error return db.Model(&user.BalanceLog{}).Order("created_at DESC").Where("user_id = ?", u.Id).Count(&total).Offset((req.Page - 1) * req.Size).Limit(req.Size).Find(&data).Error
}) })
if err != nil { if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "Query User Balance Log failed: %v", err) return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "Query User Balance Log failed: %v", err)

View File

@ -87,7 +87,7 @@ func (m *customSubscribeModel) QuerySubscribeListByShow(ctx context.Context) ([]
var list []*Subscribe var list []*Subscribe
err := m.QueryNoCacheCtx(ctx, &list, func(conn *gorm.DB, v interface{}) error { err := m.QueryNoCacheCtx(ctx, &list, func(conn *gorm.DB, v interface{}) error {
conn = conn.Model(&Subscribe{}) conn = conn.Model(&Subscribe{})
return conn.Where("`show` = true").Find(v).Error return conn.Where("`show` = true").Order("sort ASC").Find(v).Error
}) })
return list, err return list, err
} }

View File

@ -1391,6 +1391,11 @@ type QueryUserAffiliateListRequest struct {
Size int `form:"size"` Size int `form:"size"`
} }
type QueryUserBalanceLogListRequest struct {
Page int `form:"page"`
Size int `form:"size"`
}
type QueryUserAffiliateListResponse struct { type QueryUserAffiliateListResponse struct {
List []UserAffiliate `json:"list"` List []UserAffiliate `json:"list"`
Total int64 `json:"total"` Total int64 `json:"total"`

0
logs/access.log Normal file
View File

0
logs/error.log Normal file
View File

0
logs/severe.log Normal file
View File

0
logs/slow.log Normal file
View File

0
logs/stat.log Normal file
View File

View File

@ -296,7 +296,7 @@ func AnyTLSUri(data proxy.Proxy, uuid string) string {
u := url.URL{ u := url.URL{
Scheme: "anytls", Scheme: "anytls",
User: url.User(uuid), User: url.User(uuid),
Host: net.JoinHostPort(data.Server, strconv.Itoa(anytls.Port)), Host: net.JoinHostPort(data.Server, strconv.Itoa(data.Port)), // 修复:使用最终端口 data.Port
RawQuery: query.Encode(), RawQuery: query.Encode(),
Fragment: data.Name, Fragment: data.Name,
} }

View File

@ -190,6 +190,8 @@ func (l *CheckSubscriptionLogic) sendTrafficNotify(ctx context.Context, subs []i
err = tpl.Execute(&result, map[string]interface{}{ err = tpl.Execute(&result, map[string]interface{}{
"SiteLogo": l.svc.Config.Site.SiteLogo, "SiteLogo": l.svc.Config.Site.SiteLogo,
"SiteName": l.svc.Config.Site.SiteName, "SiteName": l.svc.Config.Site.SiteName,
"UsedTraffic": sub.Upload + sub.Download,
"MaxTraffic": sub.Traffic,
}) })
if err != nil { if err != nil {
logger.Errorw("[CheckSubscription] Execute template failed", logger.Field("error", err.Error())) logger.Errorw("[CheckSubscription] Execute template failed", logger.Field("error", err.Error()))