@@ -0,0 +1,329 @@
|
||||
package ai_changeface_img_ser
|
||||
|
||||
import (
|
||||
"91porn-server/app/appg"
|
||||
"91porn-server/app/service/ai_undress_server"
|
||||
"91porn-server/app/service/aiautoser"
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/aiService"
|
||||
"91porn-server/common/constant/redisconst"
|
||||
"91porn-server/common/db"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/stderr"
|
||||
"91porn-server/middleware/ua"
|
||||
"91porn-server/models/commod"
|
||||
"91porn-server/models/v/advanceordermod"
|
||||
"91porn-server/models/v/aichangefaceimgmod"
|
||||
"91porn-server/models/v/txnmod"
|
||||
"91porn-server/models/v/usermod"
|
||||
"91porn-server/models/v/walletmod"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang-module/carbon/v2"
|
||||
"github.com/shopspring/decimal"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
func List(uid uint64, req *aichangefaceimgmod.ListRequest) (interface{}, stderr.Code) {
|
||||
var data = map[string]interface{}{
|
||||
"list": []interface{}{},
|
||||
"count": 0,
|
||||
}
|
||||
count, err := aichangefaceimgmod.CountDocument(req.Filter(uid))
|
||||
if err != nil {
|
||||
return nil, stderr.ErrDbQueryError
|
||||
}
|
||||
if count == 0 {
|
||||
return data, stderr.Success
|
||||
}
|
||||
opts := options.Find().SetSkip(int64(req.Skip())).SetLimit(int64(req.Limit() + 1)).SetSort(bson.M{"createdAt": -1})
|
||||
list, err := aichangefaceimgmod.QueryAllDocument(req.Filter(uid), opts)
|
||||
if err != nil {
|
||||
return data, stderr.ErrDbQueryError
|
||||
}
|
||||
hasNext := false
|
||||
if len(list) > int(req.Limit()) {
|
||||
list = list[:req.Limit()]
|
||||
hasNext = true
|
||||
}
|
||||
data["count"] = count // 兼容旧版本
|
||||
data["hasNext"] = hasNext
|
||||
data["list"] = list
|
||||
return data, stderr.Success
|
||||
}
|
||||
|
||||
func Generate(uid uint64, req *aichangefaceimgmod.GenerateRequest, ua ua.UA, ip string) stderr.Code {
|
||||
// 获取AI模版图
|
||||
id, err := primitive.ObjectIDFromHex(req.MId)
|
||||
if err != nil {
|
||||
return stderr.ErrParamError
|
||||
}
|
||||
mod, err := aiService.NewAiService(
|
||||
aiService.AppId(int(commod.KFK_APPID)),
|
||||
aiService.Url(appg.Conf.URL.AiServer),
|
||||
aiService.Redis(appg.Redis),
|
||||
).GetTemplate(id)
|
||||
if mod.ID.IsZero() {
|
||||
return stderr.CodeEmptyData
|
||||
}
|
||||
|
||||
req.Coin = int64(mod.Coin)
|
||||
user, err := usermod.FindUserByUID(uid)
|
||||
if err != nil {
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
|
||||
if user.IsVIP(time.Now()) {
|
||||
req.Coin = int64(mod.VipCoin)
|
||||
}
|
||||
// 获取用户是否是复购
|
||||
isRepurchase, err := txnmod.CheckRepurchaseByTransTypes(uid, []txnmod.TransType{
|
||||
txnmod.AiChangeFaceImgDebitFreeTimes,
|
||||
txnmod.AiChangeFaceImgDebitGold,
|
||||
txnmod.AiChangeFaceImgDebitIncomeGold,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("txnmod.CheckRepurchaseByTransTypes fail", log.E(err))
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
privilegeFreeCount := int64(0)
|
||||
picCount := int64(1)
|
||||
hasPrivilege, advance := advanceordermod.GetUserValidOrder(uid)
|
||||
if hasPrivilege {
|
||||
// 获取可用免费次数
|
||||
validCount := advance.PrepaidPrivilege.AiUndressLimitPerDay - advance.TodayUse.AiUndressCount
|
||||
if validCount >= picCount {
|
||||
// 扣除免费次数
|
||||
debitPlan := advanceordermod.DebitPlan{}
|
||||
debitPlan.AiUndressCount = &picCount
|
||||
if err := advanceordermod.Debit(nil, uid, debitPlan); err != nil {
|
||||
return stderr.ErrDbUpdateError
|
||||
}
|
||||
privilegeFreeCount = picCount
|
||||
picCount = 0
|
||||
} else if validCount > 0 {
|
||||
// 扣除免费次数
|
||||
debitPlan := advanceordermod.DebitPlan{}
|
||||
debitPlan.AiUndressCount = &validCount
|
||||
if err := advanceordermod.Debit(nil, uid, debitPlan); err != nil {
|
||||
return stderr.ErrDbUpdateError
|
||||
}
|
||||
privilegeFreeCount = validCount
|
||||
picCount -= validCount
|
||||
}
|
||||
if validCount > 0 {
|
||||
l := &txnmod.TransactionLog{
|
||||
TransNo: primitive.NewObjectID(),
|
||||
UID: uid,
|
||||
Amount: 1,
|
||||
ActualAmount: float64(-1),
|
||||
TranType: txnmod.AiChangeFaceImgDebitFreeTimes.Key(),
|
||||
TranTypeInt: int64(txnmod.AiChangeFaceImgDebitFreeTimes),
|
||||
Desc: fmt.Sprintf("生成AI图片换脸扣除免费次数[%d次]", privilegeFreeCount),
|
||||
RealAmount: decimal.Decimal{},
|
||||
SysType: user.SysType,
|
||||
IsRepurchase: isRepurchase,
|
||||
}
|
||||
txnErr := txnmod.InsertTransactionLog(nil, l)
|
||||
if txnErr != nil {
|
||||
log.Error(fmt.Sprintf("Handle AiUnDress Generate txnmod.InsertTransactionLog error:%+v:", txnErr), log.Any("uid", uid))
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
}
|
||||
}
|
||||
var debitFreeCount, debitAmountCoins, debitIncomeCoins int64
|
||||
|
||||
if picCount > 0 {
|
||||
// 获取用户钱包
|
||||
w, err := walletmod.GetWallet(uid)
|
||||
if err != nil {
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
// 校验用户余额
|
||||
if w == nil {
|
||||
return stderr.InsufficientBalance
|
||||
}
|
||||
|
||||
debitFreeCount, debitAmountCoins, debitIncomeCoins = ai_undress_server.TotalDebit(req.Coin, picCount, *w)
|
||||
if debitFreeCount > 0 {
|
||||
req.IsFreeTimes = true
|
||||
}
|
||||
// 如果收费的部分余额不够支付
|
||||
if req.Coin*(picCount-debitFreeCount) > (w.Amount + w.Income) {
|
||||
return stderr.InsufficientBalance
|
||||
}
|
||||
}
|
||||
var orderId primitive.ObjectID
|
||||
var orderCreatedAt time.Time
|
||||
if err = appg.VideoDB.Trans(func(tool *db.MongoTool) error {
|
||||
var tl []txnmod.TransactionLog
|
||||
if debitFreeCount > 0 {
|
||||
expire := carbon.Tomorrow().StartOfDay().StdTime().Sub(time.Now())
|
||||
// 累加次数(跟ai脱衣共用这个次数)
|
||||
appg.Redis.IncrBy(redisconst.AiFreeUndressTodayUseTimesKey(uid), debitFreeCount, expire)
|
||||
// 扣除钱剩余次数
|
||||
wallet, wErr := walletmod.DebitAiFreeTimes(tool, debitFreeCount, uid)
|
||||
if wErr != nil {
|
||||
log.Error(fmt.Sprintf("Handle AIChangeFaceImg Generate walletmod.DebitAiFreeTimes error:%+v:", wErr), log.Any("uid", uid))
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
|
||||
tl = append(tl, txnmod.TransactionLog{
|
||||
TransNo: primitive.NewObjectID(),
|
||||
UID: uid,
|
||||
Amount: 1,
|
||||
ActualAmount: float64(-1),
|
||||
TranType: txnmod.AiChangeFaceImgDebitFreeTimes.Key(),
|
||||
TranTypeInt: int64(txnmod.AiChangeFaceImgDebitFreeTimes),
|
||||
Desc: fmt.Sprintf("生成AI图片换脸扣除免费次数[%d次]", debitFreeCount),
|
||||
RealAmount: walletmod.GetRealAmount(wallet),
|
||||
SysType: user.SysType,
|
||||
IsRepurchase: isRepurchase,
|
||||
})
|
||||
}
|
||||
|
||||
if debitIncomeCoins > 0 || debitAmountCoins > 0 {
|
||||
// 扣除钱包余额
|
||||
wallet, wErr := walletmod.DebitAmountAndIncome(tool, debitAmountCoins, debitIncomeCoins, uid)
|
||||
if wErr != nil {
|
||||
log.Error(fmt.Sprintf("Handle AiUnDress Generate walletmod.DebitAmount error:%+v:", wErr), log.Any("uid", uid))
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
|
||||
if debitAmountCoins > 0 {
|
||||
tl = append(tl, txnmod.TransactionLog{
|
||||
TransNo: primitive.NewObjectID(),
|
||||
UID: uid,
|
||||
Amount: -debitAmountCoins,
|
||||
ActualAmount: float64(-debitAmountCoins),
|
||||
TranType: txnmod.AiChangeFaceImgDebitGold.Key(),
|
||||
TranTypeInt: int64(txnmod.AiChangeFaceImgDebitGold),
|
||||
Desc: fmt.Sprintf("生成AI图片换脸金币-%d", debitAmountCoins),
|
||||
RealAmount: walletmod.GetRealAmount(wallet),
|
||||
SysType: user.SysType,
|
||||
IsRepurchase: isRepurchase,
|
||||
})
|
||||
}
|
||||
if debitIncomeCoins > 0 {
|
||||
tl = append(tl, txnmod.TransactionLog{
|
||||
TransNo: primitive.NewObjectID(),
|
||||
UID: uid,
|
||||
Amount: -debitIncomeCoins,
|
||||
ActualAmount: float64(-debitIncomeCoins),
|
||||
TranType: txnmod.AiChangeFaceImgDebitIncomeGold.Key(),
|
||||
TranTypeInt: int64(txnmod.AiChangeFaceImgDebitIncomeGold),
|
||||
Desc: fmt.Sprintf("生成AI图片换脸收益金币-%d", debitIncomeCoins),
|
||||
RealAmount: walletmod.GetRealAmount(wallet),
|
||||
SysType: user.SysType,
|
||||
IsRepurchase: isRepurchase,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(tl) > 0 {
|
||||
txnErr := txnmod.InsertManyTransactionLog(tool, tl)
|
||||
if txnErr != nil {
|
||||
log.Error(fmt.Sprintf("Handle AiUnDress Generate txnmod.InsertTransactionLog error:%+v:", txnErr), log.Any("uid", uid))
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
}
|
||||
|
||||
// 新增AI脱衣记录
|
||||
orderId = primitive.NewObjectID()
|
||||
orderCreatedAt = time.Now()
|
||||
if err = aichangefaceimgmod.InsertOne(tool, req.Generate(orderId, orderCreatedAt, uid, mod.Title, mod.Cover, privilegeFreeCount, debitFreeCount, debitAmountCoins, debitIncomeCoins)); err != nil {
|
||||
log.Error(fmt.Sprintf("Handle Aichangefaceimg Generate InsertOnes error:%+v:", err), log.Any("uid", uid))
|
||||
return stderr.ErrDbInsertError
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Error(fmt.Sprintf("Handle Aichangefaceimg Generate Trans error:%+v;uid:%v;", err, uid))
|
||||
return stderr.ErrDbUpdateError
|
||||
}
|
||||
common.Go(func() {
|
||||
if err := aiautoser.SubmitImage(orderId); err != nil {
|
||||
log.Error("AI图片换脸自动处理失败", log.Any("id", orderId.Hex()), log.E(err))
|
||||
}
|
||||
})
|
||||
|
||||
return stderr.Success
|
||||
}
|
||||
|
||||
func AiChangeFaceImgHide(uid uint64, req *aichangefaceimgmod.DelRequest) stderr.Code {
|
||||
acf, err := aichangefaceimgmod.FindByID(nil, req.ID)
|
||||
if err != nil {
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
if acf.ID.IsZero() {
|
||||
return stderr.CodeEmptyData
|
||||
}
|
||||
if acf.UID != uid {
|
||||
return stderr.Failure
|
||||
}
|
||||
if acf.Status == aichangefaceimgmod.Processing || acf.Status == aichangefaceimgmod.StatusSubmit {
|
||||
return stderr.AiGenningDelForbidden
|
||||
}
|
||||
if err = aichangefaceimgmod.Edit(nil, req.Filter(), req.Update()); err != nil {
|
||||
return stderr.ErrDbQueryError
|
||||
}
|
||||
return stderr.Success
|
||||
}
|
||||
|
||||
func TotalDebit(price int64, count int64, w walletmod.Wallet) (fCount, amountCoins, incomeCoins int64) {
|
||||
var (
|
||||
debitFreeTimes int64
|
||||
debitAmountCoins int64
|
||||
debitIncomeCoins int64
|
||||
)
|
||||
if w.AiUndressFreeTimes > 0 && w.AiUndressFreeTimes >= count {
|
||||
debitFreeTimes = count
|
||||
}
|
||||
|
||||
if w.AiUndressFreeTimes > 0 && w.AiUndressFreeTimes < count {
|
||||
debitFreeTimes = w.AiUndressFreeTimes
|
||||
debitCoins := (count - debitFreeTimes) * price
|
||||
if w.Amount >= debitCoins {
|
||||
debitAmountCoins = debitCoins
|
||||
}
|
||||
if w.Amount < debitCoins {
|
||||
debitAmountCoins = w.Amount
|
||||
debitIncomeCoins = debitCoins - w.Amount
|
||||
}
|
||||
}
|
||||
|
||||
if w.AiUndressFreeTimes <= 0 {
|
||||
debitCoins := price * count
|
||||
if w.Amount >= debitCoins {
|
||||
debitAmountCoins = debitCoins
|
||||
}
|
||||
if w.Amount < debitCoins {
|
||||
debitAmountCoins = w.Amount
|
||||
debitIncomeCoins = debitCoins - w.Amount
|
||||
}
|
||||
}
|
||||
return debitFreeTimes, debitAmountCoins, debitIncomeCoins
|
||||
}
|
||||
|
||||
func CheckBalance(price int64, count int64, w walletmod.Wallet) bool {
|
||||
var checkStats bool
|
||||
var totalCoins = w.Amount
|
||||
if w.Income != 0 {
|
||||
totalCoins += w.Income
|
||||
}
|
||||
if w.AiUndressFreeTimes > 0 && w.AiUndressFreeTimes >= count {
|
||||
checkStats = true
|
||||
}
|
||||
|
||||
if w.AiUndressFreeTimes > 0 && w.AiUndressFreeTimes < count && totalCoins >= price*(count-w.AiUndressFreeTimes) {
|
||||
checkStats = true
|
||||
}
|
||||
|
||||
if w.AiUndressFreeTimes <= 0 && totalCoins > price*count {
|
||||
checkStats = true
|
||||
}
|
||||
return checkStats
|
||||
}
|
||||
Reference in New Issue
Block a user