init: hgmj server initial commit

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 16:50:13 +08:00
co-authored by Claude Opus 4.7
commit 625e89c15d
1870 changed files with 254090 additions and 0 deletions
+463
View File
@@ -0,0 +1,463 @@
package daichongser
import (
"91jd-server/app/service/reportser"
"91jd-server/models/v/advanceordermod"
"context"
"errors"
"fmt"
"strconv"
"time"
"go.mongodb.org/mongo-driver/bson"
"91jd-server/app/appg"
"91jd-server/app/service"
"91jd-server/app/service/rechargeser"
"91jd-server/common/crypt"
"91jd-server/common/daichong"
"91jd-server/common/db"
"91jd-server/common/log"
"91jd-server/models/e/daichongmod"
"91jd-server/models/v/goldcfgmod"
"91jd-server/models/v/productmod"
"91jd-server/models/v/rchgordmod"
"91jd-server/models/v/txnmod"
"91jd-server/models/v/usermod"
"91jd-server/models/v/walletmod"
"github.com/shopspring/decimal"
"go.mongodb.org/mongo-driver/bson/primitive"
)
const (
rate_yinse_coin = 10 //金额转换成金币的单位 1元=10音色币
rate_yuan_feng = 100 //将元转换为分
)
func SeekScoreBaseOnAmount(customerId uint64, amount string) error {
amt, err := strconv.Atoi(amount)
if err != nil {
return err
}
localAmount := covert2Amount(int64(amt), rate_yinse_coin)
if err = appg.VideoDB.Trans(func(tool *db.MongoTool) error {
//转换成本地项目中金币单位
wallet, err := walletmod.DebitAmount(tool, localAmount, customerId)
if err != nil {
return err
}
tl := txnmod.TransactionLog{
TransNo: primitive.NewObjectID(),
UID: customerId,
Amount: -localAmount,
ActualAmount: float64(-amt),
TranType: txnmod.ChaseScore.Key(),
TranTypeInt: int64(txnmod.ChaseScore),
Desc: fmt.Sprintf("官方代充追分-%d", amt),
RealAmount: walletmod.GetRealAmount(wallet),
}
return txnmod.InsertTransactionLog(tool, &tl)
}); err != nil {
return err
}
return nil
}
// HandlerNewOrder 处理代充平台回掉调新订单通知
func HandlerNewOrder(ctx context.Context, newOrderSign daichongmod.NewOrderSign, user usermod.User) (int, error) {
log.Info("HandlerNewOrder start", log.Any("parameter", newOrderSign))
//兼容时间为空的情况
if newOrderSign.SuccessAt.IsZero() {
newOrderSign.SuccessAt = time.Now()
}
//更新订单信息
var rechargeType = string(rchgordmod.Rech_DaiChong)
//转换成本地项目中金币单位
localAmount := covert2Amount(newOrderSign.Amount, rate_yinse_coin)
localMoney := covert2Amount(newOrderSign.Amount, rate_yuan_feng)
upsert := rchgordmod.UpserSelector{
UID: &user.UID,
DevID: &user.DevID,
DevType: &user.DevType,
OID: &newOrderSign.OrderId,
TraderId: &newOrderSign.FromId,
Name: &user.Name,
Tel: &user.Mobile,
Amount: localAmount,
NotifyTime: &newOrderSign.Time,
PayMoney: &localMoney,
Money: &localMoney,
RechargeType: &rechargeType,
Channel: &rechargeType,
DiscDoc: user.DiscDoc,
}
processing := rchgordmod.Processing
upsert.Status = &processing
statusDesc := rchgordmod.Status(processing).Desc()
upsert.StatusDesc = &statusDesc
lock := rchgordmod.Lock
upsert.LockStatus = &lock
if _, err := rchgordmod.Upsert(nil, newOrderSign.OrderId, upsert); err != nil {
log.ErrorX(ctx, "daichong order inset into local db failed", log.Any("param", newOrderSign), log.E(err))
return daichong.Failed, err
}
order, err := rchgordmod.FindRechargeOrderByThirdOrderId(newOrderSign.OrderId)
if err != nil {
log.ErrorX(ctx, "daichong rechargeCoin FindRechargeOrderByThirdOrderId failed",
log.Any("orderId", newOrderSign.OrderId), log.E(err))
return daichong.Failed, err
}
var (
fn func(t *db.MongoTool) error
csm int // 分成模式
vipExpireTime time.Time
gold int64
)
// 商品信息解析
res := selectProduct(newOrderSign.ProductInfo, user.SysType)
switch res.Type {
case Gold:
// 新版充值金币
if res.Version == newVersion {
csm = rchgordmod.ChanShareCoin
order.ProductID = res.ID
if fn, gold, err = service.BuyGold(ctx, order, newOrderSign.Amount*100); err != nil {
log.ErrorX(ctx, fmt.Sprintf("官方充值-订单号[%s] 购买金币异常[%v]", order.ID, err))
}
} else {
err = rechargeCoin(ctx, localAmount, localMoney, user.SysType, newOrderSign.OrderId, newOrderSign.SuccessAt)
}
case VIP:
// 新版购买会员卡
if res.Version == newVersion {
order.ProductID = res.ID
if !res.Product.ID.IsZero() && res.Product.ProductType == productmod.AdvanceCard {
err = handleAdvanceDCOrder(order, res.Product, user)
if err != nil {
log.ErrorX(ctx, fmt.Sprintf("官方充值-订单号[%s] 购买预售卡异常[%v]", order.ID, err))
}
}
if fn, csm, vipExpireTime, err = service.BuyProduct(ctx, order, newOrderSign.Amount*100); err != nil {
log.ErrorX(ctx, fmt.Sprintf("官方充值-订单号[%s] 购买商品异常[%v]", order.ID, err))
}
} else {
log.Info("官方代充购买会员卡[旧版]")
err = buyProduct(ctx, localAmount, newOrderSign.OrderId, res.Product)
}
case FruitCoin:
order.ProductID = res.ID
if fn, err = service.BuyFruitCoin(ctx, order, newOrderSign.Amount*100); err != nil {
log.ErrorX(ctx, fmt.Sprintf("官方充值-订单号[%s] 购买果币异常[%v]", order.ID, err))
}
}
if err != nil {
log.ErrorX(ctx, "HandlerNewOrder trans error", log.E(err), log.Any("orderId", newOrderSign.OrderId))
selector := rchgordmod.ReplaceEditSelector{}
failure := rchgordmod.FAILURE
selector.Status = &failure
statusDesc := rchgordmod.Status(failure).Desc()
selector.StatusDesc = &statusDesc
failureAt := time.Now()
selector.FailureAt = &failureAt
unlock := rchgordmod.UnLock
selector.LockStatus = &unlock
_ = rchgordmod.UpdateBaseOnOidAndStatus(nil, newOrderSign.OrderId, rchgordmod.Processing, selector)
}
if err = appg.VideoDB.Trans(func(t *db.MongoTool) error {
selector := rchgordmod.ReplaceEditSelector{}
if fn != nil && res.Version == newVersion {
if err = fn(t); err != nil {
log.ErrorX(ctx, "充值金币新版执行事务异常", log.Any("order id", order.ID), log.Any("uid", order.UID),
log.E(err))
return err
}
selector.ChanShareMod = &csm
}
success := rchgordmod.SUCCESS
selector.Status = &success
statusDesc := rchgordmod.Status(success).Desc()
selector.StatusDesc = &statusDesc
successAt := newOrderSign.SuccessAt
selector.SuccessAt = &successAt
unlock := rchgordmod.UnLock
selector.LockStatus = &unlock
selector.PaymentAt = &successAt
selector.ProductID = res.ID
selector.ServiceID = res.ServiceID
//更新订单状态
if err = rchgordmod.UpdateBaseOnOidAndStatus(t, newOrderSign.OrderId, rchgordmod.Processing, selector); err != nil {
log.ErrorX(ctx, "HandlerNewOrder UpdateBaseOnOidAndStatus error", log.Any("orderId", newOrderSign.OrderId),
log.E(err))
return err
}
err = reportser.ReportOrderPaidEvent(t, order, newOrderSign.OrderId, localMoney, gold, vipExpireTime, newOrderSign.SuccessAt)
if err != nil {
log.ErrorX(ctx, "ReportOrderPaidEvent fail", log.E(err))
return err
}
return nil
}); err != nil {
log.ErrorX(ctx, "HandlerNewOrder trans error", log.E(err), log.Any("orderId", newOrderSign.OrderId))
err = reportser.ReportOrderPaidEvent(nil, order, newOrderSign.OrderId, localMoney, gold, vipExpireTime, newOrderSign.SuccessAt)
if err != nil {
log.ErrorX(ctx, "ReportOrderPaidEvent fail", log.E(err))
return daichong.Failed, err
}
selector := rchgordmod.ReplaceEditSelector{}
failure := rchgordmod.FAILURE
selector.Status = &failure
statusDesc := rchgordmod.Status(failure).Desc()
selector.StatusDesc = &statusDesc
failureAt := time.Now()
selector.FailureAt = &failureAt
unlock := rchgordmod.UnLock
selector.LockStatus = &unlock
err = rchgordmod.UpdateBaseOnOidAndStatus(nil, newOrderSign.OrderId, rchgordmod.Processing, selector)
if err != nil {
log.ErrorX(ctx, "UpdateBaseOnOidAndStatus failed", log.Any("order id", newOrderSign.OrderId), log.Any("selector", selector), log.E(err))
}
return daichong.Failed, err
}
//消息通知 充值到账成功
log.InfoX(ctx, "HandlerNewOrder success")
// common.Go(func() {
// //代充扣量
// executionDaiChongDeduction(ctx, newOrderSign.OrderId)
// })
return daichong.Success, nil
}
func handleAdvanceDCOrder(order rchgordmod.RechargeOrder, product productmod.Product, u usermod.User) error {
data, err := advanceordermod.IsExist(bson.M{"productID": product.ID, "uid": u.UID})
if err != nil {
return errors.New("advance order query IsExist err")
}
// 预付订单
var advanceOrder advanceordermod.AdvanceOrder
var advanceStatus = advanceordermod.DEFAULT
if order.PayMoney == product.AdvanceAmount*10 {
advanceStatus = advanceordermod.AdvanceProcessing
}
if order.PayMoney == product.BalanceAmount*10 {
advanceStatus = advanceordermod.BalanceProcessing
}
if advanceStatus == advanceordermod.BalanceProcessing && (data == nil || data.ID.IsZero()) {
return errors.New("advance order is null")
}
if advanceStatus == advanceordermod.DEFAULT {
return errors.New("advance order status is err")
}
if data == nil || data.ID.IsZero() {
// 创建预售订单
now := time.Now()
advanceOrder.UID = u.UID
advanceOrder.CreatedAt = now
advanceOrder.Status = advanceordermod.AdvanceProcessing
advanceOrder.AdvanceAmount = product.AdvanceAmount * 10
advanceOrder.BalanceAmount = product.BalanceAmount * 10
advanceOrder.StartTime = product.StartTime
advanceOrder.EndTime = product.EndTime
advanceOrder.ProductID = product.ID
advanceOrder.TotalAmount = (product.AdvanceAmount + product.BalanceAmount) * 10
advanceOrder.AdvOid = order.ID.Hex()
_, err = advanceordermod.CreditOrder(nil, &advanceOrder)
if err != nil {
return err
}
} else {
if (advanceStatus == advanceordermod.AdvanceProcessing && data.Status != advanceordermod.AdvanceProcessing) ||
(advanceStatus == advanceordermod.BalanceProcessing && (data.Status != advanceordermod.BalanceProcessing &&
data.Status != advanceordermod.AdvanceSUCCESS)) {
return errors.New("advance order status is err")
}
if data.Status == advanceordermod.AdvanceProcessing {
// 修改订单号
err := advanceordermod.Update(nil, data.ID, bson.M{"advOid": order.ID.Hex()})
if err != nil {
return err
}
}
if data.Status == advanceordermod.BalanceProcessing || data.Status == advanceordermod.AdvanceSUCCESS {
// 尾款订单
err := advanceordermod.Update(nil, data.ID, bson.M{"status": advanceordermod.BalanceProcessing, "balOid": order.ID.Hex()})
if err != nil {
return err
}
}
}
return nil
}
// 产品选择
func selectProduct(productInfo string, sys string) (e ExtraInfo) {
if productInfo == "" {
return
}
if err := crypt.JSON2Struct(productInfo, &e); err != nil {
log.Error(fmt.Sprintf("商品信息[%s]解析异常[%v]", productInfo, err))
return
}
switch e.Type {
case VIP:
// 查询产品信息
p, err := productmod.FindProduct(e.ID, sys)
if err != nil {
log.Error(fmt.Sprintf("商品信息[%s]查询产品信息异常[%v]", productInfo, err))
e.Type = Gold
}
e.Product = *p
}
return
}
// 根据商人回调过来的amount 转换本项目用户的分数
// 商人的数量是10 单位为元 本地项目用户的金额 单位为角
func covert2Amount(amount, rate int64) int64 {
d1 := decimal.NewFromInt(amount)
d2 := decimal.NewFromInt(rate)
return d1.Mul(d2).IntPart()
}
// 充值金币
func rechargeCoin(ctx context.Context, localAmount, localMoney int64, sysType, orderId string, successAt time.Time) error {
order, err := rchgordmod.FindRechargeOrderByThirdOrderId(orderId)
if err != nil {
log.Error("daichong rechargeCoin FindRechargeOrderByThirdOrderId failed", log.Any("orderId", orderId), log.E(err))
return err
}
csm := rchgordmod.ChanShareCoin
err = appg.VideoDB.Trans(func(trans *db.MongoTool) error {
//查询金币优惠
disCount, err := goldcfgmod.GetGoldCgfByAmountAndType(ctx, localAmount, string(rchgordmod.Rech_DaiChong))
if disCount != nil && err == nil {
if disCount.IncrAmount != 0 {
localAmount = localAmount + disCount.IncrAmount
} else if disCount.IncTax != 0.0 {
incr := decimal.NewFromFloat(disCount.IncTax)
local := decimal.NewFromInt(localAmount)
localAmount = localAmount + local.Mul(incr).IntPart()
}
}
//用户增加货币
wallet, err := walletmod.Credit(trans, walletmod.CreditPlan{Amount: &localAmount, Consumption: &localMoney}, order.UID)
if err != nil {
log.Error("HandlerNewOrder CreditAmount error", log.E(err), log.Any("orderId", order.OID))
return err
}
selector := rchgordmod.ReplaceEditSelector{}
success := rchgordmod.SUCCESS
selector.Status = &success
selector.ChanShareMod = &csm
statusDesc := rchgordmod.Status(success).Desc()
selector.StatusDesc = &statusDesc
selector.SuccessAt = &successAt
unlock := rchgordmod.UnLock
selector.LockStatus = &unlock
selector.PaymentAt = &successAt
//更新订单状态
if err = rchgordmod.UpdateBaseOnOidAndStatus(trans, order.OID, rchgordmod.Processing, selector); err != nil {
log.Error("HandlerNewOrder UpdateBaseOnOidAndStatus error", log.E(err), log.Any("orderId", order.OID))
return err
}
tl := txnmod.TransactionLog{
TransNo: order.ID,
UID: order.UID,
Amount: localAmount,
ActualAmount: float64(localAmount),
TranType: txnmod.OfficialRech.Key(),
TranTypeInt: int64(txnmod.OfficialRech),
Desc: txnmod.OfficialRech.Key() + "-" + fmt.Sprintf("到账%d金币", localAmount),
SysType: sysType,
RealAmount: walletmod.GetRealAmount(wallet),
}
if err = txnmod.InsertTransactionLog(trans, &tl); err != nil {
log.Error("HandlerNewOrder InsertTransactionLog error", log.E(err), log.Any("orderId", order.ID))
return err
}
return nil
})
return err
}
// 购买会员卡
func buyProduct(ctx context.Context, localAmount int64, orderId string, p productmod.Product) error {
order, err := rchgordmod.FindRechargeOrderByThirdOrderId(orderId)
if err != nil {
log.Error("daichong buyProduct FindRechargeOrderByThirdOrderId failed", log.Any("orderId", orderId), log.E(err))
return err
}
disCount, err := goldcfgmod.GetGoldCgfByAmountAndType(ctx, localAmount, string(rchgordmod.Rech_DaiChong))
if disCount != nil && err == nil {
if disCount.IncrAmount != 0 {
localAmount = localAmount + disCount.IncrAmount
} else if disCount.IncTax != 0.0 {
incr := decimal.NewFromFloat(disCount.IncTax)
local := decimal.NewFromInt(localAmount)
localAmount = localAmount + local.Mul(incr).IntPart()
}
}
disMoney := localAmount - p.DiscountedPrice
if disMoney < -10 {
tdesc := "购买「" + p.Name + "」实际支付" + strconv.Itoa(int(localAmount)) + ",全额转为「" + strconv.Itoa(int(localAmount)) + "」金币"
return appg.VideoDB.Trans(func(t *db.MongoTool) error {
set := rchgordmod.EditSelector{}
csm := rchgordmod.ChanShareCoin
set.ChanShareMod = &csm
now := time.Now()
set.SuccessAt = &now
set.Status = rchgordmod.SUCCESS
desc := rchgordmod.Status(rchgordmod.SUCCESS).Desc()
set.StatusDesc = &desc
set.PaymentAt = &now
if err = rchgordmod.CallBackModifyWithProcessing(ctx, t, order.ID, set); err != nil {
return err
}
return rechargeser.CallbackAddCoins(ctx, t, localAmount, localAmount, tdesc, order)
})
}
cms := 0
if p.ChanSplitMod == 1 {
cms = rchgordmod.ChanShareModVIP
}
return appg.VideoDB.Trans(func(t *db.MongoTool) error {
selector := rchgordmod.ReplaceEditSelector{}
selector.ChanShareMod = &cms
success := rchgordmod.SUCCESS
selector.Status = &success
statusDesc := rchgordmod.Status(success).Desc()
selector.StatusDesc = &statusDesc
successAt := time.Now()
selector.SuccessAt = &successAt
selector.VipID = p.ID
unlock := rchgordmod.UnLock
selector.LockStatus = &unlock
selector.PaymentAt = &successAt
if err = rchgordmod.UpdateBaseOnOidAndStatus(t, order.OID, rchgordmod.Processing, selector); err != nil {
return err
}
creditPlan := walletmod.CreditPlan{
Consumption: &localAmount,
}
if _, err = walletmod.Credit(t, creditPlan, order.UID); err != nil {
return err
}
fPayMoney := float32(localAmount)
if disMoney > 0 {
tdesc := "购买「" + p.Name + "」实际支付" + strconv.FormatFloat(float64(fPayMoney), 'f', 2, 64) + ",超额部分转为「" + strconv.FormatInt(disMoney, 10) + "」金币"
if err = rechargeser.CallbackAddCoins(ctx, t, disMoney, 0, tdesc, order); err != nil {
return err
}
}
if err = rechargeser.RechargeBuy_p(t, order.UID, p, 0); err != nil {
return err
}
return nil
})
}
+201
View File
@@ -0,0 +1,201 @@
package daichongser
import (
"strconv"
"sync"
"time"
"91jd-server/app/appg"
"91jd-server/common"
"91jd-server/common/constant"
"91jd-server/common/constant/redisconst"
"91jd-server/common/crypt"
"91jd-server/common/daichong"
"91jd-server/common/httputil"
"91jd-server/common/log"
"91jd-server/common/stderr"
"91jd-server/models/commod"
"91jd-server/models/e/daichongmod"
"91jd-server/models/v/usermod"
)
// 全局的通知商人是否在线的时间点
var notifyPoint int64
const FixTime = 5 * 60 //单位为秒
// TakeChat 发起聊天
func TakeChat(uid uint64, proT int) (daichong.ChatResp, stderr.Code) {
u, err := usermod.FindUserByUID(uid)
if err != nil || u == nil {
return daichong.ChatResp{}, stderr.AuthIsNotExist
}
chatSign := daichong.ChatSign{
UID: strconv.FormatUint(uid, 10),
NickName: u.Name,
Avatar: common.BindUrl(appg.Conf.URL.OriginUrl, u.Portrait),
Channel: "ys",
}
sign, err := daichong.Convert2Sign(chatSign, appg.Conf.DaiChong.AppSecret)
if err != nil {
log.Warn("create sign data wrong", log.Any("warn", err))
return daichong.ChatResp{}, stderr.ErrTakeChatCode
}
chatReq := daichong.ChatReq{
AppId: appg.Conf.DaiChong.AppID,
Data: sign,
ProtoType: 1,
ProductType: proT,
}
chatResp, err := daichong.TakeChat(chatReq, appg.Conf.DaiChong.Domain)
if err != nil {
log.Warn("TakeChat send http wrong", log.Any("warn", err))
return chatResp, stderr.ErrTakeChatCode
}
return chatResp, chatResp.Code
}
// 获取订单信息
func GetOrderInfo(req daichongmod.GetOrderReq) (daichong.OrderResp, stderr.Code) {
sign, err := daichong.Convert2Sign(req, appg.Conf.DaiChong.AppSecret)
if err != nil {
log.Warn("create sign data wrong", log.Any("warn", err))
return daichong.OrderResp{}, stderr.ErrGetOrderInfoCode
}
orderReq := daichong.CommonReq{
AppId: appg.Conf.DaiChong.AppID,
Data: sign,
}
orderResp, err := daichong.GetOrder(orderReq, appg.Conf.DaiChong.Domain)
if err != nil {
log.Warn("GetOrderInfo send http wrong", log.Any("warn", err))
return orderResp, stderr.ErrGetOrderInfoCode
}
return orderResp, orderResp.Code
}
// 代充上传文件
func UploadFile(filename, sessionId, data string, userId uint64) (commod.Resp, stderr.Code) {
uploadFileReq := daichong.UploadFileReq{
FileName: filename,
AppId: appg.Conf.DaiChong.AppID,
UserID: strconv.FormatUint(userId, 10),
SessionId: sessionId,
File: data,
}
resp, err := daichong.UploadFile(uploadFileReq, appg.Conf.DaiChong.UploadUrl)
if err != nil {
log.Warn("UploadFile send http wrong", log.Any("warn", err))
return resp, stderr.ErrUploadError
}
return resp, resp.Code
}
// 获取代充信息
func GetDaichongInfo(uid uint64, userAgent string, proT int) (data daichong.ChatResp, code stderr.Code) {
var user *usermod.User
var err error
wg := sync.WaitGroup{}
wg.Add(2)
common.Go(func() {
defer wg.Done()
str, err := appg.Redis.Get(redisconst.TraderChatCacheKey(uid, proT))
if str != nil && err == nil {
_ = crypt.JSON2Struct(*str, &data)
} else {
data, code = TakeChat(uid, proT)
if code == stderr.Success {
normalstr, err := crypt.StructToStrNormal(data)
if normalstr != "" && err == nil {
_ = appg.Redis.Set(redisconst.TraderChatCacheKey(uid, proT), normalstr, redisconst.TraderChatCacheExpire)
}
if len(data.Data.Traders) == 0 {
//通知客服人员 代充商人匹配不到
common.Go(func() {
sendTg()
})
}
}
}
})
common.Go(func() {
defer wg.Done()
user, err = usermod.FindUserByUID(uid)
})
wg.Wait()
if user != nil && err == nil {
data.Data.UserInfo.Name = user.Name
data.Data.UserInfo.Portrait = common.BindUrl(appg.Conf.URL.OriginUrl, user.Portrait)
data.Data.UserInfo.Gender = user.Gender
}
data.Data.TraderUrl = "/api/app/daichong/traders"
data.Data.OrdUrl = "/api/app/daichong/orderInfo"
data.Data.Limit = appg.Conf.Base.DemarcatAmout
data.Data.UserInfo.UID = uid
data.Data.UserAgent = userAgent
return
}
func sendTg() {
now := time.Now().UTC().Unix()
if appg.Conf.Base.Env != constant.ReleaseRunmod || !(notifyPoint < time.Now().UTC().Unix()-FixTime) {
return
}
notifyPoint = now
resp := commod.Resp{}
params := map[string]interface{}{
"tgName": "ys_bot",
"msgPayload": "@gaochang1 @BA1219\n\r【短视频-正式-代充商人匹配丢失】\n\r",
"text": "【WARNING】: 代充商人现在无法匹配到了,请运营人员检查是否商人在线或余额足够",
"chatId": -228259065,
}
code, err := httputil.DefaultClientPostJsonWithResp(&resp, "http://uni.ztgba.com/api/tg/send", nil, params)
log.Info("http method TgSend response code ==>", log.Any("statusCode", code), log.Any("resp", resp))
if err != nil {
log.Error("TgSend failed", log.E(err))
}
}
// 根据订单ID获取聊天记录
func GetChatRecordsByOrderId(orderId string) (daichong.RecordResp, stderr.Code) {
var param struct {
OrderId string `json:"orderId"`
Time int64 `json:"time"`
}
param.OrderId = orderId
param.Time = time.Now().Unix()
sign, err := daichong.Convert2Sign(param, appg.Conf.DaiChong.AppSecret)
if err != nil {
log.Warn("create sign data wrong", log.Any("warn", err))
return daichong.RecordResp{}, stderr.Failure
}
orderReq := daichong.CommonReq{
AppId: appg.Conf.DaiChong.AppID,
Data: sign,
}
recordResp, err := daichong.GetChatRecordsByOrderId(orderReq, appg.Conf.DaiChong.Domain)
if err != nil {
log.Warn("GetChatRecordsByOrderId send http wrong", log.Any("warn", err))
return recordResp, stderr.Failure
}
return recordResp, recordResp.Code
}
// 获取商人支付信息
func GetTraderPayInfo(req daichongmod.PayInfoReq) (daichong.PayInfoResp, stderr.Code) {
sign, err := daichong.Convert2Sign(req, appg.Conf.DaiChong.AppSecret)
if err != nil {
log.Warn("create sign data wrong", log.Any("warn", err))
return daichong.PayInfoResp{}, stderr.Failure
}
commReq := daichong.CommonReq{
AppId: appg.Conf.DaiChong.AppID,
Data: sign,
}
payInfoResp, err := daichong.GetTraderPayInfo(commReq, appg.Conf.DaiChong.Domain)
if err != nil {
log.Warn("GetTraderPayInfo send http wrong", log.Any("warn", err))
return payInfoResp, stderr.Failure
}
return payInfoResp, payInfoResp.Code
}
@@ -0,0 +1,85 @@
package daichongser
import (
"context"
"math/rand"
"strconv"
"91jd-server/app/appg"
"91jd-server/common/constant/redisconst"
"91jd-server/common/crypt"
"91jd-server/common/daichong"
"91jd-server/common/log"
"91jd-server/common/stderr"
"91jd-server/models/e/daichongmod"
"91jd-server/models/v/usermod"
)
// TakeChat 发起聊天
func NewTakeChat(ctx context.Context, uid uint64, proT int) (daichong.ChatResp, stderr.Code) {
u, err := usermod.FindUserByUID(uid)
if err != nil || u == nil {
return daichong.ChatResp{}, stderr.AuthIsNotExist
}
data := daichong.ChatResp{}
str, err := appg.Redis.Get(redisconst.TraderChatCacheKey(uid, proT))
if str != nil && err == nil {
_ = crypt.JSON2Struct(*str, &data)
return data, stderr.Success
}
chatReq := daichong.NewChatReq{
UID: strconv.Itoa(int(uid)) + "-" + appg.Conf.DaiChong.PlatName,
Name: u.Name,
Portrait: u.Portrait,
ProductType: proT,
}
chatResp, err := daichong.NewTakeChat(ctx, chatReq, appg.Conf.DaiChong.Domain)
if err != nil {
log.ErrorX(ctx, "TakeChat send http wrong", log.Any("req", chatReq), log.Any("domain", appg.Conf.DaiChong.Domain),
log.E(err))
return chatResp, stderr.ErrTakeChatCode
}
//随机拼接ordUrl接口的api域名
apiUrls := appg.Conf.URL.ApiUrls
if len(apiUrls) > 0 {
chatResp.Data.OrdUrl = apiUrls[rand.Intn(len(apiUrls))] + "/api/app/daichong/orderInfo"
}
if chatResp.Code == stderr.Success {
normalstr, err := crypt.StructToStrNormal(chatResp)
if normalstr != "" && err == nil && len(chatResp.Data.Traders) > 0 {
_ = appg.Redis.Set(redisconst.TraderChatCacheKey(uid, proT), normalstr, redisconst.TraderChatCacheExpire)
}
}
if len(chatResp.Data.Traders) > 0 {
random(&(chatResp.Data.Traders))
}
return chatResp, chatResp.Code
}
// 获取订单信息
func NewGetOrderInfo(req daichong.OrderSign) (daichong.OrderResp, stderr.Code) {
orderResp, err := daichong.NewGetOrder(req, appg.Conf.DaiChong.Domain)
if err != nil {
log.Warn("GetOrderInfo send http wrong", log.Any("warn", err))
return orderResp, stderr.ErrGetOrderInfoCode
}
return orderResp, orderResp.Code
}
// 获取商人支付信息
func NewGetTraderPayInfo(req daichongmod.PayInfoReq) (daichong.PayInfoResp, stderr.Code) {
payInfoResp, err := daichong.NewGetTraderPayInfo(req, appg.Conf.DaiChong.Domain)
if err != nil {
log.Warn("GetTraderPayInfo send http wrong", log.Any("warn", err))
return payInfoResp, stderr.Failure
}
return payInfoResp, payInfoResp.Code
}
func random(data *[]daichong.Trader) {
strings := *data
for i := len(strings) - 1; i > 0; i-- {
num := rand.Intn(i + 1)
strings[i], strings[num] = strings[num], strings[i]
}
*data = strings
}
+28
View File
@@ -0,0 +1,28 @@
package daichongser
import (
"91jd-server/models/v/productmod"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type ProductType int
const (
Gold ProductType = iota // 金币
VIP // 会员卡
FruitCoin // 果币
NudeChatService // 裸聊服务
)
// 改版区分
const newVersion = "3.0.0"
// ExtraInfo 代充携带额外信息
type ExtraInfo struct {
ID primitive.ObjectID `json:"id,omitempty"` // 产品ID
Type ProductType `json:"type"` // 产品类型
ServiceID primitive.ObjectID `json:"serviceId,omitempty"` // 裸聊服务ID
Version string `json:"version,omitempty"` // 版本区分
Product productmod.Product // 产品信息
}