337 lines
8.1 KiB
Go
337 lines
8.1 KiB
Go
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),
|
||
})
|
||
} |