Files
huangguo_server/web/service/mediacontentser/mediacontent.go
T
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

724 lines
24 KiB
Go

package mediacontentser
import (
"91porn-server/common/log"
"91porn-server/common/stderr"
"91porn-server/models/v/mediamod"
"91porn-server/models/v/vidmod"
"91porn-server/web/service/updownloadser"
"errors"
"fmt"
"path/filepath"
"strings"
"time"
"go.mongodb.org/mongo-driver/mongo/options"
"91porn-server/models/v/mediacontentmod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type WebListReq struct {
ID *string `form:"id" bson:"id,omitempty"` // ID
Name *string `form:"name" bson:"name,omitempty"` // 名称
Type *int `form:"type" bson:"type,omitempty"` // 类型 1:动漫,2:漫画
Status *int `form:"status" bson:"status,omitempty"` // 状态
IsActive *bool `form:"isActive" json:"isActive"` // 是否激活
MID *string `form:"mId" json:"mId" bson:"mId" binding:"required"` // 媒体资源ID
PageNumber uint64 `form:"pageNumber" json:"pageNumber" binding:"required,min=1"` // 当前页
PageSize uint64 `form:"pageSize" json:"pageSize" binding:"required,min=1,max=100"` // 每页条数
}
type WebListRes struct {
Total int64 `json:"total"`
List []*mediacontentmod.MediaContent `json:"list"`
}
func (q *WebListReq) Filter() bson.M {
var query = bson.M{}
if q.Name != nil {
query["name"] = primitive.Regex{Pattern: *q.Name, Options: "i"}
}
if q.Status != nil {
query["status"] = *q.Status
}
if q.MID != nil {
mid, _ := primitive.ObjectIDFromHex(*q.MID)
query["mediaId"] = mid
}
if q.Type != nil {
query["type"] = *q.Type
}
if q.IsActive != nil {
query["isActive"] = *q.IsActive
}
if q.ID != nil {
id, _ := primitive.ObjectIDFromHex(*q.ID)
query["_id"] = id
}
query["isDelete"] = false
return query
}
func (q *WebListReq) Options() *options.FindOptions {
return options.Find().SetSkip(int64((q.PageNumber - 1) * q.PageSize)).SetLimit(int64(q.PageSize)).SetSort(bson.M{"episodeNumber": 1})
}
// GetList 获取列表
func (q *WebListReq) GetList() (res *WebListRes, err error) {
var out = &WebListRes{}
count, err := mediacontentmod.QueryAllCount(q.Filter())
if err != nil {
return nil, err
}
if count == 0 {
out.List = []*mediacontentmod.MediaContent{}
out.Total = 0
return out, nil
}
out.Total = count
out.List, err = mediacontentmod.QueryAllList(q.Filter(), q.Options())
if err != nil {
log.Error(fmt.Sprintf("mediacontentmod queryAllList error:%+v:", err))
return nil, err
}
return out, nil
}
type WebCreateReq struct {
MediaID primitive.ObjectID `json:"mediaId" form:"mediaId" binding:"required"` // 媒体资源ID
MediaType string `json:"mediaType" form:"mediaType" binding:"required"` // 媒体类型
EpisodeNumber uint `json:"episodeNumber" form:"episodeNumber" ` // 第几集
ListenPermission int `json:"listenPermission" form:"listenPermission" ` // 收听权限 0:会员 1:金币购买 2:免费
Price int64 `json:"price" form:"price" ` // 购买价格
Cover string `json:"cover" form:"cover"` //封面
Name string `json:"name" form:"name" ` // 章节名
Text string `json:"text" form:"text" ` // 内容(小说专用)
Md5 string `json:"md5" form:"md5" ` // 媒体md5
SourceID string `json:"sourceID" form:"sourceID"` // 视频唯一id,对应文件服
VideoUrl string `json:"videoUrl" form:"videoUrl" ` // 视频地址
AudioUrl string `json:"audioUrl" form:"audioUrl"` // 有声小说地址
UrlSet []string `json:"urlSet" form:"urlSet"` // 地址集(多个资源地址用 例如漫画)
Filename string `json:"filename" form:"filename"` // 文件名称
IsActive bool `json:"isActive" form:"isActive" ` // 是否激活
PreviewEnabled bool `json:"previewEnabled" form:"previewEnabled"` // 是否允许试看
PreviewStart int `json:"previewStart" form:"previewStart"` // 试看起始时间(秒)
PreviewSeconds int `json:"previewSeconds" form:"previewSeconds"` // 试看时长(秒)
}
const defaultDramaPreviewSeconds = 60
func normalizeDramaPreview(enabled bool, start, seconds int, playTime uint) (bool, int, int, error) {
if !enabled {
return false, 0, 0, nil
}
if start < 0 {
return false, 0, 0, errors.New("试看起始时间不能小于0")
}
if seconds < 0 {
return false, 0, 0, errors.New("试看时长不能小于0")
}
if seconds == 0 {
seconds = defaultDramaPreviewSeconds
}
if playTime > 0 && uint64(start)+uint64(seconds) > uint64(playTime) {
return false, 0, 0, errors.New("试看起始时间与时长之和不能超过视频总时长")
}
return true, start, seconds, nil
}
func validateDramaEpisodeState(episodeNumber int, listenPermission int, price int64, name, videoURL, h265URL string, active bool, status int) error {
if episodeNumber < 1 {
return errors.New("剧集编号必须大于0")
}
if strings.TrimSpace(name) == "" {
return errors.New("剧集名称不能为空")
}
if listenPermission != 1 && listenPermission != 2 {
return errors.New("短剧剧集listenPermission只支持1或2")
}
if listenPermission == 2 && price != 0 {
return errors.New("免费剧集价格必须为0")
}
if listenPermission == 1 && price <= 0 {
return errors.New("金币剧集价格必须大于0")
}
if active {
if status != 1 {
return errors.New("视频仍在转码,暂不能上架")
}
if strings.TrimSpace(videoURL) == "" && strings.TrimSpace(h265URL) == "" {
return errors.New("剧集没有播放资源,暂不能上架")
}
}
return nil
}
func ensureEpisodeNumberUnique(mediaID primitive.ObjectID, episodeNumber int, excludeID primitive.ObjectID) error {
filter := bson.M{
"mediaId": mediaID,
"episodeNumber": episodeNumber,
"isDelete": false,
}
if !excludeID.IsZero() {
filter["_id"] = bson.M{"$ne": excludeID}
}
count, err := mediacontentmod.QueryAllCount(filter)
if err != nil {
return err
}
if count > 0 {
return errors.New("剧集编号已存在")
}
return nil
}
func fileStatusToEpisodeStatus(status string) int {
switch status {
case vidmod.ConvertCompleted, vidmod.Completed:
return 1
case vidmod.FileUploadError, vidmod.MergeError, vidmod.ConvertError:
return 2
default:
return 0
}
}
func mediaMetadataFromFs(id string) (vidmod.AwsPullResp, int, error) {
resp, err := updownloadser.PullFileInfo(id)
if err != nil {
return vidmod.AwsPullResp{}, 0, err
}
status := fileStatusToEpisodeStatus(resp.Data.Status)
return resp.Data, status, nil
}
// Create 发布数据
func (p *WebCreateReq) Create(manager string) (err error, vid primitive.ObjectID) {
now := time.Now()
media, err := mediamod.QueryMediaByID(bson.M{"_id": p.MediaID})
if err != nil {
return err, primitive.ObjectID{}
}
if media == nil || media.ID.IsZero() {
return errors.New("media info is nll"), primitive.ObjectID{}
}
if media.IsDelete || p.MediaType != media.MediaType {
return errors.New("剧集mediaType与父媒体不一致"), primitive.ObjectID{}
}
p.Name = strings.TrimSpace(p.Name)
if p.MediaType == mediamod.MediaTypeVideo || p.MediaType == mediamod.MediaTypeDrama {
vid, err = primitive.ObjectIDFromHex(p.SourceID)
if err != nil || vid.IsZero() {
return errors.New("sourceID不是有效的资源ID"), primitive.ObjectID{}
}
} else {
vid = primitive.NewObjectID()
}
if err = ensureEpisodeNumberUnique(media.ID, int(p.EpisodeNumber), primitive.NilObjectID); err != nil {
return err, primitive.ObjectID{}
}
if media.MediaType == mediamod.MediaTypeDrama {
if err = validateDramaEpisodeState(int(p.EpisodeNumber), p.ListenPermission, p.Price, p.Name, p.VideoUrl, "", false, 0); err != nil {
return err, primitive.ObjectID{}
}
if strings.TrimSpace(p.VideoUrl) == "" {
return errors.New("短剧剧集必须提供videoUrl"), primitive.ObjectID{}
}
}
previewEnabled, previewStart, previewSeconds := false, 0, 0
if media.MediaType == mediamod.MediaTypeDrama {
previewEnabled, previewStart, previewSeconds, err = normalizeDramaPreview(p.PreviewEnabled, p.PreviewStart, p.PreviewSeconds, 0)
if err != nil {
return err, primitive.ObjectID{}
}
}
mc := mediacontentmod.MediaContent{
ID: vid,
MediaID: p.MediaID,
MediaType: media.MediaType,
Cover: p.Cover,
EpisodeNumber: int(p.EpisodeNumber),
ListenPermission: p.ListenPermission,
Price: p.Price,
Name: p.Name,
IsActive: p.IsActive,
IsDelete: false,
UpdatedAct: manager,
UpdateTime: now,
CreatedAt: now,
PreviewEnabled: previewEnabled,
PreviewStart: previewStart,
PreviewSeconds: previewSeconds,
}
// 视频和短剧都使用视频资源。
if media.MediaType == mediamod.MediaTypeVideo || media.MediaType == mediamod.MediaTypeDrama {
mc.Md5 = p.Md5
mc.VideoUrl = strings.TrimSpace(p.VideoUrl)
mc.Status = 0
if p.IsActive {
metadata, status, metadataErr := mediaMetadataFromFs(vid.Hex())
if metadataErr != nil {
return errors.New("文件服务连接失败,暂不能上架剧集"), primitive.ObjectID{}
}
mc.Status = status
mc.PlayTime = metadata.PlayTime
mc.Weight = metadata.Width
mc.Height = metadata.Height
mc.MediaSize = int64(metadata.Size)
if metadata.CheckSum != "" {
mc.Md5 = metadata.CheckSum
}
mc.Ratio = metadata.Ratio
if mc.Ratio == 0 && mc.Height > 0 {
mc.Ratio = float64(mc.Weight) / float64(mc.Height)
}
if media.MediaType == mediamod.MediaTypeDrama {
mc.PreviewEnabled, mc.PreviewStart, mc.PreviewSeconds, err = normalizeDramaPreview(mc.PreviewEnabled, mc.PreviewStart, mc.PreviewSeconds, mc.PlayTime)
if err != nil {
return err, primitive.ObjectID{}
}
if err = validateDramaEpisodeState(mc.EpisodeNumber, mc.ListenPermission, mc.Price, mc.Name, mc.VideoUrl, mc.H265Url, true, mc.Status); err != nil {
return err, primitive.ObjectID{}
}
}
}
}
// 图集
if media.MediaType == mediamod.MediaTypeImage {
mc.UrlSet = p.UrlSet
}
// 小说
if media.MediaType == mediamod.MediaTypeText {
mc.AudioUrl = p.AudioUrl
}
// 创建数据
if _, err := mediacontentmod.Insert(nil, mc); err != nil {
return err, primitive.ObjectID{}
}
err = OnMediaContentChange(media.ID, media.MediaType, true, mc.IsActive)
if err != nil {
return err, primitive.ObjectID{}
}
return nil, vid
}
type WebUpdateReq struct {
ID primitive.ObjectID `json:"id" binding:"required"`
EpisodeNumber *int `json:"episodeNumber"` // 第几集
ListenPermission *int `json:"listenPermission"` // 收听权限 0:会员 1:金币购买 2:免费
Price *int64 `json:"price"` // 购买价格
Name *string `json:"name"` // 章节名
Cover *string `json:"cover"` // 封面
Text *string `json:"text"` // 内容(小说专用)
Md5 *string `json:"md5"` // 媒体md5
VideoUrl *string `json:"videoUrl"` // 视频地址
H265Url *string `json:"h265Url"` // H.265视频地址
AudioUrl *string `json:"audioUrl"` // 有声小说地址
UrlSet *[]string `json:"urlSet"` // 地址集(多个资源地址用 例如漫画)
IsActive *bool `json:"isActive"` // 是否激活
PreviewEnabled *bool `json:"previewEnabled"` // 是否允许试看
PreviewStart *int `json:"previewStart"` // 试看起始时间(秒)
PreviewSeconds *int `json:"previewSeconds"` // 试看时长(秒)
}
// Update 更新数据
func (p *WebUpdateReq) Update(manager string) error {
mediaContent, err := mediacontentmod.GetInfo(p.ID)
if err != nil {
return err
}
if mediaContent.ID.IsZero() {
return errors.New("media content is null")
}
media, err := mediamod.GetInfo(mediaContent.MediaID)
if err != nil {
return err
}
next := mediaContent
if p.EpisodeNumber != nil {
next.EpisodeNumber = *p.EpisodeNumber
}
if p.ListenPermission != nil {
next.ListenPermission = *p.ListenPermission
}
if p.Price != nil {
next.Price = *p.Price
}
if p.Name != nil {
next.Name = strings.TrimSpace(*p.Name)
}
if p.VideoUrl != nil {
next.VideoUrl = strings.TrimSpace(*p.VideoUrl)
}
if p.H265Url != nil {
next.H265Url = strings.TrimSpace(*p.H265Url)
}
if p.IsActive != nil {
next.IsActive = *p.IsActive
}
if p.PreviewEnabled != nil {
next.PreviewEnabled = *p.PreviewEnabled
}
if p.PreviewStart != nil {
next.PreviewStart = *p.PreviewStart
}
if p.PreviewSeconds != nil {
next.PreviewSeconds = *p.PreviewSeconds
}
var metadata *vidmod.AwsPullResp
if next.IsActive && (media.MediaType == mediamod.MediaTypeVideo || media.MediaType == mediamod.MediaTypeDrama) && next.Status != 1 {
loaded, status, metadataErr := mediaMetadataFromFs(mediaContent.ID.Hex())
if metadataErr != nil {
return errors.New("文件服务连接失败,暂不能上架剧集")
}
metadata = &loaded
next.Status = status
next.PlayTime = loaded.PlayTime
next.Weight = loaded.Width
next.Height = loaded.Height
next.MediaSize = int64(loaded.Size)
next.Ratio = loaded.Ratio
if next.Ratio == 0 && next.Height > 0 {
next.Ratio = float64(next.Weight) / float64(next.Height)
}
}
if media.MediaType == mediamod.MediaTypeDrama {
next.PreviewEnabled, next.PreviewStart, next.PreviewSeconds, err = normalizeDramaPreview(next.PreviewEnabled, next.PreviewStart, next.PreviewSeconds, next.PlayTime)
if err != nil {
return err
}
if err = validateDramaEpisodeState(next.EpisodeNumber, next.ListenPermission, next.Price, next.Name, next.VideoUrl, next.H265Url, next.IsActive, next.Status); err != nil {
return err
}
if err = ensureEpisodeNumberUnique(media.ID, next.EpisodeNumber, mediaContent.ID); err != nil {
return err
}
}
data := make(map[string]interface{})
if p.EpisodeNumber != nil {
data["episodeNumber"] = *p.EpisodeNumber
}
if p.ListenPermission != nil {
data["listenPermission"] = *p.ListenPermission
}
if p.Price != nil {
data["price"] = *p.Price
}
if p.Name != nil {
data["name"] = next.Name
}
if p.Cover != nil {
data["cover"] = *p.Cover
}
if p.Text != nil {
data["text"] = *p.Text
}
if p.Md5 != nil {
data["md5"] = *p.Md5
}
if p.VideoUrl != nil {
data["videoUrl"] = next.VideoUrl
}
if p.H265Url != nil {
data["h265Url"] = next.H265Url
}
if p.AudioUrl != nil {
data["audioUrl"] = *p.AudioUrl
}
if p.UrlSet != nil {
data["urlSet"] = *p.UrlSet
}
if p.IsActive != nil {
data["isActive"] = *p.IsActive
}
if media.MediaType == mediamod.MediaTypeDrama && (p.PreviewEnabled != nil || p.PreviewStart != nil || p.PreviewSeconds != nil) {
data["previewEnabled"] = next.PreviewEnabled
data["previewStart"] = next.PreviewStart
data["previewSeconds"] = next.PreviewSeconds
}
if metadata != nil {
data["playTime"] = metadata.PlayTime
data["weight"] = metadata.Width
data["height"] = metadata.Height
data["mediaSize"] = metadata.Size
data["status"] = next.Status
data["ratio"] = next.Ratio
if metadata.CheckSum != "" {
data["md5"] = metadata.CheckSum
}
}
data["updatedAct"] = manager
data["updateTime"] = time.Now()
if _, err = mediacontentmod.UpdateByID(nil, p.ID, data); err != nil {
return err
}
published := p.IsActive != nil && *p.IsActive && !mediaContent.IsActive
err = OnMediaContentChange(media.ID, media.MediaType, false, published)
if err != nil {
return err
}
return nil
}
type WebBatchUpdateReq struct {
IDS []string `json:"ids" binding:"required"`
IsActive *bool `json:"isActive"` // 是否激活
Price *int64 `json:"price"` // 价格
Permission *int `json:"permission"` // 收听权限 0:会员 1:金币购买 2:免费
FreeEpisode *int `json:"freeEpisode"` // 前几集免费
}
func (p *WebBatchUpdateReq) Filter() []primitive.ObjectID {
ids, _ := p.ValidatedIDs()
return ids
}
func (p *WebBatchUpdateReq) ValidatedIDs() ([]primitive.ObjectID, error) {
if len(p.IDS) == 0 || len(p.IDS) > 100 {
return nil, errors.New("ids数量必须在1到100之间")
}
if p.IsActive == nil && p.Price == nil && p.Permission == nil && p.FreeEpisode == nil {
return nil, errors.New("至少需要一个批量更新字段")
}
if p.FreeEpisode != nil && *p.FreeEpisode < 0 {
return nil, errors.New("freeEpisode不能小于0")
}
ids := make([]primitive.ObjectID, 0, len(p.IDS))
seen := make(map[primitive.ObjectID]struct{}, len(p.IDS))
for _, raw := range p.IDS {
id, err := primitive.ObjectIDFromHex(raw)
if err != nil || id.IsZero() {
return nil, errors.New("ids包含无效的剧集ID")
}
if _, ok := seen[id]; ok {
continue
}
seen[id] = struct{}{}
ids = append(ids, id)
}
return ids, nil
}
func (p *WebBatchUpdateReq) applyContentFields(content mediacontentmod.MediaContent) mediacontentmod.MediaContent {
if p.IsActive != nil {
content.IsActive = *p.IsActive
}
if p.Price != nil {
content.Price = *p.Price
}
if p.Permission != nil {
content.ListenPermission = *p.Permission
}
return content
}
// Update 更新数据
func (p *WebBatchUpdateReq) Update(manager string) error {
ids, err := p.ValidatedIDs()
if err != nil {
return err
}
contents, err := mediacontentmod.QueryAllList(bson.M{
"_id": bson.M{"$in": ids},
"isDelete": false,
}, options.Find().SetLimit(int64(len(ids))))
if err != nil {
return err
}
if len(contents) != len(ids) {
return errors.New("部分剧集不存在或已删除")
}
mediaID := contents[0].MediaID
mediaType := contents[0].MediaType
published := false
for _, content := range contents {
if content.MediaID != mediaID {
return errors.New("批量操作的剧集必须属于同一部短剧")
}
next := p.applyContentFields(*content)
if p.IsActive != nil && *p.IsActive && !content.IsActive {
published = true
}
validateState := p.Price != nil || p.Permission != nil || (p.IsActive != nil && *p.IsActive)
if validateState && mediaType == mediamod.MediaTypeDrama {
if err = validateDramaEpisodeState(next.EpisodeNumber, next.ListenPermission, next.Price, next.Name, next.VideoUrl, next.H265Url, next.IsActive, next.Status); err != nil {
return fmt.Errorf("第%d集:%w", content.EpisodeNumber, err)
}
}
}
data := make(map[string]interface{})
if p.IsActive != nil {
data["isActive"] = *p.IsActive
}
if p.Price != nil {
data["price"] = *p.Price
}
if p.Permission != nil {
data["listenPermission"] = *p.Permission
}
data["updatedAct"] = manager
data["updateTime"] = time.Now()
contentChanged := p.IsActive != nil || p.Price != nil || p.Permission != nil
if contentChanged {
if _, err := mediacontentmod.UpdateByIDS(nil, ids, data); err != nil {
return err
}
if err = OnMediaContentChange(mediaID, mediaType, false, published); err != nil {
return err
}
}
if p.FreeEpisode != nil {
if _, err = mediamod.UpdateByID(nil, mediaID, map[string]interface{}{
"freeEpisode": *p.FreeEpisode,
"updatedAct": manager,
"updateTime": time.Now(),
}); err != nil {
return err
}
}
return nil
}
type WebDeleteReq struct {
ID primitive.ObjectID `json:"id" binding:"required"`
}
// Delete 删除数据
func (p *WebDeleteReq) Delete() error {
mediaContent, err := mediacontentmod.GetInfo(p.ID)
if err != nil {
return err
}
if err := mediacontentmod.DeleteByID(nil, p.ID); err != nil {
return err
}
err = OnMediaContentChange(mediaContent.MediaID, mediaContent.MediaType, false, false)
if err != nil {
return err
}
return nil
}
func OnMediaContentChange(mediaId primitive.ObjectID, mediaType string, contentAdded, published bool) (err error) {
// 获取当前最小的章节,重新update
defaultContent := mediamod.DefaultContent{}
if mediaType == mediamod.MediaTypeImage {
contentList, _, _, err := mediacontentmod.GetList(bson.M{"mediaId": mediaId, "isActive": true, "isDelete": false}, 0, 1, bson.D{{Key: "episodeNumber", Value: 1}, {Key: "createdAt", Value: 1}})
if err != nil {
return err
}
if len(contentList) > 0 {
defaultContent.Id = contentList[0].ID
defaultContent.Name = contentList[0].Name
defaultContent.UrlSet = contentList[0].UrlSet
defaultContent.Cover = contentList[0].Cover
}
}
// 子集总数
count, err := mediacontentmod.QueryAllCount(bson.M{"mediaId": mediaId, "isActive": true, "isDelete": false})
if err != nil {
return err
}
// 获取子集免费章节总数
freeCount, err := mediacontentmod.QueryAllCount(bson.M{"mediaId": mediaId, "listenPermission": 2, "isActive": true, "isDelete": false})
if err != nil {
return err
}
contentsPrice, err := mediacontentmod.QueryContentsPrice(mediaId)
if err != nil {
return
}
updateData := bson.M{
"currentEpisode": count,
"contentsPrice": contentsPrice,
"freeEpisode": freeCount,
"updateTime": time.Now(),
"defaultContent": defaultContent, // 默认展示的子集内容,冗余一个字段,减少一次查询
}
now := time.Now()
if contentAdded {
updateData["contentUpdateTime"] = now
}
if published {
updateData["latestPublishedAt"] = now
}
//修改当前父级的记录
_, err = mediamod.UpdateByID(nil, mediaId, updateData)
if err != nil {
return err
}
return nil
}
// ViewMediaFromFs 查看视频转码状态
func ViewMediaFromFs(id string) (code stderr.Code, data interface{}) {
resp, err := updownloadser.PullFileInfo(id)
if err != nil {
return stderr.ErrConnectToFs, nil
}
status := fileStatusToEpisodeStatus(resp.Data.Status)
ratio := resp.Data.Ratio
if ratio == 0 && resp.Data.Height > 0 {
ratio = float64(resp.Data.Width) / float64(resp.Data.Height)
}
set := map[string]interface{}{
"status": status,
"playTime": resp.Data.PlayTime,
"weight": resp.Data.Width,
"height": resp.Data.Height,
"mediaSize": int64(resp.Data.Size),
"ratio": ratio,
"updateTime": time.Now(),
}
if resp.Data.CheckSum != "" {
set["md5"] = resp.Data.CheckSum
}
objId, _ := primitive.ObjectIDFromHex(id)
if _, err = mediacontentmod.UpdateByID(nil, objId, set); err != nil {
return stderr.ErrDbUpdateError, nil
}
back := make(map[string]interface{}, 10)
back["playTime"] = resp.Data.PlayTime
back["size"] = resp.Data.Size
back["width"] = resp.Data.Width
back["height"] = resp.Data.Height
back["status"] = resp.Data.Status
back["ratio"] = ratio
fileName := resp.Data.Filename
fieldNameFs := resp.Data.FieldNameFs
back["fileName"] = filepath.Join(filepath.Dir(fieldNameFs), fileName)
switch resp.Data.Status {
case vidmod.UploadLoadingToFs:
back["statusDesc"] = "正在上传中"
case vidmod.UploadCompleted:
back["statusDesc"] = "上传完成"
case vidmod.FileUploadError:
back["statusDesc"] = "上传错误"
case vidmod.Merging:
back["statusDesc"] = "正在合并中"
case vidmod.MergeCompleted:
back["statusDesc"] = "合并完成"
case vidmod.MergeError:
back["statusDesc"] = "合并失败"
case vidmod.Converting:
back["statusDesc"] = "正在转码中"
case vidmod.ConvertError:
back["statusDesc"] = "转码失败"
case vidmod.ConvertCompleted, vidmod.Completed:
back["statusDesc"] = "完成状态"
}
return stderr.Success, back
}