package ai_undress_service import ( "91porn-server/common" "91porn-server/models/commod" "91porn-server/models/v/aiplazamod" "91porn-server/models/v/walletmod" "fmt" "strconv" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "91porn-server/common/db" "91porn-server/common/httputil" "91porn-server/common/log" "91porn-server/common/stderr" "91porn-server/models/v/aiUnDressmod" "91porn-server/models/v/txnmod" "91porn-server/web/webg" ) func List(req *aiUnDressmod.WebListRequest) (interface{}, stderr.Code) { var data = map[string]interface{}{ "list": []interface{}{}, "count": 0, } count, err := aiUnDressmod.CountDocument(req.Filter()) if err != nil { return nil, stderr.ErrDbQueryError } if count == 0 { return data, stderr.Success } list, err := aiUnDressmod.QueryAllDocument(req.Filter(), req.Options()) if err != nil { return data, stderr.ErrDbQueryError } data["count"] = count data["list"] = list return data, stderr.Success } func Update(act string, req *aiUnDressmod.EditCond) stderr.Code { // 获取Ai记录 data, err := aiUnDressmod.FindDataByID(req.ID) if err != nil { return stderr.ErrDbQueryError } if (*req.Status == aiUnDressmod.FAILURE || *req.Status == aiUnDressmod.REFUND) && (data.Status == aiUnDressmod.FAILURE || data.Status == aiUnDressmod.REFUND) { return stderr.Success } // 根据状态判断 switch *req.Status { case aiUnDressmod.Processing: if data.Status != aiUnDressmod.SUCCESS && data.Status != aiUnDressmod.SubmitOrder { return stderr.AiUnDressStatusIsErr } err = aiUnDressmod.Edit(nil, req.Filter(), req.Update(act)) if err != nil { return stderr.ErrDbUpdateError } case aiUnDressmod.SUCCESS: err = aiUnDressmod.Edit(nil, req.Filter(), req.Update(act)) if err != nil { return stderr.ErrDbUpdateError } case aiUnDressmod.FAILURE, aiUnDressmod.REFUND: // 失败处理 退金币 deAmt := -data.DebitAmountCoin deIncome := -data.DebitIncomeCoin uid := data.UID oldVersion := false err = webg.VideoDB.Trans(func(tool *db.MongoTool) error { updateSet, _ := req.Update(act)["$set"].(bson.M) transitioned, transitionErr := aiUnDressmod.TransitionStatus(tool, data.ID, data.Status, *req.Status, updateSet) if transitionErr != nil { return transitionErr } if !transitioned { return nil } var tl []txnmod.TransactionLog // 根据是否是免费次数退回 if data.Count > 0 || data.IsFreeTimes { deCount := data.Count if data.Count == 0 { deCount = 1 } // 加钱包余额 wallet, wErr := walletmod.DebitAiFreeTimes(tool, -deCount, uid) if wErr != nil { log.Error(fmt.Sprintf("Handle AiUnDress Edit walletmod.DebitAiFreeTimes error:%+v:", wErr), log.Any("uid", uid)) return stderr.ErrDbQueryError } tl = append(tl, txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: uid, Amount: deCount, ActualAmount: float64(deCount), TranType: txnmod.AiUndressDebitFreeTimesReturn.Key(), TranTypeInt: int64(txnmod.AiUndressDebitFreeTimesReturn), Desc: fmt.Sprintf("AI脱衣免费次数退返[%d次]", deCount), RealAmount: walletmod.GetRealAmount(wallet), }) } if !data.IsFreeTimes && data.DebitAmountCoin == 0 && data.DebitIncomeCoin == 0 { deAmt = -data.Coin oldVersion = true } if data.DebitAmountCoin > 0 || data.DebitIncomeCoin > 0 || oldVersion { // 加钱包余额 wallet, wErr := walletmod.ReturnAmountAndIncome(tool, deAmt, deIncome, uid) if wErr != nil { log.Error(fmt.Sprintf("Handle AiUnDress Edit walletmod.DebitAmount error:%+v:", wErr), log.Any("uid", uid)) return stderr.ErrDbQueryError } if data.DebitIncomeCoin > 0 { tl = append(tl, txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: uid, Amount: -deIncome, ActualAmount: float64(-deIncome), TranType: txnmod.AiUndressDebitIncomeGoldReturn.Key(), TranTypeInt: int64(txnmod.AiUndressDebitIncomeGoldReturn), Desc: fmt.Sprintf("AI脱衣收益金币退返-%d", -deIncome), RealAmount: walletmod.GetRealAmount(wallet), }) } if data.DebitAmountCoin > 0 || oldVersion { tl = append(tl, txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: uid, Amount: -deAmt, ActualAmount: float64(-deAmt), TranType: txnmod.AiUndressDebitGoldReturn.Key(), TranTypeInt: int64(txnmod.AiUndressDebitGoldReturn), Desc: fmt.Sprintf("AI脱衣金币退返-%d", -deAmt), RealAmount: walletmod.GetRealAmount(wallet), }) } } txnErr := txnmod.InsertManyTransactionLog(tool, tl) if txnErr != nil { log.Error(fmt.Sprintf("Handle AiUnDress Edit txnmod.InsertManyTransactionLog error:%+v:", txnErr), log.Any("uid", uid)) return stderr.ErrDbQueryError } return nil }) if err != nil { log.Error(fmt.Sprintf("Handle AiUnDress Edit Trans error:%+v;uid:%v;", err, uid)) return stderr.ErrDbUpdateError } } return stderr.Success } // Auto 提交AI自动化服务 func Auto(act string, req *aiUnDressmod.AutoCond) stderr.Code { // 获取Ai记录 data, err := aiUnDressmod.FindDataByID(req.ID) if err != nil { return stderr.ErrDbQueryError } if data.Status == aiUnDressmod.SubmitOrder { return stderr.Success } //提交订单到第三方 notifyURL, notifyErr := webg.AICallbackURL("/api/web/admin/ai/undress/callback") if notifyErr != nil { log.Error("AI脱衣回调地址配置异常", log.E(notifyErr)) return stderr.Failure } httpReq := aiUnDressmod.AiUndressOrderReq{ AppId: int(commod.KFK_APPID), FileUrl: data.OriginPics, UserId: strconv.FormatUint(data.UID, 10), AppOrderNum: data.ID.Hex(), NotifyUrl: notifyURL, } var resp aiUnDressmod.AiUndressOrderResp url := webg.Conf.URL.AiUndressServer + "/api/undress/prd/create_job" codeJ, err := httputil.DefaultClientPostJsonWithResp(&resp, url, nil, httpReq) if err != nil { log.Error("CreateUnderss httputil.DefaultClientPostWithResp err", log.E(err)) return stderr.Failure } if codeJ != 200 { log.Error("CreateUnderss req http code error", log.Any("code", codeJ)) return stderr.Failure } //更新ai脱衣订单状态 if err := aiUnDressmod.SubmitStatus(req.ID, aiUnDressmod.SubmitOrder, "已提交"); err != nil { return stderr.ErrDbUpdateError } return stderr.Success } // CallBackOrder AI脱衣回调 func CallBackOrder(req *aiUnDressmod.CallBackReq) stderr.Code { // 获取Ai记录 data, err := aiUnDressmod.FindDataByID(req.AppOrderNum) if err != nil { return stderr.ErrDbQueryError } if data.Status != aiUnDressmod.SubmitOrder { log.Error("AI脱衣-重复回调或者状态不正确", log.Any("id", data.ID.Hex()), log.Any("status", data.Status)) return stderr.Success } var ( set = bson.M{"remark": req.Msg} // 返还次数、返还金币、返还收益金币 refoundCount, deAmt, deIncome int64 // 订单状态 status int oldVersion = false successCount = len(req.ImgUrl) uid = data.UID _id = data.ID isFreeTimes = false ) if req.ImgUrl != nil && len(req.ImgUrl) > 0 { set["newPic"] = req.ImgUrl // 同步内存中的 data.NewPic,否则下方 goroutine 读取 data.NewPic[0] 会因未更新而越界 panic data.NewPic = req.ImgUrl } if successCount > 0 { // 成功 status = aiUnDressmod.SUCCESS refoundCount = 0 deAmt = 0 deIncome = 0 } else { // 失败 status = aiUnDressmod.REFUND refoundCount = data.Count // 失败处理 退金币 deAmt = -data.DebitAmountCoin deIncome = -data.DebitIncomeCoin isFreeTimes = data.IsFreeTimes } set["status"] = status handled := false if err := webg.VideoDB.Trans(func(tool *db.MongoTool) error { transitioned, transitionErr := aiUnDressmod.TransitionStatus(tool, _id, aiUnDressmod.SubmitOrder, status, set) if transitionErr != nil { return transitionErr } if !transitioned { return nil } handled = true var tl []txnmod.TransactionLog if refoundCount > 0 || isFreeTimes { if refoundCount == 0 { refoundCount = 1 } // 加免费次数,负负为正 wallet, wErr := walletmod.DebitAiFreeTimes(tool, -refoundCount, uid) if wErr != nil { log.Error(fmt.Sprintf("Handle AiUnDress CallBackOrder walletmod.DebitAiFreeTimes error:%+v:", wErr), log.Any("uid", uid)) return stderr.ErrDbQueryError } tl = append(tl, txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: uid, Amount: refoundCount, ActualAmount: float64(refoundCount), TranType: txnmod.AiUndressDebitFreeTimesReturn.Key(), TranTypeInt: int64(txnmod.AiUndressDebitFreeTimesReturn), Desc: fmt.Sprintf("AI脱衣免费次数退返[%d次]", refoundCount), RealAmount: walletmod.GetRealAmount(wallet), }) } if !data.IsFreeTimes && data.DebitAmountCoin == 0 && data.DebitIncomeCoin == 0 { deAmt = -data.Coin oldVersion = true } if deAmt < 0 || deIncome < 0 || oldVersion { // 加钱包余额,负负为正 wallet, wErr := walletmod.ReturnAmountAndIncome(tool, deAmt, deIncome, uid) if wErr != nil { log.Error(fmt.Sprintf("Handle AiUnDress CallBackOrder walletmod.DebitAmount error:%+v:", wErr), log.Any("uid", uid)) return stderr.ErrDbUpdateError } if data.DebitIncomeCoin > 0 { tl = append(tl, txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: uid, Amount: -deIncome, ActualAmount: float64(-deIncome), TranType: txnmod.AiUndressDebitIncomeGoldReturn.Key(), TranTypeInt: int64(txnmod.AiUndressDebitIncomeGoldReturn), Desc: fmt.Sprintf("AI脱衣收益金币退返-%d", -deIncome), RealAmount: walletmod.GetRealAmount(wallet), }) } if data.DebitAmountCoin > 0 || oldVersion { tl = append(tl, txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: uid, Amount: -deAmt, ActualAmount: float64(-deAmt), TranType: txnmod.AiUndressDebitGoldReturn.Key(), TranTypeInt: int64(txnmod.AiUndressDebitGoldReturn), Desc: fmt.Sprintf("AI脱衣金币退返-%d", -deAmt), RealAmount: walletmod.GetRealAmount(wallet), }) } } if len(tl) > 0 { txnErr := txnmod.InsertManyTransactionLog(tool, tl) if txnErr != nil { log.Error(fmt.Sprintf("Handle AiUnDress CallBackOrder txnmod.InsertManyTransactionLog error:%+v:", txnErr), log.Any("uid", uid)) return stderr.ErrDbQueryError } } return nil }); err != nil { log.Error(fmt.Sprintf("Handle AiUnDress CallBackOrder Trans error:%+v;uid:%v;", err, uid)) return stderr.ErrDbUpdateError } if !handled { return stderr.Success } if successCount > 0 { common.Go(func() { if data.ShareStatus != 1 { return } // 新增一个分享 alPlaza := aiplazamod.AiPlaza{ Type: 3, OrderId: data.ID, Template: "", Uid: data.UID, Title: data.ShareTitle, OriginalImage: data.OriginPic, OriginalVideo: "", OriginContent: "", GenerateImage: data.NewPic[0], GenerateVideo: "", Status: aiplazamod.DefaultStatus, } _, err = aiplazamod.Insert(nil, alPlaza) if err != nil { log.Error("新增ai广场帖子失败", log.Any("alPlaza", alPlaza), log.E(err)) return } }) } return stderr.Success }