书籍列表接口新增参数
This commit is contained in:
@ -2,6 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/controller/activity"
|
||||
"server/internal/controller/admin"
|
||||
"server/internal/controller/auth"
|
||||
"server/internal/controller/author"
|
||||
@ -9,6 +10,9 @@ import (
|
||||
"server/internal/controller/category"
|
||||
"server/internal/controller/chapter"
|
||||
"server/internal/controller/feedback"
|
||||
"server/internal/controller/recommend"
|
||||
"server/internal/controller/system"
|
||||
"server/internal/controller/task"
|
||||
"server/internal/controller/user"
|
||||
"server/internal/middleware"
|
||||
|
||||
@ -42,6 +46,10 @@ var (
|
||||
chapter.NewV1(),
|
||||
feedback.NewV1(),
|
||||
user.NewV1(),
|
||||
recommend.NewV1(),
|
||||
activity.NewV1(),
|
||||
task.NewV1(),
|
||||
system.NewV1(),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
38
internal/consts/ads.go
Normal file
38
internal/consts/ads.go
Normal file
@ -0,0 +1,38 @@
|
||||
package consts
|
||||
|
||||
// AdState 广告状态枚举
|
||||
type AdState int
|
||||
|
||||
const (
|
||||
StateFetchFailed AdState = iota + 1 // 拉取失败
|
||||
StateFetchSuccess // 拉取成功
|
||||
StateDisplayFailed // 显示失败
|
||||
StateDisplaySuccess // 显示成功
|
||||
StateNotWatched // 未观看完成
|
||||
StateWatched // 观看完成
|
||||
StateNotClicked // 未点击
|
||||
StateClicked // 已点击
|
||||
StateNotDownloaded // 未下载
|
||||
StateDownloaded // 已下载
|
||||
)
|
||||
|
||||
// GetStateDescription 获取状态描述
|
||||
func GetStateDescription(state AdState) string {
|
||||
descriptions := map[AdState]string{
|
||||
StateFetchFailed: "拉取失败",
|
||||
StateFetchSuccess: "拉取成功",
|
||||
StateDisplayFailed: "显示失败",
|
||||
StateDisplaySuccess: "显示成功",
|
||||
StateNotWatched: "未观看完成",
|
||||
StateWatched: "观看完成",
|
||||
StateNotClicked: "未点击",
|
||||
StateClicked: "已点击",
|
||||
StateNotDownloaded: "未下载",
|
||||
StateDownloaded: "已下载",
|
||||
}
|
||||
|
||||
if desc, exists := descriptions[state]; exists {
|
||||
return desc
|
||||
}
|
||||
return "未知状态"
|
||||
}
|
||||
5
internal/controller/activity/activity.go
Normal file
5
internal/controller/activity/activity.go
Normal file
@ -0,0 +1,5 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package activity
|
||||
15
internal/controller/activity/activity_new.go
Normal file
15
internal/controller/activity/activity_new.go
Normal file
@ -0,0 +1,15 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package activity
|
||||
|
||||
import (
|
||||
"server/api/activity"
|
||||
)
|
||||
|
||||
type ControllerV1 struct{}
|
||||
|
||||
func NewV1() activity.IActivityV1 {
|
||||
return &ControllerV1{}
|
||||
}
|
||||
23
internal/controller/activity/activity_v1_item_add.go
Normal file
23
internal/controller/activity/activity_v1_item_add.go
Normal file
@ -0,0 +1,23 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/activity/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) ItemAdd(ctx context.Context, req *v1.ItemAddReq) (res *v1.ItemAddRes, err error) {
|
||||
id, err := service.SignInRewardDetails().Create(ctx, &model.SignInRewardDetail{
|
||||
RuleId: req.RuleId,
|
||||
DayNumber: req.DayNumber,
|
||||
RewardType: req.RewardType,
|
||||
Quantity: req.Quantity,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ItemAddRes{Id: id, Success: true}, nil
|
||||
}
|
||||
17
internal/controller/activity/activity_v1_item_del.go
Normal file
17
internal/controller/activity/activity_v1_item_del.go
Normal file
@ -0,0 +1,17 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/activity/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) ItemDel(ctx context.Context, req *v1.ItemDelReq) (res *v1.ItemDelRes, err error) {
|
||||
out, err := service.SignInRewardDetails().Delete(ctx, &model.SignInRewardDetailDeleteIn{Id: req.Id})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ItemDelRes{Success: out.Success}, nil
|
||||
}
|
||||
24
internal/controller/activity/activity_v1_item_edit.go
Normal file
24
internal/controller/activity/activity_v1_item_edit.go
Normal file
@ -0,0 +1,24 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/activity/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) ItemEdit(ctx context.Context, req *v1.ItemEditReq) (res *v1.ItemEditRes, err error) {
|
||||
err = service.SignInRewardDetails().Update(ctx, &model.SignInRewardDetail{
|
||||
Id: req.Id,
|
||||
RuleId: req.RuleId,
|
||||
DayNumber: req.DayNumber,
|
||||
RewardType: req.RewardType,
|
||||
Quantity: req.Quantity,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ItemEditRes{Success: true}, nil
|
||||
}
|
||||
17
internal/controller/activity/activity_v1_item_get.go
Normal file
17
internal/controller/activity/activity_v1_item_get.go
Normal file
@ -0,0 +1,17 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/activity/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) ItemGet(ctx context.Context, req *v1.ItemGetReq) (res *v1.ItemGetRes, err error) {
|
||||
out, err := service.SignInRewardDetails().Get(ctx, &model.SignInRewardDetailGetIn{Id: req.Id})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ItemGetRes{SignInRewardDetail: out.SignInRewardDetail}, nil
|
||||
}
|
||||
20
internal/controller/activity/activity_v1_item_list.go
Normal file
20
internal/controller/activity/activity_v1_item_list.go
Normal file
@ -0,0 +1,20 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
v1 "server/api/activity/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) ItemList(ctx context.Context, req *v1.ItemListReq) (res *v1.ItemListRes, err error) {
|
||||
out, err := service.SignInRewardDetails().List(ctx, &model.SignInRewardDetailListIn{
|
||||
RuleId: req.RuleId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ItemListRes{
|
||||
List: out.List,
|
||||
}, nil
|
||||
}
|
||||
19
internal/controller/activity/activity_v1_item_set_status.go
Normal file
19
internal/controller/activity/activity_v1_item_set_status.go
Normal file
@ -0,0 +1,19 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
v1 "server/api/activity/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) ItemSetStatus(ctx context.Context, req *v1.ItemSetStatusReq) (res *v1.ItemSetStatusRes, err error) {
|
||||
out, err := service.SignInRewardDetails().SetStatus(ctx, &model.SignInRewardDetailSetStatusIn{
|
||||
Id: req.Id,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ItemSetStatusRes{Success: out.Success}, nil
|
||||
}
|
||||
23
internal/controller/activity/activity_v1_rule_add.go
Normal file
23
internal/controller/activity/activity_v1_rule_add.go
Normal file
@ -0,0 +1,23 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/activity/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) RuleAdd(ctx context.Context, req *v1.RuleAddReq) (res *v1.RuleAddRes, err error) {
|
||||
out, err := service.SignInRewardRules().Create(ctx, &model.SignInRewardRulesCreateIn{
|
||||
RuleName: req.RuleName,
|
||||
StartDate: req.StartDate,
|
||||
EndDate: req.EndDate,
|
||||
CycleDays: req.CycleDays,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.RuleAddRes{Success: out.Success}, nil
|
||||
}
|
||||
19
internal/controller/activity/activity_v1_rule_del.go
Normal file
19
internal/controller/activity/activity_v1_rule_del.go
Normal file
@ -0,0 +1,19 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/activity/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) RuleDel(ctx context.Context, req *v1.RuleDelReq) (res *v1.RuleDelRes, err error) {
|
||||
out, err := service.SignInRewardRules().Delete(ctx, &model.SignInRewardRulesDeleteIn{
|
||||
Id: req.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.RuleDelRes{Success: out.Success}, nil
|
||||
}
|
||||
24
internal/controller/activity/activity_v1_rule_edit.go
Normal file
24
internal/controller/activity/activity_v1_rule_edit.go
Normal file
@ -0,0 +1,24 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/activity/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) RuleEdit(ctx context.Context, req *v1.RuleEditReq) (res *v1.RuleEditRes, err error) {
|
||||
out, err := service.SignInRewardRules().Update(ctx, &model.SignInRewardRulesUpdateIn{
|
||||
Id: req.Id,
|
||||
RuleName: req.RuleName,
|
||||
CycleDays: req.CycleDays,
|
||||
StartDate: req.StartDate,
|
||||
EndDate: req.EndDate,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.RuleEditRes{Success: out.Success}, nil
|
||||
}
|
||||
25
internal/controller/activity/activity_v1_rule_list.go
Normal file
25
internal/controller/activity/activity_v1_rule_list.go
Normal file
@ -0,0 +1,25 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/activity/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) RuleList(ctx context.Context, req *v1.RuleListReq) (res *v1.RuleListRes, err error) {
|
||||
out, err := service.SignInRewardRules().List(ctx, &model.SignInRewardRulesListIn{
|
||||
Page: req.Page,
|
||||
RuleName: req.RuleName,
|
||||
Size: req.Size,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.RuleListRes{
|
||||
Total: out.Total,
|
||||
List: out.List,
|
||||
}, nil
|
||||
}
|
||||
20
internal/controller/activity/activity_v1_rule_set_status.go
Normal file
20
internal/controller/activity/activity_v1_rule_set_status.go
Normal file
@ -0,0 +1,20 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/activity/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) RuleSetStatus(ctx context.Context, req *v1.RuleSetStatusReq) (res *v1.RuleSetStatusRes, err error) {
|
||||
out, err := service.SignInRewardRules().SetStatus(ctx, &model.SignInRewardRulesSetStatusIn{
|
||||
Id: req.Id,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.RuleSetStatusRes{Success: out.Success}, nil
|
||||
}
|
||||
26
internal/controller/activity/activity_v1_sign_in.go
Normal file
26
internal/controller/activity/activity_v1_sign_in.go
Normal file
@ -0,0 +1,26 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
v1 "server/api/activity/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) SignIn(ctx context.Context, req *v1.SignInReq) (res *v1.SignInRes, err error) {
|
||||
userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
|
||||
in := &model.UserSignInLogSignIn{
|
||||
UserId: userId,
|
||||
RuleId: req.RuleId,
|
||||
RewardDetailId: req.RewardDetailId,
|
||||
SignInDate: gtime.Now(), // 或根据 req.SignInDate 解析
|
||||
}
|
||||
out, err := service.UserSignInLogs().Sign(ctx, in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.SignInRes{Success: out.Success}, nil
|
||||
}
|
||||
24
internal/controller/activity/activity_v1_sign_in_list.go
Normal file
24
internal/controller/activity/activity_v1_sign_in_list.go
Normal file
@ -0,0 +1,24 @@
|
||||
package activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/activity/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) SignInList(ctx context.Context, req *v1.SignInListReq) (res *v1.SignInListRes, err error) {
|
||||
userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
|
||||
out, err := service.SignInRewardRules().SignInList(ctx, &model.SignInListIn{
|
||||
UserId: userId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = &v1.SignInListRes{
|
||||
List: out.List,
|
||||
}
|
||||
return &v1.SignInListRes{List: out.List}, nil
|
||||
}
|
||||
@ -2,11 +2,12 @@ package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/admin/v1"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
v1 "server/api/admin/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Info(ctx context.Context, req *v1.InfoReq) (res *v1.InfoRes, err error) {
|
||||
@ -17,7 +18,8 @@ func (c *ControllerV1) Info(ctx context.Context, req *v1.InfoReq) (res *v1.InfoR
|
||||
return nil, err
|
||||
}
|
||||
return &v1.InfoRes{
|
||||
AdminId: out.AdminId,
|
||||
Id: out.Id,
|
||||
Username: out.Username,
|
||||
Role: out.Role,
|
||||
}, nil
|
||||
}
|
||||
|
||||
5
internal/controller/ads/ads.go
Normal file
5
internal/controller/ads/ads.go
Normal file
@ -0,0 +1,5 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package ads
|
||||
15
internal/controller/ads/ads_new.go
Normal file
15
internal/controller/ads/ads_new.go
Normal file
@ -0,0 +1,15 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package ads
|
||||
|
||||
import (
|
||||
"server/api/ads"
|
||||
)
|
||||
|
||||
type ControllerV1 struct{}
|
||||
|
||||
func NewV1() ads.IAdsV1 {
|
||||
return &ControllerV1{}
|
||||
}
|
||||
27
internal/controller/ads/ads_v1_upload.go
Normal file
27
internal/controller/ads/ads_v1_upload.go
Normal file
@ -0,0 +1,27 @@
|
||||
package ads
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
v1 "server/api/ads/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Upload(ctx context.Context, req *v1.UploadReq) (res *v1.UploadRes, err error) {
|
||||
userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
|
||||
out, err := service.Ads().Upload(ctx, &model.AdsUploadIn{
|
||||
UserId: userId,
|
||||
NodeUid: req.NodeUid,
|
||||
DeviceCode: req.DeviceCode,
|
||||
Data: req.Data,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.UploadRes{
|
||||
Success: out.Success,
|
||||
}, nil
|
||||
}
|
||||
17
internal/controller/auth/auth_v1_author_login.go
Normal file
17
internal/controller/auth/auth_v1_author_login.go
Normal file
@ -0,0 +1,17 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/auth/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) AuthorLogin(ctx context.Context, req *v1.AuthorLoginReq) (res *v1.AuthorLoginRes, err error) {
|
||||
out, err := service.User().AuthorLogin(ctx, &model.UserLoginIn{Email: req.Email, Password: req.Password})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.AuthorLoginRes{Token: out.Token}, nil
|
||||
}
|
||||
@ -5,7 +5,7 @@ import (
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/auth/v1"
|
||||
v1 "server/api/auth/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) UserLogin(ctx context.Context, req *v1.UserLoginReq) (res *v1.UserLoginRes, err error) {
|
||||
|
||||
23
internal/controller/author/author_v1_apply.go
Normal file
23
internal/controller/author/author_v1_apply.go
Normal file
@ -0,0 +1,23 @@
|
||||
package author
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/author/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Apply(ctx context.Context, req *v1.ApplyReq) (res *v1.ApplyRes, err error) {
|
||||
userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
|
||||
out, err := service.Author().Apply(ctx, &model.AuthorApplyIn{
|
||||
UserId: userId,
|
||||
PenName: req.PenName,
|
||||
Bio: req.Bio,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ApplyRes{Success: out.Success, Msg: "Please wait patiently for the management review"}, nil
|
||||
}
|
||||
23
internal/controller/author/author_v1_author_info.go
Normal file
23
internal/controller/author/author_v1_author_info.go
Normal file
@ -0,0 +1,23 @@
|
||||
package author
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/author/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) AuthorInfo(ctx context.Context, req *v1.AuthorInfoReq) (res *v1.AuthorInfoRes, err error) {
|
||||
userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
|
||||
out, err := service.Author().AuthorInfo(ctx, &model.AuthorInfoIn{UserId: userId})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.AuthorInfoRes{
|
||||
Id: out.Id,
|
||||
PenName: out.PenName,
|
||||
Role: out.Role,
|
||||
}, nil
|
||||
}
|
||||
@ -13,5 +13,5 @@ func (c *ControllerV1) Detail(ctx context.Context, req *v1.DetailReq) (res *v1.D
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.DetailRes{Author: out}, nil
|
||||
return &v1.DetailRes{out}, nil
|
||||
}
|
||||
|
||||
21
internal/controller/author/author_v1_review.go
Normal file
21
internal/controller/author/author_v1_review.go
Normal file
@ -0,0 +1,21 @@
|
||||
package author
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/author/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Review(ctx context.Context, req *v1.ReviewReq) (res *v1.ReviewRes, err error) {
|
||||
out, err := service.Author().Review(ctx, &model.AuthorReviewIn{
|
||||
AuthorId: req.AuthorId,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ReviewRes{Success: out.Success}, nil
|
||||
}
|
||||
@ -23,22 +23,29 @@ func (c *ControllerV1) AppDetail(ctx context.Context, req *v1.AppDetailReq) (res
|
||||
|
||||
return &v1.AppDetailRes{
|
||||
Id: out.Id,
|
||||
AuthorId: out.AuthorId,
|
||||
CategoryId: out.CategoryId,
|
||||
Title: out.Title,
|
||||
CoverUrl: out.CoverUrl,
|
||||
Rating: out.Rating,
|
||||
Title: out.Title,
|
||||
Description: out.Description,
|
||||
AuthorId: out.AuthorId,
|
||||
Author: out.Author,
|
||||
CategoryId: out.CategoryId,
|
||||
Category: out.Category,
|
||||
Status: out.Status,
|
||||
WordsCount: out.WordsCount,
|
||||
ChaptersCount: out.ChaptersCount,
|
||||
ReadCount: out.ReadCount,
|
||||
CurrentReaders: out.CurrentReaders,
|
||||
Tags: out.Tags,
|
||||
IsRecommended: out.IsRecommended,
|
||||
Rating: out.Rating,
|
||||
CurrentReaders: out.CurrentReaders,
|
||||
CreatedAt: out.CreatedAt.String(),
|
||||
UpdatedAt: out.UpdatedAt.String(),
|
||||
// 添加阅读进度信息
|
||||
HasRead: out.HasRead,
|
||||
ReadProgress: out.ReadProgress,
|
||||
LastChapterId: out.LastChapterId,
|
||||
LastReadAt: out.LastReadAt,
|
||||
HasRated: out.HasRated,
|
||||
MyRating: out.MyRating,
|
||||
HasRead: out.HasRead,
|
||||
ReadProgress: out.ReadProgress,
|
||||
LastChapterId: out.LastChapterId,
|
||||
LastReadAt: out.LastReadAt,
|
||||
IsInBookshelf: out.IsInBookshelf,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ func (c *ControllerV1) AppList(ctx context.Context, req *v1.AppListReq) (res *v1
|
||||
IsRecommended: req.IsRecommended,
|
||||
IsFeatured: req.IsFeatured,
|
||||
IsLatest: req.IsLatest,
|
||||
IsHot: req.IsHot,
|
||||
CategoryId: req.CategoryId,
|
||||
Title: req.Title,
|
||||
AuthorId: req.AuthorId,
|
||||
|
||||
24
internal/controller/book/book_v1_book_cover_image.go
Normal file
24
internal/controller/book/book_v1_book_cover_image.go
Normal file
@ -0,0 +1,24 @@
|
||||
package book
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/book/v1"
|
||||
|
||||
"server/utility/ecode"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) BookCoverImage(ctx context.Context, req *v1.BookCoverImageReq) (res *v1.BookCoverImageRes, err error) {
|
||||
if req.File == nil {
|
||||
return nil, gerror.NewCode(ecode.Fail.Sub("image_file_required").Code())
|
||||
}
|
||||
image, err := service.Upload().UploadImage(ctx, &model.UploadImageIn{File: req.File, Type: "book"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.BookCoverImageRes{ImageUrl: image.ImageUrl}, nil
|
||||
}
|
||||
@ -3,12 +3,15 @@ package book
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
|
||||
"server/api/book/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) BookSetFeatured(ctx context.Context, req *v1.BookSetFeaturedReq) (res *v1.BookSetFeaturedRes, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
out, err := service.Book().SetFeatured(ctx, &model.BookSetFeaturedIn{Id: req.Id, IsFeatured: req.IsFeatured})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.BookSetFeaturedRes{Success: out.Success}, nil
|
||||
}
|
||||
|
||||
22
internal/controller/book/book_v1_book_set_hot.go
Normal file
22
internal/controller/book/book_v1_book_set_hot.go
Normal file
@ -0,0 +1,22 @@
|
||||
package book
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/book/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) BookSetHot(ctx context.Context, req *v1.BookSetHotReq) (res *v1.BookSetHotRes, err error) {
|
||||
out, err := service.Book().SetHot(ctx, &model.BookSetHotIn{
|
||||
Id: req.Id,
|
||||
IsHot: req.IsHot,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.BookSetHotRes{
|
||||
Success: out.Success,
|
||||
}, nil
|
||||
}
|
||||
@ -2,13 +2,16 @@ package book
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/book/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) BookSetRecommended(ctx context.Context, req *v1.BookSetRecommendedReq) (res *v1.BookSetRecommendedRes, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
out, err := service.Book().SetRecommended(ctx, &model.BookSetRecommendedIn{Id: req.Id, IsRecommended: req.IsRecommended})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.BookSetRecommendedRes{Success: out.Success}, nil
|
||||
}
|
||||
|
||||
21
internal/controller/book/book_v1_history_remove.go
Normal file
21
internal/controller/book/book_v1_history_remove.go
Normal file
@ -0,0 +1,21 @@
|
||||
package book
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/book/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) HistoryRemove(ctx context.Context, req *v1.HistoryRemoveReq) (res *v1.HistoryRemoveRes, err error) {
|
||||
userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
|
||||
out, err := service.UserReadHistory().Remove(ctx, &model.UserReadHistoryDelIn{BookIds: req.BookIds, UserId: userId})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.HistoryRemoveRes{
|
||||
Success: out.Success,
|
||||
}, nil
|
||||
}
|
||||
@ -11,11 +11,10 @@ import (
|
||||
|
||||
func (c *ControllerV1) AppProgress(ctx context.Context, req *v1.AppProgressReq) (res *v1.AppProgressRes, err error) {
|
||||
userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
|
||||
out, err := service.Chapter().AppProgress(ctx, &model.ChapterAppProgressIn{
|
||||
BookId: req.BookId,
|
||||
ChapterId: req.ChapterId,
|
||||
Progress: req.Progress,
|
||||
UserId: userId,
|
||||
out, err := service.Chapter().AppBatchProgress(ctx, &model.ChapterAppBatchProgressIn{
|
||||
BookId: req.BookId,
|
||||
Chapters: req.Chapters,
|
||||
UserId: userId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
5
internal/controller/recommend/recommend.go
Normal file
5
internal/controller/recommend/recommend.go
Normal file
@ -0,0 +1,5 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package recommend
|
||||
15
internal/controller/recommend/recommend_new.go
Normal file
15
internal/controller/recommend/recommend_new.go
Normal file
@ -0,0 +1,15 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package recommend
|
||||
|
||||
import (
|
||||
"server/api/recommend"
|
||||
)
|
||||
|
||||
type ControllerV1 struct{}
|
||||
|
||||
func NewV1() recommend.IRecommendV1 {
|
||||
return &ControllerV1{}
|
||||
}
|
||||
23
internal/controller/recommend/recommend_v1_add.go
Normal file
23
internal/controller/recommend/recommend_v1_add.go
Normal file
@ -0,0 +1,23 @@
|
||||
package recommend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/recommend/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Add(ctx context.Context, req *v1.AddReq) (res *v1.AddRes, err error) {
|
||||
out, err := service.BookRecommendations().Create(ctx, &model.BookRecommendationsCreateIn{
|
||||
BookId: req.BookId,
|
||||
Type: req.Type,
|
||||
CoverUrl: req.CoverUrl,
|
||||
SortOrder: req.SortOrder,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.AddRes{Success: out.Success}, nil
|
||||
}
|
||||
35
internal/controller/recommend/recommend_v1_app_list.go
Normal file
35
internal/controller/recommend/recommend_v1_app_list.go
Normal file
@ -0,0 +1,35 @@
|
||||
package recommend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/recommend/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) AppList(ctx context.Context, req *v1.AppListReq) (res *v1.AppListRes, err error) {
|
||||
out, err := service.BookRecommendations().AppList(ctx, &model.BookRecommendationsListIn{
|
||||
Page: req.Page,
|
||||
Size: req.Size,
|
||||
Type: req.Type,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 转换为 RecommendAppItem
|
||||
list := make([]model.RecommendAppItem, 0, len(out.List))
|
||||
for _, item := range out.List {
|
||||
list = append(list, model.RecommendAppItem{
|
||||
Id: item.Id,
|
||||
BookId: item.BookId,
|
||||
CoverUrl: item.CoverUrl,
|
||||
SortOrder: item.SortOrder,
|
||||
})
|
||||
}
|
||||
return &v1.AppListRes{
|
||||
Total: out.Total,
|
||||
List: list,
|
||||
}, nil
|
||||
}
|
||||
19
internal/controller/recommend/recommend_v1_del.go
Normal file
19
internal/controller/recommend/recommend_v1_del.go
Normal file
@ -0,0 +1,19 @@
|
||||
package recommend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/recommend/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Del(ctx context.Context, req *v1.DelReq) (res *v1.DelRes, err error) {
|
||||
out, err := service.BookRecommendations().Delete(ctx, &model.BookRecommendationsDeleteIn{
|
||||
Id: req.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.DelRes{Success: out.Success}, nil
|
||||
}
|
||||
24
internal/controller/recommend/recommend_v1_edit.go
Normal file
24
internal/controller/recommend/recommend_v1_edit.go
Normal file
@ -0,0 +1,24 @@
|
||||
package recommend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/recommend/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Edit(ctx context.Context, req *v1.EditReq) (res *v1.EditRes, err error) {
|
||||
out, err := service.BookRecommendations().Update(ctx, &model.BookRecommendationsUpdateIn{
|
||||
Id: req.Id,
|
||||
BookId: req.BookId,
|
||||
Type: req.Type,
|
||||
CoverUrl: req.CoverUrl,
|
||||
SortOrder: req.SortOrder,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.EditRes{Success: out.Success}, nil
|
||||
}
|
||||
26
internal/controller/recommend/recommend_v1_list.go
Normal file
26
internal/controller/recommend/recommend_v1_list.go
Normal file
@ -0,0 +1,26 @@
|
||||
package recommend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/recommend/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error) {
|
||||
out, err := service.BookRecommendations().List(ctx, &model.BookRecommendationsListIn{
|
||||
Page: req.Page,
|
||||
Size: req.Size,
|
||||
Type: req.Type,
|
||||
Status: req.Status,
|
||||
BookId: req.BookId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ListRes{
|
||||
Total: out.Total,
|
||||
List: out.List,
|
||||
}, nil
|
||||
}
|
||||
20
internal/controller/recommend/recommend_v1_set_status.go
Normal file
20
internal/controller/recommend/recommend_v1_set_status.go
Normal file
@ -0,0 +1,20 @@
|
||||
package recommend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/recommend/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) SetStatus(ctx context.Context, req *v1.SetStatusReq) (res *v1.SetStatusRes, err error) {
|
||||
out, err := service.BookRecommendations().SetStatus(ctx, &model.BookRecommendationsSetStatusIn{
|
||||
Id: req.Id,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.SetStatusRes{Success: out.Success}, nil
|
||||
}
|
||||
20
internal/controller/recommend/recommend_v1_sort_order.go
Normal file
20
internal/controller/recommend/recommend_v1_sort_order.go
Normal file
@ -0,0 +1,20 @@
|
||||
package recommend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/recommend/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) SortOrder(ctx context.Context, req *v1.SortOrderReq) (res *v1.SortOrderRes, err error) {
|
||||
out, err := service.BookRecommendations().SortOrder(ctx, &model.BookRecommendationsSortOrderIn{
|
||||
Id: req.Id,
|
||||
SortOrder: req.SortOrder,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.SortOrderRes{Success: out.Success}, nil
|
||||
}
|
||||
16
internal/controller/recommend/recommend_v1_upload_cover.go
Normal file
16
internal/controller/recommend/recommend_v1_upload_cover.go
Normal file
@ -0,0 +1,16 @@
|
||||
package recommend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/service"
|
||||
|
||||
v1 "server/api/recommend/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) UploadCover(ctx context.Context, req *v1.UploadCoverReq) (res *v1.UploadCoverRes, err error) {
|
||||
url, err := service.BookRecommendations().UploadCover(ctx, req.File)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.UploadCoverRes{Url: url}, nil
|
||||
}
|
||||
5
internal/controller/system/system.go
Normal file
5
internal/controller/system/system.go
Normal file
@ -0,0 +1,5 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package system
|
||||
15
internal/controller/system/system_new.go
Normal file
15
internal/controller/system/system_new.go
Normal file
@ -0,0 +1,15 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"server/api/system"
|
||||
)
|
||||
|
||||
type ControllerV1 struct{}
|
||||
|
||||
func NewV1() system.ISystemV1 {
|
||||
return &ControllerV1{}
|
||||
}
|
||||
16
internal/controller/system/system_v1_system_save.go
Normal file
16
internal/controller/system/system_v1_system_save.go
Normal file
@ -0,0 +1,16 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/system/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) SystemSave(ctx context.Context, req *v1.SystemSaveReq) (res *v1.SystemSaveRes, err error) {
|
||||
return nil, service.System().Save(ctx, &model.SystemSaveInput{
|
||||
Key: req.Key,
|
||||
Value: req.Value,
|
||||
})
|
||||
}
|
||||
16
internal/controller/system/system_v1_system_version.go
Normal file
16
internal/controller/system/system_v1_system_version.go
Normal file
@ -0,0 +1,16 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/service"
|
||||
|
||||
"server/api/system/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) SystemVersion(ctx context.Context, req *v1.SystemVersionReq) (res *v1.SystemVersionRes, err error) {
|
||||
version, err := service.System().Version(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.SystemVersionRes{Ios: version.Ios, Android: version.Android}, nil
|
||||
}
|
||||
5
internal/controller/task/task.go
Normal file
5
internal/controller/task/task.go
Normal file
@ -0,0 +1,5 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package task
|
||||
15
internal/controller/task/task_new.go
Normal file
15
internal/controller/task/task_new.go
Normal file
@ -0,0 +1,15 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package task
|
||||
|
||||
import (
|
||||
"server/api/task"
|
||||
)
|
||||
|
||||
type ControllerV1 struct{}
|
||||
|
||||
func NewV1() task.ITaskV1 {
|
||||
return &ControllerV1{}
|
||||
}
|
||||
23
internal/controller/task/task_v1_add.go
Normal file
23
internal/controller/task/task_v1_add.go
Normal file
@ -0,0 +1,23 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/task/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Add(ctx context.Context, req *v1.AddReq) (res *v1.AddRes, err error) {
|
||||
out, err := service.Task().Add(ctx, &model.TaskAddIn{
|
||||
TaskType: req.TaskType,
|
||||
Title: req.Title,
|
||||
Description: req.Description,
|
||||
RewardPoints: req.RewardPoints,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.AddRes{Success: out.Success}, nil
|
||||
}
|
||||
19
internal/controller/task/task_v1_app_list.go
Normal file
19
internal/controller/task/task_v1_app_list.go
Normal file
@ -0,0 +1,19 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/task/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) AppList(ctx context.Context, req *v1.AppListReq) (res *v1.AppListRes, err error) {
|
||||
out, err := service.Task().AppList(ctx, &model.TaskAppListIn{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.AppListRes{
|
||||
List: out.List,
|
||||
}, nil
|
||||
}
|
||||
17
internal/controller/task/task_v1_del.go
Normal file
17
internal/controller/task/task_v1_del.go
Normal file
@ -0,0 +1,17 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/task/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Del(ctx context.Context, req *v1.DelReq) (res *v1.DelRes, err error) {
|
||||
out, err := service.Task().Delete(ctx, &model.TaskDelIn{Id: req.Id})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.DelRes{Success: out.Success}, nil
|
||||
}
|
||||
24
internal/controller/task/task_v1_edit.go
Normal file
24
internal/controller/task/task_v1_edit.go
Normal file
@ -0,0 +1,24 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/task/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Edit(ctx context.Context, req *v1.EditReq) (res *v1.EditRes, err error) {
|
||||
out, err := service.Task().Edit(ctx, &model.TaskEditIn{
|
||||
Id: req.Id,
|
||||
TaskType: req.TaskType,
|
||||
Title: req.Title,
|
||||
Description: req.Description,
|
||||
RewardPoints: req.RewardPoints,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.EditRes{Success: out.Success}, nil
|
||||
}
|
||||
25
internal/controller/task/task_v1_list.go
Normal file
25
internal/controller/task/task_v1_list.go
Normal file
@ -0,0 +1,25 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "server/api/task/v1"
|
||||
"server/internal/model"
|
||||
"server/internal/service"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error) {
|
||||
out, err := service.Task().List(ctx, &model.TaskListIn{
|
||||
Page: req.Page,
|
||||
Size: req.Size,
|
||||
Title: req.Title,
|
||||
Status: req.Status,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.ListRes{
|
||||
Total: out.Total,
|
||||
List: out.List,
|
||||
}, nil
|
||||
}
|
||||
@ -23,10 +23,14 @@ func (c *ControllerV1) Info(ctx context.Context, req *v1.InfoReq) (res *v1.InfoR
|
||||
}
|
||||
|
||||
return &v1.InfoRes{
|
||||
UserId: out.UserId,
|
||||
Username: out.Username,
|
||||
Avatar: out.Avatar,
|
||||
Email: out.Email,
|
||||
Points: out.Points,
|
||||
Id: out.Id,
|
||||
Username: out.Username,
|
||||
Avatar: out.Avatar,
|
||||
Email: out.Email,
|
||||
Points: out.Points,
|
||||
BackgroundUrl: out.BackgroundUrl,
|
||||
AttentionCount: out.AttentionCount,
|
||||
IsAuthor: out.IsAuthor,
|
||||
AuthorStatus: out.AuthorStatus,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -2,13 +2,15 @@ package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
"server/api/user/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Logout(ctx context.Context, req *v1.LogoutReq) (res *v1.LogoutRes, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
g.Redis().Do(ctx, "SETEX", fmt.Sprintf("blacklist:%s", g.RequestFromCtx(ctx).GetCtxVar("jti").String()), "1")
|
||||
return &v1.LogoutRes{
|
||||
Success: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
27
internal/dao/ad_event_logs.go
Normal file
27
internal/dao/ad_event_logs.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalAdEventLogsDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalAdEventLogsDao = *internal.AdEventLogsDao
|
||||
|
||||
// adEventLogsDao is the data access object for the table ad_event_logs.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type adEventLogsDao struct {
|
||||
internalAdEventLogsDao
|
||||
}
|
||||
|
||||
var (
|
||||
// AdEventLogs is a globally accessible object for table ad_event_logs operations.
|
||||
AdEventLogs = adEventLogsDao{
|
||||
internal.NewAdEventLogsDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
27
internal/dao/ad_event_transitions.go
Normal file
27
internal/dao/ad_event_transitions.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalAdEventTransitionsDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalAdEventTransitionsDao = *internal.AdEventTransitionsDao
|
||||
|
||||
// adEventTransitionsDao is the data access object for the table ad_event_transitions.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type adEventTransitionsDao struct {
|
||||
internalAdEventTransitionsDao
|
||||
}
|
||||
|
||||
var (
|
||||
// AdEventTransitions is a globally accessible object for table ad_event_transitions operations.
|
||||
AdEventTransitions = adEventTransitionsDao{
|
||||
internal.NewAdEventTransitionsDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
27
internal/dao/book_recommendations.go
Normal file
27
internal/dao/book_recommendations.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalBookRecommendationsDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalBookRecommendationsDao = *internal.BookRecommendationsDao
|
||||
|
||||
// bookRecommendationsDao is the data access object for the table book_recommendations.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type bookRecommendationsDao struct {
|
||||
internalBookRecommendationsDao
|
||||
}
|
||||
|
||||
var (
|
||||
// BookRecommendations is a globally accessible object for table book_recommendations operations.
|
||||
BookRecommendations = bookRecommendationsDao{
|
||||
internal.NewBookRecommendationsDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
97
internal/dao/internal/ad_event_logs.go
Normal file
97
internal/dao/internal/ad_event_logs.go
Normal file
@ -0,0 +1,97 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// AdEventLogsDao is the data access object for the table ad_event_logs.
|
||||
type AdEventLogsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns AdEventLogsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// AdEventLogsColumns defines and stores column names for the table ad_event_logs.
|
||||
type AdEventLogsColumns struct {
|
||||
Id string // 广告事件ID
|
||||
UserId string // 用户ID
|
||||
AdsPlatId string // 平台ID:1-META,2-ADMOB
|
||||
AdsCategoryId string // 广告类型:1-横幅,2-插页,3-激励插页,4-激励,5-原生,6-开屏
|
||||
AppPackage string // App包名
|
||||
Status string // 广告状态:1-拉取失败,2-拉取成功,3-显示失败,4-显示成功,5-未观看完成,6-观看完成,7-未点击,8-已点击,9-未下载,10-已下载
|
||||
StatusDesc string // 状态描述
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
}
|
||||
|
||||
// adEventLogsColumns holds the columns for the table ad_event_logs.
|
||||
var adEventLogsColumns = AdEventLogsColumns{
|
||||
Id: "id",
|
||||
UserId: "user_id",
|
||||
AdsPlatId: "ads_plat_id",
|
||||
AdsCategoryId: "ads_category_id",
|
||||
AppPackage: "app_package",
|
||||
Status: "status",
|
||||
StatusDesc: "status_desc",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewAdEventLogsDao creates and returns a new DAO object for table data access.
|
||||
func NewAdEventLogsDao(handlers ...gdb.ModelHandler) *AdEventLogsDao {
|
||||
return &AdEventLogsDao{
|
||||
group: "default",
|
||||
table: "ad_event_logs",
|
||||
columns: adEventLogsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *AdEventLogsDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *AdEventLogsDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *AdEventLogsDao) Columns() AdEventLogsColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *AdEventLogsDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *AdEventLogsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdEventLogsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
89
internal/dao/internal/ad_event_transitions.go
Normal file
89
internal/dao/internal/ad_event_transitions.go
Normal file
@ -0,0 +1,89 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// AdEventTransitionsDao is the data access object for the table ad_event_transitions.
|
||||
type AdEventTransitionsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns AdEventTransitionsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// AdEventTransitionsColumns defines and stores column names for the table ad_event_transitions.
|
||||
type AdEventTransitionsColumns struct {
|
||||
Id string // 状态流转记录ID
|
||||
EventId string // 所属广告事件ID,关联ad_event_logs.id
|
||||
FromStatus string // 原状态(首次记录为空)
|
||||
ToStatus string // 目标状态
|
||||
CreatedAt string // 状态变更时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
}
|
||||
|
||||
// adEventTransitionsColumns holds the columns for the table ad_event_transitions.
|
||||
var adEventTransitionsColumns = AdEventTransitionsColumns{
|
||||
Id: "id",
|
||||
EventId: "event_id",
|
||||
FromStatus: "from_status",
|
||||
ToStatus: "to_status",
|
||||
CreatedAt: "created_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewAdEventTransitionsDao creates and returns a new DAO object for table data access.
|
||||
func NewAdEventTransitionsDao(handlers ...gdb.ModelHandler) *AdEventTransitionsDao {
|
||||
return &AdEventTransitionsDao{
|
||||
group: "default",
|
||||
table: "ad_event_transitions",
|
||||
columns: adEventTransitionsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *AdEventTransitionsDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *AdEventTransitionsDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *AdEventTransitionsDao) Columns() AdEventTransitionsColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *AdEventTransitionsDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *AdEventTransitionsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *AdEventTransitionsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// AdminsDao is the data access object for the table admins.
|
||||
type AdminsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns AdminsColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns AdminsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// AdminsColumns defines and stores column names for the table admins.
|
||||
@ -39,11 +40,12 @@ var adminsColumns = AdminsColumns{
|
||||
}
|
||||
|
||||
// NewAdminsDao creates and returns a new DAO object for table data access.
|
||||
func NewAdminsDao() *AdminsDao {
|
||||
func NewAdminsDao(handlers ...gdb.ModelHandler) *AdminsDao {
|
||||
return &AdminsDao{
|
||||
group: "default",
|
||||
table: "admins",
|
||||
columns: adminsColumns,
|
||||
group: "default",
|
||||
table: "admins",
|
||||
columns: adminsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +71,11 @@ func (dao *AdminsDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *AdminsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
@ -13,41 +13,45 @@ import (
|
||||
|
||||
// AuthorsDao is the data access object for the table authors.
|
||||
type AuthorsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns AuthorsColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns AuthorsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// AuthorsColumns defines and stores column names for the table authors.
|
||||
type AuthorsColumns struct {
|
||||
Id string // 作者ID
|
||||
UserId string // 用户ID
|
||||
PenName string // 笔名
|
||||
Bio string // 作者简介
|
||||
Status string // 状态:1=正常,2=禁用
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
Id string // 作者ID
|
||||
UserId string // 用户ID
|
||||
PenName string // 笔名
|
||||
Bio string // 作者简介
|
||||
FollowerCount string // 粉丝数量
|
||||
Status string // 状态:1=正常,2=待审核, 3=未通过
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
}
|
||||
|
||||
// authorsColumns holds the columns for the table authors.
|
||||
var authorsColumns = AuthorsColumns{
|
||||
Id: "id",
|
||||
UserId: "user_id",
|
||||
PenName: "pen_name",
|
||||
Bio: "bio",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
Id: "id",
|
||||
UserId: "user_id",
|
||||
PenName: "pen_name",
|
||||
Bio: "bio",
|
||||
FollowerCount: "follower_count",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewAuthorsDao creates and returns a new DAO object for table data access.
|
||||
func NewAuthorsDao() *AuthorsDao {
|
||||
func NewAuthorsDao(handlers ...gdb.ModelHandler) *AuthorsDao {
|
||||
return &AuthorsDao{
|
||||
group: "default",
|
||||
table: "authors",
|
||||
columns: authorsColumns,
|
||||
group: "default",
|
||||
table: "authors",
|
||||
columns: authorsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +77,11 @@ func (dao *AuthorsDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *AuthorsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// BookRatingsDao is the data access object for the table book_ratings.
|
||||
type BookRatingsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns BookRatingsColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns BookRatingsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// BookRatingsColumns defines and stores column names for the table book_ratings.
|
||||
@ -39,11 +40,12 @@ var bookRatingsColumns = BookRatingsColumns{
|
||||
}
|
||||
|
||||
// NewBookRatingsDao creates and returns a new DAO object for table data access.
|
||||
func NewBookRatingsDao() *BookRatingsDao {
|
||||
func NewBookRatingsDao(handlers ...gdb.ModelHandler) *BookRatingsDao {
|
||||
return &BookRatingsDao{
|
||||
group: "default",
|
||||
table: "book_ratings",
|
||||
columns: bookRatingsColumns,
|
||||
group: "default",
|
||||
table: "book_ratings",
|
||||
columns: bookRatingsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +71,11 @@ func (dao *BookRatingsDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *BookRatingsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
95
internal/dao/internal/book_recommendations.go
Normal file
95
internal/dao/internal/book_recommendations.go
Normal file
@ -0,0 +1,95 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// BookRecommendationsDao is the data access object for the table book_recommendations.
|
||||
type BookRecommendationsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns BookRecommendationsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// BookRecommendationsColumns defines and stores column names for the table book_recommendations.
|
||||
type BookRecommendationsColumns struct {
|
||||
Id string // 主键
|
||||
BookId string // 书籍ID,关联 books 表
|
||||
Type string // 推荐类型:1=首页Banner,2=编辑推荐,3=分类推荐等
|
||||
CoverUrl string // 推荐封面图(横图)
|
||||
SortOrder string // 展示排序,越小越靠前
|
||||
Status string // 是否启用:1=启用,0=禁用
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
}
|
||||
|
||||
// bookRecommendationsColumns holds the columns for the table book_recommendations.
|
||||
var bookRecommendationsColumns = BookRecommendationsColumns{
|
||||
Id: "id",
|
||||
BookId: "book_id",
|
||||
Type: "type",
|
||||
CoverUrl: "cover_url",
|
||||
SortOrder: "sort_order",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewBookRecommendationsDao creates and returns a new DAO object for table data access.
|
||||
func NewBookRecommendationsDao(handlers ...gdb.ModelHandler) *BookRecommendationsDao {
|
||||
return &BookRecommendationsDao{
|
||||
group: "default",
|
||||
table: "book_recommendations",
|
||||
columns: bookRecommendationsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *BookRecommendationsDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *BookRecommendationsDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *BookRecommendationsDao) Columns() BookRecommendationsColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *BookRecommendationsDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *BookRecommendationsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *BookRecommendationsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// BooksDao is the data access object for the table books.
|
||||
type BooksDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns BooksColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns BooksColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// BooksColumns defines and stores column names for the table books.
|
||||
@ -38,6 +39,7 @@ type BooksColumns struct {
|
||||
DeletedAt string // 软删除时间戳
|
||||
IsRecommended string // 是否推荐:0=否,1=是
|
||||
IsFeatured string // 是否精选:0=否,1=是
|
||||
IsHot string // 是否热门:0=否,1=是
|
||||
Language string // 语言,如 zh=中文,en=英文,jp=日文
|
||||
}
|
||||
|
||||
@ -61,15 +63,17 @@ var booksColumns = BooksColumns{
|
||||
DeletedAt: "deleted_at",
|
||||
IsRecommended: "is_recommended",
|
||||
IsFeatured: "is_featured",
|
||||
IsHot: "is_hot",
|
||||
Language: "language",
|
||||
}
|
||||
|
||||
// NewBooksDao creates and returns a new DAO object for table data access.
|
||||
func NewBooksDao() *BooksDao {
|
||||
func NewBooksDao(handlers ...gdb.ModelHandler) *BooksDao {
|
||||
return &BooksDao{
|
||||
group: "default",
|
||||
table: "books",
|
||||
columns: booksColumns,
|
||||
group: "default",
|
||||
table: "books",
|
||||
columns: booksColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +99,11 @@ func (dao *BooksDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *BooksDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// BookshelvesDao is the data access object for the table bookshelves.
|
||||
type BookshelvesDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns BookshelvesColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns BookshelvesColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// BookshelvesColumns defines and stores column names for the table bookshelves.
|
||||
@ -43,11 +44,12 @@ var bookshelvesColumns = BookshelvesColumns{
|
||||
}
|
||||
|
||||
// NewBookshelvesDao creates and returns a new DAO object for table data access.
|
||||
func NewBookshelvesDao() *BookshelvesDao {
|
||||
func NewBookshelvesDao(handlers ...gdb.ModelHandler) *BookshelvesDao {
|
||||
return &BookshelvesDao{
|
||||
group: "default",
|
||||
table: "bookshelves",
|
||||
columns: bookshelvesColumns,
|
||||
group: "default",
|
||||
table: "bookshelves",
|
||||
columns: bookshelvesColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +75,11 @@ func (dao *BookshelvesDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *BookshelvesDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// CategoriesDao is the data access object for the table categories.
|
||||
type CategoriesDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns CategoriesColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns CategoriesColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// CategoriesColumns defines and stores column names for the table categories.
|
||||
@ -39,11 +40,12 @@ var categoriesColumns = CategoriesColumns{
|
||||
}
|
||||
|
||||
// NewCategoriesDao creates and returns a new DAO object for table data access.
|
||||
func NewCategoriesDao() *CategoriesDao {
|
||||
func NewCategoriesDao(handlers ...gdb.ModelHandler) *CategoriesDao {
|
||||
return &CategoriesDao{
|
||||
group: "default",
|
||||
table: "categories",
|
||||
columns: categoriesColumns,
|
||||
group: "default",
|
||||
table: "categories",
|
||||
columns: categoriesColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +71,11 @@ func (dao *CategoriesDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *CategoriesDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// ChaptersDao is the data access object for the table chapters.
|
||||
type ChaptersDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns ChaptersColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns ChaptersColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// ChaptersColumns defines and stores column names for the table chapters.
|
||||
@ -49,11 +50,12 @@ var chaptersColumns = ChaptersColumns{
|
||||
}
|
||||
|
||||
// NewChaptersDao creates and returns a new DAO object for table data access.
|
||||
func NewChaptersDao() *ChaptersDao {
|
||||
func NewChaptersDao(handlers ...gdb.ModelHandler) *ChaptersDao {
|
||||
return &ChaptersDao{
|
||||
group: "default",
|
||||
table: "chapters",
|
||||
columns: chaptersColumns,
|
||||
group: "default",
|
||||
table: "chapters",
|
||||
columns: chaptersColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +81,11 @@ func (dao *ChaptersDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *ChaptersDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// FeedbacksDao is the data access object for the table feedbacks.
|
||||
type FeedbacksDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns FeedbacksColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns FeedbacksColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// FeedbacksColumns defines and stores column names for the table feedbacks.
|
||||
@ -39,11 +40,12 @@ var feedbacksColumns = FeedbacksColumns{
|
||||
}
|
||||
|
||||
// NewFeedbacksDao creates and returns a new DAO object for table data access.
|
||||
func NewFeedbacksDao() *FeedbacksDao {
|
||||
func NewFeedbacksDao(handlers ...gdb.ModelHandler) *FeedbacksDao {
|
||||
return &FeedbacksDao{
|
||||
group: "default",
|
||||
table: "feedbacks",
|
||||
columns: feedbacksColumns,
|
||||
group: "default",
|
||||
table: "feedbacks",
|
||||
columns: feedbacksColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +71,11 @@ func (dao *FeedbacksDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *FeedbacksDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
95
internal/dao/internal/sign_in_reward_details.go
Normal file
95
internal/dao/internal/sign_in_reward_details.go
Normal file
@ -0,0 +1,95 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// SignInRewardDetailsDao is the data access object for the table sign_in_reward_details.
|
||||
type SignInRewardDetailsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns SignInRewardDetailsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// SignInRewardDetailsColumns defines and stores column names for the table sign_in_reward_details.
|
||||
type SignInRewardDetailsColumns struct {
|
||||
Id string // 主键
|
||||
RuleId string // 规则ID,关联 sign_in_reward_rules 表
|
||||
DayNumber string // 签到天数(1到cycle_days)
|
||||
RewardType string // 奖励类型:1=积分
|
||||
Quantity string // 奖励数量,如积分数量或礼包数量
|
||||
Status string // 记录状态:1=启用,0=禁用
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
}
|
||||
|
||||
// signInRewardDetailsColumns holds the columns for the table sign_in_reward_details.
|
||||
var signInRewardDetailsColumns = SignInRewardDetailsColumns{
|
||||
Id: "id",
|
||||
RuleId: "rule_id",
|
||||
DayNumber: "day_number",
|
||||
RewardType: "reward_type",
|
||||
Quantity: "quantity",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewSignInRewardDetailsDao creates and returns a new DAO object for table data access.
|
||||
func NewSignInRewardDetailsDao(handlers ...gdb.ModelHandler) *SignInRewardDetailsDao {
|
||||
return &SignInRewardDetailsDao{
|
||||
group: "default",
|
||||
table: "sign_in_reward_details",
|
||||
columns: signInRewardDetailsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *SignInRewardDetailsDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *SignInRewardDetailsDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *SignInRewardDetailsDao) Columns() SignInRewardDetailsColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *SignInRewardDetailsDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *SignInRewardDetailsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SignInRewardDetailsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
95
internal/dao/internal/sign_in_reward_rules.go
Normal file
95
internal/dao/internal/sign_in_reward_rules.go
Normal file
@ -0,0 +1,95 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// SignInRewardRulesDao is the data access object for the table sign_in_reward_rules.
|
||||
type SignInRewardRulesDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns SignInRewardRulesColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// SignInRewardRulesColumns defines and stores column names for the table sign_in_reward_rules.
|
||||
type SignInRewardRulesColumns struct {
|
||||
Id string // 主键
|
||||
RuleName string // 规则名称,如“7天签到活动”
|
||||
CycleDays string // 奖励周期天数,如7天
|
||||
StartDate string // 活动开始日期
|
||||
EndDate string // 活动结束日期
|
||||
Status string // 规则状态:1=启用,0=禁用
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
}
|
||||
|
||||
// signInRewardRulesColumns holds the columns for the table sign_in_reward_rules.
|
||||
var signInRewardRulesColumns = SignInRewardRulesColumns{
|
||||
Id: "id",
|
||||
RuleName: "rule_name",
|
||||
CycleDays: "cycle_days",
|
||||
StartDate: "start_date",
|
||||
EndDate: "end_date",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewSignInRewardRulesDao creates and returns a new DAO object for table data access.
|
||||
func NewSignInRewardRulesDao(handlers ...gdb.ModelHandler) *SignInRewardRulesDao {
|
||||
return &SignInRewardRulesDao{
|
||||
group: "default",
|
||||
table: "sign_in_reward_rules",
|
||||
columns: signInRewardRulesColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *SignInRewardRulesDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *SignInRewardRulesDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *SignInRewardRulesDao) Columns() SignInRewardRulesColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *SignInRewardRulesDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *SignInRewardRulesDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SignInRewardRulesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
81
internal/dao/internal/system.go
Normal file
81
internal/dao/internal/system.go
Normal file
@ -0,0 +1,81 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// SystemDao is the data access object for the table system.
|
||||
type SystemDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns SystemColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// SystemColumns defines and stores column names for the table system.
|
||||
type SystemColumns struct {
|
||||
Key string //
|
||||
Value string //
|
||||
}
|
||||
|
||||
// systemColumns holds the columns for the table system.
|
||||
var systemColumns = SystemColumns{
|
||||
Key: "key",
|
||||
Value: "value",
|
||||
}
|
||||
|
||||
// NewSystemDao creates and returns a new DAO object for table data access.
|
||||
func NewSystemDao(handlers ...gdb.ModelHandler) *SystemDao {
|
||||
return &SystemDao{
|
||||
group: "default",
|
||||
table: "system",
|
||||
columns: systemColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *SystemDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *SystemDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *SystemDao) Columns() SystemColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *SystemDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *SystemDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *SystemDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
93
internal/dao/internal/task_logs.go
Normal file
93
internal/dao/internal/task_logs.go
Normal file
@ -0,0 +1,93 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// TaskLogsDao is the data access object for the table task_logs.
|
||||
type TaskLogsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns TaskLogsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// TaskLogsColumns defines and stores column names for the table task_logs.
|
||||
type TaskLogsColumns struct {
|
||||
Id string // 任务日志ID
|
||||
TaskId string // 任务ID,关联 tasks.id
|
||||
UserId string // 用户ID,关联 users.id
|
||||
RewardPoints string // 本次任务获得的积分
|
||||
ActionTime string // 操作时间(如完成时间)
|
||||
Status string // 日志状态:1=有效,2=无效
|
||||
Extra string // 扩展信息,例如来源、IP 等
|
||||
CreatedAt string // 创建时间
|
||||
}
|
||||
|
||||
// taskLogsColumns holds the columns for the table task_logs.
|
||||
var taskLogsColumns = TaskLogsColumns{
|
||||
Id: "id",
|
||||
TaskId: "task_id",
|
||||
UserId: "user_id",
|
||||
RewardPoints: "reward_points",
|
||||
ActionTime: "action_time",
|
||||
Status: "status",
|
||||
Extra: "extra",
|
||||
CreatedAt: "created_at",
|
||||
}
|
||||
|
||||
// NewTaskLogsDao creates and returns a new DAO object for table data access.
|
||||
func NewTaskLogsDao(handlers ...gdb.ModelHandler) *TaskLogsDao {
|
||||
return &TaskLogsDao{
|
||||
group: "default",
|
||||
table: "task_logs",
|
||||
columns: taskLogsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *TaskLogsDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *TaskLogsDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *TaskLogsDao) Columns() TaskLogsColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *TaskLogsDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *TaskLogsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *TaskLogsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
83
internal/dao/internal/task_types.go
Normal file
83
internal/dao/internal/task_types.go
Normal file
@ -0,0 +1,83 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// TaskTypesDao is the data access object for the table task_types.
|
||||
type TaskTypesDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns TaskTypesColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// TaskTypesColumns defines and stores column names for the table task_types.
|
||||
type TaskTypesColumns struct {
|
||||
Id string // 任务类型ID
|
||||
Name string // 任务类型名称,例如:广告、写一本书、首次登录
|
||||
Description string // 任务类型描述
|
||||
Status string // 状态:1=启用,2=禁用
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
}
|
||||
|
||||
// taskTypesColumns holds the columns for the table task_types.
|
||||
var taskTypesColumns = TaskTypesColumns{
|
||||
Id: "id",
|
||||
Name: "name",
|
||||
Description: "description",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
}
|
||||
|
||||
// NewTaskTypesDao creates and returns a new DAO object for table data access.
|
||||
func NewTaskTypesDao() *TaskTypesDao {
|
||||
return &TaskTypesDao{
|
||||
group: "default",
|
||||
table: "task_types",
|
||||
columns: taskTypesColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *TaskTypesDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *TaskTypesDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *TaskTypesDao) Columns() TaskTypesColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *TaskTypesDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *TaskTypesDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *TaskTypesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
95
internal/dao/internal/tasks.go
Normal file
95
internal/dao/internal/tasks.go
Normal file
@ -0,0 +1,95 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// TasksDao is the data access object for the table tasks.
|
||||
type TasksDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns TasksColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// TasksColumns defines and stores column names for the table tasks.
|
||||
type TasksColumns struct {
|
||||
Id string // 任务ID
|
||||
TaskType string // 任务类型:1=首次登录,2=广告,3=发布书籍
|
||||
Title string // 任务标题
|
||||
Description string // 任务描述
|
||||
RewardPoints string // 完成任务奖励的积分数
|
||||
Status string // 状态:1=启用,2=禁用
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
}
|
||||
|
||||
// tasksColumns holds the columns for the table tasks.
|
||||
var tasksColumns = TasksColumns{
|
||||
Id: "id",
|
||||
TaskType: "task_type",
|
||||
Title: "title",
|
||||
Description: "description",
|
||||
RewardPoints: "reward_points",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewTasksDao creates and returns a new DAO object for table data access.
|
||||
func NewTasksDao(handlers ...gdb.ModelHandler) *TasksDao {
|
||||
return &TasksDao{
|
||||
group: "default",
|
||||
table: "tasks",
|
||||
columns: tasksColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *TasksDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *TasksDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *TasksDao) Columns() TasksColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *TasksDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *TasksDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *TasksDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// UserChapterPurchasesDao is the data access object for the table user_chapter_purchases.
|
||||
type UserChapterPurchasesDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserChapterPurchasesColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserChapterPurchasesColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// UserChapterPurchasesColumns defines and stores column names for the table user_chapter_purchases.
|
||||
@ -39,11 +40,12 @@ var userChapterPurchasesColumns = UserChapterPurchasesColumns{
|
||||
}
|
||||
|
||||
// NewUserChapterPurchasesDao creates and returns a new DAO object for table data access.
|
||||
func NewUserChapterPurchasesDao() *UserChapterPurchasesDao {
|
||||
func NewUserChapterPurchasesDao(handlers ...gdb.ModelHandler) *UserChapterPurchasesDao {
|
||||
return &UserChapterPurchasesDao{
|
||||
group: "default",
|
||||
table: "user_chapter_purchases",
|
||||
columns: userChapterPurchasesColumns,
|
||||
group: "default",
|
||||
table: "user_chapter_purchases",
|
||||
columns: userChapterPurchasesColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +71,11 @@ func (dao *UserChapterPurchasesDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *UserChapterPurchasesDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// UserFollowAuthorsDao is the data access object for the table user_follow_authors.
|
||||
type UserFollowAuthorsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserFollowAuthorsColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserFollowAuthorsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// UserFollowAuthorsColumns defines and stores column names for the table user_follow_authors.
|
||||
@ -35,11 +36,12 @@ var userFollowAuthorsColumns = UserFollowAuthorsColumns{
|
||||
}
|
||||
|
||||
// NewUserFollowAuthorsDao creates and returns a new DAO object for table data access.
|
||||
func NewUserFollowAuthorsDao() *UserFollowAuthorsDao {
|
||||
func NewUserFollowAuthorsDao(handlers ...gdb.ModelHandler) *UserFollowAuthorsDao {
|
||||
return &UserFollowAuthorsDao{
|
||||
group: "default",
|
||||
table: "user_follow_authors",
|
||||
columns: userFollowAuthorsColumns,
|
||||
group: "default",
|
||||
table: "user_follow_authors",
|
||||
columns: userFollowAuthorsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,7 +67,11 @@ func (dao *UserFollowAuthorsDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *UserFollowAuthorsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// UserPointsLogsDao is the data access object for the table user_points_logs.
|
||||
type UserPointsLogsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserPointsLogsColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserPointsLogsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// UserPointsLogsColumns defines and stores column names for the table user_points_logs.
|
||||
@ -41,11 +42,12 @@ var userPointsLogsColumns = UserPointsLogsColumns{
|
||||
}
|
||||
|
||||
// NewUserPointsLogsDao creates and returns a new DAO object for table data access.
|
||||
func NewUserPointsLogsDao() *UserPointsLogsDao {
|
||||
func NewUserPointsLogsDao(handlers ...gdb.ModelHandler) *UserPointsLogsDao {
|
||||
return &UserPointsLogsDao{
|
||||
group: "default",
|
||||
table: "user_points_logs",
|
||||
columns: userPointsLogsColumns,
|
||||
group: "default",
|
||||
table: "user_points_logs",
|
||||
columns: userPointsLogsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +73,11 @@ func (dao *UserPointsLogsDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *UserPointsLogsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// UserReadHistoryDao is the data access object for the table user_read_history.
|
||||
type UserReadHistoryDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserReadHistoryColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserReadHistoryColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// UserReadHistoryColumns defines and stores column names for the table user_read_history.
|
||||
@ -37,11 +38,12 @@ var userReadHistoryColumns = UserReadHistoryColumns{
|
||||
}
|
||||
|
||||
// NewUserReadHistoryDao creates and returns a new DAO object for table data access.
|
||||
func NewUserReadHistoryDao() *UserReadHistoryDao {
|
||||
func NewUserReadHistoryDao(handlers ...gdb.ModelHandler) *UserReadHistoryDao {
|
||||
return &UserReadHistoryDao{
|
||||
group: "default",
|
||||
table: "user_read_history",
|
||||
columns: userReadHistoryColumns,
|
||||
group: "default",
|
||||
table: "user_read_history",
|
||||
columns: userReadHistoryColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +69,11 @@ func (dao *UserReadHistoryDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *UserReadHistoryDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
@ -13,9 +13,10 @@ import (
|
||||
|
||||
// UserReadRecordsDao is the data access object for the table user_read_records.
|
||||
type UserReadRecordsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserReadRecordsColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserReadRecordsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// UserReadRecordsColumns defines and stores column names for the table user_read_records.
|
||||
@ -43,11 +44,12 @@ var userReadRecordsColumns = UserReadRecordsColumns{
|
||||
}
|
||||
|
||||
// NewUserReadRecordsDao creates and returns a new DAO object for table data access.
|
||||
func NewUserReadRecordsDao() *UserReadRecordsDao {
|
||||
func NewUserReadRecordsDao(handlers ...gdb.ModelHandler) *UserReadRecordsDao {
|
||||
return &UserReadRecordsDao{
|
||||
group: "default",
|
||||
table: "user_read_records",
|
||||
columns: userReadRecordsColumns,
|
||||
group: "default",
|
||||
table: "user_read_records",
|
||||
columns: userReadRecordsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,7 +75,11 @@ func (dao *UserReadRecordsDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *UserReadRecordsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
97
internal/dao/internal/user_sign_in_logs.go
Normal file
97
internal/dao/internal/user_sign_in_logs.go
Normal file
@ -0,0 +1,97 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// UserSignInLogsDao is the data access object for the table user_sign_in_logs.
|
||||
type UserSignInLogsDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UserSignInLogsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// UserSignInLogsColumns defines and stores column names for the table user_sign_in_logs.
|
||||
type UserSignInLogsColumns struct {
|
||||
Id string // 主键
|
||||
UserId string // 用户ID,关联 users 表
|
||||
RuleId string // 规则ID,关联 sign_in_reward_rules 表
|
||||
RewardDetailId string // 奖励详情ID,关联 sign_in_reward_details 表
|
||||
SignInDate string // 签到日期
|
||||
Quantity string // 奖励数量,如积分数量或礼包数量
|
||||
Status string // 记录状态:1=有效,0=无效
|
||||
CreatedAt string // 创建时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
}
|
||||
|
||||
// userSignInLogsColumns holds the columns for the table user_sign_in_logs.
|
||||
var userSignInLogsColumns = UserSignInLogsColumns{
|
||||
Id: "id",
|
||||
UserId: "user_id",
|
||||
RuleId: "rule_id",
|
||||
RewardDetailId: "reward_detail_id",
|
||||
SignInDate: "sign_in_date",
|
||||
Quantity: "quantity",
|
||||
Status: "status",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
}
|
||||
|
||||
// NewUserSignInLogsDao creates and returns a new DAO object for table data access.
|
||||
func NewUserSignInLogsDao(handlers ...gdb.ModelHandler) *UserSignInLogsDao {
|
||||
return &UserSignInLogsDao{
|
||||
group: "default",
|
||||
table: "user_sign_in_logs",
|
||||
columns: userSignInLogsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *UserSignInLogsDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *UserSignInLogsDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *UserSignInLogsDao) Columns() UserSignInLogsColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *UserSignInLogsDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *UserSignInLogsDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rolls back the transaction and returns the error if function f returns a non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note: Do not commit or roll back the transaction in function f,
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *UserSignInLogsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@ -13,43 +13,49 @@ import (
|
||||
|
||||
// UsersDao is the data access object for the table users.
|
||||
type UsersDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UsersColumns // columns contains all the column names of Table for convenient usage.
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of the current DAO.
|
||||
columns UsersColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// UsersColumns defines and stores column names for the table users.
|
||||
type UsersColumns struct {
|
||||
Id string // 用户ID
|
||||
Username string // 用户名
|
||||
PasswordHash string // 密码哈希
|
||||
Avatar string // 头像URL
|
||||
Email string // 邮箱
|
||||
Points string // 积分
|
||||
CreatedAt string // 注册时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
Id string // 用户ID
|
||||
Username string // 用户名
|
||||
PasswordHash string // 密码哈希
|
||||
Avatar string // 头像URL
|
||||
Email string // 邮箱
|
||||
Points string // 积分
|
||||
CreatedAt string // 注册时间
|
||||
UpdatedAt string // 更新时间
|
||||
DeletedAt string // 软删除时间戳
|
||||
BackgroundUrl string // 作者背景图
|
||||
AttentionCount string // 关注他人的数量 attention count
|
||||
}
|
||||
|
||||
// usersColumns holds the columns for the table users.
|
||||
var usersColumns = UsersColumns{
|
||||
Id: "id",
|
||||
Username: "username",
|
||||
PasswordHash: "password_hash",
|
||||
Avatar: "avatar",
|
||||
Email: "email",
|
||||
Points: "points",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
Id: "id",
|
||||
Username: "username",
|
||||
PasswordHash: "password_hash",
|
||||
Avatar: "avatar",
|
||||
Email: "email",
|
||||
Points: "points",
|
||||
CreatedAt: "created_at",
|
||||
UpdatedAt: "updated_at",
|
||||
DeletedAt: "deleted_at",
|
||||
BackgroundUrl: "background_url",
|
||||
AttentionCount: "attention_count",
|
||||
}
|
||||
|
||||
// NewUsersDao creates and returns a new DAO object for table data access.
|
||||
func NewUsersDao() *UsersDao {
|
||||
func NewUsersDao(handlers ...gdb.ModelHandler) *UsersDao {
|
||||
return &UsersDao{
|
||||
group: "default",
|
||||
table: "users",
|
||||
columns: usersColumns,
|
||||
group: "default",
|
||||
table: "users",
|
||||
columns: usersColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +81,11 @@ func (dao *UsersDao) Group() string {
|
||||
|
||||
// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
|
||||
func (dao *UsersDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
model := dao.DB().Model(dao.table)
|
||||
for _, handler := range dao.handlers {
|
||||
model = handler(model)
|
||||
}
|
||||
return model.Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
|
||||
27
internal/dao/sign_in_reward_details.go
Normal file
27
internal/dao/sign_in_reward_details.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalSignInRewardDetailsDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalSignInRewardDetailsDao = *internal.SignInRewardDetailsDao
|
||||
|
||||
// signInRewardDetailsDao is the data access object for the table sign_in_reward_details.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type signInRewardDetailsDao struct {
|
||||
internalSignInRewardDetailsDao
|
||||
}
|
||||
|
||||
var (
|
||||
// SignInRewardDetails is a globally accessible object for table sign_in_reward_details operations.
|
||||
SignInRewardDetails = signInRewardDetailsDao{
|
||||
internal.NewSignInRewardDetailsDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
27
internal/dao/sign_in_reward_rules.go
Normal file
27
internal/dao/sign_in_reward_rules.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalSignInRewardRulesDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalSignInRewardRulesDao = *internal.SignInRewardRulesDao
|
||||
|
||||
// signInRewardRulesDao is the data access object for the table sign_in_reward_rules.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type signInRewardRulesDao struct {
|
||||
internalSignInRewardRulesDao
|
||||
}
|
||||
|
||||
var (
|
||||
// SignInRewardRules is a globally accessible object for table sign_in_reward_rules operations.
|
||||
SignInRewardRules = signInRewardRulesDao{
|
||||
internal.NewSignInRewardRulesDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
27
internal/dao/system.go
Normal file
27
internal/dao/system.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalSystemDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalSystemDao = *internal.SystemDao
|
||||
|
||||
// systemDao is the data access object for the table system.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type systemDao struct {
|
||||
internalSystemDao
|
||||
}
|
||||
|
||||
var (
|
||||
// System is a globally accessible object for table system operations.
|
||||
System = systemDao{
|
||||
internal.NewSystemDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
27
internal/dao/task_logs.go
Normal file
27
internal/dao/task_logs.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalTaskLogsDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalTaskLogsDao = *internal.TaskLogsDao
|
||||
|
||||
// taskLogsDao is the data access object for the table task_logs.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type taskLogsDao struct {
|
||||
internalTaskLogsDao
|
||||
}
|
||||
|
||||
var (
|
||||
// TaskLogs is a globally accessible object for table task_logs operations.
|
||||
TaskLogs = taskLogsDao{
|
||||
internal.NewTaskLogsDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
27
internal/dao/task_types.go
Normal file
27
internal/dao/task_types.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalTaskTypesDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalTaskTypesDao = *internal.TaskTypesDao
|
||||
|
||||
// taskTypesDao is the data access object for the table task_types.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type taskTypesDao struct {
|
||||
internalTaskTypesDao
|
||||
}
|
||||
|
||||
var (
|
||||
// TaskTypes is a globally accessible object for table task_types operations.
|
||||
TaskTypes = taskTypesDao{
|
||||
internal.NewTaskTypesDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
27
internal/dao/tasks.go
Normal file
27
internal/dao/tasks.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalTasksDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalTasksDao = *internal.TasksDao
|
||||
|
||||
// tasksDao is the data access object for the table tasks.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type tasksDao struct {
|
||||
internalTasksDao
|
||||
}
|
||||
|
||||
var (
|
||||
// Tasks is a globally accessible object for table tasks operations.
|
||||
Tasks = tasksDao{
|
||||
internal.NewTasksDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
27
internal/dao/user_sign_in_logs.go
Normal file
27
internal/dao/user_sign_in_logs.go
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"server/internal/dao/internal"
|
||||
)
|
||||
|
||||
// internalUserSignInLogsDao is an internal type for wrapping the internal DAO implementation.
|
||||
type internalUserSignInLogsDao = *internal.UserSignInLogsDao
|
||||
|
||||
// userSignInLogsDao is the data access object for the table user_sign_in_logs.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type userSignInLogsDao struct {
|
||||
internalUserSignInLogsDao
|
||||
}
|
||||
|
||||
var (
|
||||
// UserSignInLogs is a globally accessible object for table user_sign_in_logs operations.
|
||||
UserSignInLogs = userSignInLogsDao{
|
||||
internal.NewUserSignInLogsDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
273
internal/logic/ad_event_logs/ad_event_logs.go
Normal file
273
internal/logic/ad_event_logs/ad_event_logs.go
Normal file
@ -0,0 +1,273 @@
|
||||
package ads
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"server/internal/consts"
|
||||
"server/internal/dao"
|
||||
"server/internal/model"
|
||||
"server/internal/model/do"
|
||||
"server/internal/service"
|
||||
"server/utility/ecode"
|
||||
"server/utility/encrypt"
|
||||
"server/utility/mqtt"
|
||||
"server/utility/state_machine"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type sAds struct {
|
||||
stateMachine *state_machine.AdStateMachine
|
||||
}
|
||||
|
||||
func New() service.IAds {
|
||||
return &sAds{
|
||||
stateMachine: state_machine.NewAdStateMachine(),
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
service.RegisterAds(New())
|
||||
}
|
||||
|
||||
// Upload 广告数据上传 - 处理用户广告状态流转
|
||||
func (s *sAds) Upload(ctx context.Context, in *model.AdsUploadIn) (out *model.AdsUploadOut, err error) {
|
||||
// 解密广告数据
|
||||
adsData, err := encrypt.DecryptAdsData(in.Data)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("data_decrypt_failed")
|
||||
}
|
||||
|
||||
// 验证数据
|
||||
if adsData.AdsPlatId <= 0 || adsData.AdsCategoryId <= 0 || adsData.AppPackage == "" {
|
||||
return nil, ecode.Params.Sub("invalid_ads_data")
|
||||
}
|
||||
|
||||
// 使用事务同时操作多个表
|
||||
err = dao.AdEventLogs.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
// 1. 查找用户该广告的最新记录,确保状态流转是在同一条广告记录上进行的
|
||||
var fromState consts.AdState
|
||||
var adEventId int64 // 广告事件ID,用于关联状态流转记录
|
||||
var isNewLifecycle bool // 是否是新的生命周期
|
||||
|
||||
// 当前状态
|
||||
toState := consts.AdState(adsData.Status)
|
||||
|
||||
// 拉取成功和拉取失败总是新的广告生命周期的开始
|
||||
if toState == consts.StateFetchSuccess || toState == consts.StateFetchFailed {
|
||||
isNewLifecycle = true
|
||||
fromState = 0
|
||||
glog.Infof(ctx, "Starting new ad lifecycle with fetch state for user %d, app %s, state: %s",
|
||||
in.UserId, adsData.AppPackage, consts.GetStateDescription(toState))
|
||||
} else {
|
||||
// 查询条件:同一用户、同一平台、同一广告类型、同一APP包名
|
||||
latestLog, err := dao.AdEventLogs.Ctx(ctx).TX(tx).
|
||||
Where(do.AdEventLogs{
|
||||
UserId: in.UserId,
|
||||
AdsPlatId: adsData.AdsPlatId,
|
||||
AdsCategoryId: adsData.AdsCategoryId,
|
||||
AppPackage: adsData.AppPackage,
|
||||
}).
|
||||
Order("created_at DESC").
|
||||
One()
|
||||
|
||||
if err == nil && !latestLog.IsEmpty() {
|
||||
fromState = consts.AdState(latestLog["status"].Int())
|
||||
adEventId = latestLog["id"].Int64()
|
||||
|
||||
// 检查是否是终止状态,如果是终止状态,则需要创建新的广告记录
|
||||
if s.stateMachine.IsTerminalState(fromState) {
|
||||
// 如果是终止状态,则表示这是一个新的广告生命周期
|
||||
isNewLifecycle = true
|
||||
fromState = 0 // 重置状态,表示新的生命周期开始
|
||||
glog.Infof(ctx, "Starting new ad lifecycle after terminal state for user %d, app %s",
|
||||
in.UserId, adsData.AppPackage)
|
||||
} else {
|
||||
glog.Infof(ctx, "Continuing ad lifecycle for user %d, app %s, from state %d to %d",
|
||||
in.UserId, adsData.AppPackage, fromState, adsData.Status)
|
||||
}
|
||||
} else {
|
||||
// 没有找到记录,这是第一次上传该广告数据
|
||||
isNewLifecycle = true
|
||||
glog.Infof(ctx, "First ad upload for user %d, app %s", in.UserId, adsData.AppPackage)
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 使用状态机验证状态转换
|
||||
flowID := generateFlowID(in.UserId, adsData.AppPackage)
|
||||
|
||||
// 如果不是新的生命周期,则验证状态转换
|
||||
if !isNewLifecycle {
|
||||
err = s.stateMachine.Transition(ctx, flowID, in.UserId, fromState, toState, "用户操作")
|
||||
if err != nil {
|
||||
glog.Warningf(ctx, "Invalid state transition: %s -> %s for user %d, app %s",
|
||||
consts.GetStateDescription(fromState), consts.GetStateDescription(toState),
|
||||
in.UserId, adsData.AppPackage)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 插入或更新广告事件日志
|
||||
var eventId int64
|
||||
if isNewLifecycle {
|
||||
// 新的生命周期,创建新记录
|
||||
eventId, err = dao.AdEventLogs.Ctx(ctx).TX(tx).Data(do.AdEventLogs{
|
||||
UserId: in.UserId,
|
||||
AdsPlatId: adsData.AdsPlatId,
|
||||
AdsCategoryId: adsData.AdsCategoryId,
|
||||
AppPackage: adsData.AppPackage,
|
||||
Status: adsData.Status,
|
||||
StatusDesc: consts.GetStateDescription(toState),
|
||||
}).InsertAndGetId()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("database_save_failed")
|
||||
}
|
||||
} else {
|
||||
// 继续现有生命周期,更新状态
|
||||
_, err = dao.AdEventLogs.Ctx(ctx).TX(tx).
|
||||
Where("id", adEventId).
|
||||
Data(do.AdEventLogs{
|
||||
Status: adsData.Status,
|
||||
StatusDesc: consts.GetStateDescription(toState),
|
||||
}).
|
||||
Update()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("database_update_failed")
|
||||
}
|
||||
eventId = adEventId
|
||||
}
|
||||
|
||||
// 4. 插入状态流转记录
|
||||
var fromStatus interface{}
|
||||
if fromState != 0 {
|
||||
fromStatus = int(fromState)
|
||||
}
|
||||
|
||||
_, err = dao.AdEventTransitions.Ctx(ctx).TX(tx).Data(do.AdEventTransitions{
|
||||
EventId: eventId,
|
||||
FromStatus: fromStatus,
|
||||
ToStatus: adsData.Status,
|
||||
}).Insert()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("transition_save_failed")
|
||||
}
|
||||
|
||||
// 5. 如果状态是观看完成(StateWatched),则给用户增加积分
|
||||
if toState == consts.StateWatched {
|
||||
// 查询任务表中状态为1(启用)且任务类型为2(广告)的任务
|
||||
taskInfo, err := dao.Tasks.Ctx(ctx).TX(tx).
|
||||
Fields("id, reward_points").
|
||||
Where("task_type", 2).
|
||||
Where("status", 1).
|
||||
One()
|
||||
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "Failed to query ad task: %v", err)
|
||||
return ecode.Fail.Sub("task_query_failed")
|
||||
}
|
||||
|
||||
if !taskInfo.IsEmpty() {
|
||||
taskId := taskInfo["id"].Int64()
|
||||
rewardPoints := taskInfo["reward_points"].Uint()
|
||||
|
||||
if rewardPoints > 0 {
|
||||
// 更新用户积分
|
||||
_, err = dao.Users.Ctx(ctx).TX(tx).
|
||||
Where("id", in.UserId).
|
||||
Increment("points", rewardPoints)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "Failed to update user points: %v", err)
|
||||
return ecode.Fail.Sub("user_points_update_failed")
|
||||
}
|
||||
|
||||
// 记录积分日志
|
||||
_, err = dao.UserPointsLogs.Ctx(ctx).TX(tx).Data(do.UserPointsLogs{
|
||||
UserId: in.UserId,
|
||||
ChangeType: 2, // 2=收入(earn)
|
||||
PointsChange: int(rewardPoints),
|
||||
RelatedOrderId: eventId,
|
||||
Description: "观看广告奖励",
|
||||
}).Insert()
|
||||
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "Failed to create user points log: %v", err)
|
||||
return ecode.Fail.Sub("user_points_log_create_failed")
|
||||
}
|
||||
|
||||
// 记录任务日志
|
||||
_, err = dao.TaskLogs.Ctx(ctx).TX(tx).Data(do.TaskLogs{
|
||||
TaskId: taskId,
|
||||
UserId: in.UserId,
|
||||
RewardPoints: rewardPoints,
|
||||
}).Insert()
|
||||
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "Failed to create task log: %v", err)
|
||||
return ecode.Fail.Sub("task_log_create_failed")
|
||||
}
|
||||
|
||||
glog.Infof(ctx, "User %d earned %d points for watching ad", in.UserId, rewardPoints)
|
||||
}
|
||||
} else {
|
||||
glog.Warningf(ctx, "No active ad task found")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 构建MQTT消息
|
||||
mqttMessage := map[string]interface{}{
|
||||
"type": "ads",
|
||||
"node_uid": in.NodeUid,
|
||||
"device_code": in.DeviceCode,
|
||||
"data": map[string]interface{}{
|
||||
"ads_plat_id": adsData.AdsPlatId,
|
||||
"ads_category_id": adsData.AdsCategoryId,
|
||||
"app_package": adsData.AppPackage,
|
||||
"status": adsData.Status,
|
||||
"timestamp": time.Now().Unix(),
|
||||
},
|
||||
}
|
||||
|
||||
// 发送到MQTT
|
||||
s.publishToMQTT(ctx, mqttMessage)
|
||||
|
||||
return &model.AdsUploadOut{Success: true}, nil
|
||||
}
|
||||
|
||||
// generateFlowID 生成流转ID
|
||||
func generateFlowID(userID int64, appPackage string) string {
|
||||
return fmt.Sprintf("flow_%d_%s_%d", userID, appPackage, time.Now().Unix())
|
||||
}
|
||||
|
||||
// publishToMQTT 发送消息到MQTT
|
||||
func (s *sAds) publishToMQTT(ctx context.Context, message map[string]interface{}) {
|
||||
mqttClient := mqtt.GetMQTTClient("amazon_sqs")
|
||||
if mqttClient == nil {
|
||||
glog.Errorf(ctx, "MQTT client not initialized")
|
||||
return
|
||||
}
|
||||
|
||||
queueName := g.Cfg().MustGet(ctx, "sqs.ads").String()
|
||||
if queueName == "" {
|
||||
glog.Errorf(ctx, "MQTT queue name not configured")
|
||||
return
|
||||
}
|
||||
|
||||
err := mqttClient.Publish(ctx, queueName, message)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "Failed to publish message to MQTT: %v", err)
|
||||
} else {
|
||||
glog.Infof(ctx, "Message published to MQTT: %v", message)
|
||||
}
|
||||
}
|
||||
@ -62,8 +62,9 @@ func (s *sAdmin) Info(ctx context.Context, in *model.AdminInfoIn) (out *model.Ad
|
||||
return nil, ecode.Fail.Sub("admin_query_failed")
|
||||
}
|
||||
return &model.AdminInfoOut{
|
||||
AdminId: admin.Id,
|
||||
Id: admin.Id,
|
||||
Username: admin.Username,
|
||||
Role: consts.AdminRoleCode,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ func (s *sAuthor) List(ctx context.Context, in *model.AuthorListIn) (out *model.
|
||||
if in.Status != 0 {
|
||||
m = m.Where(dao.Authors.Columns().Status, in.Status)
|
||||
}
|
||||
if err = m.Page(in.Page, in.Size).ScanAndCount(&out.List, &out.Total, false); err != nil {
|
||||
if err = m.Page(in.Page, in.Size).WithAll().ScanAndCount(&out.List, &out.Total, false); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
@ -226,13 +226,8 @@ func (s *sAuthor) Delete(ctx context.Context, in *model.AuthorDelIn) (out *model
|
||||
|
||||
// Apply 允许用户申请成为作者
|
||||
func (s *sAuthor) Apply(ctx context.Context, in *model.AuthorApplyIn) (out *model.AuthorApplyOut, err error) {
|
||||
userIdVal := ctx.Value("id")
|
||||
userId, ok := userIdVal.(int64)
|
||||
if !ok || userId == 0 {
|
||||
return nil, ecode.Fail.Sub("user_id_invalid")
|
||||
}
|
||||
exist, err := dao.Authors.Ctx(ctx).
|
||||
Where(dao.Authors.Columns().UserId, userId).
|
||||
Where(dao.Authors.Columns().UserId, in.UserId).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("author_query_failed")
|
||||
@ -241,10 +236,10 @@ func (s *sAuthor) Apply(ctx context.Context, in *model.AuthorApplyIn) (out *mode
|
||||
return nil, ecode.Params.Sub("author_user_exists")
|
||||
}
|
||||
if _, err := dao.Authors.Ctx(ctx).Data(do.Authors{
|
||||
UserId: userId,
|
||||
UserId: in.UserId,
|
||||
PenName: in.PenName,
|
||||
Bio: in.Bio,
|
||||
Status: 1, // 默认正常
|
||||
Status: 2, // 默认禁用
|
||||
}).Insert(); err != nil {
|
||||
return nil, ecode.Fail.Sub("author_create_failed")
|
||||
}
|
||||
@ -252,17 +247,74 @@ func (s *sAuthor) Apply(ctx context.Context, in *model.AuthorApplyIn) (out *mode
|
||||
}
|
||||
func (s *sAuthor) Detail(ctx context.Context, in *model.AuthorDetailIn) (out *model.AuthorDetailOut, err error) {
|
||||
out = &model.AuthorDetailOut{}
|
||||
exist, err := dao.Authors.Ctx(ctx).
|
||||
WherePri(in.AuthorId).
|
||||
Exist()
|
||||
err = dao.Authors.Ctx(ctx).WherePri(in.AuthorId).WithAll().Scan(&out)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("author_query_failed")
|
||||
}
|
||||
if out == nil {
|
||||
return nil, ecode.NotFound.Sub("author_not_found")
|
||||
}
|
||||
userId := ctx.Value("id")
|
||||
if userId != nil {
|
||||
exist, err := dao.UserFollowAuthors.Ctx(ctx).
|
||||
Where(dao.UserFollowAuthors.Columns().UserId, userId).
|
||||
Where(dao.UserFollowAuthors.Columns().AuthorId, in.AuthorId).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("user_follow_author_query_failed")
|
||||
}
|
||||
out.IsFollowed = exist
|
||||
}
|
||||
// 查询作者作品数量
|
||||
out.WorksCount, err = dao.Books.Ctx(ctx).
|
||||
Where(dao.Books.Columns().AuthorId, in.AuthorId).
|
||||
Count()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("author_book_count_failed")
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AuthorInfo 获取作者信息
|
||||
func (s *sAuthor) AuthorInfo(ctx context.Context, in *model.AuthorInfoIn) (out *model.AuthorInfoOut, err error) {
|
||||
exist, err := dao.Authors.Ctx(ctx).Where(dao.Authors.Columns().UserId, in.UserId).Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("author_query_failed")
|
||||
}
|
||||
if !exist {
|
||||
return nil, ecode.NotFound.Sub("author_not_found")
|
||||
}
|
||||
if err = dao.Authors.Ctx(ctx).WherePri(in.AuthorId).WithAll().Scan(&out); err != nil {
|
||||
|
||||
var author struct {
|
||||
Id int64 `json:"id"`
|
||||
PenName string `json:"penName"`
|
||||
}
|
||||
err = dao.Authors.Ctx(ctx).Where(dao.Authors.Columns().UserId, in.UserId).Fields("id, pen_name").Scan(&author)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("author_query_failed")
|
||||
}
|
||||
return out, nil
|
||||
|
||||
return &model.AuthorInfoOut{
|
||||
Id: author.Id,
|
||||
PenName: author.PenName,
|
||||
Role: "author",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 审核作者申请(通过/拒绝)
|
||||
func (s *sAuthor) Review(ctx context.Context, in *model.AuthorReviewIn) (out *model.AuthorReviewOut, err error) {
|
||||
exist, err := dao.Authors.Ctx(ctx).WherePri(in.AuthorId).Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("author_query_failed")
|
||||
}
|
||||
if !exist {
|
||||
return nil, ecode.NotFound.Sub("author_not_found")
|
||||
}
|
||||
_, err = dao.Authors.Ctx(ctx).WherePri(in.AuthorId).Data(do.Authors{
|
||||
Status: in.Status,
|
||||
}).Update()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("author_review_failed")
|
||||
}
|
||||
return &model.AuthorReviewOut{Success: true}, nil
|
||||
}
|
||||
|
||||
@ -232,6 +232,9 @@ func (s *sBook) AppList(ctx context.Context, in *model.BookAppListIn) (out *mode
|
||||
if in.IsFeatured {
|
||||
m = m.Where(dao.Books.Columns().IsFeatured, 1)
|
||||
}
|
||||
if in.IsHot {
|
||||
m = m.Where(dao.Books.Columns().IsHot, 1)
|
||||
}
|
||||
if in.Sort != "" {
|
||||
m = m.Order(in.Sort)
|
||||
}
|
||||
@ -278,6 +281,30 @@ func (s *sBook) AppList(ctx context.Context, in *model.BookAppListIn) (out *mode
|
||||
out.List[i].MyRating = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 查询用户书架
|
||||
type shelfRow struct {
|
||||
BookId int64 `json:"bookId"`
|
||||
}
|
||||
shelves := make([]shelfRow, 0)
|
||||
err = dao.Bookshelves.Ctx(ctx).
|
||||
Fields("book_id").
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
WhereIn(dao.Bookshelves.Columns().BookId, bookIds).
|
||||
Scan(&shelves)
|
||||
if err == nil && len(shelves) > 0 {
|
||||
shelfMap := make(map[int64]bool, len(shelves))
|
||||
for _, s := range shelves {
|
||||
shelfMap[s.BookId] = true
|
||||
}
|
||||
for i := range out.List {
|
||||
out.List[i].IsInBookshelf = shelfMap[out.List[i].Id]
|
||||
}
|
||||
} else {
|
||||
for i := range out.List {
|
||||
out.List[i].IsInBookshelf = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
@ -323,7 +350,7 @@ func (s *sBook) AppRate(ctx context.Context, in *model.BookAppRateIn) (out *mode
|
||||
// 开启事务处理评分
|
||||
if err := dao.BookRatings.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
// 检查是否已经评分过
|
||||
exist, err := dao.BookRatings.Ctx(ctx).TX(tx).
|
||||
exist, err := dao.BookRatings.Ctx(ctx).
|
||||
Where(dao.BookRatings.Columns().UserId, in.UserId).
|
||||
Where(dao.BookRatings.Columns().BookId, in.BookId).
|
||||
Exist()
|
||||
@ -333,7 +360,7 @@ func (s *sBook) AppRate(ctx context.Context, in *model.BookAppRateIn) (out *mode
|
||||
|
||||
if exist {
|
||||
// 更新现有评分
|
||||
_, err = dao.BookRatings.Ctx(ctx).TX(tx).
|
||||
_, err = dao.BookRatings.Ctx(ctx).
|
||||
Where(dao.BookRatings.Columns().UserId, in.UserId).
|
||||
Where(dao.BookRatings.Columns().BookId, in.BookId).
|
||||
Data(do.BookRatings{
|
||||
@ -344,7 +371,7 @@ func (s *sBook) AppRate(ctx context.Context, in *model.BookAppRateIn) (out *mode
|
||||
}
|
||||
} else {
|
||||
// 创建新评分记录
|
||||
_, err = dao.BookRatings.Ctx(ctx).TX(tx).Data(do.BookRatings{
|
||||
_, err = dao.BookRatings.Ctx(ctx).Data(do.BookRatings{
|
||||
UserId: in.UserId,
|
||||
BookId: in.BookId,
|
||||
Score: in.Rating,
|
||||
@ -355,20 +382,22 @@ func (s *sBook) AppRate(ctx context.Context, in *model.BookAppRateIn) (out *mode
|
||||
}
|
||||
|
||||
// 重新计算书籍平均评分
|
||||
var avgRating float64
|
||||
err = dao.BookRatings.Ctx(ctx).TX(tx).
|
||||
var result struct {
|
||||
AvgRating float64 `json:"avg_rating"`
|
||||
}
|
||||
err = dao.BookRatings.Ctx(ctx).
|
||||
Where(dao.BookRatings.Columns().BookId, in.BookId).
|
||||
Fields("AVG(score) as avg_rating").
|
||||
Scan(&avgRating)
|
||||
Fields("COALESCE(AVG(" + dao.BookRatings.Columns().Score + "), 0) as avg_rating").
|
||||
Scan(&result)
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("rating_calculation_failed")
|
||||
}
|
||||
|
||||
// 更新书籍的平均评分
|
||||
_, err = dao.Books.Ctx(ctx).TX(tx).
|
||||
_, err = dao.Books.Ctx(ctx).
|
||||
Where(dao.Books.Columns().Id, in.BookId).
|
||||
Data(do.Books{
|
||||
Rating: avgRating,
|
||||
Rating: result.AvgRating,
|
||||
}).Update()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("book_rating_update_failed")
|
||||
@ -397,7 +426,7 @@ func (s *sBook) AppDetail(ctx context.Context, in *model.BookAppDetailIn) (out *
|
||||
m = m.Where(dao.Books.Columns().Id, in.Id)
|
||||
|
||||
// 执行查询
|
||||
if err = m.Scan(out); err != nil {
|
||||
if err = m.WithAll().Scan(out); err != nil {
|
||||
return nil, ecode.Fail.Sub("book_query_failed")
|
||||
}
|
||||
|
||||
@ -408,6 +437,29 @@ func (s *sBook) AppDetail(ctx context.Context, in *model.BookAppDetailIn) (out *
|
||||
|
||||
// 如果用户已登录,查询阅读进度
|
||||
if in.UserId > 0 {
|
||||
// 查询用户是否已将本书加入书架
|
||||
count, err := dao.Bookshelves.Ctx(ctx).
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
Where(dao.Bookshelves.Columns().BookId, in.Id).
|
||||
Count()
|
||||
if err == nil {
|
||||
out.IsInBookshelf = count > 0
|
||||
}
|
||||
|
||||
// 查询用户是否已评分
|
||||
var ratingRecord struct {
|
||||
Score float64 `json:"score"`
|
||||
}
|
||||
err = dao.BookRatings.Ctx(ctx).
|
||||
Fields("score").
|
||||
Where(dao.BookRatings.Columns().UserId, in.UserId).
|
||||
Where(dao.BookRatings.Columns().BookId, in.Id).
|
||||
Scan(&ratingRecord)
|
||||
if err == nil && ratingRecord.Score > 0 {
|
||||
out.HasRated = true
|
||||
out.MyRating = ratingRecord.Score
|
||||
}
|
||||
|
||||
// 查询用户对该书籍的历史记录
|
||||
var historyRecord struct {
|
||||
ChapterId int64 `json:"chapterId"`
|
||||
@ -435,7 +487,7 @@ func (s *sBook) AppDetail(ctx context.Context, in *model.BookAppDetailIn) (out *
|
||||
readChapters, err := dao.UserReadRecords.Ctx(ctx).
|
||||
Where(dao.UserReadRecords.Columns().UserId, in.UserId).
|
||||
Where(dao.UserReadRecords.Columns().BookId, in.Id).
|
||||
Where(dao.UserReadRecords.Columns().ChapterId, ">", 0). // 只统计有章节ID的记录
|
||||
WhereGT(dao.UserReadRecords.Columns().ChapterId, 0). // 只统计有章节ID的记录
|
||||
Count()
|
||||
|
||||
if err == nil {
|
||||
@ -454,274 +506,174 @@ func (s *sBook) AppDetail(ctx context.Context, in *model.BookAppDetailIn) (out *
|
||||
func (s *sBook) MyList(ctx context.Context, in *model.MyBookListIn) (out *model.MyBookListOut, err error) {
|
||||
out = &model.MyBookListOut{}
|
||||
|
||||
// 验证用户ID
|
||||
if in.UserId == 0 {
|
||||
return nil, ecode.Fail.Sub("user_id_required")
|
||||
}
|
||||
|
||||
// 验证类型参数
|
||||
if in.Type < 1 || in.Type > 3 {
|
||||
return nil, ecode.Fail.Sub("type_invalid")
|
||||
}
|
||||
|
||||
var list []model.MyBookItem
|
||||
var total int
|
||||
var (
|
||||
ids []int64
|
||||
extraMap map[int64]struct {
|
||||
Progress int
|
||||
LastReadAt string
|
||||
}
|
||||
total int
|
||||
)
|
||||
|
||||
switch in.Type {
|
||||
case 1: // 正在读
|
||||
// 查询书架表中read_status=1的记录
|
||||
case 1, 2:
|
||||
var bookshelves []struct {
|
||||
BookId int64 `json:"bookId"`
|
||||
LastReadPercent float64 `json:"lastReadPercent"`
|
||||
LastReadAt string `json:"lastReadAt"`
|
||||
}
|
||||
|
||||
if in.Sort != "" {
|
||||
err = dao.Bookshelves.Ctx(ctx).
|
||||
Fields("book_id, last_read_percent, last_read_at").
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
Where(dao.Bookshelves.Columns().ReadStatus, 1).
|
||||
Order(in.Sort).
|
||||
Page(in.Page, in.Size).
|
||||
ScanAndCount(&bookshelves, &total, false)
|
||||
} else {
|
||||
err = dao.Bookshelves.Ctx(ctx).
|
||||
Fields("book_id, last_read_percent, last_read_at").
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
Where(dao.Bookshelves.Columns().ReadStatus, 1).
|
||||
Page(in.Page, in.Size).
|
||||
ScanAndCount(&bookshelves, &total, false)
|
||||
readStatus := 1
|
||||
if in.Type == 2 {
|
||||
readStatus = 2
|
||||
}
|
||||
q := dao.Bookshelves.Ctx(ctx).
|
||||
Fields("book_id, last_read_percent, last_read_at").
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
Where(dao.Bookshelves.Columns().ReadStatus, readStatus)
|
||||
if in.Sort != "" {
|
||||
q = q.Order(in.Sort)
|
||||
} else {
|
||||
q = q
|
||||
}
|
||||
err = q.Page(in.Page, in.Size).ScanAndCount(&bookshelves, &total, false)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("bookshelf_query_failed")
|
||||
}
|
||||
|
||||
// 获取书籍详细信息
|
||||
if len(bookshelves) > 0 {
|
||||
bookIds := make([]int64, 0, len(bookshelves))
|
||||
for _, bs := range bookshelves {
|
||||
bookIds = append(bookIds, bs.BookId)
|
||||
}
|
||||
|
||||
var books []model.Book
|
||||
err = dao.Books.Ctx(ctx).
|
||||
WhereIn(dao.Books.Columns().Id, bookIds).
|
||||
Scan(&books)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_query_failed")
|
||||
}
|
||||
|
||||
// 构建书籍ID到书架信息的映射
|
||||
bookshelfMap := make(map[int64]struct {
|
||||
LastReadPercent float64
|
||||
LastReadAt string
|
||||
})
|
||||
for _, bs := range bookshelves {
|
||||
bookshelfMap[bs.BookId] = struct {
|
||||
LastReadPercent float64
|
||||
LastReadAt string
|
||||
}{
|
||||
LastReadPercent: bs.LastReadPercent,
|
||||
LastReadAt: bs.LastReadAt,
|
||||
}
|
||||
}
|
||||
|
||||
// 构建返回列表
|
||||
for _, book := range books {
|
||||
bsInfo := bookshelfMap[book.Id]
|
||||
list = append(list, model.MyBookItem{
|
||||
Id: book.Id,
|
||||
Title: book.Title,
|
||||
CoverUrl: book.CoverUrl,
|
||||
Description: book.Description,
|
||||
Progress: int(bsInfo.LastReadPercent),
|
||||
IsInShelf: true,
|
||||
LastReadAt: bsInfo.LastReadAt,
|
||||
Status: book.Status,
|
||||
AuthorId: book.AuthorId,
|
||||
CategoryId: book.CategoryId,
|
||||
})
|
||||
ids = make([]int64, 0, len(bookshelves))
|
||||
extraMap = make(map[int64]struct {
|
||||
Progress int
|
||||
LastReadAt string
|
||||
}, len(bookshelves))
|
||||
for _, bs := range bookshelves {
|
||||
ids = append(ids, bs.BookId)
|
||||
extraMap[bs.BookId] = struct {
|
||||
Progress int
|
||||
LastReadAt string
|
||||
}{
|
||||
Progress: int(bs.LastReadPercent),
|
||||
LastReadAt: bs.LastReadAt,
|
||||
}
|
||||
}
|
||||
|
||||
case 2: // 已读完
|
||||
// 查询书架表中read_status=2的记录
|
||||
var bookshelves []struct {
|
||||
BookId int64 `json:"bookId"`
|
||||
LastReadPercent float64 `json:"lastReadPercent"`
|
||||
LastReadAt string `json:"lastReadAt"`
|
||||
}
|
||||
|
||||
if in.Sort != "" {
|
||||
err = dao.Bookshelves.Ctx(ctx).
|
||||
Fields("book_id, last_read_percent, last_read_at").
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
Where(dao.Bookshelves.Columns().ReadStatus, 2).
|
||||
Order(in.Sort).
|
||||
Page(in.Page, in.Size).
|
||||
ScanAndCount(&bookshelves, &total, false)
|
||||
} else {
|
||||
err = dao.Bookshelves.Ctx(ctx).
|
||||
Fields("book_id, last_read_percent, last_read_at").
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
Where(dao.Bookshelves.Columns().ReadStatus, 2).
|
||||
Page(in.Page, in.Size).
|
||||
ScanAndCount(&bookshelves, &total, false)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("bookshelf_query_failed")
|
||||
}
|
||||
|
||||
// 获取书籍详细信息
|
||||
if len(bookshelves) > 0 {
|
||||
bookIds := make([]int64, 0, len(bookshelves))
|
||||
for _, bs := range bookshelves {
|
||||
bookIds = append(bookIds, bs.BookId)
|
||||
}
|
||||
|
||||
var books []model.Book
|
||||
err = dao.Books.Ctx(ctx).
|
||||
WhereIn(dao.Books.Columns().Id, bookIds).
|
||||
Scan(&books)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_query_failed")
|
||||
}
|
||||
|
||||
// 构建书籍ID到书架信息的映射
|
||||
bookshelfMap := make(map[int64]struct {
|
||||
LastReadPercent float64
|
||||
LastReadAt string
|
||||
})
|
||||
for _, bs := range bookshelves {
|
||||
bookshelfMap[bs.BookId] = struct {
|
||||
LastReadPercent float64
|
||||
LastReadAt string
|
||||
}{
|
||||
LastReadPercent: bs.LastReadPercent,
|
||||
LastReadAt: bs.LastReadAt,
|
||||
}
|
||||
}
|
||||
|
||||
// 构建返回列表
|
||||
for _, book := range books {
|
||||
bsInfo := bookshelfMap[book.Id]
|
||||
list = append(list, model.MyBookItem{
|
||||
Id: book.Id,
|
||||
Title: book.Title,
|
||||
CoverUrl: book.CoverUrl,
|
||||
Description: book.Description,
|
||||
Progress: int(bsInfo.LastReadPercent),
|
||||
IsInShelf: true,
|
||||
LastReadAt: bsInfo.LastReadAt,
|
||||
Status: book.Status,
|
||||
AuthorId: book.AuthorId,
|
||||
CategoryId: book.CategoryId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
case 3: // 历史记录
|
||||
// 查询user_read_history表
|
||||
case 3:
|
||||
var histories []struct {
|
||||
BookId int64 `json:"bookId"`
|
||||
ChapterId int64 `json:"chapterId"`
|
||||
ReadAt string `json:"readAt"`
|
||||
}
|
||||
|
||||
q := dao.UserReadHistory.Ctx(ctx).
|
||||
Fields("book_id, chapter_id, read_at").
|
||||
Where(dao.UserReadHistory.Columns().UserId, in.UserId)
|
||||
if in.Sort != "" {
|
||||
err = dao.UserReadHistory.Ctx(ctx).
|
||||
Fields("book_id, chapter_id, read_at").
|
||||
Where(dao.UserReadHistory.Columns().UserId, in.UserId).
|
||||
Order(in.Sort).
|
||||
Page(in.Page, in.Size).
|
||||
ScanAndCount(&histories, &total, false)
|
||||
q = q.Order(in.Sort)
|
||||
} else {
|
||||
err = dao.UserReadHistory.Ctx(ctx).
|
||||
Fields("book_id, chapter_id, read_at").
|
||||
Where(dao.UserReadHistory.Columns().UserId, in.UserId).
|
||||
OrderDesc(dao.UserReadHistory.Columns().ReadAt).
|
||||
Page(in.Page, in.Size).
|
||||
ScanAndCount(&histories, &total, false)
|
||||
q = q.OrderDesc(dao.UserReadHistory.Columns().ReadAt)
|
||||
}
|
||||
err = q.Page(in.Page, in.Size).ScanAndCount(&histories, &total, false)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("history_query_failed")
|
||||
}
|
||||
|
||||
// 获取书籍详细信息
|
||||
if len(histories) > 0 {
|
||||
bookIds := make([]int64, 0, len(histories))
|
||||
for _, history := range histories {
|
||||
bookIds = append(bookIds, history.BookId)
|
||||
}
|
||||
|
||||
var books []model.Book
|
||||
err = dao.Books.Ctx(ctx).
|
||||
WhereIn(dao.Books.Columns().Id, bookIds).
|
||||
Scan(&books)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_query_failed")
|
||||
}
|
||||
|
||||
// 构建书籍ID到历史信息的映射
|
||||
historyMap := make(map[int64]struct {
|
||||
ChapterId int64
|
||||
ReadAt string
|
||||
})
|
||||
for _, history := range histories {
|
||||
historyMap[history.BookId] = struct {
|
||||
ChapterId int64
|
||||
ReadAt string
|
||||
}{
|
||||
ChapterId: history.ChapterId,
|
||||
ReadAt: history.ReadAt,
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否在书架中
|
||||
var bookshelves []struct {
|
||||
BookId int64 `json:"bookId"`
|
||||
}
|
||||
err = dao.Bookshelves.Ctx(ctx).
|
||||
Fields("book_id").
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
WhereIn(dao.Bookshelves.Columns().BookId, bookIds).
|
||||
Scan(&bookshelves)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("bookshelf_query_failed")
|
||||
}
|
||||
|
||||
// 构建书架ID集合
|
||||
shelfBookIds := make(map[int64]bool)
|
||||
for _, bs := range bookshelves {
|
||||
shelfBookIds[bs.BookId] = true
|
||||
}
|
||||
|
||||
// 构建返回列表
|
||||
for _, book := range books {
|
||||
historyInfo := historyMap[book.Id]
|
||||
list = append(list, model.MyBookItem{
|
||||
Id: book.Id,
|
||||
Title: book.Title,
|
||||
CoverUrl: book.CoverUrl,
|
||||
Description: book.Description,
|
||||
Progress: 0, // 历史记录不显示进度
|
||||
IsInShelf: shelfBookIds[book.Id],
|
||||
LastReadAt: historyInfo.ReadAt,
|
||||
Status: book.Status,
|
||||
AuthorId: book.AuthorId,
|
||||
CategoryId: book.CategoryId,
|
||||
})
|
||||
ids = make([]int64, 0, len(histories))
|
||||
extraMap = make(map[int64]struct {
|
||||
Progress int
|
||||
LastReadAt string
|
||||
}, len(histories))
|
||||
for _, h := range histories {
|
||||
ids = append(ids, h.BookId)
|
||||
extraMap[h.BookId] = struct {
|
||||
Progress int
|
||||
LastReadAt string
|
||||
}{
|
||||
Progress: 0,
|
||||
LastReadAt: h.ReadAt,
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
// 返回空列表
|
||||
}
|
||||
|
||||
out = &model.MyBookListOut{
|
||||
Total: total,
|
||||
List: list,
|
||||
var books []model.MyBookItem
|
||||
if len(ids) > 0 {
|
||||
err = dao.Books.Ctx(ctx).WhereIn(dao.Books.Columns().Id, ids).Scan(&books)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_query_failed")
|
||||
}
|
||||
}
|
||||
|
||||
// type3 需要查书架
|
||||
shelfBookIds := map[int64]bool{}
|
||||
if in.Type == 3 && len(ids) > 0 {
|
||||
var bookshelves []struct{ BookId int64 }
|
||||
err = dao.Bookshelves.Ctx(ctx).
|
||||
Fields("book_id").
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
WhereIn(dao.Bookshelves.Columns().BookId, ids).
|
||||
Scan(&bookshelves)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("bookshelf_query_failed")
|
||||
}
|
||||
for _, bs := range bookshelves {
|
||||
shelfBookIds[bs.BookId] = true
|
||||
}
|
||||
}
|
||||
|
||||
for i := range books {
|
||||
if info, ok := extraMap[books[i].Id]; ok {
|
||||
books[i].Progress = info.Progress
|
||||
books[i].LastReadAt = info.LastReadAt
|
||||
}
|
||||
if in.Type == 1 || in.Type == 2 {
|
||||
books[i].IsInShelf = true
|
||||
} else if in.Type == 3 {
|
||||
books[i].IsInShelf = shelfBookIds[books[i].Id]
|
||||
}
|
||||
}
|
||||
|
||||
// 查询用户评分信息
|
||||
if len(books) > 0 {
|
||||
bookIds := make([]int64, 0, len(books))
|
||||
for _, book := range books {
|
||||
bookIds = append(bookIds, book.Id)
|
||||
}
|
||||
|
||||
type ratingRow struct {
|
||||
BookId int64 `json:"bookId"`
|
||||
Score float64 `json:"score"`
|
||||
}
|
||||
ratings := make([]ratingRow, 0)
|
||||
err = dao.BookRatings.Ctx(ctx).
|
||||
Fields("book_id, score").
|
||||
Where(dao.BookRatings.Columns().UserId, in.UserId).
|
||||
WhereIn(dao.BookRatings.Columns().BookId, bookIds).
|
||||
Scan(&ratings)
|
||||
if err == nil && len(ratings) > 0 {
|
||||
ratingMap := make(map[int64]float64, len(ratings))
|
||||
for _, r := range ratings {
|
||||
ratingMap[r.BookId] = r.Score
|
||||
}
|
||||
for i := range books {
|
||||
if score, ok := ratingMap[books[i].Id]; ok {
|
||||
books[i].HasRated = true
|
||||
books[i].MyRating = score
|
||||
} else {
|
||||
books[i].HasRated = false
|
||||
books[i].MyRating = 0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i := range books {
|
||||
books[i].HasRated = false
|
||||
books[i].MyRating = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.Total = total
|
||||
out.List = books
|
||||
return
|
||||
}
|
||||
|
||||
@ -762,3 +714,22 @@ func (s *sBook) SetRecommended(ctx context.Context, in *model.BookSetRecommended
|
||||
}
|
||||
return &model.BookCRUDOut{Success: true}, nil
|
||||
}
|
||||
|
||||
// SetHot: 单独修改书籍的热门状态
|
||||
func (s *sBook) SetHot(ctx context.Context, in *model.BookSetHotIn) (out *model.BookCRUDOut, err error) {
|
||||
// 检查书籍是否存在
|
||||
exist, err := dao.Books.Ctx(ctx).WherePri(in.Id).Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_query_failed")
|
||||
}
|
||||
if !exist {
|
||||
return nil, ecode.NotFound.Sub("book_not_found")
|
||||
}
|
||||
_, err = dao.Books.Ctx(ctx).WherePri(in.Id).Data(do.Books{
|
||||
IsHot: in.IsHot,
|
||||
}).Update()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_update_failed")
|
||||
}
|
||||
return &model.BookCRUDOut{Success: true}, nil
|
||||
}
|
||||
|
||||
226
internal/logic/book_recommendations/book_recommendations.go
Normal file
226
internal/logic/book_recommendations/book_recommendations.go
Normal file
@ -0,0 +1,226 @@
|
||||
package book_recommendations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"server/internal/dao"
|
||||
"server/internal/model"
|
||||
"server/internal/model/do"
|
||||
"server/internal/service"
|
||||
"server/utility/ecode"
|
||||
"server/utility/oss"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
type sBookRecommendations struct{}
|
||||
|
||||
func New() service.IBookRecommendations {
|
||||
return &sBookRecommendations{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
service.RegisterBookRecommendations(New())
|
||||
}
|
||||
|
||||
// List 获取推荐列表
|
||||
func (s *sBookRecommendations) List(ctx context.Context, in *model.BookRecommendationsListIn) (out *model.BookRecommendationsListOut, err error) {
|
||||
out = &model.BookRecommendationsListOut{}
|
||||
m := dao.BookRecommendations.Ctx(ctx)
|
||||
if in.Type != 0 {
|
||||
m = m.Where(dao.BookRecommendations.Columns().Type, in.Type)
|
||||
}
|
||||
if in.Status != 0 {
|
||||
m = m.Where(dao.BookRecommendations.Columns().Status, in.Status)
|
||||
}
|
||||
if in.BookId != 0 {
|
||||
m = m.Where(dao.BookRecommendations.Columns().BookId, in.BookId)
|
||||
}
|
||||
m = m.Order(dao.BookRecommendations.Columns().SortOrder)
|
||||
if err = m.Page(in.Page, in.Size).WithAll().ScanAndCount(&out.List, &out.Total, false); err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_query_failed")
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AppList 获取APP端推荐列表
|
||||
func (s *sBookRecommendations) AppList(ctx context.Context, in *model.BookRecommendationsListIn) (out *model.BookRecommendationsAppListOut, err error) {
|
||||
out = &model.BookRecommendationsAppListOut{}
|
||||
m := dao.BookRecommendations.Ctx(ctx)
|
||||
// 直接筛选状态为1的记录
|
||||
m = m.Where(dao.BookRecommendations.Columns().Status, 1)
|
||||
// 根据排序字段排序
|
||||
m = m.Order(dao.BookRecommendations.Columns().SortOrder)
|
||||
var list []model.RecommendAppItem
|
||||
if err = m.Page(in.Page, in.Size).ScanAndCount(&list, &out.Total, false); err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_query_failed")
|
||||
}
|
||||
out.List = list
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Create 新增推荐
|
||||
func (s *sBookRecommendations) Create(ctx context.Context, in *model.BookRecommendationsCreateIn) (out *model.BookRecommendationsCRUDOut, err error) {
|
||||
// 检查同类型同书籍是否已存在(未软删除)
|
||||
exist, err := dao.BookRecommendations.Ctx(ctx).
|
||||
Where(dao.BookRecommendations.Columns().BookId, in.BookId).
|
||||
Where(dao.BookRecommendations.Columns().Type, in.Type).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_query_failed")
|
||||
}
|
||||
if exist {
|
||||
return nil, ecode.Params.Sub("book_recommendation_exists")
|
||||
}
|
||||
// 插入数据
|
||||
_, err = dao.BookRecommendations.Ctx(ctx).Data(do.BookRecommendations{
|
||||
BookId: in.BookId,
|
||||
Type: in.Type,
|
||||
CoverUrl: in.CoverUrl,
|
||||
SortOrder: in.SortOrder,
|
||||
Status: in.Status,
|
||||
}).Insert()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_create_failed")
|
||||
}
|
||||
return &model.BookRecommendationsCRUDOut{Success: true}, nil
|
||||
}
|
||||
|
||||
// Update 编辑推荐
|
||||
func (s *sBookRecommendations) Update(ctx context.Context, in *model.BookRecommendationsUpdateIn) (out *model.BookRecommendationsCRUDOut, err error) {
|
||||
// 检查是否存在
|
||||
exist, err := dao.BookRecommendations.Ctx(ctx).
|
||||
Where(dao.BookRecommendations.Columns().Id, in.Id).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_query_failed")
|
||||
}
|
||||
if !exist {
|
||||
return nil, ecode.NotFound.Sub("book_recommendation_not_found")
|
||||
}
|
||||
// 检查同类型同书籍是否有重复(排除自己)
|
||||
repeat, err := dao.BookRecommendations.Ctx(ctx).
|
||||
Where(dao.BookRecommendations.Columns().BookId, in.BookId).
|
||||
Where(dao.BookRecommendations.Columns().Type, in.Type).
|
||||
WhereNot(dao.BookRecommendations.Columns().Id, in.Id).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_query_failed")
|
||||
}
|
||||
if repeat {
|
||||
return nil, ecode.Params.Sub("book_recommendation_exists")
|
||||
}
|
||||
_, err = dao.BookRecommendations.Ctx(ctx).
|
||||
Where(dao.BookRecommendations.Columns().Id, in.Id).
|
||||
Data(do.BookRecommendations{
|
||||
BookId: in.BookId,
|
||||
Type: in.Type,
|
||||
CoverUrl: in.CoverUrl,
|
||||
SortOrder: in.SortOrder,
|
||||
Status: in.Status,
|
||||
}).Update()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_update_failed")
|
||||
}
|
||||
return &model.BookRecommendationsCRUDOut{Success: true}, nil
|
||||
}
|
||||
|
||||
// Delete 删除推荐
|
||||
func (s *sBookRecommendations) Delete(ctx context.Context, in *model.BookRecommendationsDeleteIn) (out *model.BookRecommendationsCRUDOut, err error) {
|
||||
// 检查是否存在
|
||||
exist, err := dao.BookRecommendations.Ctx(ctx).
|
||||
Where(dao.BookRecommendations.Columns().Id, in.Id).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_query_failed")
|
||||
}
|
||||
if !exist {
|
||||
return nil, ecode.NotFound.Sub("book_recommendation_not_found")
|
||||
}
|
||||
// 直接调用 Delete
|
||||
_, err = dao.BookRecommendations.Ctx(ctx).
|
||||
Where(dao.BookRecommendations.Columns().Id, in.Id).
|
||||
Delete()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_delete_failed")
|
||||
}
|
||||
return &model.BookRecommendationsCRUDOut{Success: true}, nil
|
||||
}
|
||||
|
||||
// SetStatus 启用/禁用推荐
|
||||
func (s *sBookRecommendations) SetStatus(ctx context.Context, in *model.BookRecommendationsSetStatusIn) (out *model.BookRecommendationsCRUDOut, err error) {
|
||||
// 检查是否存在
|
||||
exist, err := dao.BookRecommendations.Ctx(ctx).
|
||||
Where(dao.BookRecommendations.Columns().Id, in.Id).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_query_failed")
|
||||
}
|
||||
if !exist {
|
||||
return nil, ecode.NotFound.Sub("book_recommendation_not_found")
|
||||
}
|
||||
_, err = dao.BookRecommendations.Ctx(ctx).
|
||||
Where(dao.BookRecommendations.Columns().Id, in.Id).
|
||||
Data(do.BookRecommendations{
|
||||
Status: in.Status,
|
||||
}).Update()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_update_failed")
|
||||
}
|
||||
return &model.BookRecommendationsCRUDOut{Success: true}, nil
|
||||
}
|
||||
|
||||
// SortOrder 设置排序
|
||||
func (s *sBookRecommendations) SortOrder(ctx context.Context, in *model.BookRecommendationsSortOrderIn) (out *model.BookRecommendationsCRUDOut, err error) {
|
||||
// 检查是否存在
|
||||
exist, err := dao.BookRecommendations.Ctx(ctx).
|
||||
Where(dao.BookRecommendations.Columns().Id, in.Id).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_query_failed")
|
||||
}
|
||||
if !exist {
|
||||
return nil, ecode.NotFound.Sub("book_recommendation_not_found")
|
||||
}
|
||||
_, err = dao.BookRecommendations.Ctx(ctx).
|
||||
Where(dao.BookRecommendations.Columns().Id, in.Id).
|
||||
Data(do.BookRecommendations{
|
||||
SortOrder: in.SortOrder,
|
||||
}).Update()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("book_recommendation_update_failed")
|
||||
}
|
||||
return &model.BookRecommendationsCRUDOut{Success: true}, nil
|
||||
}
|
||||
|
||||
// UploadCover 上传推荐封面图
|
||||
func (s *sBookRecommendations) UploadCover(ctx context.Context, file *ghttp.UploadFile) (url string, err error) {
|
||||
if file == nil {
|
||||
return "", ecode.Params.Sub("image_file_required")
|
||||
}
|
||||
// 校验文件类型(只允许图片)
|
||||
contentType := file.Header.Get("Content-Type")
|
||||
if contentType == "" || contentType[:6] != "image/" {
|
||||
return "", ecode.Params.Sub("image_type_invalid")
|
||||
}
|
||||
allowedTypes := map[string]bool{
|
||||
"image/jpeg": true,
|
||||
"image/png": true,
|
||||
"image/gif": true,
|
||||
"image/webp": true,
|
||||
}
|
||||
if !allowedTypes[contentType] {
|
||||
return "", ecode.Params.Sub("image_format_invalid")
|
||||
}
|
||||
if file.Size > 1*1024*1024 {
|
||||
return "", ecode.Params.Sub("image_size_exceeded")
|
||||
}
|
||||
client := oss.GetOSSClient("amazon_s3")
|
||||
if client == nil {
|
||||
return "", ecode.Fail.Sub("server_error")
|
||||
}
|
||||
url, err = client.Upload(file, "recommend")
|
||||
if err != nil {
|
||||
return "", ecode.Fail.Sub("image_upload_failed")
|
||||
}
|
||||
return url, nil
|
||||
}
|
||||
@ -55,3 +55,4 @@ func (s *sBookshelve) Delete(ctx context.Context, in *model.BookshelveDelIn) (ou
|
||||
}
|
||||
return &model.BookshelveCRUDOut{Success: true}, nil
|
||||
}
|
||||
|
||||
|
||||
@ -180,13 +180,34 @@ func (s *sChapter) AppList(ctx context.Context, in *model.ChapterAppListIn) (out
|
||||
return nil, ecode.Fail.Sub("read_record_query_failed")
|
||||
}
|
||||
|
||||
// 查询购买记录
|
||||
purchaseRecords := make([]struct {
|
||||
ChapterId int64 `json:"chapterId"`
|
||||
}, 0)
|
||||
|
||||
err = dao.UserChapterPurchases.Ctx(ctx).
|
||||
Fields("chapter_id").
|
||||
Where(dao.UserChapterPurchases.Columns().UserId, in.UserId).
|
||||
Where(dao.UserChapterPurchases.Columns().BookId, in.BookId).
|
||||
WhereIn(dao.UserChapterPurchases.Columns().ChapterId, chapterIds).
|
||||
Scan(&purchaseRecords)
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("purchase_record_query_failed")
|
||||
}
|
||||
|
||||
// 构建阅读记录映射
|
||||
readMap := make(map[int64]*gtime.Time)
|
||||
for _, record := range readRecords {
|
||||
readMap[record.ChapterId] = record.ReadAt
|
||||
}
|
||||
|
||||
// 为每个章节设置阅读进度
|
||||
// 构建购买记录映射
|
||||
purchaseMap := make(map[int64]bool)
|
||||
for _, record := range purchaseRecords {
|
||||
purchaseMap[record.ChapterId] = true
|
||||
}
|
||||
|
||||
// 为每个章节设置阅读进度和购买状态
|
||||
for i := range out.List {
|
||||
if readAt, exists := readMap[out.List[i].Id]; exists {
|
||||
out.List[i].ReadAt = readAt
|
||||
@ -195,6 +216,19 @@ func (s *sChapter) AppList(ctx context.Context, in *model.ChapterAppListIn) (out
|
||||
out.List[i].ReadProgress = 0 // 未读
|
||||
out.List[i].ReadAt = nil
|
||||
}
|
||||
|
||||
// 设置购买状态
|
||||
if out.List[i].IsLocked == 0 {
|
||||
// 免费章节,直接设置为已购买
|
||||
out.List[i].IsPurchased = true
|
||||
} else {
|
||||
// 付费章节,根据购买记录设置
|
||||
if purchaseMap[out.List[i].Id] {
|
||||
out.List[i].IsPurchased = true
|
||||
} else {
|
||||
out.List[i].IsPurchased = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -473,7 +507,7 @@ func (s *sChapter) AppProgress(ctx context.Context, in *model.ChapterAppProgress
|
||||
readChapters, err = dao.UserReadRecords.Ctx(ctx).TX(tx).
|
||||
Where(dao.UserReadRecords.Columns().UserId, in.UserId).
|
||||
Where(dao.UserReadRecords.Columns().BookId, in.BookId).
|
||||
Where(dao.UserReadRecords.Columns().ChapterId, ">", 0).
|
||||
WhereGT(dao.UserReadRecords.Columns().ChapterId, 0).
|
||||
Count()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("read_chapter_count_failed")
|
||||
@ -525,3 +559,211 @@ func (s *sChapter) AppProgress(ctx context.Context, in *model.ChapterAppProgress
|
||||
out.Success = true
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AppBatchProgress uploads batch reading progress for app
|
||||
func (s *sChapter) AppBatchProgress(ctx context.Context, in *model.ChapterAppBatchProgressIn) (out *model.ChapterAppProgressOut, err error) {
|
||||
out = &model.ChapterAppProgressOut{}
|
||||
|
||||
// 必须指定用户ID
|
||||
if in.UserId == 0 {
|
||||
return nil, ecode.Fail.Sub("user_id_required")
|
||||
}
|
||||
|
||||
// 必须指定书籍ID
|
||||
if in.BookId == 0 {
|
||||
return nil, ecode.Fail.Sub("book_id_required")
|
||||
}
|
||||
|
||||
// 必须指定章节列表
|
||||
if len(in.Chapters) == 0 {
|
||||
return nil, ecode.Fail.Sub("chapters_required")
|
||||
}
|
||||
|
||||
// 检查用户是否存在
|
||||
exist, err := dao.Users.Ctx(ctx).Where(dao.Users.Columns().Id, in.UserId).Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("user_query_failed")
|
||||
}
|
||||
if !exist {
|
||||
return nil, ecode.NotFound.Sub("user_not_found")
|
||||
}
|
||||
|
||||
// 验证所有章节进度
|
||||
for _, chapter := range in.Chapters {
|
||||
if chapter.ChapterId == 0 {
|
||||
return nil, ecode.Fail.Sub("chapter_id_required")
|
||||
}
|
||||
if chapter.Progress < 0 || chapter.Progress > 100 {
|
||||
return nil, ecode.Fail.Sub("progress_invalid")
|
||||
}
|
||||
}
|
||||
|
||||
// 检查所有章节是否存在
|
||||
chapterIds := make([]int64, 0)
|
||||
for _, chapter := range in.Chapters {
|
||||
chapterIds = append(chapterIds, chapter.ChapterId)
|
||||
}
|
||||
|
||||
exist, err = dao.Chapters.Ctx(ctx).
|
||||
WhereIn(dao.Chapters.Columns().Id, chapterIds).
|
||||
Where(dao.Chapters.Columns().BookId, in.BookId).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return nil, ecode.Fail.Sub("chapter_query_failed")
|
||||
}
|
||||
if !exist {
|
||||
return nil, ecode.NotFound.Sub("chapter_not_found")
|
||||
}
|
||||
|
||||
// 开启事务处理
|
||||
if err := dao.UserReadRecords.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
// 批量处理每个章节的进度
|
||||
for _, chapter := range in.Chapters {
|
||||
// 1. 更新或创建阅读记录
|
||||
exist, err := dao.UserReadRecords.Ctx(ctx).TX(tx).
|
||||
Where(dao.UserReadRecords.Columns().UserId, in.UserId).
|
||||
Where(dao.UserReadRecords.Columns().BookId, in.BookId).
|
||||
Where(dao.UserReadRecords.Columns().ChapterId, chapter.ChapterId).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("read_record_query_failed")
|
||||
}
|
||||
|
||||
if exist {
|
||||
// 更新现有记录
|
||||
_, err = dao.UserReadRecords.Ctx(ctx).TX(tx).
|
||||
Where(dao.UserReadRecords.Columns().UserId, in.UserId).
|
||||
Where(dao.UserReadRecords.Columns().BookId, in.BookId).
|
||||
Where(dao.UserReadRecords.Columns().ChapterId, chapter.ChapterId).
|
||||
Data(do.UserReadRecords{
|
||||
Progress: chapter.Progress,
|
||||
ReadAt: gtime.Now(),
|
||||
}).Update()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("read_record_update_failed")
|
||||
}
|
||||
} else {
|
||||
// 创建新记录
|
||||
_, err = dao.UserReadRecords.Ctx(ctx).TX(tx).Data(do.UserReadRecords{
|
||||
UserId: in.UserId,
|
||||
BookId: in.BookId,
|
||||
ChapterId: chapter.ChapterId,
|
||||
Progress: chapter.Progress,
|
||||
ReadAt: gtime.Now(),
|
||||
}).Insert()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("read_record_create_failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 更新或创建历史记录(使用最后一个章节作为当前阅读章节)
|
||||
lastChapter := in.Chapters[len(in.Chapters)-1]
|
||||
exist, err = dao.UserReadHistory.Ctx(ctx).TX(tx).
|
||||
Where(dao.UserReadHistory.Columns().UserId, in.UserId).
|
||||
Where(dao.UserReadHistory.Columns().BookId, in.BookId).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("history_query_failed")
|
||||
}
|
||||
|
||||
if exist {
|
||||
// 更新现有历史记录
|
||||
_, err = dao.UserReadHistory.Ctx(ctx).TX(tx).
|
||||
Where(dao.UserReadHistory.Columns().UserId, in.UserId).
|
||||
Where(dao.UserReadHistory.Columns().BookId, in.BookId).
|
||||
Data(do.UserReadHistory{
|
||||
ChapterId: lastChapter.ChapterId,
|
||||
ReadAt: gtime.Now(),
|
||||
}).Update()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("history_update_failed")
|
||||
}
|
||||
} else {
|
||||
// 创建新历史记录
|
||||
_, err = dao.UserReadHistory.Ctx(ctx).TX(tx).Data(do.UserReadHistory{
|
||||
UserId: in.UserId,
|
||||
BookId: in.BookId,
|
||||
ChapterId: lastChapter.ChapterId,
|
||||
ReadAt: gtime.Now(),
|
||||
}).Insert()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("history_create_failed")
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 更新书架记录(如果存在)
|
||||
exist, err = dao.Bookshelves.Ctx(ctx).TX(tx).
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
Where(dao.Bookshelves.Columns().BookId, in.BookId).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("bookshelf_query_failed")
|
||||
}
|
||||
|
||||
if exist {
|
||||
// 计算阅读进度百分比
|
||||
totalChapters, err := dao.Chapters.Ctx(ctx).TX(tx).
|
||||
Where(dao.Chapters.Columns().BookId, in.BookId).
|
||||
Count()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("chapter_count_failed")
|
||||
}
|
||||
|
||||
var readChapters int
|
||||
if totalChapters > 0 {
|
||||
readChapters, err = dao.UserReadRecords.Ctx(ctx).TX(tx).
|
||||
Where(dao.UserReadRecords.Columns().UserId, in.UserId).
|
||||
Where(dao.UserReadRecords.Columns().BookId, in.BookId).
|
||||
WhereGT(dao.UserReadRecords.Columns().ChapterId, 0).
|
||||
Count()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("read_chapter_count_failed")
|
||||
}
|
||||
}
|
||||
|
||||
readPercent := 0.0
|
||||
if totalChapters > 0 {
|
||||
readPercent = float64(readChapters) / float64(totalChapters) * 100
|
||||
if readPercent > 100 {
|
||||
readPercent = 100
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否为最后一章
|
||||
lastChapterInfo, err := dao.Chapters.Ctx(ctx).TX(tx).
|
||||
Where(dao.Chapters.Columns().BookId, in.BookId).
|
||||
OrderDesc(dao.Chapters.Columns().Sort).
|
||||
One()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("chapter_query_failed")
|
||||
}
|
||||
|
||||
readStatus := 1 // 默认为正在读
|
||||
if lastChapterInfo != nil && lastChapterInfo["id"].Int64() == lastChapter.ChapterId {
|
||||
readStatus = 2 // 如果是最后一章,标记为已读完
|
||||
}
|
||||
|
||||
// 更新书架记录
|
||||
_, err = dao.Bookshelves.Ctx(ctx).TX(tx).
|
||||
Where(dao.Bookshelves.Columns().UserId, in.UserId).
|
||||
Where(dao.Bookshelves.Columns().BookId, in.BookId).
|
||||
Data(do.Bookshelves{
|
||||
LastReadChapterId: lastChapter.ChapterId,
|
||||
LastReadPercent: readPercent,
|
||||
LastReadAt: gtime.Now(),
|
||||
ReadStatus: readStatus,
|
||||
}).Update()
|
||||
if err != nil {
|
||||
return ecode.Fail.Sub("bookshelf_update_failed")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out.Success = true
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@ -5,14 +5,22 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
_ "server/internal/logic/ad_event_logs"
|
||||
_ "server/internal/logic/admin"
|
||||
_ "server/internal/logic/author"
|
||||
_ "server/internal/logic/book"
|
||||
_ "server/internal/logic/book_recommendations"
|
||||
_ "server/internal/logic/bookshelve"
|
||||
_ "server/internal/logic/category"
|
||||
_ "server/internal/logic/chapter"
|
||||
_ "server/internal/logic/feedback"
|
||||
_ "server/internal/logic/sign_in_reward_details"
|
||||
_ "server/internal/logic/sign_in_reward_rules"
|
||||
_ "server/internal/logic/system"
|
||||
_ "server/internal/logic/task"
|
||||
_ "server/internal/logic/upload"
|
||||
_ "server/internal/logic/user"
|
||||
_ "server/internal/logic/user_follow_author"
|
||||
_ "server/internal/logic/user_read_record"
|
||||
_ "server/internal/logic/user_read_history"
|
||||
_ "server/internal/logic/user_sign_in_logs"
|
||||
)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user