package ai_text_to_novel_ser import ( "91porn-server/common/db" "91porn-server/common/log" "91porn-server/common/stderr" "91porn-server/models/cache/aitexttonoveldata" "91porn-server/models/commod" "91porn-server/models/v/aitexttonovelmod" "91porn-server/models/v/txnmod" "91porn-server/models/v/walletmod" "91porn-server/web/webg" "errors" "fmt" "strings" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) type WebListReq struct { ID *string `json:"id" form:"id"` // ID UID *uint64 `json:"uid" form:"uid"` // 用户ID Status *int `json:"status" form:"status"` // 状态 commod.Page } func (q *WebListReq) Filter() primitive.M { filter := bson.M{} if q.ID != nil { id, _ := primitive.ObjectIDFromHex(*q.ID) filter["_id"] = id } if q.Status != nil { filter["status"] = q.Status } if q.UID != nil { filter["uid"] = q.UID } return filter } func (q *WebListReq) Sort() primitive.D { return bson.D{{Key: "createdAt", Value: -1}} } type WebListRes struct { Total int64 `json:"total"` HasNext bool `json:"hasNext"` List []aitexttonovelmod.AiTextToNovel `json:"list"` } // GetList 获取列表 func (q *WebListReq) GetList() (res WebListRes, err error) { res.List, res.Total, res.HasNext, err = aitexttonovelmod.GetList(q.Filter(), int64(q.Skip()), int64(q.Limit()), q.Sort()) return } type WebUpdateReq struct { ID primitive.ObjectID `json:"id" binding:"required"` UID *uint64 `json:"uid"` // 用户ID Background *string `json:"background"` // 小说人物设定/故事背景等 Scene *string `json:"scene"` // 地点场景 Text *string `json:"text"` // 故事情节描述 Other *string `json:"other"` // 小说其他要求 ModelType *string `json:"modelType"` // AI小说模型 1,2 Content *string `json:"content"` // AI生成小说正文 Status *int `json:"status"` // 状态 Coin *int64 `json:"coin"` // AI小说金币个数 DebitAmountCoin *int64 `json:"debitAmountCoin"` // 此次AI小说扣除金币个数 DebitIncomeCoin *int64 `json:"debitIncomeCoin"` // 此次AI小说扣除收益金币个数 IsFreeTimes *bool `json:"isFreeTimes"` // 是否使用免费次数 IsHide *bool `json:"isHide"` // 是否被用户隐藏 Remark *string `json:"remark"` // 备注 IsDelete *bool `json:"isDelete"` // 是否删除 } // Update 更新数据 func (p *WebUpdateReq) Update() error { info, err := aitexttonovelmod.GetInfo(p.ID) if err != nil { return err } if info.ID.IsZero() { return errors.New("data is null") } data := make(map[string]interface{}) if p.UID != nil { data["uid"] = *p.UID } if p.Background != nil { data["background"] = *p.Background } if p.Scene != nil { data["scene"] = *p.Scene } if p.Text != nil { data["text"] = *p.Text } if p.Other != nil { data["other"] = *p.Other } if p.ModelType != nil { data["modelType"] = *p.ModelType } if p.Content != nil { data["content"] = *p.Content } if p.Status != nil { data["status"] = *p.Status } if p.Coin != nil { data["coin"] = *p.Coin } if p.DebitAmountCoin != nil { data["debitAmountCoin"] = *p.DebitAmountCoin } if p.DebitIncomeCoin != nil { data["debitIncomeCoin"] = *p.DebitIncomeCoin } if p.IsFreeTimes != nil { data["isFreeTimes"] = *p.IsFreeTimes } if p.IsHide != nil { data["isHide"] = *p.IsHide } if p.Remark != nil { data["remark"] = *p.Remark } if p.IsDelete != nil { data["isDelete"] = *p.IsDelete } data["updatedAt"] = time.Now() if p.Status != nil && *p.Status == 5 { if info.Status == int(aitexttonovelmod.StatusRefunded) || info.Status == int(aitexttonovelmod.StatusGenerationFailed) { return errors.New("Please do not refund repeatedly.") } if err = webg.VideoDB.Trans(func(t *db.MongoTool) error { if _, err = aitexttonovelmod.UpdateByID(t, info.ID, data); err != nil { return err } // 退款 if info.DebitAmountCoin == 0 && info.DebitIncomeCoin == 0 { // 总金额为0则不需要退款 return nil } // 退款进入钱包余额 wallet, err := walletmod.ReturnAmountAndIncome(t, -info.DebitAmountCoin, -info.DebitIncomeCoin, info.UID) if err != nil { log.Error(fmt.Sprintf("Handle text to novel Edit walletmod.DebitAmount error:%+v:", err), log.Any("uid", info.UID)) return err } var tl []txnmod.TransactionLog if info.DebitAmountCoin > 0 { tl = append(tl, txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: info.UID, Amount: info.DebitAmountCoin, ActualAmount: float64(info.DebitAmountCoin), TranType: txnmod.AiTextToNovelDebitGoldReturn.Key(), TranTypeInt: int64(txnmod.AiTextToNovelDebitGoldReturn), Desc: fmt.Sprintf("退还AI小说金币-%d", info.DebitAmountCoin), RealAmount: walletmod.GetRealAmount(wallet), }) } if info.DebitIncomeCoin > 0 { tl = append(tl, txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: info.UID, Amount: info.DebitIncomeCoin, ActualAmount: float64(info.DebitIncomeCoin), TranType: txnmod.AiTextToNovelDebitIncomeGoldReturn.Key(), TranTypeInt: int64(txnmod.AiTextToNovelDebitIncomeGoldReturn), Desc: fmt.Sprintf("退还AI小说收益金币-%d", info.DebitIncomeCoin), RealAmount: walletmod.GetRealAmount(wallet), }) } if len(tl) > 0 { txnErr := txnmod.InsertManyTransactionLog(t, tl) if txnErr != nil { log.Error(fmt.Sprintf("Handle ai text to novel txnmod.InsertTransactionLog error:%+v:", txnErr), log.Any("uid", info.UID)) return stderr.ErrDbQueryError } } return nil }); err != nil { if e, ok := err.(stderr.Code); ok { return e } return stderr.ErrDbQueryError } return nil } else { if _, err = aitexttonoveldata.UpdateData(nil, p.ID.Hex(), data); err != nil { } return err } } type WebDeleteReq struct { ID primitive.ObjectID `json:"id" binding:"required"` } // Delete 删除数据 func (p *WebDeleteReq) Delete() error { data, err := aitexttonovelmod.GetInfo(p.ID) if err != nil { return err } if err = validateDeleteStatus(data.Status); err != nil { return err } if err := aitexttonoveldata.DeleteData(nil, p.ID); err != nil { return err } return nil } func validateDeleteStatus(status int) error { if status == int(aitexttonovelmod.StatusOrderSuccess) || status == int(aitexttonovelmod.StatusSubmitted) { return stderr.AiGenningDelForbidden } return nil } // CallbackReq 换脸订单回调请求 type CallbackReq struct { Content string `json:"content"` // AI小说内容 AppOrderNum string `json:"appOrderNum"` // app订单号 Status int `json:"status"` // 订单状态 1:成功,2:失败 Msg string `json:"msg"` // 消息 } func (p *CallbackReq) Callback() error { id, _ := primitive.ObjectIDFromHex(p.AppOrderNum) // 查询该笔订单是否存在 data, err := aitexttonovelmod.GetInfo(id) if err != nil { return stderr.ErrDbQueryError } if data.ID.IsZero() { return errors.New("ai text to novel data is null") } if data.Status != int(aitexttonovelmod.StatusSubmitted) { log.Error("AI小说-重复回调或者状态不正确", log.Any("id", data.ID.Hex()), log.Any("status", data.Status)) return nil } var status = aitexttonovelmod.StatusGenerationSuccess // 处理金币退款以及后续操作 set := bson.M{} if p.Content != "" { set["content"] = strings.TrimSpace(p.Content) } if p.Status != 1 { set["remark"] = p.Msg set["content"] = "" status = aitexttonovelmod.StatusGenerationFailed } set["status"] = status set["updatedAt"] = time.Now() switch status { case aitexttonovelmod.StatusGenerationSuccess: if _, err = aitexttonovelmod.UpdateByID(nil, id, set); err != nil { return stderr.ErrDbUpdateError } return nil case aitexttonovelmod.StatusGenerationFailed: // 退款 if err = webg.VideoDB.Trans(func(t *db.MongoTool) error { if _, err = aitexttonovelmod.UpdateByID(t, id, set); err != nil { return err } // 退款 if data.DebitAmountCoin == 0 && data.DebitIncomeCoin == 0 { // 总金额为0则不需要退款 return nil } // 退款进入钱包余额 wallet, err := walletmod.ReturnAmountAndIncome(t, -data.DebitAmountCoin, -data.DebitIncomeCoin, data.UID) if err != nil { log.Error(fmt.Sprintf("Handle Callback Edit walletmod.DebitAmount error:%+v:", err), log.Any("uid", data.UID)) return err } var tl []txnmod.TransactionLog if data.DebitAmountCoin > 0 { tl = append(tl, txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: data.UID, Amount: data.DebitAmountCoin, ActualAmount: float64(data.DebitAmountCoin), TranType: txnmod.AiTextToNovelDebitGoldReturn.Key(), TranTypeInt: int64(txnmod.AiTextToNovelDebitGoldReturn), Desc: fmt.Sprintf("退还AI小说金币-%d", data.DebitAmountCoin), RealAmount: walletmod.GetRealAmount(wallet), }) } if data.DebitIncomeCoin > 0 { tl = append(tl, txnmod.TransactionLog{ TransNo: primitive.NewObjectID(), UID: data.UID, Amount: data.DebitIncomeCoin, ActualAmount: float64(data.DebitIncomeCoin), TranType: txnmod.AiTextToNovelDebitIncomeGoldReturn.Key(), TranTypeInt: int64(txnmod.AiTextToNovelDebitIncomeGoldReturn), Desc: fmt.Sprintf("退还AI小说收益金币-%d", data.DebitIncomeCoin), RealAmount: walletmod.GetRealAmount(wallet), }) } if len(tl) > 0 { txnErr := txnmod.InsertManyTransactionLog(t, tl) if txnErr != nil { log.Error(fmt.Sprintf("Handle ai text to image Callback txnmod.InsertTransactionLog error:%+v:", txnErr), log.Any("uid", data.UID)) return stderr.ErrDbQueryError } } return nil }); err != nil { if e, ok := err.(stderr.Code); ok { return e } return stderr.ErrDbQueryError } return nil default: } return nil }