Files
huangguo_server/app/api/ai_changeface_ctrl/ai_changeface.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

248 lines
8.0 KiB
Go

package ai_changeface_ctrl
import (
"91porn-server/app/service/ai_changeface_ser"
"91porn-server/app/service/m3u8ticket"
"91porn-server/common"
"91porn-server/common/constant"
"91porn-server/common/log"
"91porn-server/common/stderr"
"91porn-server/models/commod"
"91porn-server/models/l/operatorlgmod"
"91porn-server/models/v/aichangefacemod"
"encoding/json"
"errors"
"fmt"
"strconv"
"github.com/gin-gonic/gin"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// List doc
// @Summary AI换脸列表
// @Description AI换脸列表
// @Tags AI视频换脸
// @Accept json
// @Produce json
// @Param status query int false "记录状态"
// @Param pageNumber query int true "第几页"
// @Param pageSize query int true "每页数量"
// @Success 200 object interface{} "成功后返回"
// @Failure 400 {string} json "{"msg": "操作失败"}"
// @Router /ai/changeface/list [get]
func List(c *gin.Context) {
uid, err := common.GetUID(c)
if err != nil {
common.ServeJSON(c, stderr.ErrNoToken, err)
return
}
var req struct {
Status *aichangefacemod.AiChangeFaceStatus `form:"status" json:"status"` // 0 未完成; 1 已完成; -1 已退款
commod.Page
}
if err = c.ShouldBindQuery(&req); err != nil {
common.ServeJSON(c, stderr.ErrNoToken, err)
return
}
list, hasNext, err := ai_changeface_ser.List(uid, req.Status, int(req.Skip()), int(req.Limit()))
if err != nil {
log.Error(fmt.Sprintf("ai_changeface_ser List error%v, uid%v", err.Error(), uid))
common.ServeJSON(c, stderr.ErrDbQueryError, nil)
return
}
for i := range list {
m3u8ticket.SignURL(c, uid, &list[i].ModVideo, true, false)
m3u8ticket.SignURL(c, uid, &list[i].Url, true, false)
}
common.ServeJSON(c, stderr.Success, gin.H{
"list": list,
"hasNext": hasNext,
})
}
// Generate doc
// @Summary 生成AI换脸记录
// @Description 生成AI换脸记录
// @Tags AI视频换脸
// @Accept json
// @Produce json
// @Param q body aichangefacemod.GenerateRequest false "请求参数"
// @Success 200 {string} json "{"msg": "操作成功"}"
// @Failure 400 {string} json "{"msg": "操作失败"}"
// @Router /ai/changeface/generate [post]
func Generate(ctx *gin.Context) {
uid, err := common.GetUID(ctx)
if err != nil {
common.ServeJSON(ctx, stderr.ErrNoToken, err)
return
}
var in aichangefacemod.GenerateRequest
if err = ctx.ShouldBind(&in); err != nil {
log.Error(fmt.Sprintf("undress Generate param err%v\n", err))
common.ServeJSON(ctx, stderr.ErrParamError, err)
return
}
if len(in.Pic) == 0 || in.VidModID.IsZero() {
common.ServeJSON(ctx, stderr.ErrParamError, nil)
return
}
ua, _ := common.GetUA(ctx)
ip := common.GetIP(ctx)
code := ai_changeface_ser.Generate(uid, in.Pic, in.VidModID, in.Discount, in.ShareTitle, in.ShareStatus, ua, ip)
if code != stderr.Success {
log.Error(fmt.Sprintf("undress Generate err%v", code))
common.ServeJSON(ctx, code, code.Error())
return
}
updateLog, _ := json.Marshal(in)
_ = operatorlgmod.RecordOperation(strconv.FormatUint(uid, 10), constant.AiChangeface, constant.Add, string(updateLog), ctx.Request.URL.RequestURI())
common.ServeJSON(ctx, stderr.Success, stderr.Success.Msg())
}
// Hide doc
// @Summary 删除AI换脸记录
// @Description 删除AI换脸记录
// @Tags AI视频换脸
// @Accept json
// @Produce json
// @Param id formData string false "AI订单ID"
// @Success 200 {string} json "{"msg": "操作成功"}"
// @Failure 400 {string} json "{"msg": "操作失败"}"
// @Router /ai/changeface/hide [post]
func Hide(ctx *gin.Context) {
uid, err := common.GetUID(ctx)
if err != nil {
common.ServeJSON(ctx, stderr.ErrNoToken, err)
return
}
var req struct {
ID primitive.ObjectID `json:"id"`
}
if err = ctx.ShouldBind(&req); err != nil {
log.Error(fmt.Sprintf("changeface Generate param err%v\n", err))
common.ServeJSON(ctx, stderr.ErrParamError, err)
return
}
if req.ID.IsZero() {
common.ServeJSON(ctx, stderr.ErrParamError, err)
return
}
acf, err := aichangefacemod.FindByID(nil, req.ID)
if err != nil {
common.ServeJSON(ctx, stderr.ErrDbQueryError, err)
return
}
if acf.ID.IsZero() {
common.ServeJSON(ctx, stderr.Failure, errors.New("ai换脸订单未找到"))
return
}
if acf.Uid != uid {
common.ServeJSON(ctx, stderr.Failure, errors.New("只能删除自己的订单"))
return
}
if acf.Status == aichangefacemod.StatusGenning || acf.Status == aichangefacemod.StatusSubmit {
common.ServeJSON(ctx, stderr.AiGenningDelForbidden, errors.New("不能删除排队中的订单"))
return
}
if err = aichangefacemod.Hide(uid, req.ID); err != nil {
common.ServeJSON(ctx, stderr.ErrDbQueryError, err)
return
}
updateLog, _ := json.Marshal(req)
_ = operatorlgmod.RecordOperation(strconv.FormatUint(uid, 10), constant.AiChangeface, constant.Delete, string(updateLog), ctx.Request.URL.RequestURI())
common.ServeJSON(ctx, stderr.Success, stderr.Success.Msg())
}
// ModList doc
// @Summary AI模版列表
// @Description AI模版列表
// @Tags AI模版
// @Accept json
// @Produce json
// @Success 200 object aichangefacevidmod.AppResponse "成功后返回"
// @Failure 400 {string} json "{"msg": "操作失败"}"
// @Router /app/ai/mod/list [get]
func ModList(c *gin.Context) {
uid, err := common.GetUID(c)
if err != nil {
common.ServeJSON(c, stderr.ErrNoToken, err)
return
}
data, err := ai_changeface_ser.ModList(uid)
if err != nil {
log.Error(fmt.Sprintf("ai_changeface_ser ModList error%v,uid%v", err.Error(), uid))
common.ServeJSON(c, stderr.ErrDbQueryError, nil)
return
}
if data != nil {
for i := range data.AiChangeFaceVideoMod {
m3u8ticket.SignURL(c, uid, &data.AiChangeFaceVideoMod[i].SourceURL, true, false)
}
for i := range data.AiImgToVideoMod {
m3u8ticket.SignURL(c, uid, &data.AiImgToVideoMod[i].NewUrl, true, false)
}
}
common.ServeJSON(c, stderr.Success, data)
}
// ModListV2 doc
// @Summary AI模版列表
// @Description AI模版列表
// @Tags AI模版
// @Accept json
// @Produce json
// @Param q query ai_changeface_ser.ModListV2Req false "请求参数"
// @Success 200 object ai_changeface_ser.ModListV2Resp "成功后返回"
// @Failure 400 {string} json "{"msg": "操作失败"}"
// @Router /api/app/ai/mod/v2/list [get]
func ModListV2(ctx *gin.Context) {
var req ai_changeface_ser.ModListV2Req
if err := ctx.ShouldBind(&req); err != nil {
common.ServeJSON(ctx, stderr.ErrParamError, err)
return
}
data, err := ai_changeface_ser.ModListV2(req)
if err != nil {
log.Error("ai_changeface_ser.ModListV2 fail", log.Any("req", req), log.E(err))
common.ServeJSON(ctx, stderr.ErrDbQueryError, nil)
return
}
uid := common.TryGetUID(ctx)
for i := range data.TemplateList {
if data.TemplateList[i] == nil {
continue
}
m3u8ticket.SignURL(ctx, uid, &data.TemplateList[i].M3u8Url, true, false)
}
common.ServeJSON(ctx, stderr.Success, data)
}
// ModInfo doc
// @Summary AI模版详情
// @Description AI模版详情
// @Tags AI模版
// @Accept json
// @Produce json
// @Param q query ai_changeface_ser.ModInfoReq false "请求参数"
// @Success 200 object ai_changeface_ser.ModInfoResp "成功"
// @Failure 400 {string} json "{"msg": "操作失败"}"
// @Router /app/ai/mod/info [get]
func ModInfo(ctx *gin.Context) {
var req ai_changeface_ser.ModInfoReq
if err := ctx.ShouldBind(&req); err != nil {
common.ServeJSON(ctx, stderr.ErrParamError, err)
return
}
data, err := req.GetInfo()
if err != nil {
common.ServeJSON(ctx, stderr.ErrDbQueryError, nil)
return
}
uid := common.TryGetUID(ctx)
m3u8ticket.SignURL(ctx, uid, &data.AiChangeFaceMod.M3u8Url, true, false)
m3u8ticket.SignURL(ctx, uid, &data.AiImgToVideoMod.NewUrl, true, false)
common.ServeJSON(ctx, stderr.Success, data)
}