初始化v1
This commit is contained in:
370
internal/controller/admin/admin.go
Normal file
370
internal/controller/admin/admin.go
Normal file
@@ -0,0 +1,370 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
|
||||
"nl-video-api/internal/model/entity"
|
||||
"nl-video-api/utility/crypto"
|
||||
"nl-video-api/utility/jwt"
|
||||
"nl-video-api/utility/response"
|
||||
)
|
||||
|
||||
type AdminController struct{}
|
||||
|
||||
// AdminLoginReq 管理员登录请求
|
||||
type AdminLoginReq struct {
|
||||
Username string `json:"username" v:"required|length:3,20#用户名不能为空|用户名长度为3-20位"`
|
||||
Password string `json:"password" v:"required|length:6,20#密码不能为空|密码长度为6-20位"`
|
||||
}
|
||||
|
||||
// AdminLoginRes 管理员登录响应
|
||||
type AdminLoginRes struct {
|
||||
Token string `json:"token"`
|
||||
AdminInfo *entity.NlAdmin `json:"admin_info"`
|
||||
}
|
||||
|
||||
// AdminRegisterReq 管理员注册请求
|
||||
type AdminRegisterReq struct {
|
||||
Username string `json:"username" v:"required|length:3,20#用户名不能为空|用户名长度为3-20位"`
|
||||
Password string `json:"password" v:"required|length:6,20#密码不能为空|密码长度为6-20位"`
|
||||
Email string `json:"email" v:"required|email#邮箱不能为空|邮箱格式不正确"`
|
||||
RealName string `json:"real_name" v:"required|length:2,10#真实姓名不能为空|真实姓名长度为2-10位"`
|
||||
}
|
||||
|
||||
// AdminProfileRes 管理员信息响应
|
||||
type AdminProfileRes struct {
|
||||
AdminInfo *entity.NlAdmin `json:"admin_info"`
|
||||
}
|
||||
|
||||
// AdminUpdateReq 更新管理员信息请求
|
||||
type AdminUpdateReq struct {
|
||||
Email string `json:"email" v:"email#邮箱格式不正确"`
|
||||
RealName string `json:"real_name" v:"length:2,10#真实姓名长度为2-10位"`
|
||||
Avatar string `json:"avatar" v:"url#头像必须是有效的URL"`
|
||||
}
|
||||
|
||||
// Login 管理员登录
|
||||
func (c *AdminController) Login(r *ghttp.Request) {
|
||||
ctx := r.Context()
|
||||
var req AdminLoginReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据库连接
|
||||
if err := g.DB().PingMaster(); err != nil {
|
||||
g.Log().Error(ctx, "数据库连接失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "数据库连接失败,请稍后重试")
|
||||
return
|
||||
}
|
||||
|
||||
// 查询管理员信息
|
||||
var admin *entity.NlAdmin
|
||||
err := g.DB().Model("nl_admin").Where("username", req.Username).Scan(&admin)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "查询管理员失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "数据库查询失败")
|
||||
return
|
||||
}
|
||||
|
||||
if admin == nil {
|
||||
response.Error(r, response.CodeInvalidParam, "用户名或密码错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
if !crypto.CheckPassword(req.Password, admin.Password) {
|
||||
response.Error(r, response.CodeInvalidParam, "用户名或密码错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查管理员状态
|
||||
if admin.Status != 1 {
|
||||
response.Error(r, response.CodeForbidden, "账号已被禁用")
|
||||
return
|
||||
}
|
||||
|
||||
// 生成JWT Token
|
||||
token, err := jwt.GenerateToken(admin.Id, admin.Username, "admin")
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "生成Token失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 更新最后登录时间
|
||||
now := int(time.Now().Unix())
|
||||
_, err = g.DB().Model("nl_admin").Where("id", admin.Id).Update(g.Map{
|
||||
"last_login_time": now,
|
||||
"last_login_ip": r.GetClientIp(),
|
||||
"updated_at": now,
|
||||
})
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "更新登录时间失败:", err)
|
||||
}
|
||||
|
||||
// 格式化管理员信息返回
|
||||
adminMap := g.Map{
|
||||
"id": admin.Id,
|
||||
"username": admin.Username,
|
||||
"nick_name": admin.NickName,
|
||||
"avatar": admin.Avatar,
|
||||
"phone": admin.Phone,
|
||||
"email": admin.Email,
|
||||
"role_id": admin.RoleId,
|
||||
"department": admin.Department,
|
||||
"status": admin.Status,
|
||||
"last_login_time": response.FormatTimestamp(now),
|
||||
"created_at": response.FormatTimestamp(admin.CreatedAt),
|
||||
"updated_at": response.FormatTimestamp(now),
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"token": token,
|
||||
"admin_info": adminMap,
|
||||
})
|
||||
}
|
||||
|
||||
// Register 管理员注册
|
||||
func (c *AdminController) Register(r *ghttp.Request) {
|
||||
ctx := r.Context()
|
||||
var req AdminRegisterReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 检查用户名是否已存在
|
||||
count, err := g.DB().Model("nl_admin").Where("username", req.Username).Count()
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "查询管理员失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
if count > 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "用户名已存在")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查邮箱是否已存在
|
||||
count, err = g.DB().Model("nl_admin").Where("email", req.Email).Count()
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "查询邮箱失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
if count > 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "邮箱已存在")
|
||||
return
|
||||
}
|
||||
|
||||
// 加密密码
|
||||
hashedPassword, err := crypto.HashPassword(req.Password)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "密码加密失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 创建管理员
|
||||
now := int(time.Now().Unix())
|
||||
adminData := g.Map{
|
||||
"username": req.Username,
|
||||
"password": hashedPassword,
|
||||
"email": req.Email,
|
||||
"nick_name": req.RealName,
|
||||
"role_id": 1, // 默认角色ID
|
||||
"status": 1, // 默认启用
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
}
|
||||
|
||||
result, err := g.DB().Model("nl_admin").Insert(adminData)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "创建管理员失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取新创建的管理员ID
|
||||
adminId, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "获取管理员ID失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 生成JWT Token
|
||||
token, err := jwt.GenerateToken(gconv.Uint(adminId), req.Username, "admin")
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "生成Token失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 查询新创建的管理员信息
|
||||
var admin *entity.NlAdmin
|
||||
err = g.DB().Model("nl_admin").Where("id", adminId).Scan(&admin)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "查询管理员失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 清除密码字段
|
||||
admin.Password = ""
|
||||
|
||||
response.Success(r, AdminLoginRes{
|
||||
Token: token,
|
||||
AdminInfo: admin,
|
||||
})
|
||||
}
|
||||
|
||||
// Profile 获取管理员信息
|
||||
func (c *AdminController) Profile(r *ghttp.Request) {
|
||||
ctx := r.Context()
|
||||
// 从上下文获取管理员ID
|
||||
adminId := r.GetCtxVar("admin_id")
|
||||
if adminId == nil {
|
||||
response.Error(r, response.CodeUnauthorized, "未授权访问")
|
||||
return
|
||||
}
|
||||
|
||||
// 查询管理员信息
|
||||
var admin *entity.NlAdmin
|
||||
err := g.DB().Model("nl_admin").Where("id", adminId).Scan(&admin)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "查询管理员失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
if admin == nil {
|
||||
response.Error(r, response.CodeNotFound, "管理员不存在")
|
||||
return
|
||||
}
|
||||
|
||||
// 清除密码字段
|
||||
admin.Password = ""
|
||||
|
||||
response.Success(r, AdminProfileRes{
|
||||
AdminInfo: admin,
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateProfile 更新管理员信息
|
||||
func (c *AdminController) UpdateProfile(r *ghttp.Request) {
|
||||
ctx := r.Context()
|
||||
var req AdminUpdateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数错误: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从上下文获取管理员ID
|
||||
adminId := r.GetCtxVar("admin_id")
|
||||
if adminId == nil {
|
||||
response.Error(r, response.CodeUnauthorized, "未授权访问")
|
||||
return
|
||||
}
|
||||
|
||||
// 构建更新数据
|
||||
updateData := g.Map{
|
||||
"updated_at": int(time.Now().Unix()),
|
||||
}
|
||||
|
||||
if req.Email != "" {
|
||||
// 检查邮箱是否已被其他管理员使用
|
||||
count, err := g.DB().Model("nl_admin").Where("email", req.Email).Where("id !=", adminId).Count()
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "查询邮箱失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
if count > 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "邮箱已被使用")
|
||||
return
|
||||
}
|
||||
updateData["email"] = req.Email
|
||||
}
|
||||
|
||||
if req.RealName != "" {
|
||||
updateData["real_name"] = req.RealName
|
||||
}
|
||||
|
||||
if req.Avatar != "" {
|
||||
updateData["avatar"] = req.Avatar
|
||||
}
|
||||
|
||||
// 更新管理员信息
|
||||
_, err := g.DB().Model("nl_admin").Where("id", adminId).Update(updateData)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "更新管理员信息失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 查询更新后的管理员信息
|
||||
var admin *entity.NlAdmin
|
||||
err = g.DB().Model("nl_admin").Where("id", adminId).Scan(&admin)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "查询管理员失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 清除密码字段
|
||||
admin.Password = ""
|
||||
|
||||
response.Success(r, AdminProfileRes{
|
||||
AdminInfo: admin,
|
||||
})
|
||||
}
|
||||
|
||||
// Logout 管理员登出
|
||||
func (c *AdminController) Logout(r *ghttp.Request) {
|
||||
// 这里可以实现Token黑名单机制
|
||||
// 目前简单返回成功
|
||||
response.Success(r, nil)
|
||||
}
|
||||
|
||||
// RefreshToken 刷新Token
|
||||
func (c *AdminController) RefreshToken(r *ghttp.Request) {
|
||||
// 从上下文获取管理员ID
|
||||
adminId := r.GetCtxVar("admin_id")
|
||||
if adminId == nil {
|
||||
response.Error(r, response.CodeUnauthorized, "未授权访问")
|
||||
return
|
||||
}
|
||||
|
||||
// 查询管理员信息获取用户名
|
||||
var admin *entity.NlAdmin
|
||||
err := g.DB().Model("nl_admin").Where("id", adminId).Scan(&admin)
|
||||
if err != nil {
|
||||
g.Log().Error(r.Context(), "查询管理员失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
if admin == nil {
|
||||
response.Error(r, response.CodeNotFound, "管理员不存在")
|
||||
return
|
||||
}
|
||||
|
||||
// 生成新的Token
|
||||
token, err := jwt.GenerateToken(admin.Id, admin.Username, "admin")
|
||||
if err != nil {
|
||||
g.Log().Error(r.Context(), "生成Token失败:", err)
|
||||
response.Error(r, response.CodeInternalError, "系统错误")
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"token": token,
|
||||
})
|
||||
}
|
||||
74
internal/controller/admin/attachment.go
Normal file
74
internal/controller/admin/attachment.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/service"
|
||||
)
|
||||
|
||||
// AttachmentController 管理员附件管理控制器
|
||||
type AttachmentController struct{}
|
||||
|
||||
// NewAttachmentController 创建管理员附件管理控制器实例
|
||||
func NewAttachmentController() *AttachmentController {
|
||||
return &AttachmentController{}
|
||||
}
|
||||
|
||||
// GetList 获取附件列表
|
||||
func (c *AttachmentController) GetList(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminGetList(r)
|
||||
}
|
||||
|
||||
// GetDetail 获取附件详情
|
||||
func (c *AttachmentController) GetDetail(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminGetDetail(r)
|
||||
}
|
||||
|
||||
// Update 更新附件
|
||||
func (c *AttachmentController) Update(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminUpdate(r)
|
||||
}
|
||||
|
||||
// Delete 删除附件
|
||||
func (c *AttachmentController) Delete(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminDelete(r)
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除附件
|
||||
func (c *AttachmentController) BatchDelete(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminBatchDelete(r)
|
||||
}
|
||||
|
||||
// Download 下载附件
|
||||
func (c *AttachmentController) Download(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminDownload(r)
|
||||
}
|
||||
|
||||
// Move 移动附件
|
||||
func (c *AttachmentController) Move(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminMove(r)
|
||||
}
|
||||
|
||||
// Copy 复制附件
|
||||
func (c *AttachmentController) Copy(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminCopy(r)
|
||||
}
|
||||
|
||||
// Rename 重命名附件
|
||||
func (c *AttachmentController) Rename(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminRename(r)
|
||||
}
|
||||
|
||||
// Search 搜索附件
|
||||
func (c *AttachmentController) Search(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminSearch(r)
|
||||
}
|
||||
|
||||
// GetCategoryList 获取附件分类列表
|
||||
func (c *AttachmentController) GetCategoryList(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminGetCategoryList(r)
|
||||
}
|
||||
|
||||
// GetStatistics 获取附件统计
|
||||
func (c *AttachmentController) GetStatistics(r *ghttp.Request) {
|
||||
service.NewAttachmentService().AdminGetStatistics(r)
|
||||
}
|
||||
162
internal/controller/admin/banner.go
Normal file
162
internal/controller/admin/banner.go
Normal file
@@ -0,0 +1,162 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/service"
|
||||
"nl-video-api/utility/response"
|
||||
)
|
||||
|
||||
var Banner = cAdminBanner{}
|
||||
|
||||
type cAdminBanner struct{}
|
||||
|
||||
// Create 创建轮播图
|
||||
func (c *cAdminBanner) Create(r *ghttp.Request) {
|
||||
service.Banner.AdminCreate(r)
|
||||
}
|
||||
|
||||
// Update 更新轮播图
|
||||
func (c *cAdminBanner) Update(r *ghttp.Request) {
|
||||
var req *service.AdminBannerUpdateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL路径获取ID
|
||||
if req.Id == 0 {
|
||||
idStr := r.Get("id").String()
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
req.Id = uint(id)
|
||||
}
|
||||
}
|
||||
|
||||
err := service.Banner.AdminUpdate(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 删除轮播图
|
||||
func (c *cAdminBanner) Delete(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, 1001, "轮播图ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
req := &service.AdminBannerDeleteReq{Id: uint(id)}
|
||||
err = service.Banner.AdminDelete(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "删除成功",
|
||||
})
|
||||
}
|
||||
|
||||
// GetDetail 获取轮播图详情
|
||||
func (c *cAdminBanner) GetDetail(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, 1001, "轮播图ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
req := &service.AdminBannerDetailReq{Id: uint(id)}
|
||||
result, err := service.Banner.AdminGetDetail(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, result)
|
||||
}
|
||||
|
||||
// GetList 获取轮播图列表
|
||||
func (c *cAdminBanner) GetList(r *ghttp.Request) {
|
||||
var req *service.AdminBannerListReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 设置默认分页参数
|
||||
if req.Page <= 0 {
|
||||
req.Page = 1
|
||||
}
|
||||
if req.Size <= 0 {
|
||||
req.Size = 10
|
||||
}
|
||||
|
||||
result, err := service.Banner.AdminGetList(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, result)
|
||||
}
|
||||
|
||||
// UpdateStatus 更新轮播图状态
|
||||
func (c *cAdminBanner) UpdateStatus(r *ghttp.Request) {
|
||||
var req *service.AdminBannerUpdateStatusReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL路径获取ID
|
||||
if req.Id == 0 {
|
||||
idStr := r.Get("id").String()
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
req.Id = uint(id)
|
||||
}
|
||||
}
|
||||
|
||||
err := service.Banner.AdminUpdateStatus(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "状态更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除轮播图
|
||||
func (c *cAdminBanner) BatchDelete(r *ghttp.Request) {
|
||||
var req *service.AdminBannerBatchDeleteReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(req.Ids) == 0 {
|
||||
response.Error(r, 1001, "轮播图ID列表不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
err := service.Banner.AdminBatchDelete(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "批量删除成功",
|
||||
})
|
||||
}
|
||||
27
internal/controller/admin/comment.go
Normal file
27
internal/controller/admin/comment.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// CommentController 管理员评论控制器
|
||||
type CommentController struct{}
|
||||
|
||||
var Comment = &CommentController{}
|
||||
|
||||
// List 管理员评论列表
|
||||
func (c *CommentController) List(r *ghttp.Request) {
|
||||
service.Comment.AdminList(r)
|
||||
}
|
||||
|
||||
// UpdateStatus 更新评论状态
|
||||
func (c *CommentController) UpdateStatus(r *ghttp.Request) {
|
||||
service.Comment.AdminUpdateStatus(r)
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除评论
|
||||
func (c *CommentController) BatchDelete(r *ghttp.Request) {
|
||||
service.Comment.AdminBatchDelete(r)
|
||||
}
|
||||
109
internal/controller/admin/config.go
Normal file
109
internal/controller/admin/config.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/service"
|
||||
)
|
||||
|
||||
// ConfigController 系统配置管理控制器
|
||||
type ConfigController struct{}
|
||||
|
||||
// NewConfigController 创建系统配置管理控制器实例
|
||||
func NewConfigController() *ConfigController {
|
||||
return &ConfigController{}
|
||||
}
|
||||
|
||||
// List 获取配置列表
|
||||
func (c *ConfigController) List(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminList(r)
|
||||
}
|
||||
|
||||
// Detail 获取配置详情
|
||||
func (c *ConfigController) Detail(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminDetail(r)
|
||||
}
|
||||
|
||||
// Create 创建配置
|
||||
func (c *ConfigController) Create(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminCreate(r)
|
||||
}
|
||||
|
||||
// Update 更新配置
|
||||
func (c *ConfigController) Update(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminUpdate(r)
|
||||
}
|
||||
|
||||
// Delete 删除配置
|
||||
func (c *ConfigController) Delete(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminDelete(r)
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除配置
|
||||
func (c *ConfigController) BatchDelete(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminBatchDelete(r)
|
||||
}
|
||||
|
||||
// GetByKey 根据键获取配置
|
||||
func (c *ConfigController) GetByKey(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminGetByKey(r)
|
||||
}
|
||||
|
||||
// GetByGroup 根据分组获取配置
|
||||
func (c *ConfigController) GetByGroup(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminGetByGroup(r)
|
||||
}
|
||||
|
||||
// Set 设置配置
|
||||
func (c *ConfigController) Set(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminSet(r)
|
||||
}
|
||||
|
||||
// BatchSet 批量设置配置
|
||||
func (c *ConfigController) BatchSet(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminBatchSet(r)
|
||||
}
|
||||
|
||||
// GetGroupList 获取配置分组列表
|
||||
func (c *ConfigController) GetGroupList(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminGetGroupList(r)
|
||||
}
|
||||
|
||||
// Export 导出配置
|
||||
func (c *ConfigController) Export(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminExport(r)
|
||||
}
|
||||
|
||||
// Import 导入配置
|
||||
func (c *ConfigController) Import(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminImport(r)
|
||||
}
|
||||
|
||||
// Cache 缓存配置
|
||||
func (c *ConfigController) Cache(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminCache(r)
|
||||
}
|
||||
|
||||
// ClearCache 清除配置缓存
|
||||
func (c *ConfigController) ClearCache(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminClearCache(r)
|
||||
}
|
||||
|
||||
// Validate 验证配置
|
||||
func (c *ConfigController) Validate(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminValidate(r)
|
||||
}
|
||||
|
||||
// Backup 备份配置
|
||||
func (c *ConfigController) Backup(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminBackup(r)
|
||||
}
|
||||
|
||||
// Restore 恢复配置
|
||||
func (c *ConfigController) Restore(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminRestore(r)
|
||||
}
|
||||
|
||||
// GetHistory 获取配置历史
|
||||
func (c *ConfigController) GetHistory(r *ghttp.Request) {
|
||||
service.NewConfigService().AdminGetHistory(r)
|
||||
}
|
||||
88
internal/controller/admin/log.go
Normal file
88
internal/controller/admin/log.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/service"
|
||||
)
|
||||
|
||||
// LogController 日志管理控制器
|
||||
type LogController struct{}
|
||||
|
||||
// NewLogController 创建日志管理控制器实例
|
||||
func NewLogController() *LogController {
|
||||
return &LogController{}
|
||||
}
|
||||
|
||||
// ===== 管理员日志管理 =====
|
||||
|
||||
// AdminLogList 获取管理员日志列表
|
||||
func (c *LogController) AdminLogList(r *ghttp.Request) {
|
||||
service.NewLogService().AdminLogList(r)
|
||||
}
|
||||
|
||||
// AdminLogDetail 获取管理员日志详情
|
||||
func (c *LogController) AdminLogDetail(r *ghttp.Request) {
|
||||
service.NewLogService().AdminLogDetail(r)
|
||||
}
|
||||
|
||||
// AdminLogDelete 删除管理员日志
|
||||
func (c *LogController) AdminLogDelete(r *ghttp.Request) {
|
||||
service.NewLogService().AdminLogDelete(r)
|
||||
}
|
||||
|
||||
// AdminLogBatchDelete 批量删除管理员日志
|
||||
func (c *LogController) AdminLogBatchDelete(r *ghttp.Request) {
|
||||
service.NewLogService().AdminLogBatchDelete(r)
|
||||
}
|
||||
|
||||
// AdminLogClear 清空管理员日志
|
||||
func (c *LogController) AdminLogClear(r *ghttp.Request) {
|
||||
service.NewLogService().AdminLogClear(r)
|
||||
}
|
||||
|
||||
// AdminLogExport 导出管理员日志
|
||||
func (c *LogController) AdminLogExport(r *ghttp.Request) {
|
||||
service.NewLogService().AdminLogExport(r)
|
||||
}
|
||||
|
||||
// AdminLogStats 管理员日志统计
|
||||
func (c *LogController) AdminLogStats(r *ghttp.Request) {
|
||||
service.NewLogService().AdminLogStats(r)
|
||||
}
|
||||
|
||||
// ===== 用户日志管理 =====
|
||||
|
||||
// UserLogList 获取用户日志列表
|
||||
func (c *LogController) UserLogList(r *ghttp.Request) {
|
||||
service.NewLogService().UserLogList(r)
|
||||
}
|
||||
|
||||
// UserLogDetail 获取用户日志详情
|
||||
func (c *LogController) UserLogDetail(r *ghttp.Request) {
|
||||
service.NewLogService().UserLogDetail(r)
|
||||
}
|
||||
|
||||
// UserLogDelete 删除用户日志
|
||||
func (c *LogController) UserLogDelete(r *ghttp.Request) {
|
||||
service.NewLogService().UserLogDelete(r)
|
||||
}
|
||||
|
||||
// UserLogBatchDelete 批量删除用户日志
|
||||
func (c *LogController) UserLogBatchDelete(r *ghttp.Request) {
|
||||
service.NewLogService().UserLogBatchDelete(r)
|
||||
}
|
||||
|
||||
// UserLogClear 清空用户日志
|
||||
func (c *LogController) UserLogClear(r *ghttp.Request) {
|
||||
service.NewLogService().UserLogClear(r)
|
||||
}
|
||||
|
||||
// UserLogExport 导出用户日志
|
||||
func (c *LogController) UserLogExport(r *ghttp.Request) {
|
||||
service.NewLogService().UserLogExport(r)
|
||||
}
|
||||
|
||||
// UserLogStats 用户日志统计
|
||||
func (c *LogController) UserLogStats(r *ghttp.Request) {
|
||||
service.NewLogService().UserLogStats(r)
|
||||
}
|
||||
74
internal/controller/admin/payment_order.go
Normal file
74
internal/controller/admin/payment_order.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/service"
|
||||
"nl-video-api/utility/response"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
var PaymentOrder = cAdminPaymentOrder{}
|
||||
|
||||
type cAdminPaymentOrder struct{}
|
||||
|
||||
// GetList 管理员获取支付订单列表
|
||||
func (c *cAdminPaymentOrder) GetList(r *ghttp.Request) {
|
||||
service.NewPaymentOrderService().AdminGetList(r)
|
||||
}
|
||||
|
||||
// GetDetail 管理员获取支付订单详情
|
||||
func (c *cAdminPaymentOrder) GetDetail(r *ghttp.Request) {
|
||||
service.NewPaymentOrderService().AdminGetDetail(r)
|
||||
}
|
||||
|
||||
// Refund 管理员订单退款
|
||||
func (c *cAdminPaymentOrder) Refund(r *ghttp.Request) {
|
||||
// 获取请求参数
|
||||
id := r.Get("id").Uint()
|
||||
reason := r.Get("reason").String()
|
||||
|
||||
if id == 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "订单ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
req := &service.PaymentOrderRefundReq{
|
||||
Id: id,
|
||||
Reason: reason,
|
||||
}
|
||||
|
||||
err := service.NewPaymentOrderService().AdminRefund(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeInternalError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, "退款成功")
|
||||
}
|
||||
|
||||
// GetStatistics 获取支付统计
|
||||
func (c *cAdminPaymentOrder) GetStatistics(r *ghttp.Request) {
|
||||
startDate := r.Get("start_date").String()
|
||||
endDate := r.Get("end_date").String()
|
||||
|
||||
// 设置默认时间范围
|
||||
if startDate == "" {
|
||||
startDate = "2024-01-01"
|
||||
}
|
||||
if endDate == "" {
|
||||
endDate = "2024-12-31"
|
||||
}
|
||||
|
||||
result, err := service.NewPaymentOrderService().GetStatistics(r.Context(), startDate, endDate)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeInternalError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, result)
|
||||
}
|
||||
|
||||
// Create 创建支付订单
|
||||
func (c *cAdminPaymentOrder) Create(r *ghttp.Request) {
|
||||
service.NewPaymentOrderService().Create(r)
|
||||
}
|
||||
245
internal/controller/admin/permission.go
Normal file
245
internal/controller/admin/permission.go
Normal file
@@ -0,0 +1,245 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/dao"
|
||||
"nl-video-api/internal/service/auth"
|
||||
"nl-video-api/utility/response"
|
||||
)
|
||||
|
||||
// PermissionController 权限控制器
|
||||
type PermissionController struct{}
|
||||
|
||||
var Permission = &PermissionController{}
|
||||
|
||||
// Create 创建权限
|
||||
func (c *PermissionController) Create(r *ghttp.Request) {
|
||||
var req *auth.PermissionCreateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
id, err := auth.Permission.Create(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"id": id,
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新权限
|
||||
func (c *PermissionController) Update(r *ghttp.Request) {
|
||||
var req *auth.PermissionUpdateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL路径获取ID
|
||||
if req.Id == 0 {
|
||||
idStr := r.Get("id").String()
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
req.Id = id
|
||||
}
|
||||
}
|
||||
|
||||
if req.Id <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "权限ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
err := auth.Permission.Update(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, "更新成功")
|
||||
}
|
||||
|
||||
// GetById 获取权限详情
|
||||
func (c *PermissionController) GetById(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "权限ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
permission, err := auth.Permission.GetById(r.Context(), id)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if permission == nil {
|
||||
response.Error(r, response.CodeNotFound, "权限不存在")
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, permission)
|
||||
}
|
||||
|
||||
// GetList 获取权限列表
|
||||
func (c *PermissionController) GetList(r *ghttp.Request) {
|
||||
var req *dao.PermissionListReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
permissions, total, err := auth.Permission.GetList(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"list": permissions,
|
||||
"total": total,
|
||||
"page": req.Page,
|
||||
"page_size": req.PageSize,
|
||||
})
|
||||
}
|
||||
|
||||
// GetTree 获取权限树形结构
|
||||
func (c *PermissionController) GetTree(r *ghttp.Request) {
|
||||
permissions, err := auth.Permission.GetTree(r.Context())
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"tree": permissions,
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 删除权限
|
||||
func (c *PermissionController) Delete(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "权限ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
err = auth.Permission.Delete(r.Context(), id)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, "删除成功")
|
||||
}
|
||||
|
||||
// GetMenuPermissions 获取菜单权限
|
||||
func (c *PermissionController) GetMenuPermissions(r *ghttp.Request) {
|
||||
permissions, err := auth.Permission.GetMenuPermissions(r.Context())
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"list": permissions,
|
||||
})
|
||||
}
|
||||
|
||||
// GetApiPermissions 获取API权限
|
||||
func (c *PermissionController) GetApiPermissions(r *ghttp.Request) {
|
||||
permissions, err := auth.Permission.GetApiPermissions(r.Context())
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"list": permissions,
|
||||
})
|
||||
}
|
||||
|
||||
// GetUserPermissions 获取用户权限
|
||||
func (c *PermissionController) GetUserPermissions(r *ghttp.Request) {
|
||||
userIdStr := r.Get("user_id").String()
|
||||
userId, err := strconv.Atoi(userIdStr)
|
||||
if err != nil || userId <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "用户ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
permissions, err := auth.Permission.GetUserPermissions(r.Context(), userId)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"list": permissions,
|
||||
})
|
||||
}
|
||||
|
||||
// CheckPermission 检查权限
|
||||
func (c *PermissionController) CheckPermission(r *ghttp.Request) {
|
||||
userIdStr := r.Get("user_id").String()
|
||||
userId, err := strconv.Atoi(userIdStr)
|
||||
if err != nil || userId <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "用户ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
permissionCode := r.Get("permission_code").String()
|
||||
if permissionCode == "" {
|
||||
response.Error(r, response.CodeInvalidParam, "权限编码不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
hasPermission, err := auth.Permission.CheckUserPermission(r.Context(), userId, permissionCode)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"has_permission": hasPermission,
|
||||
})
|
||||
}
|
||||
|
||||
// CheckApiPermission 检查API权限
|
||||
func (c *PermissionController) CheckApiPermission(r *ghttp.Request) {
|
||||
userIdStr := r.Get("user_id").String()
|
||||
userId, err := strconv.Atoi(userIdStr)
|
||||
if err != nil || userId <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "用户ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
apiPath := r.Get("api_path").String()
|
||||
if apiPath == "" {
|
||||
response.Error(r, response.CodeInvalidParam, "API路径不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
method := r.Get("method").String()
|
||||
if method == "" {
|
||||
response.Error(r, response.CodeInvalidParam, "请求方法不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
hasPermission, err := auth.Permission.CheckApiPermission(r.Context(), userId, apiPath, method)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"has_permission": hasPermission,
|
||||
})
|
||||
}
|
||||
270
internal/controller/admin/role.go
Normal file
270
internal/controller/admin/role.go
Normal file
@@ -0,0 +1,270 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/dao"
|
||||
"nl-video-api/internal/service/auth"
|
||||
"nl-video-api/utility/response"
|
||||
)
|
||||
|
||||
// RoleController 角色控制器
|
||||
type RoleController struct{}
|
||||
|
||||
var Role = &RoleController{}
|
||||
|
||||
// Create 创建角色
|
||||
func (c *RoleController) Create(r *ghttp.Request) {
|
||||
var req *auth.RoleCreateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
id, err := auth.Role.Create(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"id": id,
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新角色
|
||||
func (c *RoleController) Update(r *ghttp.Request) {
|
||||
var req *auth.RoleUpdateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL路径获取ID
|
||||
if req.Id == 0 {
|
||||
idStr := r.Get("id").String()
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
req.Id = id
|
||||
}
|
||||
}
|
||||
|
||||
if req.Id <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "角色ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
err := auth.Role.Update(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, "更新成功")
|
||||
}
|
||||
|
||||
// GetById 获取角色详情
|
||||
func (c *RoleController) GetById(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "角色ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
role, err := auth.Role.GetById(r.Context(), id)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if role == nil {
|
||||
response.Error(r, response.CodeNotFound, "角色不存在")
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, role)
|
||||
}
|
||||
|
||||
// GetList 获取角色列表
|
||||
func (c *RoleController) GetList(r *ghttp.Request) {
|
||||
var req *dao.RoleListReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
roles, total, err := auth.Role.GetList(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"list": roles,
|
||||
"total": total,
|
||||
"page": req.Page,
|
||||
"page_size": req.PageSize,
|
||||
})
|
||||
}
|
||||
|
||||
// GetAll 获取所有角色
|
||||
func (c *RoleController) GetAll(r *ghttp.Request) {
|
||||
roles, err := auth.Role.GetAll(r.Context())
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"list": roles,
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 删除角色
|
||||
func (c *RoleController) Delete(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "角色ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
err = auth.Role.Delete(r.Context(), id)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, "删除成功")
|
||||
}
|
||||
|
||||
// AssignPermissions 为角色分配权限
|
||||
func (c *RoleController) AssignPermissions(r *ghttp.Request) {
|
||||
var req *auth.RolePermissionReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL路径获取角色ID
|
||||
if req.RoleId == 0 {
|
||||
idStr := r.Get("id").String()
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
req.RoleId = id
|
||||
}
|
||||
}
|
||||
|
||||
if req.RoleId <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "角色ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
err := auth.Role.AssignPermissions(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, "权限分配成功")
|
||||
}
|
||||
|
||||
// GetRolePermissions 获取角色权限
|
||||
func (c *RoleController) GetRolePermissions(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "角色ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
permissions, err := auth.Role.GetRolePermissions(r.Context(), id)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 同时返回权限ID列表,方便前端处理
|
||||
permissionIds, _ := auth.Role.GetRolePermissionIds(r.Context(), id)
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"permissions": permissions,
|
||||
"permission_ids": permissionIds,
|
||||
})
|
||||
}
|
||||
|
||||
// BatchUpdateStatus 批量更新角色状态
|
||||
func (c *RoleController) BatchUpdateStatus(r *ghttp.Request) {
|
||||
type BatchUpdateReq struct {
|
||||
Ids []int `json:"ids" v:"required#请选择要操作的角色"`
|
||||
Status int `json:"status" v:"required|in:0,1#状态只能为0或1"`
|
||||
}
|
||||
|
||||
var req BatchUpdateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(req.Ids) == 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "请选择要操作的角色")
|
||||
return
|
||||
}
|
||||
|
||||
err := auth.Role.BatchUpdateStatus(r.Context(), req.Ids, req.Status)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"count": len(req.Ids),
|
||||
})
|
||||
}
|
||||
|
||||
// CopyRole 复制角色
|
||||
func (c *RoleController) CopyRole(r *ghttp.Request) {
|
||||
type CopyRoleReq struct {
|
||||
SourceId int `json:"source_id" v:"required|min:1#源角色ID不能为空"`
|
||||
Name string `json:"name" v:"required|length:2,50#角色名称不能为空|角色名称长度为2-50位"`
|
||||
Code string `json:"code" v:"required|length:2,50#角色编码不能为空|角色编码长度为2-50位"`
|
||||
}
|
||||
|
||||
var req CopyRoleReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
newRoleId, err := auth.Role.CopyRole(r.Context(), req.SourceId, req.Name, req.Code)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"id": newRoleId,
|
||||
})
|
||||
}
|
||||
|
||||
// GetRolesByLevel 根据等级获取角色
|
||||
func (c *RoleController) GetRolesByLevel(r *ghttp.Request) {
|
||||
levelStr := r.Get("level").String()
|
||||
level, err := strconv.Atoi(levelStr)
|
||||
if err != nil || level <= 0 {
|
||||
response.Error(r, response.CodeInvalidParam, "角色等级无效")
|
||||
return
|
||||
}
|
||||
|
||||
roles, err := auth.Role.GetRolesByLevel(r.Context(), level)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"list": roles,
|
||||
"level": level,
|
||||
})
|
||||
}
|
||||
295
internal/controller/admin/user.go
Normal file
295
internal/controller/admin/user.go
Normal file
@@ -0,0 +1,295 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"nl-video-api/internal/dao"
|
||||
"nl-video-api/internal/service/user"
|
||||
"nl-video-api/utility/crypto"
|
||||
"nl-video-api/utility/response"
|
||||
)
|
||||
|
||||
var User = cAdminUser{}
|
||||
|
||||
type cAdminUser struct{}
|
||||
|
||||
// AdminUserCreateReq 管理员创建用户请求
|
||||
type AdminUserCreateReq struct {
|
||||
Username string `json:"username" v:"required|length:3,20#用户名不能为空|用户名长度为3-20位"`
|
||||
Password string `json:"password" v:"required|length:6,20#密码不能为空|密码长度为6-20位"`
|
||||
Email string `json:"email" v:"email#邮箱格式不正确"`
|
||||
Phone string `json:"phone" v:"phone#手机号格式不正确"`
|
||||
Status int `json:"status" v:"in:0,1#状态值不正确"`
|
||||
}
|
||||
|
||||
// AdminUserUpdateReq 管理员更新用户请求
|
||||
type AdminUserUpdateReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#用户ID不能为空"`
|
||||
Username string `json:"username" v:"length:3,20#用户名长度为3-20位"`
|
||||
Email string `json:"email" v:"email#邮箱格式不正确"`
|
||||
Phone string `json:"phone" v:"phone#手机号格式不正确"`
|
||||
Status int `json:"status" v:"in:0,1#状态值不正确"`
|
||||
}
|
||||
|
||||
// AdminUserDetailReq 管理员获取用户详情请求
|
||||
type AdminUserDetailReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#用户ID不能为空"`
|
||||
}
|
||||
|
||||
// AdminUserListReq 管理员获取用户列表请求
|
||||
type AdminUserListReq struct {
|
||||
Page int `json:"page" v:"min:1#页码不能小于1"`
|
||||
Size int `json:"size" v:"min:1|max:100#每页数量不能小于1且不能大于100"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Status int `json:"status" v:"in:-1,0,1#状态值不正确"`
|
||||
}
|
||||
|
||||
// AdminUserDeleteReq 管理员删除用户请求
|
||||
type AdminUserDeleteReq struct {
|
||||
Id uint `json:"id" v:"required|min:1#用户ID不能为空"`
|
||||
}
|
||||
|
||||
// Create 管理员创建用户
|
||||
func (c *cAdminUser) Create(r *ghttp.Request) {
|
||||
var req *AdminUserCreateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 构造用户创建请求
|
||||
createReq := &user.UserCreateReq{
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
Email: req.Email,
|
||||
Phone: req.Phone,
|
||||
}
|
||||
|
||||
// 调用用户服务创建用户
|
||||
_, err := user.User.Create(r.Context(), createReq)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "创建成功",
|
||||
})
|
||||
}
|
||||
|
||||
// Update 管理员更新用户
|
||||
func (c *cAdminUser) Update(r *ghttp.Request) {
|
||||
var req *AdminUserUpdateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL路径获取ID
|
||||
if req.Id == 0 {
|
||||
idStr := r.Get("id").String()
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
req.Id = uint(id)
|
||||
}
|
||||
}
|
||||
|
||||
if req.Id == 0 {
|
||||
response.Error(r, 1001, "用户ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 构造用户更新请求
|
||||
updateReq := &user.UserUpdateReq{
|
||||
Id: int(req.Id),
|
||||
Username: req.Username,
|
||||
Email: req.Email,
|
||||
Phone: req.Phone,
|
||||
Status: req.Status,
|
||||
}
|
||||
|
||||
// 调用用户服务更新用户
|
||||
err := user.User.Update(r.Context(), updateReq)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// GetDetail 管理员获取用户详情
|
||||
func (c *cAdminUser) GetDetail(r *ghttp.Request) {
|
||||
var req *AdminUserDetailReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL路径获取ID
|
||||
if req.Id == 0 {
|
||||
idStr := r.Get("id").String()
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
req.Id = uint(id)
|
||||
}
|
||||
}
|
||||
|
||||
if req.Id == 0 {
|
||||
response.Error(r, 1001, "用户ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 调用用户服务获取用户详情
|
||||
result, err := user.User.GetById(r.Context(), int(req.Id))
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, result)
|
||||
}
|
||||
|
||||
// GetList 管理员获取用户列表
|
||||
func (c *cAdminUser) GetList(r *ghttp.Request) {
|
||||
var req *AdminUserListReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 设置默认分页参数
|
||||
if req.Page <= 0 {
|
||||
req.Page = 1
|
||||
}
|
||||
if req.Size <= 0 {
|
||||
req.Size = 10
|
||||
}
|
||||
|
||||
// 构造用户列表请求
|
||||
listReq := &dao.UserListReq{
|
||||
Page: req.Page,
|
||||
Username: req.Username,
|
||||
Email: req.Email,
|
||||
Status: req.Status,
|
||||
}
|
||||
|
||||
// 调用用户服务获取用户列表
|
||||
result, total, err := user.User.GetList(r.Context(), listReq)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 构造响应数据
|
||||
responseData := g.Map{
|
||||
"list": result,
|
||||
"total": total,
|
||||
"page": req.Page,
|
||||
"size": req.Size,
|
||||
}
|
||||
|
||||
response.Success(r, responseData)
|
||||
}
|
||||
|
||||
// Delete 管理员删除用户
|
||||
func (c *cAdminUser) Delete(r *ghttp.Request) {
|
||||
var req *AdminUserDeleteReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL路径获取ID
|
||||
if req.Id == 0 {
|
||||
idStr := r.Get("id").String()
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
req.Id = uint(id)
|
||||
}
|
||||
}
|
||||
|
||||
if req.Id == 0 {
|
||||
response.Error(r, 1001, "用户ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 调用用户服务删除用户
|
||||
err := user.User.Delete(r.Context(), int(req.Id))
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "删除成功",
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateStatus 管理员更新用户状态
|
||||
func (c *cAdminUser) UpdateStatus(r *ghttp.Request) {
|
||||
id := r.Get("id").Uint()
|
||||
status := r.Get("status").Int()
|
||||
|
||||
if id == 0 {
|
||||
response.Error(r, 1001, "用户ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 构造用户更新请求
|
||||
updateReq := &user.UserUpdateReq{
|
||||
Id: int(id),
|
||||
Status: status,
|
||||
}
|
||||
|
||||
// 调用用户服务更新用户
|
||||
err := user.User.Update(r.Context(), updateReq)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "状态更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// ResetPassword 管理员重置用户密码
|
||||
func (c *cAdminUser) ResetPassword(r *ghttp.Request) {
|
||||
id := r.Get("id").Uint()
|
||||
newPassword := r.Get("password").String()
|
||||
|
||||
if id == 0 {
|
||||
response.Error(r, 1001, "用户ID不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
if newPassword == "" {
|
||||
response.Error(r, 1001, "新密码不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 直接更新密码,管理员重置不需要原密码验证
|
||||
hashedPassword, err := crypto.HashPassword(newPassword)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, "密码加密失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 更新用户密码
|
||||
_, err = g.DB().Model("nl_user").Ctx(r.Context()).Where("id", id).Data(g.Map{
|
||||
"password": hashedPassword,
|
||||
"updated_at": gtime.Now(),
|
||||
}).Update()
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "密码重置成功",
|
||||
})
|
||||
}
|
||||
59
internal/controller/admin/vip_level.go
Normal file
59
internal/controller/admin/vip_level.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/service"
|
||||
)
|
||||
|
||||
// VipLevelController VIP等级控制器(管理端)
|
||||
type VipLevelController struct{}
|
||||
|
||||
// NewVipLevelController 创建VIP等级控制器实例
|
||||
func NewVipLevelController() *VipLevelController {
|
||||
return &VipLevelController{}
|
||||
}
|
||||
|
||||
// Create 创建VIP等级
|
||||
func (c *VipLevelController) Create(r *ghttp.Request) {
|
||||
service.VipLevel.AdminCreate(r)
|
||||
}
|
||||
|
||||
// Update 更新VIP等级
|
||||
func (c *VipLevelController) Update(r *ghttp.Request) {
|
||||
service.VipLevel.AdminUpdate(r)
|
||||
}
|
||||
|
||||
// List 获取VIP等级列表
|
||||
func (c *VipLevelController) List(r *ghttp.Request) {
|
||||
service.VipLevel.AdminGetList(r)
|
||||
}
|
||||
|
||||
// Detail 获取VIP等级详情
|
||||
func (c *VipLevelController) Detail(r *ghttp.Request) {
|
||||
service.VipLevel.GetDetail(r)
|
||||
}
|
||||
|
||||
// Delete 删除VIP等级
|
||||
func (c *VipLevelController) Delete(r *ghttp.Request) {
|
||||
service.VipLevel.AdminDelete(r)
|
||||
}
|
||||
|
||||
// UpdateStatus 更新VIP等级状态
|
||||
func (c *VipLevelController) UpdateStatus(r *ghttp.Request) {
|
||||
service.VipLevel.AdminUpdateStatus(r)
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除VIP等级
|
||||
func (c *VipLevelController) BatchDelete(r *ghttp.Request) {
|
||||
service.VipLevel.AdminBatchDelete(r)
|
||||
}
|
||||
|
||||
// GetAll 获取所有VIP等级
|
||||
func (c *VipLevelController) GetAll(r *ghttp.Request) {
|
||||
service.VipLevel.GetAll(r)
|
||||
}
|
||||
|
||||
// GetActiveList 获取启用的VIP等级列表
|
||||
func (c *VipLevelController) GetActiveList(r *ghttp.Request) {
|
||||
service.VipLevel.GetActiveList(r)
|
||||
}
|
||||
283
internal/controller/auth/auth.go
Normal file
283
internal/controller/auth/auth.go
Normal file
@@ -0,0 +1,283 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/consts"
|
||||
"nl-video-api/internal/model/entity"
|
||||
"nl-video-api/utility/crypto"
|
||||
"nl-video-api/utility/jwt"
|
||||
"nl-video-api/utility/response"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
type cAuth struct{}
|
||||
|
||||
var Auth = cAuth{}
|
||||
|
||||
// LoginReq 登录请求
|
||||
type LoginReq struct {
|
||||
Username string `json:"username" v:"required#用户名不能为空"`
|
||||
Password string `json:"password" v:"required#密码不能为空"`
|
||||
}
|
||||
|
||||
// RegisterReq 注册请求
|
||||
type RegisterReq struct {
|
||||
Username string `json:"username" v:"required|length:3,20#用户名不能为空|用户名长度为3-20位"`
|
||||
Phone string `json:"phone" v:"required|phone#手机号不能为空|手机号格式错误"`
|
||||
Password string `json:"password" v:"required|length:6,20#密码不能为空|密码长度为6-20位"`
|
||||
Code string `json:"code" v:"required#验证码不能为空"`
|
||||
}
|
||||
|
||||
// UpdateProfileReq 更新资料请求
|
||||
type UpdateProfileReq struct {
|
||||
Nickname string `json:"nickname" v:"length:1,20#昵称长度为1-20位"`
|
||||
Avatar string `json:"avatar" v:"url#头像格式错误"`
|
||||
Gender int `json:"gender" v:"in:0,1,2#性别参数错误"`
|
||||
Birthday string `json:"birthday" v:"date#生日格式错误"`
|
||||
}
|
||||
|
||||
// Login 用户登录
|
||||
func (c *cAuth) Login(r *ghttp.Request) {
|
||||
var req LoginReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 查询用户
|
||||
var user entity.NlUser
|
||||
err := g.DB().Model("nl_user").Where("username = ? OR phone = ?", req.Username, req.Username).Scan(&user)
|
||||
if err != nil || user.Id == 0 {
|
||||
response.Error(r, response.CodeError, "用户名或密码错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
if !crypto.CheckPassword(req.Password, user.Password) {
|
||||
response.Error(r, response.CodeError, "用户名或密码错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查用户状态
|
||||
if user.Status != consts.UserStatusNormal {
|
||||
response.Error(r, response.CodeError, "账号已被禁用")
|
||||
return
|
||||
}
|
||||
|
||||
// 生成Token
|
||||
token, err := jwt.GenerateToken(user.Id, user.Username, consts.UserTypeUser)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeServerError, "Token生成失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 更新最后登录信息
|
||||
now := int(time.Now().Unix())
|
||||
clientIP := r.GetClientIp()
|
||||
// 将IPv6地址::1转换为IPv4地址127.0.0.1,或者使用IP地址的哈希值
|
||||
if clientIP == "::1" {
|
||||
clientIP = "127.0.0.1"
|
||||
}
|
||||
|
||||
g.DB().Model("nl_user").Where("id", user.Id).Update(g.Map{
|
||||
"last_login_time": now,
|
||||
"last_login_ip": clientIP,
|
||||
"login_count": g.DB().Raw("login_count + 1"),
|
||||
})
|
||||
|
||||
// 格式化用户信息返回
|
||||
userMap := g.Map{
|
||||
"id": user.Id,
|
||||
"username": user.Username,
|
||||
"nick_name": user.NickName,
|
||||
"avatar": user.Avatar,
|
||||
"phone": user.Phone,
|
||||
"email": user.Email,
|
||||
"gender": user.Gender,
|
||||
"vip_level": user.VipLevel,
|
||||
"vip_expire_time": response.FormatTimestamp(user.VipExpireTime),
|
||||
"balance": user.Balance,
|
||||
"points": user.Points,
|
||||
"status": user.Status,
|
||||
"last_login_time": response.FormatTimestamp(now),
|
||||
"created_at": response.FormatTimestamp(user.CreatedAt),
|
||||
"updated_at": response.FormatTimestamp(user.UpdatedAt),
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"token": token,
|
||||
"user": userMap,
|
||||
})
|
||||
}
|
||||
|
||||
// Register 用户注册
|
||||
func (c *cAuth) Register(r *ghttp.Request) {
|
||||
var req RegisterReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 验证验证码(这里简化处理,实际应该验证短信验证码)
|
||||
if req.Code != "123456" {
|
||||
response.Error(r, response.CodeError, "验证码错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查用户名是否存在
|
||||
count, _ := g.DB().Model("nl_user").Where("username", req.Username).Count()
|
||||
if count > 0 {
|
||||
response.Error(r, response.CodeError, "用户名已存在")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查手机号是否存在
|
||||
count, _ = g.DB().Model("nl_user").Where("phone", req.Phone).Count()
|
||||
if count > 0 {
|
||||
response.Error(r, response.CodeError, "手机号已注册")
|
||||
return
|
||||
}
|
||||
|
||||
// 加密密码
|
||||
hashedPassword, err := crypto.HashPassword(req.Password)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeServerError, "密码加密失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 创建用户
|
||||
now := int(time.Now().Unix())
|
||||
userId, err := g.DB().Model("nl_user").InsertAndGetId(g.Map{
|
||||
"username": req.Username,
|
||||
"nick_name": req.Username,
|
||||
"phone": req.Phone,
|
||||
"password": hashedPassword,
|
||||
"vip_level": consts.VipLevelNormal,
|
||||
"status": consts.UserStatusNormal,
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
})
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeServerError, "注册失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 生成Token
|
||||
token, err := jwt.GenerateToken(uint(userId), req.Username, consts.UserTypeUser)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeServerError, "Token生成失败")
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"token": token,
|
||||
"user_id": userId,
|
||||
"message": "注册成功",
|
||||
})
|
||||
}
|
||||
|
||||
// Profile 获取用户信息
|
||||
func (c *cAuth) Profile(r *ghttp.Request) {
|
||||
userId := r.GetCtxVar("user_id").Uint()
|
||||
|
||||
var user entity.NlUser
|
||||
err := g.DB().Model("nl_user").Where("id", userId).Scan(&user)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeServerError, "获取用户信息失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 格式化用户信息返回
|
||||
userMap := g.Map{
|
||||
"id": user.Id,
|
||||
"username": user.Username,
|
||||
"nick_name": user.NickName,
|
||||
"avatar": user.Avatar,
|
||||
"phone": user.Phone,
|
||||
"email": user.Email,
|
||||
"gender": user.Gender,
|
||||
"birthday": user.Birthday,
|
||||
"vip_level": user.VipLevel,
|
||||
"vip_expire_time": response.FormatTimestamp(user.VipExpireTime),
|
||||
"balance": user.Balance,
|
||||
"points": user.Points,
|
||||
"status": user.Status,
|
||||
"last_login_time": response.FormatTimestamp(user.LastLoginTime),
|
||||
"login_count": user.LoginCount,
|
||||
"desc": user.Desc,
|
||||
"created_at": response.FormatTimestamp(user.CreatedAt),
|
||||
"updated_at": response.FormatTimestamp(user.UpdatedAt),
|
||||
}
|
||||
|
||||
response.Success(r, userMap)
|
||||
}
|
||||
|
||||
// UpdateProfile 更新用户信息
|
||||
func (c *cAuth) UpdateProfile(r *ghttp.Request) {
|
||||
var req UpdateProfileReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, response.CodeInvalidParam, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
userId := r.GetCtxVar("user_id").Uint()
|
||||
|
||||
// 构建更新数据
|
||||
updateData := g.Map{
|
||||
"updated_at": int(time.Now().Unix()),
|
||||
}
|
||||
|
||||
if req.Nickname != "" {
|
||||
updateData["nickname"] = req.Nickname
|
||||
}
|
||||
if req.Avatar != "" {
|
||||
updateData["avatar"] = req.Avatar
|
||||
}
|
||||
if req.Gender > 0 {
|
||||
updateData["gender"] = req.Gender
|
||||
}
|
||||
if req.Birthday != "" {
|
||||
updateData["birthday"] = req.Birthday
|
||||
}
|
||||
|
||||
// 更新用户信息
|
||||
_, err := g.DB().Model("nl_user").Where("id", userId).Update(updateData)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeServerError, "更新失败")
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// Logout 用户登出
|
||||
func (c *cAuth) Logout(r *ghttp.Request) {
|
||||
// 这里可以将token加入黑名单,简化处理直接返回成功
|
||||
response.Success(r, g.Map{
|
||||
"message": "登出成功",
|
||||
})
|
||||
}
|
||||
|
||||
// RefreshToken 刷新Token
|
||||
func (c *cAuth) RefreshToken(r *ghttp.Request) {
|
||||
authHeader := r.Header.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
response.Error(r, response.CodeUnauthorized, "请提供认证令牌")
|
||||
return
|
||||
}
|
||||
|
||||
tokenString := authHeader[7:] // 去掉 "Bearer "
|
||||
newToken, err := jwt.RefreshToken(tokenString)
|
||||
if err != nil {
|
||||
response.Error(r, response.CodeTokenInvalid, "Token刷新失败")
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"token": newToken,
|
||||
})
|
||||
}
|
||||
5
internal/controller/hello/hello.go
Normal file
5
internal/controller/hello/hello.go
Normal file
@@ -0,0 +1,5 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package hello
|
||||
16
internal/controller/hello/hello_new.go
Normal file
16
internal/controller/hello/hello_new.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package hello
|
||||
|
||||
import (
|
||||
"nl-video-api/api/hello"
|
||||
)
|
||||
|
||||
type ControllerV1 struct{}
|
||||
|
||||
func NewV1() hello.IHelloV1 {
|
||||
return &ControllerV1{}
|
||||
}
|
||||
|
||||
13
internal/controller/hello/hello_v1_hello.go
Normal file
13
internal/controller/hello/hello_v1_hello.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package hello
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
|
||||
"nl-video-api/api/hello/v1"
|
||||
)
|
||||
|
||||
func (c *ControllerV1) Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error) {
|
||||
g.RequestFromCtx(ctx).Response.Writeln("Hello World!")
|
||||
return
|
||||
}
|
||||
337
internal/controller/movie/episode.go
Normal file
337
internal/controller/movie/episode.go
Normal file
@@ -0,0 +1,337 @@
|
||||
package movie
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"nl-video-api/internal/dao"
|
||||
"nl-video-api/internal/service/movie"
|
||||
"nl-video-api/utility/response"
|
||||
)
|
||||
|
||||
// EpisodeController 集数控制器
|
||||
type EpisodeController struct{}
|
||||
|
||||
var Episode = &EpisodeController{}
|
||||
|
||||
// Create 创建集数
|
||||
func (c *EpisodeController) Create(r *ghttp.Request) {
|
||||
var req *movie.EpisodeCreateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
episodeService := movie.NewEpisodeService()
|
||||
err := episodeService.Create(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "创建成功",
|
||||
"id": req.MovieId,
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新集数
|
||||
func (c *EpisodeController) Update(r *ghttp.Request) {
|
||||
var req *movie.EpisodeUpdateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL路径获取ID
|
||||
if req.Id == 0 {
|
||||
idStr := r.Get("id").String()
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
req.Id = id
|
||||
}
|
||||
}
|
||||
|
||||
if req.Id <= 0 {
|
||||
response.Error(r, 1001, "集数ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
episodeService := movie.NewEpisodeService()
|
||||
err := episodeService.Update(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// GetById 获取集数详情
|
||||
func (c *EpisodeController) GetById(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, 1001, "集数ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
episodeService := movie.NewEpisodeService()
|
||||
episode, err := episodeService.GetById(r.Context(), &movie.EpisodeDetailReq{Id: id})
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "获取成功",
|
||||
"data": episode,
|
||||
})
|
||||
}
|
||||
|
||||
// GetByMovieId 根据影片ID获取集数列表
|
||||
func (c *EpisodeController) GetByMovieId(r *ghttp.Request) {
|
||||
movieIdStr := r.Get("movie_id").String()
|
||||
movieId, err := strconv.Atoi(movieIdStr)
|
||||
if err != nil || movieId <= 0 {
|
||||
response.Error(r, 1001, "影片ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
episodeService := movie.NewEpisodeService()
|
||||
episodes, err := episodeService.GetByMovieId(r.Context(), movieId)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "获取成功",
|
||||
"list": episodes,
|
||||
"total": len(episodes),
|
||||
"movie_id": movieId,
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 删除集数
|
||||
func (c *EpisodeController) Delete(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, 1001, "集数ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
episodeService := movie.NewEpisodeService()
|
||||
err = episodeService.Delete(r.Context(), &movie.EpisodeDeleteReq{Id: id})
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "删除成功",
|
||||
})
|
||||
}
|
||||
|
||||
// BatchCreate 批量创建集数
|
||||
func (c *EpisodeController) BatchCreate(r *ghttp.Request) {
|
||||
type BatchCreateReq struct {
|
||||
MovieId int `json:"movie_id" v:"required|min:1#请选择影片"`
|
||||
Episodes []movie.EpisodeCreateReq `json:"episodes" v:"required#集数列表不能为空"`
|
||||
}
|
||||
|
||||
var req BatchCreateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(req.Episodes) == 0 {
|
||||
response.Error(r, 1001, "集数列表不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 设置影片ID
|
||||
for i := range req.Episodes {
|
||||
req.Episodes[i].MovieId = req.MovieId
|
||||
}
|
||||
|
||||
episodeService := movie.NewEpisodeService()
|
||||
// 由于BatchCreate方法不存在,我们逐个创建
|
||||
successCount := 0
|
||||
for _, episodeReq := range req.Episodes {
|
||||
if err := episodeService.Create(r.Context(), &episodeReq); err != nil {
|
||||
g.Log().Errorf(r.Context(), "创建集数失败: %v", err)
|
||||
} else {
|
||||
successCount++
|
||||
}
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "批量创建完成",
|
||||
"movie_id": req.MovieId,
|
||||
"total_count": len(req.Episodes),
|
||||
"success_count": successCount,
|
||||
"fail_count": len(req.Episodes) - successCount,
|
||||
})
|
||||
}
|
||||
|
||||
// UploadVideo 上传集数视频
|
||||
func (c *EpisodeController) UploadVideo(r *ghttp.Request) {
|
||||
file := r.GetUploadFile("video")
|
||||
if file == nil {
|
||||
response.Error(r, 1001, "请选择要上传的视频文件")
|
||||
return
|
||||
}
|
||||
|
||||
// 验证文件类型
|
||||
allowedTypes := []string{"video/mp4", "video/avi", "video/mkv", "video/mov", "video/wmv"}
|
||||
isValidType := false
|
||||
for _, allowedType := range allowedTypes {
|
||||
if file.Header.Get("Content-Type") == allowedType {
|
||||
isValidType = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isValidType {
|
||||
response.Error(r, 1001, "不支持的视频格式")
|
||||
return
|
||||
}
|
||||
|
||||
// 检查文件大小(限制5GB)
|
||||
maxSize := int64(5 * 1024 * 1024 * 1024)
|
||||
if file.Size > maxSize {
|
||||
response.Error(r, 1001, "视频文件过大,最大支持5GB")
|
||||
return
|
||||
}
|
||||
|
||||
// 生成文件名
|
||||
timestamp := gtime.Now().TimestampStr()
|
||||
filename := timestamp + "_" + file.Filename
|
||||
uploadPath := "resource/public/uploads/episodes/" + filename
|
||||
|
||||
// 保存文件
|
||||
if _, err := file.Save(uploadPath); err != nil {
|
||||
response.Error(r, 1002, "视频上传失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 返回文件信息
|
||||
relativePath := "/uploads/episodes/" + filename
|
||||
response.Success(r, g.Map{
|
||||
"message": "上传成功",
|
||||
"url": relativePath,
|
||||
"filename": filename,
|
||||
"size": file.Size,
|
||||
})
|
||||
}
|
||||
|
||||
// GenerateThumbnail 生成缩略图
|
||||
func (c *EpisodeController) GenerateThumbnail(r *ghttp.Request) {
|
||||
videoUrl := r.Get("video_url").String()
|
||||
if videoUrl == "" {
|
||||
response.Error(r, 1001, "视频地址不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 生成缩略图文件路径
|
||||
timestamp := gtime.Now().TimestampStr()
|
||||
filename := "thumb_" + timestamp + ".jpg"
|
||||
thumbDir := "resource/public/uploads/thumbnails"
|
||||
_ = thumbDir + "/" + filename // 避免未使用变量错误
|
||||
|
||||
// 提取缩略图 (这里需要实际的视频处理库)
|
||||
// if err := video.ExtractCover(videoUrl, thumbPath); err != nil {
|
||||
// response.Error(r, 1002, "生成缩略图失败: "+err.Error())
|
||||
// return
|
||||
// }
|
||||
|
||||
// 返回缩略图信息
|
||||
relativePath := "/uploads/thumbnails/" + filename
|
||||
response.Success(r, g.Map{
|
||||
"message": "生成成功",
|
||||
"thumbnail": relativePath,
|
||||
"filename": filename,
|
||||
})
|
||||
}
|
||||
|
||||
// GetVideoInfo 获取视频信息
|
||||
func (c *EpisodeController) GetVideoInfo(r *ghttp.Request) {
|
||||
videoUrl := r.Get("video_url").String()
|
||||
if videoUrl == "" {
|
||||
response.Error(r, 1001, "视频地址不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取视频信息 (这里需要实际的视频处理库)
|
||||
// videoInfo, err := video.GetVideoInfo(videoUrl)
|
||||
// if err != nil {
|
||||
// response.Error(r, 1002, "获取视频信息失败: "+err.Error())
|
||||
// return
|
||||
// }
|
||||
|
||||
// 模拟返回视频信息
|
||||
videoInfo := g.Map{
|
||||
"duration": 0,
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"bitrate": "2000kbps",
|
||||
"format": "mp4",
|
||||
"size": 0,
|
||||
"created_at": "",
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "获取成功",
|
||||
"data": videoInfo,
|
||||
})
|
||||
}
|
||||
|
||||
// BatchUpdateStatus 批量更新集数状态
|
||||
func (c *EpisodeController) BatchUpdateStatus(r *ghttp.Request) {
|
||||
type BatchUpdateReq struct {
|
||||
Ids []int `json:"ids" v:"required#请选择要操作的集数"`
|
||||
Status int `json:"status" v:"required|in:0,1#状态只能为0或1"`
|
||||
}
|
||||
|
||||
var req BatchUpdateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(req.Ids) == 0 {
|
||||
response.Error(r, 1001, "请选择要操作的集数")
|
||||
return
|
||||
}
|
||||
|
||||
ctx := r.Context()
|
||||
successCount := 0
|
||||
failCount := 0
|
||||
|
||||
for _, id := range req.Ids {
|
||||
updateData := g.Map{
|
||||
"status": req.Status,
|
||||
}
|
||||
|
||||
episodeDao := dao.NewEpisodeDao()
|
||||
if err := episodeDao.Update(ctx, id, updateData); err != nil {
|
||||
g.Log().Errorf(ctx, "批量更新集数状态失败: ID=%d, 错误=%v", id, err)
|
||||
failCount++
|
||||
} else {
|
||||
successCount++
|
||||
}
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "批量更新完成",
|
||||
"success_count": successCount,
|
||||
"fail_count": failCount,
|
||||
"total_count": len(req.Ids),
|
||||
})
|
||||
}
|
||||
418
internal/controller/movie/movie.go
Normal file
418
internal/controller/movie/movie.go
Normal file
@@ -0,0 +1,418 @@
|
||||
package movie
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/service/movie"
|
||||
"nl-video-api/utility/response"
|
||||
)
|
||||
|
||||
// MovieController 影片控制器
|
||||
type MovieController struct{}
|
||||
|
||||
var Movie = &MovieController{}
|
||||
|
||||
// Create 创建影片
|
||||
func (c *MovieController) Create(r *ghttp.Request) {
|
||||
var req *movie.MovieCreateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
err := movieService.Create(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "创建成功",
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新影片
|
||||
func (c *MovieController) Update(r *ghttp.Request) {
|
||||
var req *movie.MovieUpdateReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 从URL路径获取ID
|
||||
if req.Id == 0 {
|
||||
idStr := r.Get("id").String()
|
||||
if id, err := strconv.Atoi(idStr); err == nil {
|
||||
req.Id = id
|
||||
}
|
||||
}
|
||||
|
||||
if req.Id <= 0 {
|
||||
response.Error(r, 1001, "影片ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
err := movieService.Update(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// GetById 获取影片详情
|
||||
func (c *MovieController) GetById(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, 1001, "影片ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
movieDetail, err := movieService.GetById(r.Context(), &movie.MovieDetailReq{Id: id})
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "获取成功",
|
||||
"data": movieDetail,
|
||||
})
|
||||
}
|
||||
|
||||
// GetList 获取影片列表
|
||||
func (c *MovieController) GetList(r *ghttp.Request) {
|
||||
var req *movie.MovieListReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 设置默认分页参数
|
||||
if req.Page <= 0 {
|
||||
req.Page = 1
|
||||
}
|
||||
if req.PageSize <= 0 {
|
||||
req.PageSize = 10
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
result, err := movieService.GetList(r.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "获取成功",
|
||||
"data": result,
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 删除影片
|
||||
func (c *MovieController) Delete(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, 1001, "影片ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
err = movieService.Delete(r.Context(), &movie.MovieDeleteReq{Id: id})
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "删除成功",
|
||||
})
|
||||
}
|
||||
|
||||
// GetHot 获取热门影片
|
||||
func (c *MovieController) GetHot(r *ghttp.Request) {
|
||||
limitStr := r.Get("limit", "10").String()
|
||||
limit, err := strconv.Atoi(limitStr)
|
||||
if err != nil || limit <= 0 {
|
||||
limit = 10
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
movies, err := movieService.GetHotMovies(r.Context(), limit)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "获取成功",
|
||||
"data": movies,
|
||||
})
|
||||
}
|
||||
|
||||
// GetRecommend 获取推荐影片
|
||||
func (c *MovieController) GetRecommend(r *ghttp.Request) {
|
||||
limitStr := r.Get("limit", "10").String()
|
||||
limit, err := strconv.Atoi(limitStr)
|
||||
if err != nil || limit <= 0 {
|
||||
limit = 10
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
movies, err := movieService.GetRecommendMovies(r.Context(), limit)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "获取成功",
|
||||
"data": movies,
|
||||
})
|
||||
}
|
||||
|
||||
// GetNew 获取最新影片
|
||||
func (c *MovieController) GetNew(r *ghttp.Request) {
|
||||
limitStr := r.Get("limit", "10").String()
|
||||
limit, err := strconv.Atoi(limitStr)
|
||||
if err != nil || limit <= 0 {
|
||||
limit = 10
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
movies, err := movieService.GetNewMovies(r.Context(), limit)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "获取成功",
|
||||
"data": movies,
|
||||
})
|
||||
}
|
||||
|
||||
// Search 搜索影片
|
||||
func (c *MovieController) Search(r *ghttp.Request) {
|
||||
keyword := r.Get("keyword").String()
|
||||
if keyword == "" {
|
||||
response.Error(r, 1001, "搜索关键词不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
pageStr := r.Get("page", "1").String()
|
||||
page, err := strconv.Atoi(pageStr)
|
||||
if err != nil || page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
pageSizeStr := r.Get("page_size", "10").String()
|
||||
pageSize, err := strconv.Atoi(pageSizeStr)
|
||||
if err != nil || pageSize <= 0 {
|
||||
pageSize = 10
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
movies, total, err := movieService.SearchMovies(r.Context(), keyword, page, pageSize)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "搜索成功",
|
||||
"data": g.Map{
|
||||
"list": movies,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"page_size": pageSize,
|
||||
"keyword": keyword,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// GetByCategory 根据分类获取影片
|
||||
func (c *MovieController) GetByCategory(r *ghttp.Request) {
|
||||
categoryIdStr := r.Get("category_id").String()
|
||||
categoryId, err := strconv.Atoi(categoryIdStr)
|
||||
if err != nil || categoryId <= 0 {
|
||||
response.Error(r, 1001, "分类ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
pageStr := r.Get("page", "1").String()
|
||||
page, err := strconv.Atoi(pageStr)
|
||||
if err != nil || page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
pageSizeStr := r.Get("page_size", "10").String()
|
||||
pageSize, err := strconv.Atoi(pageSizeStr)
|
||||
if err != nil || pageSize <= 0 {
|
||||
pageSize = 10
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
movies, total, err := movieService.GetMoviesByCategory(r.Context(), categoryId, page, pageSize)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "获取成功",
|
||||
"data": g.Map{
|
||||
"list": movies,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"page_size": pageSize,
|
||||
"category_id": categoryId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateViewCount 更新观看次数
|
||||
func (c *MovieController) UpdateViewCount(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, 1001, "影片ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
err = movieService.UpdateViewCount(r.Context(), id)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateLikeCount 更新点赞数
|
||||
func (c *MovieController) UpdateLikeCount(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, 1001, "影片ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
incrementStr := r.Get("increment", "1").String()
|
||||
increment, err := strconv.Atoi(incrementStr)
|
||||
if err != nil {
|
||||
increment = 1
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
err = movieService.UpdateLikeCount(r.Context(), id, increment)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateCollectCount 更新收藏数
|
||||
func (c *MovieController) UpdateCollectCount(r *ghttp.Request) {
|
||||
idStr := r.Get("id").String()
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil || id <= 0 {
|
||||
response.Error(r, 1001, "影片ID无效")
|
||||
return
|
||||
}
|
||||
|
||||
incrementStr := r.Get("increment", "1").String()
|
||||
increment, err := strconv.Atoi(incrementStr)
|
||||
if err != nil {
|
||||
increment = 1
|
||||
}
|
||||
|
||||
movieService := movie.NewMovieService()
|
||||
err = movieService.UpdateCollectCount(r.Context(), id, increment)
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// GetStatistics 获取影片统计
|
||||
func (c *MovieController) GetStatistics(r *ghttp.Request) {
|
||||
movieService := movie.NewMovieService()
|
||||
stats, err := movieService.GetStatistics(r.Context())
|
||||
if err != nil {
|
||||
response.Error(r, 1002, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(r, g.Map{
|
||||
"message": "获取成功",
|
||||
"data": stats,
|
||||
})
|
||||
}
|
||||
|
||||
// BatchUpdate 批量更新影片
|
||||
func (c *MovieController) BatchUpdate(r *ghttp.Request) {
|
||||
var req struct {
|
||||
Ids []int `json:"ids" v:"required#影片ID列表不能为空"`
|
||||
Status *int `json:"status"`
|
||||
IsVip *int `json:"is_vip"`
|
||||
}
|
||||
|
||||
if err := r.Parse(&req); err != nil {
|
||||
response.Error(r, 1001, "参数解析失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(req.Ids) == 0 {
|
||||
response.Error(r, 1001, "影片ID列表不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: 实现批量更新逻辑
|
||||
response.Success(r, g.Map{
|
||||
"message": "批量更新成功",
|
||||
})
|
||||
}
|
||||
|
||||
// UploadVideo 上传视频
|
||||
func (c *MovieController) UploadVideo(r *ghttp.Request) {
|
||||
// TODO: 实现视频上传逻辑
|
||||
response.Success(r, g.Map{
|
||||
"message": "视频上传成功",
|
||||
"data": g.Map{
|
||||
"url": "/uploads/videos/example.mp4",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// UploadPoster 上传海报
|
||||
func (c *MovieController) UploadPoster(r *ghttp.Request) {
|
||||
// TODO: 实现海报上传逻辑
|
||||
response.Success(r, g.Map{
|
||||
"message": "海报上传成功",
|
||||
"data": g.Map{
|
||||
"url": "/uploads/posters/example.jpg",
|
||||
},
|
||||
})
|
||||
}
|
||||
64
internal/controller/user/attachment.go
Normal file
64
internal/controller/user/attachment.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"nl-video-api/internal/service"
|
||||
)
|
||||
|
||||
// AttachmentController 用户附件管理控制器
|
||||
type AttachmentController struct{}
|
||||
|
||||
// NewAttachmentController 创建用户附件管理控制器实例
|
||||
func NewAttachmentController() *AttachmentController {
|
||||
return &AttachmentController{}
|
||||
}
|
||||
|
||||
// Upload 上传附件
|
||||
func (c *AttachmentController) Upload(r *ghttp.Request) {
|
||||
service.NewAttachmentService().UserUpload(r)
|
||||
}
|
||||
|
||||
// GetList 获取用户附件列表
|
||||
func (c *AttachmentController) GetList(r *ghttp.Request) {
|
||||
service.NewAttachmentService().UserGetList(r)
|
||||
}
|
||||
|
||||
// GetDetail 获取附件详情
|
||||
func (c *AttachmentController) GetDetail(r *ghttp.Request) {
|
||||
service.NewAttachmentService().UserGetDetail(r)
|
||||
}
|
||||
|
||||
// Update 更新附件
|
||||
func (c *AttachmentController) Update(r *ghttp.Request) {
|
||||
service.NewAttachmentService().UserUpdate(r)
|
||||
}
|
||||
|
||||
// Delete 删除附件
|
||||
func (c *AttachmentController) Delete(r *ghttp.Request) {
|
||||
service.NewAttachmentService().UserDelete(r)
|
||||
}
|
||||
|
||||
// Download 下载附件
|
||||
func (c *AttachmentController) Download(r *ghttp.Request) {
|
||||
service.NewAttachmentService().UserDownload(r)
|
||||
}
|
||||
|
||||
// Copy 复制附件
|
||||
func (c *AttachmentController) Copy(r *ghttp.Request) {
|
||||
service.NewAttachmentService().UserCopy(r)
|
||||
}
|
||||
|
||||
// Rename 重命名附件
|
||||
func (c *AttachmentController) Rename(r *ghttp.Request) {
|
||||
service.NewAttachmentService().UserRename(r)
|
||||
}
|
||||
|
||||
// Search 搜索附件
|
||||
func (c *AttachmentController) Search(r *ghttp.Request) {
|
||||
service.NewAttachmentService().UserSearch(r)
|
||||
}
|
||||
|
||||
// GetCategoryList 获取附件分类列表
|
||||
func (c *AttachmentController) GetCategoryList(r *ghttp.Request) {
|
||||
service.NewAttachmentService().UserGetCategoryList(r)
|
||||
}
|
||||
21
internal/controller/user/banner.go
Normal file
21
internal/controller/user/banner.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
var Banner = cBanner{}
|
||||
|
||||
type cBanner struct{}
|
||||
|
||||
// GetList 获取轮播图列表
|
||||
func (c *cBanner) GetList(r *ghttp.Request) {
|
||||
service.Banner.UserGetList(r)
|
||||
}
|
||||
|
||||
// GetDetail 获取轮播图详情
|
||||
func (c *cBanner) GetDetail(r *ghttp.Request) {
|
||||
service.Banner.UserGetDetail(r)
|
||||
}
|
||||
42
internal/controller/user/comment.go
Normal file
42
internal/controller/user/comment.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// CommentController 评论控制器
|
||||
type CommentController struct{}
|
||||
|
||||
var Comment = &CommentController{}
|
||||
|
||||
// Add 添加评论
|
||||
func (c *CommentController) Add(r *ghttp.Request) {
|
||||
service.Comment.Add(r)
|
||||
}
|
||||
|
||||
// List 评论列表
|
||||
func (c *CommentController) List(r *ghttp.Request) {
|
||||
service.Comment.GetList(r)
|
||||
}
|
||||
|
||||
// Delete 删除评论
|
||||
func (c *CommentController) Delete(r *ghttp.Request) {
|
||||
service.Comment.Delete(r)
|
||||
}
|
||||
|
||||
// Like 点赞评论
|
||||
func (c *CommentController) Like(r *ghttp.Request) {
|
||||
service.Comment.Like(r)
|
||||
}
|
||||
|
||||
// Unlike 取消点赞
|
||||
func (c *CommentController) Unlike(r *ghttp.Request) {
|
||||
service.Comment.Unlike(r)
|
||||
}
|
||||
|
||||
// Report 举报评论
|
||||
func (c *CommentController) Report(r *ghttp.Request) {
|
||||
service.Comment.Report(r)
|
||||
}
|
||||
22
internal/controller/user/config.go
Normal file
22
internal/controller/user/config.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// ConfigController 系统配置控制器
|
||||
type ConfigController struct{}
|
||||
|
||||
var Config = &ConfigController{}
|
||||
|
||||
// GetList 获取配置列表
|
||||
func (c *ConfigController) GetList(r *ghttp.Request) {
|
||||
service.Config.GetList(r)
|
||||
}
|
||||
|
||||
// GetByKey 根据键获取配置
|
||||
func (c *ConfigController) GetByKey(r *ghttp.Request) {
|
||||
service.Config.GetByKey(r)
|
||||
}
|
||||
17
internal/controller/user/log.go
Normal file
17
internal/controller/user/log.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// LogController 日志控制器
|
||||
type LogController struct{}
|
||||
|
||||
var Log = &LogController{}
|
||||
|
||||
// GetList 获取日志列表
|
||||
func (c *LogController) GetList(r *ghttp.Request) {
|
||||
service.Log.GetList(r)
|
||||
}
|
||||
37
internal/controller/user/payment_order.go
Normal file
37
internal/controller/user/payment_order.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// PaymentOrderController 支付订单控制器
|
||||
type PaymentOrderController struct{}
|
||||
|
||||
var PaymentOrder = &PaymentOrderController{}
|
||||
|
||||
// Create 创建支付订单
|
||||
func (c *PaymentOrderController) Create(r *ghttp.Request) {
|
||||
service.PaymentOrder.Create(r)
|
||||
}
|
||||
|
||||
// GetList 获取支付订单列表
|
||||
func (c *PaymentOrderController) GetList(r *ghttp.Request) {
|
||||
service.PaymentOrder.GetList(r)
|
||||
}
|
||||
|
||||
// GetDetail 获取支付订单详情
|
||||
func (c *PaymentOrderController) GetDetail(r *ghttp.Request) {
|
||||
service.PaymentOrder.GetDetail(r)
|
||||
}
|
||||
|
||||
// Pay 支付订单
|
||||
func (c *PaymentOrderController) Pay(r *ghttp.Request) {
|
||||
service.PaymentOrder.Pay(r)
|
||||
}
|
||||
|
||||
// Cancel 取消订单
|
||||
func (c *PaymentOrderController) Cancel(r *ghttp.Request) {
|
||||
service.PaymentOrder.Cancel(r)
|
||||
}
|
||||
49
internal/controller/user/user_collect.go
Normal file
49
internal/controller/user/user_collect.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// UserCollectController 用户收藏控制器
|
||||
type UserCollectController struct{}
|
||||
|
||||
var UserCollect = &UserCollectController{}
|
||||
|
||||
// Add 添加收藏
|
||||
func (c *UserCollectController) Add(r *ghttp.Request) {
|
||||
service.UserCollect.Add(r)
|
||||
}
|
||||
|
||||
// Remove 取消收藏
|
||||
func (c *UserCollectController) Remove(r *ghttp.Request) {
|
||||
service.UserCollect.Remove(r)
|
||||
}
|
||||
|
||||
// GetList 获取收藏列表
|
||||
func (c *UserCollectController) GetList(r *ghttp.Request) {
|
||||
service.NewUserCollectService().GetList(r)
|
||||
}
|
||||
|
||||
// List 获取收藏列表(别名方法)
|
||||
func (c *UserCollectController) List(r *ghttp.Request) {
|
||||
c.GetList(r)
|
||||
}
|
||||
|
||||
// Check 检查收藏状态
|
||||
func (c *UserCollectController) Check(r *ghttp.Request) {
|
||||
// TODO: 实现检查收藏状态逻辑
|
||||
r.Response.WriteJson(map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "检查成功",
|
||||
"data": map[string]interface{}{
|
||||
"is_collected": false,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// CheckCollect 检查是否已收藏
|
||||
func (c *UserCollectController) CheckCollect(r *ghttp.Request) {
|
||||
service.UserCollect.CheckCollect(r)
|
||||
}
|
||||
80
internal/controller/user/user_watch_history.go
Normal file
80
internal/controller/user/user_watch_history.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/service"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// UserWatchHistoryController 用户观看历史控制器
|
||||
type UserWatchHistoryController struct{}
|
||||
|
||||
var UserWatchHistory = &UserWatchHistoryController{}
|
||||
|
||||
// Add 添加观看历史
|
||||
func (c *UserWatchHistoryController) Add(r *ghttp.Request) {
|
||||
service.NewUserWatchHistoryService().Add(r)
|
||||
}
|
||||
|
||||
// GetList 获取观看历史列表
|
||||
func (c *UserWatchHistoryController) GetList(r *ghttp.Request) {
|
||||
service.NewUserWatchHistoryService().GetList(r)
|
||||
}
|
||||
|
||||
// Delete 删除观看历史
|
||||
func (c *UserWatchHistoryController) Delete(r *ghttp.Request) {
|
||||
service.NewUserWatchHistoryService().Delete(r)
|
||||
}
|
||||
|
||||
// Clear 清空观看历史
|
||||
func (c *UserWatchHistoryController) Clear(r *ghttp.Request) {
|
||||
// 获取用户ID(需要实现GetUserIdFromContext函数)
|
||||
userId := service.GetUserIdFromContext(r.Context())
|
||||
if userId == 0 {
|
||||
r.Response.WriteJson(map[string]interface{}{
|
||||
"code": 401,
|
||||
"message": "请先登录",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err := service.NewUserWatchHistoryService().Clear(r.Context(), &service.UserWatchHistoryClearReq{
|
||||
UserId: uint(userId),
|
||||
})
|
||||
if err != nil {
|
||||
r.Response.WriteJson(map[string]interface{}{
|
||||
"code": 1002,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
r.Response.WriteJson(map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "清空成功",
|
||||
})
|
||||
}
|
||||
|
||||
// GetProgress 获取观看进度
|
||||
func (c *UserWatchHistoryController) GetProgress(r *ghttp.Request) {
|
||||
service.NewUserWatchHistoryService().GetProgress(r)
|
||||
}
|
||||
|
||||
// List 获取观看历史列表(别名方法)
|
||||
func (c *UserWatchHistoryController) List(r *ghttp.Request) {
|
||||
c.GetList(r)
|
||||
}
|
||||
|
||||
// Get 获取单个观看历史记录
|
||||
func (c *UserWatchHistoryController) Get(r *ghttp.Request) {
|
||||
// TODO: 实现获取单个观看历史记录逻辑
|
||||
r.Response.WriteJson(map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "获取成功",
|
||||
"data": map[string]interface{}{
|
||||
"id": 1,
|
||||
"movie_id": 1,
|
||||
"progress": 50,
|
||||
"watch_time": 3600,
|
||||
},
|
||||
})
|
||||
}
|
||||
27
internal/controller/user/vip_level.go
Normal file
27
internal/controller/user/vip_level.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"nl-video-api/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
// VipLevelController VIP等级控制器
|
||||
type VipLevelController struct{}
|
||||
|
||||
var VipLevel = &VipLevelController{}
|
||||
|
||||
// GetList 获取VIP等级列表
|
||||
func (c *VipLevelController) GetList(r *ghttp.Request) {
|
||||
service.VipLevel.GetList(r)
|
||||
}
|
||||
|
||||
// GetAll 获取所有VIP等级
|
||||
func (c *VipLevelController) GetAll(r *ghttp.Request) {
|
||||
service.VipLevel.GetAll(r)
|
||||
}
|
||||
|
||||
// GetDetail 获取VIP等级详情
|
||||
func (c *VipLevelController) GetDetail(r *ghttp.Request) {
|
||||
service.VipLevel.GetDetail(r)
|
||||
}
|
||||
Reference in New Issue
Block a user