初始化项目框架,完成部分接口开发

This commit is contained in:
2025-07-10 21:04:29 +08:00
commit b2871ec0d2
168 changed files with 6399 additions and 0 deletions

50
internal/cmd/cmd.go Normal file
View File

@ -0,0 +1,50 @@
package cmd
import (
"context"
"server/internal/controller/admin"
"server/internal/controller/auth"
"server/internal/controller/book"
"server/internal/controller/category"
"server/internal/controller/chapter"
"server/internal/controller/feedback"
"server/internal/controller/user"
"server/internal/middleware"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcmd"
)
var (
Main = gcmd.Command{
Name: "main",
Usage: "main",
Brief: "start http server",
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
s := g.Server()
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(middleware.Language) // 语言检测中间件
group.Middleware(middleware.Response)
group.Middleware(ghttp.MiddlewareCORS)
group.Bind(
auth.NewV1(),
)
group.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(middleware.Auth)
group.Middleware(middleware.Casbin)
group.Bind(
admin.NewV1(),
book.NewV1(),
category.NewV1(),
chapter.NewV1(),
feedback.NewV1(),
user.NewV1(),
)
})
})
s.Run()
return nil
},
}
)

View File

@ -0,0 +1 @@
package consts

8
internal/consts/role.go Normal file
View File

@ -0,0 +1,8 @@
package consts
const (
GuestRoleCode = "guest"
UserRoleCode = "user"
AuthorRoleCode = "author"
AdminRoleCode = "admin"
)

6
internal/consts/user.go Normal file
View File

@ -0,0 +1,6 @@
package consts
const (
UserEnable = iota + 1
UserDisable
)

View File

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package admin

View File

@ -0,0 +1,15 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package admin
import (
"server/api/admin"
)
type ControllerV1 struct{}
func NewV1() admin.IAdminV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,17 @@
package admin
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/admin/v1"
)
func (c *ControllerV1) AdminEditPass(ctx context.Context, req *v1.AdminEditPassReq) (res *v1.AdminEditPassRes, err error) {
out, err := service.Admin().EditPass(ctx, &model.AdminEditPassIn{NewPass: req.NewPass, OldPass: req.OldPass})
if err != nil {
return nil, err
}
return &v1.AdminEditPassRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,22 @@
package admin
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"server/internal/model"
"server/internal/service"
"server/api/admin/v1"
)
func (c *ControllerV1) AdminInfo(ctx context.Context, req *v1.AdminInfoReq) (res *v1.AdminInfoRes, err error) {
adminId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
out, err := service.Admin().Info(ctx, &model.AdminInfoIn{AdminId: adminId})
if err != nil {
return nil, err
}
return &v1.AdminInfoRes{
AdminId: out.AdminId,
Username: out.Username,
}, nil
}

View File

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package auth

View File

@ -0,0 +1,15 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package auth
import (
"server/api/auth"
)
type ControllerV1 struct{}
func NewV1() auth.IAuthV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,17 @@
package auth
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/auth/v1"
)
func (c *ControllerV1) AdminLogin(ctx context.Context, req *v1.AdminLoginReq) (res *v1.AdminLoginRes, err error) {
out, err := service.Admin().Login(ctx, &model.AdminLoginIn{Username: req.Username, Password: req.Password})
if err != nil {
return nil, err
}
return &v1.AdminLoginRes{Token: out.Token}, nil
}

View File

@ -0,0 +1,17 @@
package auth
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/auth/v1"
)
func (c *ControllerV1) UserCode(ctx context.Context, req *v1.UserCodeReq) (res *v1.UserCodeRes, err error) {
out, err := service.User().Code(ctx, &model.UserCodeIn{Email: req.Email})
if err != nil {
return nil, err
}
return &v1.UserCodeRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,17 @@
package auth
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/auth/v1"
)
func (c *ControllerV1) UserEditPass(ctx context.Context, req *v1.UserEditPassReq) (res *v1.UserEditPassRes, err error) {
out, err := service.User().EditPass(ctx, &model.UserEditPassIn{Email: req.Email, Password: req.Password, Password2: req.Password2, Sign: req.Sign})
if err != nil {
return nil, err
}
return &v1.UserEditPassRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,18 @@
package auth
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/auth/v1"
)
func (c *ControllerV1) UserLogin(ctx context.Context, req *v1.UserLoginReq) (res *v1.UserLoginRes, err error) {
out, err := service.User().Login(ctx, &model.UserLoginIn{Email: req.Email, Password: req.Password})
if err != nil {
return nil, err
}
return &v1.UserLoginRes{Token: out.Token}, nil
}

View File

@ -0,0 +1,17 @@
package auth
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/auth/v1"
)
func (c *ControllerV1) UserRegister(ctx context.Context, req *v1.UserRegisterReq) (res *v1.UserRegisterRes, err error) {
out, err := service.User().Register(ctx, &model.UserRegisterIn{Email: req.Email, Password: req.Password, Password2: req.Password2})
if err != nil {
return nil, err
}
return &v1.UserRegisterRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package book

View File

@ -0,0 +1,15 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package book
import (
"server/api/book"
)
type ControllerV1 struct{}
func NewV1() book.IBookV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,26 @@
package book
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/book/v1"
)
func (c *ControllerV1) BookAdd(ctx context.Context, req *v1.BookAddReq) (res *v1.BookAddRes, err error) {
out, err := service.Book().Create(ctx, &model.BookAddIn{
AuthorId: req.AuthorId,
CategoryId: req.CategoryId,
CoverUrl: req.CoverUrl,
Description: req.Description,
IsRecommended: req.IsRecommended,
Status: req.Status,
Tags: req.Tags,
Title: req.Title,
})
if err != nil {
return nil, err
}
return &v1.BookAddRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,19 @@
package book
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/book/v1"
)
func (c *ControllerV1) BookDel(ctx context.Context, req *v1.BookDelReq) (res *v1.BookDelRes, err error) {
out, err := service.Book().Delete(ctx, &model.BookDelIn{
Id: req.Id,
})
if err != nil {
return nil, err
}
return &v1.BookDelRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,27 @@
package book
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/book/v1"
)
func (c *ControllerV1) BookEdit(ctx context.Context, req *v1.BookEditReq) (res *v1.BookEditRes, err error) {
out, err := service.Book().Update(ctx, &model.BookEditIn{
AuthorId: req.AuthorId,
CategoryId: req.CategoryId,
CoverUrl: req.CoverUrl,
Description: req.Description,
Id: req.Id,
IsRecommended: req.IsRecommended,
Status: req.Status,
Tags: req.Tags,
Title: req.Title,
})
if err != nil {
return nil, err
}
return &v1.BookEditRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,28 @@
package book
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/book/v1"
)
func (c *ControllerV1) BookList(ctx context.Context, req *v1.BookListReq) (res *v1.BookListRes, err error) {
out, err := service.Book().List(ctx, &model.BookListIn{
AuthorId: req.AuthorId,
CategoryId: req.CategoryId,
IsRecommended: req.IsRecommended,
Page: req.Page,
Size: req.Size,
Status: req.Status,
Title: req.Title,
})
if err != nil {
return nil, err
}
return &v1.BookListRes{
List: out.List,
Total: out.Total,
}, nil
}

View File

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package category

View File

@ -0,0 +1,15 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package category
import (
"server/api/category"
)
type ControllerV1 struct{}
func NewV1() category.ICategoryV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,22 @@
package category
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/category/v1"
)
func (c *ControllerV1) CategoryAdd(ctx context.Context, req *v1.CategoryAddReq) (res *v1.CategoryAddRes, err error) {
out, err := service.Category().Create(ctx, &model.CategoryAddIn{
Name: req.Name,
Type: req.Type,
})
if err != nil {
return nil, err
}
return &v1.CategoryAddRes{
Success: out.Success,
}, nil
}

View File

@ -0,0 +1,21 @@
package category
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/category/v1"
)
func (c *ControllerV1) CategoryDel(ctx context.Context, req *v1.CategoryDelReq) (res *v1.CategoryDelRes, err error) {
out, err := service.Category().Delete(ctx, &model.CategoryDelIn{
Id: req.Id,
})
if err != nil {
return nil, err
}
return &v1.CategoryDelRes{
Success: out.Success,
}, nil
}

View File

@ -0,0 +1,23 @@
package category
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/category/v1"
)
func (c *ControllerV1) CategoryEdit(ctx context.Context, req *v1.CategoryEditReq) (res *v1.CategoryEditRes, err error) {
out, err := service.Category().Update(ctx, &model.CategoryEditIn{
Id: req.Id,
Name: req.Name,
Type: req.Type,
})
if err != nil {
return nil, err
}
return &v1.CategoryEditRes{
Success: out.Success,
}, nil
}

View File

@ -0,0 +1,25 @@
package category
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/category/v1"
)
func (c *ControllerV1) CategoryList(ctx context.Context, req *v1.CategoryListReq) (res *v1.CategoryListRes, err error) {
out, err := service.Category().List(ctx, &model.CategoryListIn{
Name: req.Name,
Page: req.Page,
Size: req.Size,
Type: req.Type,
})
if err != nil {
return nil, err
}
return &v1.CategoryListRes{
List: out.List,
Total: out.Total,
}, nil
}

View File

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package chapter

View File

@ -0,0 +1,15 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package chapter
import (
"server/api/chapter"
)
type ControllerV1 struct{}
func NewV1() chapter.IChapterV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,27 @@
package chapter
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/chapter/v1"
)
func (c *ControllerV1) ChapterAdd(ctx context.Context, req *v1.ChapterAddReq) (res *v1.ChapterAddRes, err error) {
out, err := service.Chapter().Create(ctx, &model.ChapterAddIn{
BookId: req.BookId,
Content: req.Content,
IsLocked: req.IsLocked,
RequiredScore: req.RequiredScore,
Sort: req.Sort,
Title: req.Title,
WordCount: req.WordCount,
})
if err != nil {
return nil, err
}
return &v1.ChapterAddRes{
Success: out.Success,
}, nil
}

View File

@ -0,0 +1,19 @@
package chapter
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/chapter/v1"
)
func (c *ControllerV1) ChapterDel(ctx context.Context, req *v1.ChapterDelReq) (res *v1.ChapterDelRes, err error) {
out, err := service.Chapter().Delete(ctx, &model.ChapterDelIn{
Id: req.Id,
})
if err != nil {
return nil, err
}
return &v1.ChapterDelRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,28 @@
package chapter
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/chapter/v1"
)
func (c *ControllerV1) ChapterEdit(ctx context.Context, req *v1.ChapterEditReq) (res *v1.ChapterEditRes, err error) {
out, err := service.Chapter().Update(ctx, &model.ChapterEditIn{
BookId: req.BookId,
Content: req.Content,
Id: req.Id,
IsLocked: req.IsLocked,
RequiredScore: req.RequiredScore,
Sort: req.Sort,
Title: req.Title,
WordCount: req.WordCount,
})
if err != nil {
return nil, err
}
return &v1.ChapterEditRes{
Success: out.Success,
}, nil
}

View File

@ -0,0 +1,26 @@
package chapter
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/chapter/v1"
)
func (c *ControllerV1) ChapterList(ctx context.Context, req *v1.ChapterListReq) (res *v1.ChapterListRes, err error) {
out, err := service.Chapter().List(ctx, &model.ChapterListIn{
BookId: req.BookId,
IsLocked: req.IsLocked,
Page: req.Page,
Size: req.Size,
Title: req.Title,
})
if err != nil {
return nil, err
}
return &v1.ChapterListRes{
List: out.List,
Total: out.Total,
}, nil
}

View File

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package feedback

View File

@ -0,0 +1,15 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package feedback
import (
"server/api/feedback"
)
type ControllerV1 struct{}
func NewV1() feedback.IFeedbackV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,24 @@
package feedback
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"server/internal/model"
"server/internal/service"
"server/api/feedback/v1"
)
func (c *ControllerV1) FeedbackAdd(ctx context.Context, req *v1.FeedbackAddReq) (res *v1.FeedbackAddRes, err error) {
userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
out, err := service.Feedback().Create(ctx, &model.FeedbackAddIn{
Content: req.Content,
UserId: userId,
})
if err != nil {
return nil, err
}
return &v1.FeedbackAddRes{
Success: out.Success,
}, nil
}

View File

@ -0,0 +1,25 @@
package feedback
import (
"context"
"server/internal/model"
"server/internal/service"
"server/api/feedback/v1"
)
func (c *ControllerV1) FeedbackList(ctx context.Context, req *v1.FeedbackListReq) (res *v1.FeedbackListRes, err error) {
out, err := service.Feedback().List(ctx, &model.FeedbackListIn{
Page: req.Page,
Size: req.Size,
Status: req.Status,
UserId: req.UserId,
})
if err != nil {
return nil, err
}
return &v1.FeedbackListRes{
List: out.List,
Total: out.Total,
}, nil
}

View File

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package user

View File

@ -0,0 +1,15 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package user
import (
"server/api/user"
)
type ControllerV1 struct{}
func NewV1() user.IUserV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,19 @@
package user
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"server/internal/model"
"server/internal/service"
"server/api/user/v1"
)
func (c *ControllerV1) Delete(ctx context.Context, req *v1.DeleteReq) (res *v1.DeleteRes, err error) {
userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
out, err := service.User().Delete(ctx, &model.UserDeleteIn{UserId: userId, Password: req.Password})
if err != nil {
return nil, err
}
return &v1.DeleteRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,14 @@
package user
import (
"context"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"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)
}

View File

@ -0,0 +1,24 @@
package user
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"server/internal/model"
"server/internal/service"
"server/api/user/v1"
)
func (c *ControllerV1) UserInfo(ctx context.Context, req *v1.UserInfoReq) (res *v1.UserInfoRes, err error) {
userId := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
info, err := service.User().Info(ctx, &model.UserInfoIn{UserId: userId})
if err != nil {
return nil, err
}
return &v1.UserInfoRes{
Username: info.Username,
Avatar: info.Avatar,
Email: info.Email,
Points: info.Points,
}, nil
}

27
internal/dao/admins.go Normal file
View 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"
)
// internalAdminsDao is an internal type for wrapping the internal DAO implementation.
type internalAdminsDao = *internal.AdminsDao
// adminsDao is the data access object for the table admins.
// You can define custom methods on it to extend its functionality as needed.
type adminsDao struct {
internalAdminsDao
}
var (
// Admins is a globally accessible object for table admins operations.
Admins = adminsDao{
internal.NewAdminsDao(),
}
)
// Add your custom methods and functionality below.

27
internal/dao/authors.go Normal file
View 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"
)
// internalAuthorsDao is an internal type for wrapping the internal DAO implementation.
type internalAuthorsDao = *internal.AuthorsDao
// authorsDao is the data access object for the table authors.
// You can define custom methods on it to extend its functionality as needed.
type authorsDao struct {
internalAuthorsDao
}
var (
// Authors is a globally accessible object for table authors operations.
Authors = authorsDao{
internal.NewAuthorsDao(),
}
)
// Add your custom methods and functionality below.

View 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"
)
// internalBookRatingsDao is an internal type for wrapping the internal DAO implementation.
type internalBookRatingsDao = *internal.BookRatingsDao
// bookRatingsDao is the data access object for the table book_ratings.
// You can define custom methods on it to extend its functionality as needed.
type bookRatingsDao struct {
internalBookRatingsDao
}
var (
// BookRatings is a globally accessible object for table book_ratings operations.
BookRatings = bookRatingsDao{
internal.NewBookRatingsDao(),
}
)
// Add your custom methods and functionality below.

27
internal/dao/books.go Normal file
View 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"
)
// internalBooksDao is an internal type for wrapping the internal DAO implementation.
type internalBooksDao = *internal.BooksDao
// booksDao is the data access object for the table books.
// You can define custom methods on it to extend its functionality as needed.
type booksDao struct {
internalBooksDao
}
var (
// Books is a globally accessible object for table books operations.
Books = booksDao{
internal.NewBooksDao(),
}
)
// Add your custom methods and functionality below.

View 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"
)
// internalBookshelvesDao is an internal type for wrapping the internal DAO implementation.
type internalBookshelvesDao = *internal.BookshelvesDao
// bookshelvesDao is the data access object for the table bookshelves.
// You can define custom methods on it to extend its functionality as needed.
type bookshelvesDao struct {
internalBookshelvesDao
}
var (
// Bookshelves is a globally accessible object for table bookshelves operations.
Bookshelves = bookshelvesDao{
internal.NewBookshelvesDao(),
}
)
// Add your custom methods and functionality below.

View 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"
)
// internalCategoriesDao is an internal type for wrapping the internal DAO implementation.
type internalCategoriesDao = *internal.CategoriesDao
// categoriesDao is the data access object for the table categories.
// You can define custom methods on it to extend its functionality as needed.
type categoriesDao struct {
internalCategoriesDao
}
var (
// Categories is a globally accessible object for table categories operations.
Categories = categoriesDao{
internal.NewCategoriesDao(),
}
)
// Add your custom methods and functionality below.

27
internal/dao/chapters.go Normal file
View 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"
)
// internalChaptersDao is an internal type for wrapping the internal DAO implementation.
type internalChaptersDao = *internal.ChaptersDao
// chaptersDao is the data access object for the table chapters.
// You can define custom methods on it to extend its functionality as needed.
type chaptersDao struct {
internalChaptersDao
}
var (
// Chapters is a globally accessible object for table chapters operations.
Chapters = chaptersDao{
internal.NewChaptersDao(),
}
)
// Add your custom methods and functionality below.

27
internal/dao/feedbacks.go Normal file
View 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"
)
// internalFeedbacksDao is an internal type for wrapping the internal DAO implementation.
type internalFeedbacksDao = *internal.FeedbacksDao
// feedbacksDao is the data access object for the table feedbacks.
// You can define custom methods on it to extend its functionality as needed.
type feedbacksDao struct {
internalFeedbacksDao
}
var (
// Feedbacks is a globally accessible object for table feedbacks operations.
Feedbacks = feedbacksDao{
internal.NewFeedbacksDao(),
}
)
// Add your custom methods and functionality below.

View 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"
)
// 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.
}
// AdminsColumns defines and stores column names for the table admins.
type AdminsColumns struct {
Id string // 管理员ID
Username string // 管理员用户名
PasswordHash string // 密码哈希
CreatedAt string // 创建时间
UpdatedAt string // 更新时间
DeletedAt string // 软删除时间戳
}
// adminsColumns holds the columns for the table admins.
var adminsColumns = AdminsColumns{
Id: "id",
Username: "username",
PasswordHash: "password_hash",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
DeletedAt: "deleted_at",
}
// NewAdminsDao creates and returns a new DAO object for table data access.
func NewAdminsDao() *AdminsDao {
return &AdminsDao{
group: "default",
table: "admins",
columns: adminsColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *AdminsDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *AdminsDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *AdminsDao) Columns() AdminsColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *AdminsDao) 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 *AdminsDao) 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 *AdminsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -0,0 +1,87 @@
// ==========================================================================
// 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"
)
// 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.
}
// 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 // 软删除时间戳
}
// 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",
}
// NewAuthorsDao creates and returns a new DAO object for table data access.
func NewAuthorsDao() *AuthorsDao {
return &AuthorsDao{
group: "default",
table: "authors",
columns: authorsColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *AuthorsDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *AuthorsDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *AuthorsDao) Columns() AuthorsColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *AuthorsDao) 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 *AuthorsDao) 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 *AuthorsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View 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"
)
// 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.
}
// BookRatingsColumns defines and stores column names for the table book_ratings.
type BookRatingsColumns struct {
Id string // 评分ID
UserId string // 用户ID
BookId string // 小说ID
Score string // 评分0~10
Comment string // 用户评论
CreatedAt string // 创建时间
}
// bookRatingsColumns holds the columns for the table book_ratings.
var bookRatingsColumns = BookRatingsColumns{
Id: "id",
UserId: "user_id",
BookId: "book_id",
Score: "score",
Comment: "comment",
CreatedAt: "created_at",
}
// NewBookRatingsDao creates and returns a new DAO object for table data access.
func NewBookRatingsDao() *BookRatingsDao {
return &BookRatingsDao{
group: "default",
table: "book_ratings",
columns: bookRatingsColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *BookRatingsDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *BookRatingsDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *BookRatingsDao) Columns() BookRatingsColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *BookRatingsDao) 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 *BookRatingsDao) 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 *BookRatingsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -0,0 +1,105 @@
// ==========================================================================
// 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"
)
// 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.
}
// BooksColumns defines and stores column names for the table books.
type BooksColumns struct {
Id string // 小说ID
AuthorId string // 作者ID
CategoryId string // 分类ID
Title string // 小说标题
CoverUrl string // 封面图片URL
Description string // 小说简介
Status string // 状态1=连载中2=完结3=下架
WordsCount string // 字数
ChaptersCount string // 章节数
LatestChapterId string // 最新章节ID
Rating string // 评分0.00~10.00
ReadCount string // 阅读人数
Tags string // 标签(逗号分隔)
CreatedAt string // 创建时间
UpdatedAt string // 更新时间
DeletedAt string // 软删除时间戳
IsRecommended string // 是否推荐0=否1=是
}
// booksColumns holds the columns for the table books.
var booksColumns = BooksColumns{
Id: "id",
AuthorId: "author_id",
CategoryId: "category_id",
Title: "title",
CoverUrl: "cover_url",
Description: "description",
Status: "status",
WordsCount: "words_count",
ChaptersCount: "chapters_count",
LatestChapterId: "latest_chapter_id",
Rating: "rating",
ReadCount: "read_count",
Tags: "tags",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
DeletedAt: "deleted_at",
IsRecommended: "is_recommended",
}
// NewBooksDao creates and returns a new DAO object for table data access.
func NewBooksDao() *BooksDao {
return &BooksDao{
group: "default",
table: "books",
columns: booksColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *BooksDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *BooksDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *BooksDao) Columns() BooksColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *BooksDao) 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 *BooksDao) 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 *BooksDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -0,0 +1,85 @@
// ==========================================================================
// 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"
)
// 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.
}
// BookshelvesColumns defines and stores column names for the table bookshelves.
type BookshelvesColumns struct {
Id string // 记录ID
UserId string // 用户ID
BookId string // 小说ID
AddedAt string // 加入书架时间
LastReadChapterId string // 最后阅读章节ID
LastReadPercent string // 阅读进度百分比0.00~100.00
LastReadAt string // 最后阅读时间
}
// bookshelvesColumns holds the columns for the table bookshelves.
var bookshelvesColumns = BookshelvesColumns{
Id: "id",
UserId: "user_id",
BookId: "book_id",
AddedAt: "added_at",
LastReadChapterId: "last_read_chapter_id",
LastReadPercent: "last_read_percent",
LastReadAt: "last_read_at",
}
// NewBookshelvesDao creates and returns a new DAO object for table data access.
func NewBookshelvesDao() *BookshelvesDao {
return &BookshelvesDao{
group: "default",
table: "bookshelves",
columns: bookshelvesColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *BookshelvesDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *BookshelvesDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *BookshelvesDao) Columns() BookshelvesColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *BookshelvesDao) 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 *BookshelvesDao) 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 *BookshelvesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View 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"
)
// 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.
}
// CategoriesColumns defines and stores column names for the table categories.
type CategoriesColumns struct {
Id string // 分类ID
Name string // 分类名称
Type string // 分类类型1=男频, 2=女频
CreatedAt string // 创建时间
UpdatedAt string // 更新时间
DeletedAt string // 软删除时间戳
}
// categoriesColumns holds the columns for the table categories.
var categoriesColumns = CategoriesColumns{
Id: "id",
Name: "name",
Type: "type",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
DeletedAt: "deleted_at",
}
// NewCategoriesDao creates and returns a new DAO object for table data access.
func NewCategoriesDao() *CategoriesDao {
return &CategoriesDao{
group: "default",
table: "categories",
columns: categoriesColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *CategoriesDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *CategoriesDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *CategoriesDao) Columns() CategoriesColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *CategoriesDao) 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 *CategoriesDao) 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 *CategoriesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View 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"
)
// 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.
}
// ChaptersColumns defines and stores column names for the table chapters.
type ChaptersColumns struct {
Id string // 章节ID
BookId string // 小说ID
Title string // 章节标题
Content string // 章节内容
WordCount string // 章节字数
Sort string // 排序序号
IsLocked string // 是否锁定0=免费1=需积分解锁
RequiredScore string // 解锁该章节所需积分
CreatedAt string // 创建时间
UpdatedAt string // 更新时间
DeletedAt string // 软删除时间戳
}
// chaptersColumns holds the columns for the table chapters.
var chaptersColumns = ChaptersColumns{
Id: "id",
BookId: "book_id",
Title: "title",
Content: "content",
WordCount: "word_count",
Sort: "sort",
IsLocked: "is_locked",
RequiredScore: "required_score",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
DeletedAt: "deleted_at",
}
// NewChaptersDao creates and returns a new DAO object for table data access.
func NewChaptersDao() *ChaptersDao {
return &ChaptersDao{
group: "default",
table: "chapters",
columns: chaptersColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *ChaptersDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *ChaptersDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *ChaptersDao) Columns() ChaptersColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *ChaptersDao) 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 *ChaptersDao) 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 *ChaptersDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View 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"
)
// 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.
}
// FeedbacksColumns defines and stores column names for the table feedbacks.
type FeedbacksColumns struct {
Id string // 反馈ID
UserId string // 用户ID
Content string // 反馈内容
Status string // 处理状态1=未处理2=处理中3=已处理
CreatedAt string // 反馈时间
UpdatedAt string // 更新时间
}
// feedbacksColumns holds the columns for the table feedbacks.
var feedbacksColumns = FeedbacksColumns{
Id: "id",
UserId: "user_id",
Content: "content",
Status: "status",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
}
// NewFeedbacksDao creates and returns a new DAO object for table data access.
func NewFeedbacksDao() *FeedbacksDao {
return &FeedbacksDao{
group: "default",
table: "feedbacks",
columns: feedbacksColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *FeedbacksDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *FeedbacksDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *FeedbacksDao) Columns() FeedbacksColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *FeedbacksDao) 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 *FeedbacksDao) 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 *FeedbacksDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View 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"
)
// ReadRecordsDao is the data access object for the table read_records.
type ReadRecordsDao 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 ReadRecordsColumns // columns contains all the column names of Table for convenient usage.
}
// ReadRecordsColumns defines and stores column names for the table read_records.
type ReadRecordsColumns struct {
Id string // 记录ID
UserId string // 用户ID
BookId string // 小说ID
ChapterId string // 章节ID
ReadAt string // 阅读时间
}
// readRecordsColumns holds the columns for the table read_records.
var readRecordsColumns = ReadRecordsColumns{
Id: "id",
UserId: "user_id",
BookId: "book_id",
ChapterId: "chapter_id",
ReadAt: "read_at",
}
// NewReadRecordsDao creates and returns a new DAO object for table data access.
func NewReadRecordsDao() *ReadRecordsDao {
return &ReadRecordsDao{
group: "default",
table: "read_records",
columns: readRecordsColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *ReadRecordsDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *ReadRecordsDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *ReadRecordsDao) Columns() ReadRecordsColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *ReadRecordsDao) 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 *ReadRecordsDao) 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 *ReadRecordsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View 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"
)
// TagsDao is the data access object for the table tags.
type TagsDao 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 TagsColumns // columns contains all the column names of Table for convenient usage.
}
// TagsColumns defines and stores column names for the table tags.
type TagsColumns struct {
Id string // 标签ID
Name string // 标签名称
Type string // 标签类型1=主题, 2=角色, 3=情节
CreatedAt string // 创建时间
UpdatedAt string // 更新时间
DeletedAt string // 软删除时间戳
}
// tagsColumns holds the columns for the table tags.
var tagsColumns = TagsColumns{
Id: "id",
Name: "name",
Type: "type",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
DeletedAt: "deleted_at",
}
// NewTagsDao creates and returns a new DAO object for table data access.
func NewTagsDao() *TagsDao {
return &TagsDao{
group: "default",
table: "tags",
columns: tagsColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *TagsDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *TagsDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *TagsDao) Columns() TagsColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *TagsDao) 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 *TagsDao) 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 *TagsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View 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"
)
// 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.
}
// UserChapterPurchasesColumns defines and stores column names for the table user_chapter_purchases.
type UserChapterPurchasesColumns struct {
Id string // 购买记录ID
UserId string // 用户ID
BookId string // 小说ID
ChapterId string // 章节ID
PointsUsed string // 消耗积分数
PurchaseTime string // 购买时间
}
// userChapterPurchasesColumns holds the columns for the table user_chapter_purchases.
var userChapterPurchasesColumns = UserChapterPurchasesColumns{
Id: "id",
UserId: "user_id",
BookId: "book_id",
ChapterId: "chapter_id",
PointsUsed: "points_used",
PurchaseTime: "purchase_time",
}
// NewUserChapterPurchasesDao creates and returns a new DAO object for table data access.
func NewUserChapterPurchasesDao() *UserChapterPurchasesDao {
return &UserChapterPurchasesDao{
group: "default",
table: "user_chapter_purchases",
columns: userChapterPurchasesColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *UserChapterPurchasesDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *UserChapterPurchasesDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *UserChapterPurchasesDao) Columns() UserChapterPurchasesColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *UserChapterPurchasesDao) 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 *UserChapterPurchasesDao) 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 *UserChapterPurchasesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -0,0 +1,79 @@
// ==========================================================================
// 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"
)
// 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.
}
// UserFollowAuthorsColumns defines and stores column names for the table user_follow_authors.
type UserFollowAuthorsColumns struct {
Id string // 关注ID
UserId string // 用户ID
AuthorId string // 作者ID
FollowedAt string // 关注时间
}
// userFollowAuthorsColumns holds the columns for the table user_follow_authors.
var userFollowAuthorsColumns = UserFollowAuthorsColumns{
Id: "id",
UserId: "user_id",
AuthorId: "author_id",
FollowedAt: "followed_at",
}
// NewUserFollowAuthorsDao creates and returns a new DAO object for table data access.
func NewUserFollowAuthorsDao() *UserFollowAuthorsDao {
return &UserFollowAuthorsDao{
group: "default",
table: "user_follow_authors",
columns: userFollowAuthorsColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *UserFollowAuthorsDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *UserFollowAuthorsDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *UserFollowAuthorsDao) Columns() UserFollowAuthorsColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *UserFollowAuthorsDao) 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 *UserFollowAuthorsDao) 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 *UserFollowAuthorsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -0,0 +1,79 @@
// ==========================================================================
// 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"
)
// UserPointsDao is the data access object for the table user_points.
type UserPointsDao 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 UserPointsColumns // columns contains all the column names of Table for convenient usage.
}
// UserPointsColumns defines and stores column names for the table user_points.
type UserPointsColumns struct {
Id string // 积分账户ID
UserId string // 用户ID
PointsBalance string // 当前积分余额
UpdatedAt string // 更新时间
}
// userPointsColumns holds the columns for the table user_points.
var userPointsColumns = UserPointsColumns{
Id: "id",
UserId: "user_id",
PointsBalance: "points_balance",
UpdatedAt: "updated_at",
}
// NewUserPointsDao creates and returns a new DAO object for table data access.
func NewUserPointsDao() *UserPointsDao {
return &UserPointsDao{
group: "default",
table: "user_points",
columns: userPointsColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *UserPointsDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *UserPointsDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *UserPointsDao) Columns() UserPointsColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *UserPointsDao) 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 *UserPointsDao) 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 *UserPointsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -0,0 +1,85 @@
// ==========================================================================
// 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"
)
// 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.
}
// UserPointsLogsColumns defines and stores column names for the table user_points_logs.
type UserPointsLogsColumns struct {
Id string // 积分流水ID
UserId string // 用户ID
ChangeType string // 变动类型,例如 earn、spend、refund 等
PointsChange string // 积分变化数,正数增加,负数减少
RelatedOrderId string // 关联订单ID
Description string // 变动说明
CreatedAt string // 变动时间
}
// userPointsLogsColumns holds the columns for the table user_points_logs.
var userPointsLogsColumns = UserPointsLogsColumns{
Id: "id",
UserId: "user_id",
ChangeType: "change_type",
PointsChange: "points_change",
RelatedOrderId: "related_order_id",
Description: "description",
CreatedAt: "created_at",
}
// NewUserPointsLogsDao creates and returns a new DAO object for table data access.
func NewUserPointsLogsDao() *UserPointsLogsDao {
return &UserPointsLogsDao{
group: "default",
table: "user_points_logs",
columns: userPointsLogsColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *UserPointsLogsDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *UserPointsLogsDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *UserPointsLogsDao) Columns() UserPointsLogsColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *UserPointsLogsDao) 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 *UserPointsLogsDao) 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 *UserPointsLogsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View 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"
)
// 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.
}
// 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 // 软删除时间戳
}
// 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",
}
// NewUsersDao creates and returns a new DAO object for table data access.
func NewUsersDao() *UsersDao {
return &UsersDao{
group: "default",
table: "users",
columns: usersColumns,
}
}
// DB retrieves and returns the underlying raw database management object of the current DAO.
func (dao *UsersDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of the current DAO.
func (dao *UsersDao) Table() string {
return dao.table
}
// Columns returns all column names of the current DAO.
func (dao *UsersDao) Columns() UsersColumns {
return dao.columns
}
// Group returns the database configuration group name of the current DAO.
func (dao *UsersDao) 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 *UsersDao) 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 *UsersDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View 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"
)
// internalReadRecordsDao is an internal type for wrapping the internal DAO implementation.
type internalReadRecordsDao = *internal.ReadRecordsDao
// readRecordsDao is the data access object for the table read_records.
// You can define custom methods on it to extend its functionality as needed.
type readRecordsDao struct {
internalReadRecordsDao
}
var (
// ReadRecords is a globally accessible object for table read_records operations.
ReadRecords = readRecordsDao{
internal.NewReadRecordsDao(),
}
)
// Add your custom methods and functionality below.

27
internal/dao/tags.go Normal file
View 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"
)
// internalTagsDao is an internal type for wrapping the internal DAO implementation.
type internalTagsDao = *internal.TagsDao
// tagsDao is the data access object for the table tags.
// You can define custom methods on it to extend its functionality as needed.
type tagsDao struct {
internalTagsDao
}
var (
// Tags is a globally accessible object for table tags operations.
Tags = tagsDao{
internal.NewTagsDao(),
}
)
// Add your custom methods and functionality below.

View 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"
)
// internalUserChapterPurchasesDao is an internal type for wrapping the internal DAO implementation.
type internalUserChapterPurchasesDao = *internal.UserChapterPurchasesDao
// userChapterPurchasesDao is the data access object for the table user_chapter_purchases.
// You can define custom methods on it to extend its functionality as needed.
type userChapterPurchasesDao struct {
internalUserChapterPurchasesDao
}
var (
// UserChapterPurchases is a globally accessible object for table user_chapter_purchases operations.
UserChapterPurchases = userChapterPurchasesDao{
internal.NewUserChapterPurchasesDao(),
}
)
// Add your custom methods and functionality below.

View 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"
)
// internalUserFollowAuthorsDao is an internal type for wrapping the internal DAO implementation.
type internalUserFollowAuthorsDao = *internal.UserFollowAuthorsDao
// userFollowAuthorsDao is the data access object for the table user_follow_authors.
// You can define custom methods on it to extend its functionality as needed.
type userFollowAuthorsDao struct {
internalUserFollowAuthorsDao
}
var (
// UserFollowAuthors is a globally accessible object for table user_follow_authors operations.
UserFollowAuthors = userFollowAuthorsDao{
internal.NewUserFollowAuthorsDao(),
}
)
// Add your custom methods and functionality below.

View 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"
)
// internalUserPointsDao is an internal type for wrapping the internal DAO implementation.
type internalUserPointsDao = *internal.UserPointsDao
// userPointsDao is the data access object for the table user_points.
// You can define custom methods on it to extend its functionality as needed.
type userPointsDao struct {
internalUserPointsDao
}
var (
// UserPoints is a globally accessible object for table user_points operations.
UserPoints = userPointsDao{
internal.NewUserPointsDao(),
}
)
// Add your custom methods and functionality below.

View 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"
)
// internalUserPointsLogsDao is an internal type for wrapping the internal DAO implementation.
type internalUserPointsLogsDao = *internal.UserPointsLogsDao
// userPointsLogsDao is the data access object for the table user_points_logs.
// You can define custom methods on it to extend its functionality as needed.
type userPointsLogsDao struct {
internalUserPointsLogsDao
}
var (
// UserPointsLogs is a globally accessible object for table user_points_logs operations.
UserPointsLogs = userPointsLogsDao{
internal.NewUserPointsLogsDao(),
}
)
// Add your custom methods and functionality below.

27
internal/dao/users.go Normal file
View 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"
)
// internalUsersDao is an internal type for wrapping the internal DAO implementation.
type internalUsersDao = *internal.UsersDao
// usersDao is the data access object for the table users.
// You can define custom methods on it to extend its functionality as needed.
type usersDao struct {
internalUsersDao
}
var (
// Users is a globally accessible object for table users operations.
Users = usersDao{
internal.NewUsersDao(),
}
)
// Add your custom methods and functionality below.

View File

@ -0,0 +1,92 @@
package admin
import (
"context"
"server/internal/consts"
"server/internal/dao"
"server/internal/model"
"server/internal/model/do"
"server/internal/model/entity"
"server/internal/service"
"server/utility/ecode"
"server/utility/encrypt"
"server/utility/jwt"
)
type sAdmin struct{}
func init() {
service.RegisterAdmin(New())
}
func New() service.IAdmin {
return &sAdmin{}
}
func (s *sAdmin) Login(ctx context.Context, in *model.AdminLoginIn) (out *model.AdminLoginOut, err error) {
admin, err := dao.Admins.Ctx(ctx).Where(dao.Admins.Columns().Username, in.Username).One()
if err != nil {
return nil, ecode.Fail.Sub("database_query_failed")
}
if admin.IsEmpty() {
return nil, ecode.Auth
}
if !encrypt.ComparePassword(admin[dao.Admins.Columns().PasswordHash].String(), in.Password) {
return nil, ecode.Password
}
token, err := jwt.GenerateToken(&jwt.TokenIn{
Role: consts.AdminRoleCode,
UserId: admin[dao.Admins.Columns().Id].Int64(),
})
if err != nil {
return nil, ecode.Fail.Sub("token_generation_failed")
}
return &model.AdminLoginOut{
Token: token,
}, nil
}
func (s *sAdmin) Info(ctx context.Context, in *model.AdminInfoIn) (out *model.AdminInfoOut, err error) {
exist, err := dao.Admins.Ctx(ctx).WherePri(in.AdminId).Exist()
if err != nil {
return nil, ecode.Fail.Sub("admin_query_failed")
}
if !exist {
return nil, ecode.Auth.Sub("admin_not_found")
}
var admin entity.Admins
err = dao.Admins.Ctx(ctx).WherePri(in.AdminId).Scan(&admin)
if err != nil {
return nil, ecode.Fail.Sub("admin_query_failed")
}
return &model.AdminInfoOut{
AdminId: admin.Id,
Username: admin.Username,
}, nil
}
func (s *sAdmin) EditPass(ctx context.Context, in *model.AdminEditPassIn) (out *model.AdminEditPassOut, err error) {
admin, err := dao.Admins.Ctx(ctx).WherePri(in.AdminId).One()
if err != nil {
return nil, ecode.Fail.Sub("admin_query_failed")
}
if admin.IsEmpty() {
return nil, ecode.Auth.Sub("admin_not_found")
}
if !encrypt.ComparePassword(admin[dao.Admins.Columns().PasswordHash].String(), in.OldPass) {
return nil, ecode.Password.Sub("password_incorrect")
}
hash, err := encrypt.EncryptPassword(in.NewPass)
if err != nil {
return nil, ecode.Fail.Sub("password_encryption_failed")
}
_, err = dao.Admins.Ctx(ctx).WherePri(in.AdminId).Data(do.Admins{PasswordHash: hash}).Update()
if err != nil {
return nil, ecode.Fail.Sub("password_update_failed")
}
return &model.AdminEditPassOut{
Success: true,
}, nil
}

138
internal/logic/book/book.go Normal file
View File

@ -0,0 +1,138 @@
package book
import (
"context"
"server/internal/dao"
"server/internal/model"
"server/internal/model/do"
"server/internal/service"
"server/utility/ecode"
)
type sBook struct{}
func New() service.IBook {
return &sBook{}
}
func init() {
service.RegisterBook(New())
}
// List retrieves a paginated list of books
func (s *sBook) List(ctx context.Context, in *model.BookListIn) (out *model.BookListOut, err error) {
out = &model.BookListOut{}
m := dao.Books.Ctx(ctx)
if in.Title != "" {
m = m.Where(dao.Books.Columns().Title+" like ?", "%"+in.Title+"%")
}
if in.CategoryId != 0 {
m = m.Where(dao.Books.Columns().CategoryId, in.CategoryId)
}
if in.AuthorId != 0 {
m = m.Where(dao.Books.Columns().AuthorId, in.AuthorId)
}
if in.Status != 0 {
m = m.Where(dao.Books.Columns().Status, in.Status)
}
if in.IsRecommended != 0 {
m = m.Where(dao.Books.Columns().IsRecommended, in.IsRecommended)
}
if err = m.Page(in.Page, in.Size).ScanAndCount(&out.List, &out.Total, false); err != nil {
return
}
return
}
func (s *sBook) Create(ctx context.Context, in *model.BookAddIn) (out *model.BookCRUDOut, err error) {
exist, err := dao.Books.Ctx(ctx).
Where(dao.Books.Columns().Title, in.Title).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("book_query_failed")
}
if exist {
return nil, ecode.Params.Sub("book_exists")
}
if _, err := dao.Books.Ctx(ctx).Data(do.Books{
AuthorId: in.AuthorId,
CategoryId: in.CategoryId,
Title: in.Title,
CoverUrl: in.CoverUrl,
Description: in.Description,
Status: in.Status,
Tags: in.Tags,
IsRecommended: in.IsRecommended,
}).Insert(); err != nil {
return nil, ecode.Fail.Sub("book_create_failed")
}
return &model.BookCRUDOut{
Success: true,
}, nil
}
func (s *sBook) Update(ctx context.Context, in *model.BookEditIn) (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")
}
exist, err = dao.Books.Ctx(ctx).
Where(dao.Books.Columns().Title, in.Title).
Where("id != ?", in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("book_query_failed")
}
if exist {
return nil, ecode.Params.Sub("book_exists")
}
_, err = dao.Books.Ctx(ctx).
WherePri(in.Id).
Data(do.Books{
AuthorId: in.AuthorId,
CategoryId: in.CategoryId,
Title: in.Title,
CoverUrl: in.CoverUrl,
Description: in.Description,
Status: in.Status,
Tags: in.Tags,
IsRecommended: in.IsRecommended,
}).Update()
if err != nil {
return nil, ecode.Fail.Sub("book_update_failed")
}
return &model.BookCRUDOut{
Success: true,
}, nil
}
func (s *sBook) Delete(ctx context.Context, in *model.BookDelIn) (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).Delete()
if err != nil {
return nil, ecode.Fail.Sub("book_delete_failed")
}
return &model.BookCRUDOut{
Success: true,
}, nil
}

View File

@ -0,0 +1,123 @@
package category
import (
"context"
"server/internal/dao"
"server/internal/model"
"server/internal/model/do"
"server/internal/service"
"server/utility/ecode"
)
type sCategory struct {
}
func New() service.ICategory {
return &sCategory{}
}
func init() {
service.RegisterCategory(New())
}
// List retrieves a paginated list of categories
func (s *sCategory) List(ctx context.Context, in *model.CategoryListIn) (out *model.CategoryListOut, err error) {
out = &model.CategoryListOut{}
m := dao.Categories.Ctx(ctx)
if in.Type != 0 {
m = m.Where(dao.Categories.Columns().Type, in.Type)
}
if err = m.Page(in.Page, in.Size).ScanAndCount(&out.List, &out.Total, false); err != nil {
return
}
return
}
func (s *sCategory) Create(ctx context.Context, in *model.CategoryAddIn) (out *model.CategoryCRUDOut, err error) {
if in.Type != 1 && in.Type != 2 {
return nil, ecode.Params.Sub("category_type_invalid")
}
exist, err := dao.Categories.Ctx(ctx).
Where(dao.Categories.Columns().Name, in.Name).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("category_query_failed")
}
if exist {
return nil, ecode.Params.Sub("category_exists")
}
if _, err := dao.Categories.Ctx(ctx).Data(do.Categories{
Name: in.Name,
Type: in.Type,
}).Insert(); err != nil {
return nil, ecode.Fail.Sub("category_create_failed")
}
return &model.CategoryCRUDOut{
Success: true,
}, nil
}
func (s *sCategory) Update(ctx context.Context, in *model.CategoryEditIn) (out *model.CategoryCRUDOut, err error) {
if in.Type != 1 && in.Type != 2 {
return nil, ecode.Params.Sub("category_type_invalid")
}
exist, err := dao.Categories.Ctx(ctx).
WherePri(in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("category_query_failed")
}
if !exist {
return nil, ecode.NotFound.Sub("category_not_found")
}
exist, err = dao.Categories.Ctx(ctx).
Where(dao.Categories.Columns().Name, in.Name).
Where("id != ?", in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("category_query_failed")
}
if exist {
return nil, ecode.Params.Sub("category_exists")
}
// Update category
_, err = dao.Categories.Ctx(ctx).
WherePri(in.Id).
Data(do.Categories{
Name: in.Name,
Type: in.Type,
}).Update()
if err != nil {
return nil, ecode.Fail.Sub("category_update_failed")
}
return &model.CategoryCRUDOut{
Success: true,
}, nil
}
func (s *sCategory) Delete(ctx context.Context, in *model.CategoryDelIn) (out *model.CategoryCRUDOut, err error) {
exist, err := dao.Categories.Ctx(ctx).
WherePri(in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("category_query_failed")
}
if !exist {
return nil, ecode.NotFound.Sub("category_not_found")
}
// Soft delete category
_, err = dao.Categories.Ctx(ctx).WherePri(in.Id).Delete()
if err != nil {
return nil, ecode.Fail.Sub("category_delete_failed")
}
return &model.CategoryCRUDOut{
Success: true,
}, nil
}

View File

@ -0,0 +1,98 @@
package chapter
import (
"context"
"server/internal/dao"
"server/internal/model"
"server/internal/model/do"
"server/internal/service"
"server/utility/ecode"
)
type sChapter struct{}
func New() service.IChapter {
return &sChapter{}
}
func init() {
service.RegisterChapter(New())
}
// List retrieves a paginated list of chapters
func (s *sChapter) List(ctx context.Context, in *model.ChapterListIn) (out *model.ChapterListOut, err error) {
out = &model.ChapterListOut{}
m := dao.Chapters.Ctx(ctx)
if in.BookId != 0 {
m = m.Where(dao.Chapters.Columns().BookId, in.BookId)
}
if in.Title != "" {
m = m.Where(dao.Chapters.Columns().Title+" like ?", "%"+in.Title+"%")
}
if in.IsLocked != 0 {
m = m.Where(dao.Chapters.Columns().IsLocked, in.IsLocked)
}
if err = m.Page(in.Page, in.Size).ScanAndCount(&out.List, &out.Total, false); err != nil {
return
}
return
}
func (s *sChapter) Create(ctx context.Context, in *model.ChapterAddIn) (out *model.ChapterCRUDOut, err error) {
if _, err := dao.Chapters.Ctx(ctx).Data(do.Chapters{
BookId: in.BookId,
Title: in.Title,
Content: in.Content,
WordCount: in.WordCount,
Sort: in.Sort,
IsLocked: in.IsLocked,
RequiredScore: in.RequiredScore,
}).Insert(); err != nil {
return nil, ecode.Fail.Sub("chapter_create_failed")
}
return &model.ChapterCRUDOut{Success: true}, nil
}
func (s *sChapter) Update(ctx context.Context, in *model.ChapterEditIn) (out *model.ChapterCRUDOut, err error) {
exist, err := dao.Chapters.Ctx(ctx).
WherePri(in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("chapter_query_failed")
}
if !exist {
return nil, ecode.NotFound.Sub("chapter_not_found")
}
_, err = dao.Chapters.Ctx(ctx).
WherePri(in.Id).
Data(do.Chapters{
BookId: in.BookId,
Title: in.Title,
Content: in.Content,
WordCount: in.WordCount,
Sort: in.Sort,
IsLocked: in.IsLocked,
RequiredScore: in.RequiredScore,
}).Update()
if err != nil {
return nil, ecode.Fail.Sub("chapter_update_failed")
}
return &model.ChapterCRUDOut{Success: true}, nil
}
func (s *sChapter) Delete(ctx context.Context, in *model.ChapterDelIn) (out *model.ChapterCRUDOut, err error) {
exist, err := dao.Chapters.Ctx(ctx).
WherePri(in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("chapter_query_failed")
}
if !exist {
return nil, ecode.NotFound.Sub("chapter_not_found")
}
_, err = dao.Chapters.Ctx(ctx).WherePri(in.Id).Delete()
if err != nil {
return nil, ecode.Fail.Sub("chapter_delete_failed")
}
return &model.ChapterCRUDOut{Success: true}, nil
}

View File

@ -0,0 +1,47 @@
package feedback
import (
"context"
"server/internal/dao"
"server/internal/model"
"server/internal/model/do"
"server/internal/service"
"server/utility/ecode"
)
type sFeedback struct{}
func New() service.IFeedback {
return &sFeedback{}
}
func init() {
service.RegisterFeedback(New())
}
// List retrieves a paginated list of feedbacks
func (s *sFeedback) List(ctx context.Context, in *model.FeedbackListIn) (out *model.FeedbackListOut, err error) {
out = &model.FeedbackListOut{}
m := dao.Feedbacks.Ctx(ctx)
if in.UserId != 0 {
m = m.Where(dao.Feedbacks.Columns().UserId, in.UserId)
}
if in.Status != 0 {
m = m.Where(dao.Feedbacks.Columns().Status, in.Status)
}
if err = m.Page(in.Page, in.Size).ScanAndCount(&out.List, &out.Total, false); err != nil {
return
}
return
}
// Create adds a new feedback
func (s *sFeedback) Create(ctx context.Context, in *model.FeedbackAddIn) (out *model.FeedbackCRUDOut, err error) {
if _, err := dao.Feedbacks.Ctx(ctx).Data(do.Feedbacks{
UserId: in.UserId,
Content: in.Content,
Status: 1, // 默认未处理
}).Insert(); err != nil {
return nil, ecode.Fail.Sub("feedback_create_failed")
}
return &model.FeedbackCRUDOut{Success: true}, nil
}

16
internal/logic/logic.go Normal file
View File

@ -0,0 +1,16 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic
import (
_ "server/internal/logic/admin"
_ "server/internal/logic/book"
_ "server/internal/logic/category"
_ "server/internal/logic/chapter"
_ "server/internal/logic/feedback"
_ "server/internal/logic/read_record"
_ "server/internal/logic/tag"
_ "server/internal/logic/user"
)

View File

@ -0,0 +1,68 @@
package read_record
import (
"context"
"server/internal/dao"
"server/internal/model"
"server/internal/model/do"
"server/internal/service"
"server/utility/ecode"
)
type sReadRecord struct{}
func New() service.IReadRecord {
return &sReadRecord{}
}
func init() {
service.RegisterReadRecord(New())
}
// List retrieves a paginated list of read records
func (s *sReadRecord) List(ctx context.Context, in *model.ReadRecordListIn) (out *model.ReadRecordListOut, err error) {
out = &model.ReadRecordListOut{}
m := dao.ReadRecords.Ctx(ctx)
if in.UserId != 0 {
m = m.Where(dao.ReadRecords.Columns().UserId, in.UserId)
}
if in.BookId != 0 {
m = m.Where(dao.ReadRecords.Columns().BookId, in.BookId)
}
if in.ChapterId != 0 {
m = m.Where(dao.ReadRecords.Columns().ChapterId, in.ChapterId)
}
if err = m.Page(in.Page, in.Size).ScanAndCount(&out.List, &out.Total, false); err != nil {
return
}
return
}
// Create adds a new read record
func (s *sReadRecord) Create(ctx context.Context, in *model.ReadRecordAddIn) (out *model.ReadRecordCRUDOut, err error) {
if _, err := dao.ReadRecords.Ctx(ctx).Data(do.ReadRecords{
UserId: in.UserId,
BookId: in.BookId,
ChapterId: in.ChapterId,
}).Insert(); err != nil {
return nil, ecode.Fail.Sub("read_record_create_failed")
}
return &model.ReadRecordCRUDOut{Success: true}, nil
}
// Delete removes a read record by id
func (s *sReadRecord) Delete(ctx context.Context, in *model.ReadRecordDelIn) (out *model.ReadRecordCRUDOut, err error) {
exist, err := dao.ReadRecords.Ctx(ctx).
WherePri(in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("read_record_query_failed")
}
if !exist {
return nil, ecode.NotFound.Sub("read_record_not_found")
}
_, err = dao.ReadRecords.Ctx(ctx).WherePri(in.Id).Delete()
if err != nil {
return nil, ecode.Fail.Sub("read_record_delete_failed")
}
return &model.ReadRecordCRUDOut{Success: true}, nil
}

119
internal/logic/tag/tag.go Normal file
View File

@ -0,0 +1,119 @@
package tag
import (
"context"
"server/internal/dao"
"server/internal/model"
"server/internal/model/do"
"server/internal/service"
"server/utility/ecode"
)
type sTag struct{}
func New() service.ITag {
return &sTag{}
}
func init() {
service.RegisterTag(New())
}
// List retrieves a paginated list of tags
func (s *sTag) List(ctx context.Context, in *model.TagListIn) (out *model.TagListOut, err error) {
out = &model.TagListOut{}
m := dao.Tags.Ctx(ctx)
if in.Name != "" {
m = m.Where(dao.Tags.Columns().Name+" like ?", "%"+in.Name+"%")
}
if in.Type != 0 {
m = m.Where(dao.Tags.Columns().Type, in.Type)
}
if err = m.Page(in.Page, in.Size).ScanAndCount(&out.List, &out.Total, false); err != nil {
return
}
return
}
func (s *sTag) Create(ctx context.Context, in *model.TagAddIn) (out *model.TagCRUDOut, err error) {
exist, err := dao.Tags.Ctx(ctx).
Where(dao.Tags.Columns().Name, in.Name).
Where(dao.Tags.Columns().Type, in.Type).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("tag_query_failed")
}
if exist {
return nil, ecode.Params.Sub("tag_exists")
}
if _, err := dao.Tags.Ctx(ctx).Data(do.Tags{
Name: in.Name,
Type: in.Type,
}).Insert(); err != nil {
return nil, ecode.Fail.Sub("tag_create_failed")
}
return &model.TagCRUDOut{
Success: true,
}, nil
}
func (s *sTag) Update(ctx context.Context, in *model.TagEditIn) (out *model.TagCRUDOut, err error) {
exist, err := dao.Tags.Ctx(ctx).
WherePri(in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("tag_query_failed")
}
if !exist {
return nil, ecode.NotFound.Sub("tag_not_found")
}
exist, err = dao.Tags.Ctx(ctx).
Where(dao.Tags.Columns().Name, in.Name).
Where(dao.Tags.Columns().Type, in.Type).
Where("id != ?", in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("tag_query_failed")
}
if exist {
return nil, ecode.Params.Sub("tag_exists")
}
_, err = dao.Tags.Ctx(ctx).
WherePri(in.Id).
Data(do.Tags{
Name: in.Name,
Type: in.Type,
}).Update()
if err != nil {
return nil, ecode.Fail.Sub("tag_update_failed")
}
return &model.TagCRUDOut{
Success: true,
}, nil
}
func (s *sTag) Delete(ctx context.Context, in *model.TagDelIn) (out *model.TagCRUDOut, err error) {
exist, err := dao.Tags.Ctx(ctx).
WherePri(in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("tag_query_failed")
}
if !exist {
return nil, ecode.NotFound.Sub("tag_not_found")
}
_, err = dao.Tags.Ctx(ctx).WherePri(in.Id).Delete()
if err != nil {
return nil, ecode.Fail.Sub("tag_delete_failed")
}
return &model.TagCRUDOut{
Success: true,
}, nil
}

136
internal/logic/user/user.go Normal file
View File

@ -0,0 +1,136 @@
package user
import (
"context"
"server/internal/dao"
"server/internal/model"
"server/internal/model/do"
"server/internal/model/entity"
"server/internal/service"
"server/utility/ecode"
"server/utility/encrypt"
"server/utility/jwt"
"strings"
)
type sUser struct{}
func New() service.IUser {
return &sUser{}
}
func init() {
service.RegisterUser(New())
}
func (s *sUser) Login(ctx context.Context, in *model.UserLoginIn) (out *model.UserLoginOut, err error) {
user, err := dao.Users.Ctx(ctx).Where(do.Users{Email: in.Email}).One()
if err != nil {
return nil, ecode.Fail.Sub("database_query_failed")
}
if user == nil {
return nil, ecode.Auth // 账户名或密码不正确
}
var entityUser entity.Users
if err = user.Struct(&entityUser); err != nil {
return nil, ecode.Fail.Sub("data_conversion_failed")
}
if !encrypt.ComparePassword(entityUser.PasswordHash, in.Password) {
return nil, ecode.Password // 密码不正确
}
token, err := jwt.GenerateToken(&jwt.TokenIn{UserId: entityUser.Id, Role: "user"})
if err != nil {
return nil, ecode.Fail.Sub("token_generation_failed")
}
return &model.UserLoginOut{Token: token}, nil
}
func (s *sUser) Register(ctx context.Context, in *model.UserRegisterIn) (out *model.UserRegisterOut, err error) {
if in.Password != in.Password2 {
return nil, ecode.Password.Sub("password_mismatch")
}
exist, err := dao.Users.Ctx(ctx).Where(do.Users{Email: in.Email}).Count()
if err != nil {
return nil, ecode.Fail.Sub("database_query_failed")
}
if exist > 0 {
return nil, ecode.EmailExist // 该邮箱已被注册
}
hash, err := encrypt.EncryptPassword(in.Password)
if err != nil {
return nil, ecode.Fail.Sub("password_encryption_failed")
}
_, err = dao.Users.Ctx(ctx).Data(do.Users{
Email: in.Email,
PasswordHash: hash,
Username: strings.Split(in.Email, "@")[0],
}).Insert()
if err != nil {
return nil, ecode.Fail.Sub("registration_failed")
}
return &model.UserRegisterOut{Success: true}, nil
}
func (s *sUser) Info(ctx context.Context, in *model.UserInfoIn) (out *model.UserInfoOut, err error) {
user, err := dao.Users.Ctx(ctx).Where(do.Users{Id: in.UserId}).One()
if err != nil {
return nil, ecode.Fail.Sub("database_query_failed")
}
if user == nil {
return nil, ecode.Auth.Sub("user_not_found")
}
var entityUser entity.Users
if err = user.Struct(&entityUser); err != nil {
return nil, ecode.Fail.Sub("data_conversion_failed")
}
return &model.UserInfoOut{
UserId: entityUser.Id,
Username: entityUser.Username,
Email: entityUser.Email,
Avatar: entityUser.Avatar,
Points: entityUser.Points, // 如有积分表可补充
}, nil
}
func (s *sUser) Delete(ctx context.Context, in *model.UserDeleteIn) (out *model.UserDeleteOut, err error) {
// FIXME
return &model.UserDeleteOut{Success: true}, nil
}
func (s *sUser) Code(ctx context.Context, in *model.UserCodeIn) (out *model.UserCodeOut, err error) {
exist, err := dao.Users.Ctx(ctx).Where(do.Users{Email: in.Email}).Exist()
if err != nil {
return nil, ecode.Fail.Sub("database_query_failed")
}
if !exist {
return nil, ecode.Params.Sub("email_not_found")
}
return &model.UserCodeOut{Success: true}, nil
}
func (s *sUser) EditPass(ctx context.Context, in *model.UserEditPassIn) (out *model.UserEditPassOut, err error) {
exist, err := dao.Users.Ctx(ctx).Where(do.Users{Email: in.Email}).Exist()
if err != nil {
return nil, ecode.Fail.Sub("database_query_failed")
}
if !exist {
return nil, ecode.Params.Sub("email_not_found")
}
if in.Sign != "123456" {
return nil, ecode.Params.Sub("sign_error")
}
if in.Password != in.Password2 {
return nil, ecode.Password.Sub("password_mismatch")
}
hash, err := encrypt.EncryptPassword(in.Password)
if err != nil {
return nil, ecode.Fail.Sub("password_encryption_failed")
}
_, err = dao.Users.Ctx(ctx).Where(do.Users{Email: in.Email}).Data(do.Users{PasswordHash: hash}).Update()
if err != nil {
return nil, ecode.Fail.Sub("password_update_failed")
}
return &model.UserEditPassOut{
Success: true,
}, nil
}

View File

@ -0,0 +1,66 @@
package user_follow_author
import (
"context"
"server/internal/dao"
"server/internal/model"
"server/internal/model/do"
"server/utility/ecode"
)
type sUserFollowAuthor struct{}
// List retrieves a paginated list of user follow authors
func (s *sUserFollowAuthor) List(ctx context.Context, in *model.UserFollowAuthorListIn) (out *model.UserFollowAuthorListOut, err error) {
out = &model.UserFollowAuthorListOut{}
m := dao.UserFollowAuthors.Ctx(ctx)
if in.UserId != 0 {
m = m.Where(dao.UserFollowAuthors.Columns().UserId, in.UserId)
}
if in.AuthorId != 0 {
m = m.Where(dao.UserFollowAuthors.Columns().AuthorId, in.AuthorId)
}
if err = m.Page(in.Page, in.Size).ScanAndCount(&out.List, &out.Total, false); err != nil {
return
}
return
}
// Create adds a new user follow author
func (s *sUserFollowAuthor) Create(ctx context.Context, in *model.UserFollowAuthorAddIn) (out *model.UserFollowAuthorCRUDOut, err error) {
exist, err := dao.UserFollowAuthors.Ctx(ctx).
Where(dao.UserFollowAuthors.Columns().UserId, in.UserId).
Where(dao.UserFollowAuthors.Columns().AuthorId, in.AuthorId).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("user_follow_author_query_failed")
}
if exist {
return nil, ecode.Params.Sub("user_follow_author_exists")
}
if _, err := dao.UserFollowAuthors.Ctx(ctx).Data(do.UserFollowAuthors{
UserId: in.UserId,
AuthorId: in.AuthorId,
}).Insert(); err != nil {
return nil, ecode.Fail.Sub("user_follow_author_create_failed")
}
return &model.UserFollowAuthorCRUDOut{Success: true}, nil
}
// Delete removes a user follow author by id
func (s *sUserFollowAuthor) Delete(ctx context.Context, in *model.UserFollowAuthorDelIn) (out *model.UserFollowAuthorCRUDOut, err error) {
exist, err := dao.UserFollowAuthors.Ctx(ctx).
WherePri(in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("user_follow_author_query_failed")
}
if !exist {
return nil, ecode.NotFound.Sub("user_follow_author_not_found")
}
_, err = dao.UserFollowAuthors.Ctx(ctx).WherePri(in.Id).Delete()
if err != nil {
return nil, ecode.Fail.Sub("user_follow_author_delete_failed")
}
return &model.UserFollowAuthorCRUDOut{Success: true}, nil
}

View File

@ -0,0 +1,52 @@
package middleware
import (
"server/utility/ecode"
"server/utility/jwt"
"strings"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/glog"
)
// Auth 是用于权限验证的中间件。
//
// 它会从请求头中读取 Authorization 字段,验证 JWT Token 的合法性。
// 如果请求未携带 Token则默认赋予 "guest" 权限。
// 如果 Token 存在且合法则将用户信息userId、permission、jti注入到请求上下文中。
//
// Token 应采用 Bearer 方案,例如:
//
// Authorization: Bearer <token>
//
// 参数:
//
// r *ghttp.Request - 当前的请求对象,由 ghttp 框架自动注入。
//
// 行为:
// - 若无 Token设定 permission 为 guest放行请求。
// - 若 Token 格式非法或解析失败:终止请求并返回错误。
// - 若 Token 合法:将用户信息写入上下文,继续执行下一个中间件或处理函数。
func Auth(r *ghttp.Request) {
token := r.GetHeader("Authorization")
ctx := r.GetCtx()
if token == "" {
glog.Infof(ctx, "未登录用户访问: %s %s", r.URL.Path, r.Method)
r.SetCtxVar("role", "guest")
} else {
if !strings.HasPrefix(token, "Bearer ") {
r.SetError(ecode.InvalidOperation.Sub("invalid_token_format"))
return
}
tokenOut, err := jwt.ParseToken(token)
if err != nil {
r.SetError(err)
return
}
r.SetCtxVar("id", tokenOut.UserId)
r.SetCtxVar("role", tokenOut.Role)
r.SetCtxVar("jti", tokenOut.JTI)
glog.Infof(ctx, "%s用户Id:%d 访问: %s %s", tokenOut.Role, tokenOut.UserId, r.URL.Path, r.Method)
}
r.Middleware.Next()
}

View File

@ -0,0 +1,29 @@
package middleware
import (
"server/utility/ecode"
"server/utility/myCasbin"
"github.com/gogf/gf/v2/net/ghttp"
)
// Casbin 是用于访问权限控制的中间件。
//
// 该中间件基于 Casbin 权限控制框架,校验当前用户是否有权访问指定的 URL 和请求方法。
// 用户权限从请求上下文中的 "permission" 字段获取,该字段通常由前置中间件(如 Auth注入。
//
// 参数:
//
// r *ghttp.Request - 当前的 HTTP 请求对象,由框架自动传入。
//
// 行为:
// - 如果权限验证未通过终止请求返回权限不足的错误ecode.Denied
// - 如果权限验证通过:继续执行后续中间件或处理逻辑。
func Casbin(r *ghttp.Request) {
role := r.GetCtxVar("role").String()
if !myCasbin.GetMyCasbin().HasPermission(role, r.URL.Path, r.Method) {
r.SetError(ecode.Denied)
return
}
r.Middleware.Next()
}

View File

@ -0,0 +1,14 @@
package middleware
import (
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/net/ghttp"
)
func Exit(r *ghttp.Request, err error) {
r.Response.WriteJsonExit(ghttp.DefaultHandlerResponse{
Code: gerror.Code(err).Code(),
Message: gerror.Code(err).Message(),
Data: nil,
})
}

View File

@ -0,0 +1,20 @@
package middleware
import (
"server/utility/i18n"
"github.com/gogf/gf/v2/net/ghttp"
)
// Language 语言检测中间件
// 从请求头或查询参数中检测语言设置,并设置到上下文中
func Language(r *ghttp.Request) {
// 获取语言设置
lang := i18n.GetLanguage(r.GetCtx())
// 将语言设置到上下文中,供后续使用
r.SetCtxVar("language", lang)
// 继续下一个中间件
r.Middleware.Next()
}

View File

@ -0,0 +1,69 @@
package middleware
import (
"net/http"
"server/utility/ecode"
"server/utility/i18n"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/util/gconv"
)
func Response(r *ghttp.Request) {
r.Middleware.Next()
if r.Response.BufferLength() > 0 {
return
}
var (
msg string
err = r.GetError()
res = r.GetHandlerResponse()
code = gerror.Code(err)
ctx = r.GetCtx()
)
glog.Debug(gctx.New(), "错误", err)
if err != nil {
if gconv.String(code.Detail()) != "customer" && code.Code() != 51 {
msg = ecode.Fail.MessageI18n(ctx)
} else if code.Code() == 51 {
msg = ecode.Params.MessageI18n(ctx)
} else {
// 尝试从国际化系统获取消息
msg = i18n.T(ctx, code.Message())
if msg == code.Message() {
// 如果没有找到国际化消息,使用原始消息
msg = code.Message()
}
}
} else if r.Response.Status > 0 && r.Response.Status != http.StatusOK {
// HTTP状态码错误消息的国际化
switch r.Response.Status {
case http.StatusNotFound:
code = gcode.CodeNotFound
msg = i18n.T(ctx, "not_found")
case http.StatusForbidden:
code = gcode.CodeNotAuthorized
msg = i18n.T(ctx, "forbidden")
case http.StatusUnauthorized:
code = gcode.CodeNotAuthorized
msg = i18n.T(ctx, "unauthorized")
default:
code = gcode.CodeUnknown
msg = i18n.T(ctx, "unknown_error")
}
} else {
code = gcode.CodeOK
msg = i18n.T(ctx, "success")
}
r.Response.WriteJson(ghttp.DefaultHandlerResponse{
Code: code.Code(),
Message: msg,
Data: res,
})
}

31
internal/model/admin.go Normal file
View File

@ -0,0 +1,31 @@
package model
type Admin struct {
}
type AdminLoginIn struct {
Username string
Password string
}
type AdminLoginOut struct {
Token string
}
type AdminInfoIn struct {
AdminId int64 // 管理员ID
}
type AdminInfoOut struct {
AdminId int64 // 管理员ID
Username string // 用户名
}
type AdminEditPassIn struct {
AdminId int64 // 管理员ID
OldPass string // 旧密码
NewPass string // 新密码
}
type AdminEditPassOut struct {
Success bool // 是否成功
}

13
internal/model/base.go Normal file
View File

@ -0,0 +1,13 @@
package model
import (
"github.com/gogf/gf/v2/os/gtime"
)
// Base 包含数据库表常见的公共字段
type Base struct {
Id int64 `json:"id" orm:"id,primary"` // 主键 ID
CreatedAt *gtime.Time `json:"created_at" orm:"created_at"` // 创建时间
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at"` // 更新时间
DeletedAt *gtime.Time `json:"deleted_at" orm:"deleted_at"` // 软删除时间
}

64
internal/model/book.go Normal file
View File

@ -0,0 +1,64 @@
package model
import "github.com/gogf/gf/v2/frame/g"
type Book struct {
g.Meta `orm:"table:books"`
Id int64 `json:"id"`
AuthorId int64 `json:"authorId"`
CategoryId int64 `json:"categoryId"`
Title string `json:"title"`
CoverUrl string `json:"coverUrl"`
Description string `json:"description"`
Status int `json:"status"`
WordsCount int `json:"wordsCount"`
ChaptersCount int `json:"chaptersCount"`
LatestChapterId int64 `json:"latestChapterId"`
Rating float64 `json:"rating"`
ReadCount int64 `json:"readCount"`
Tags string `json:"tags"`
IsRecommended int `json:"isRecommended"`
}
type BookListIn struct {
Page int
Size int
Title string
CategoryId int64
AuthorId int64
Status int
IsRecommended int
}
type BookListOut struct {
Total int
List []Book
}
type BookAddIn struct {
AuthorId int64
CategoryId int64
Title string
CoverUrl string
Description string
Status int
Tags string
IsRecommended int
}
type BookEditIn struct {
Id int64
AuthorId int64
CategoryId int64
Title string
CoverUrl string
Description string
Status int
Tags string
IsRecommended int
}
type BookDelIn struct {
Id int64
}
type BookCRUDOut struct {
Success bool
}

View File

@ -0,0 +1,38 @@
package model
import "github.com/gogf/gf/v2/frame/g"
type Category struct {
g.Meta `orm:"table:categories"`
Id int64 `json:"id" orm:"id"` // 分类ID
Name string `json:"name" orm:"name"` // 分类名称
Type int `json:type orm:"type"` // 类型1 男频2 女频
}
type CategoryListIn struct {
Page int
Size int
Name string
Type int
}
type CategoryListOut struct {
Total int
List []Category
}
type CategoryAddIn struct {
Name string
Type int // 类型1 男频2 女频
}
type CategoryEditIn struct {
Id int
Name string
Type int // 类型1 男频2 女频
}
type CategoryDelIn struct {
Id int
}
type CategoryCRUDOut struct {
Success bool
}

54
internal/model/chapter.go Normal file
View File

@ -0,0 +1,54 @@
package model
import "github.com/gogf/gf/v2/frame/g"
type Chapter struct {
g.Meta `orm:"table:chapters"`
Id int64 `json:"id"`
BookId int64 `json:"bookId"`
Title string `json:"title"`
Content string `json:"content"`
WordCount int `json:"wordCount"`
Sort int `json:"sort"`
IsLocked int `json:"isLocked"`
RequiredScore int `json:"requiredScore"`
}
type ChapterListIn struct {
Page int
Size int
BookId int64
Title string
IsLocked int
}
type ChapterListOut struct {
Total int
List []Chapter
}
type ChapterAddIn struct {
BookId int64
Title string
Content string
WordCount int
Sort int
IsLocked int
RequiredScore int
}
type ChapterEditIn struct {
Id int64
BookId int64
Title string
Content string
WordCount int
Sort int
IsLocked int
RequiredScore int
}
type ChapterDelIn struct {
Id int64
}
type ChapterCRUDOut struct {
Success bool
}

View File

@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Admins is the golang structure of table admins for DAO operations like Where/Data.
type Admins struct {
g.Meta `orm:"table:admins, do:true"`
Id interface{} // 管理员ID
Username interface{} // 管理员用户名
PasswordHash interface{} // 密码哈希
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
DeletedAt *gtime.Time // 软删除时间戳
}

View File

@ -0,0 +1,23 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Authors is the golang structure of table authors for DAO operations like Where/Data.
type Authors struct {
g.Meta `orm:"table:authors, do:true"`
Id interface{} // 作者ID
UserId interface{} // 用户ID
PenName interface{} // 笔名
Bio interface{} // 作者简介
Status interface{} // 状态1=正常2=禁用
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
DeletedAt *gtime.Time // 软删除时间戳
}

View File

@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// BookRatings is the golang structure of table book_ratings for DAO operations like Where/Data.
type BookRatings struct {
g.Meta `orm:"table:book_ratings, do:true"`
Id interface{} // 评分ID
UserId interface{} // 用户ID
BookId interface{} // 小说ID
Score interface{} // 评分0~10
Comment interface{} // 用户评论
CreatedAt *gtime.Time // 创建时间
}

View File

@ -0,0 +1,32 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Books is the golang structure of table books for DAO operations like Where/Data.
type Books struct {
g.Meta `orm:"table:books, do:true"`
Id interface{} // 小说ID
AuthorId interface{} // 作者ID
CategoryId interface{} // 分类ID
Title interface{} // 小说标题
CoverUrl interface{} // 封面图片URL
Description interface{} // 小说简介
Status interface{} // 状态1=连载中2=完结3=下架
WordsCount interface{} // 字数
ChaptersCount interface{} // 章节数
LatestChapterId interface{} // 最新章节ID
Rating interface{} // 评分0.00~10.00
ReadCount interface{} // 阅读人数
Tags interface{} // 标签(逗号分隔)
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
DeletedAt *gtime.Time // 软删除时间戳
IsRecommended interface{} // 是否推荐0=否1=是
}

View File

@ -0,0 +1,22 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Bookshelves is the golang structure of table bookshelves for DAO operations like Where/Data.
type Bookshelves struct {
g.Meta `orm:"table:bookshelves, do:true"`
Id interface{} // 记录ID
UserId interface{} // 用户ID
BookId interface{} // 小说ID
AddedAt *gtime.Time // 加入书架时间
LastReadChapterId interface{} // 最后阅读章节ID
LastReadPercent interface{} // 阅读进度百分比0.00~100.00
LastReadAt *gtime.Time // 最后阅读时间
}

View File

@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Categories is the golang structure of table categories for DAO operations like Where/Data.
type Categories struct {
g.Meta `orm:"table:categories, do:true"`
Id interface{} // 分类ID
Name interface{} // 分类名称
Type interface{} // 分类类型1=男频, 2=女频
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
DeletedAt *gtime.Time // 软删除时间戳
}

View File

@ -0,0 +1,26 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Chapters is the golang structure of table chapters for DAO operations like Where/Data.
type Chapters struct {
g.Meta `orm:"table:chapters, do:true"`
Id interface{} // 章节ID
BookId interface{} // 小说ID
Title interface{} // 章节标题
Content interface{} // 章节内容
WordCount interface{} // 章节字数
Sort interface{} // 排序序号
IsLocked interface{} // 是否锁定0=免费1=需积分解锁
RequiredScore interface{} // 解锁该章节所需积分
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
DeletedAt *gtime.Time // 软删除时间戳
}

View File

@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Feedbacks is the golang structure of table feedbacks for DAO operations like Where/Data.
type Feedbacks struct {
g.Meta `orm:"table:feedbacks, do:true"`
Id interface{} // 反馈ID
UserId interface{} // 用户ID
Content interface{} // 反馈内容
Status interface{} // 处理状态1=未处理2=处理中3=已处理
CreatedAt *gtime.Time // 反馈时间
UpdatedAt *gtime.Time // 更新时间
}

Some files were not shown because too many files have changed in this diff Show More