This commit is contained in:
lwl0608 2024-06-13 16:40:22 +08:00
parent 056fbabd14
commit 571a961151
16 changed files with 155 additions and 47 deletions

View File

@ -58,9 +58,12 @@ func (vo *ApiZoneVO) SetIsSuperfanshipUnlocked(is_superfanship_unlocked int64) {
func (vo *ApiZoneVO) CopyZoneVas(zv *dbstruct.ZoneVas) {
if zv != nil {
vo.AdmissionPrice = zv.AdmissionPrice
vo.AdmissionCoinPrice = zv.GetAdmissionCoinPrice()
vo.IronfanshipPrice = zv.IronfanshipPrice
vo.IronfanshipCoinPrice = zv.GetIronfanshipCoinPrice()
vo.IsSuperfanshipEnabled = zv.IsSuperfanshipEnabled
vo.SuperfanshipPrice = zv.SuperfanshipPrice
vo.SuperfanshipCoinPrice = zv.GetSuperfanshipCoinPrice()
vo.SuperfanshipValidPeriod = zv.SuperfanshipValidPeriod
vo.IsSuperfanshipGiveWechat = zv.IsSuperfanshipGiveWechat
}

View File

@ -15,6 +15,7 @@ type ApiZoneMomentVO struct {
IsZoneMomentUnlocked int64 `json:"is_zone_moment_unlocked"`
Expenditure int64 `json:"expenditure"`
IronfanshipPrice int64 `json:"ironfanship_price"`
IronfanshipCoinPrice int64 `json:"ironfanship_coin_price"`
BuyerCnt int64 `json:"buyer_cnt"` // 动态购买人数
IsSuperfanshipEnabled int64 `json:"is_superfanship_enabled"`
}

View File

@ -6,6 +6,7 @@ import (
"service/app/mix/service"
"service/bizcommon/common"
"service/bizcommon/util"
"service/dbstruct"
"service/library/logger"
"time"
@ -50,6 +51,12 @@ func CreateOrder(ctx *gin.Context) {
ReplyErrCodeMsg(ctx, errcode.ErrCodeBadParam)
return
}
// 检查能用金币支付的商品
if req.PayType == vasproto.PayTypeCoin && !dbstruct.CoinPayValidProductIdMap[req.ProductId] {
ReplyErrorMsg(ctx, "商品错误")
return
}
data, ec, err := service.DefaultService.CreateOrder(ctx, req)
if ec != errcode.ErrCodeVasSrvOk {
logger.Error("CreateOrder fail, req: %v, ec: %v", util.ToJson(req), ec)

View File

@ -6,6 +6,7 @@ import (
vasproto "service/api/proto/vas/proto"
"service/app/mix/service"
"service/bizcommon/util"
"service/dbstruct"
"service/library/logger"
)
@ -16,6 +17,12 @@ func ZoneCreateOrder(ctx *gin.Context) {
ReplyErrCodeMsg(ctx, errcode.ErrCodeBadParam)
return
}
// 检查能用金币支付的商品
if req.PayType == vasproto.PayTypeCoin && !dbstruct.CoinPayValidProductIdMap[req.ProductId] {
ReplyErrorMsg(ctx, "商品错误")
return
}
data, ec, err := service.DefaultService.ZoneCreateOrder(ctx, req)
if ec != errcode.ErrCodeVasSrvOk {
logger.Error("ZoneCreateOrder fail, req: %v, ec: %v", util.ToJson(req), ec)

View File

@ -377,7 +377,7 @@ func (v *Vas) CreateOrderByCoin(ctx *gin.Context, req *vasproto.CreateOrderReq,
logger.Error("CheckWalletExist fail, mid: %v, err: %v", req.Mid, err)
return
}
if wallet.GetCoins() <= priceCoin {
if wallet.GetCoins() < priceCoin {
err = errs.ErrVasNoEnoughCoin
logger.Error("not enough coin, mid: %v, coins: %v, err: %v", req.Mid, wallet.Coins, err)
return
@ -403,7 +403,7 @@ func (v *Vas) CreateOrderByCoin(ctx *gin.Context, req *vasproto.CreateOrderReq,
Oid3: goproto.String(req.Oid3),
ProductId: goproto.String(req.ProductId),
PayType: goproto.String(req.PayType),
PayAmount: goproto.Int64(product.RealPrice),
PayAmount: goproto.Int64(priceCoin),
Coins: goproto.Int64(product.ValueCoins),
OrderStatus: goproto.Int32(dbstruct.VasOrderStatusInit),
OrderFrom: goproto.String(req.From),
@ -1493,6 +1493,9 @@ func (v *Vas) PayCallback(ctx *gin.Context, p *vasproto.PayCallbackParamIn) erro
Count: goproto.Int64(order.GetCoins()),
Ct: goproto.Int64(time.Now().Unix()),
}
if order.GetPayType() == vasproto.PayTypeCoin {
ch.TypeId = goproto.String(ch.GetTypeId() + ":_:pay_type=coin")
}
switch product.Id {
case dbstruct.ProductIdMembership:
ch.SType = goproto.Int32(dbstruct.CHSTypeChargeMembership)
@ -2212,6 +2215,9 @@ func (v *Vas) UnlockMembership(ctx *gin.Context, tx *sqlx.Tx, mid int64, product
// 计算收入
var totalDias = int64(float64(order.GetPayAmount()) / 100.0 * 10.0)
if order.GetPayType() == vasproto.PayTypeCoin {
totalDias = order.GetPayAmount()
}
incomeList, err := v.calcAndUpdateIncome(ctx, tx, order.GetUid(), mid, order.GetDid(), orderId, order.GetProductId(), totalDias, dbstruct.CHSTypeIncomeMembership)
if err != nil {
logger.Error("calcAndUpdateIncome fail, order: %v, err: %v", util.ToJson(order), err)
@ -2544,7 +2550,7 @@ func (v *Vas) refundMembership(ctx *gin.Context, order *dbstruct.Order, req *vas
}
// 退款
err = v.payRefund(ctx, order)
err = v.payRefund(ctx, tx, order)
if err != nil {
return err
}
@ -2642,7 +2648,7 @@ func (v *Vas) refundCoins(ctx *gin.Context, order *dbstruct.Order, req *vasproto
}
// 退款
err = v.payRefund(ctx, order)
err = v.payRefund(ctx, tx, order)
if err != nil {
return err
}
@ -2740,7 +2746,7 @@ func (v *Vas) refundMoneyContactWechat(ctx *gin.Context, order *dbstruct.Order,
}
// 退款
err = v.payRefund(ctx, order)
err = v.payRefund(ctx, tx, order)
if err != nil {
return err
}
@ -2966,7 +2972,7 @@ func (v *Vas) refundZoneAdmission(ctx *gin.Context, order *dbstruct.Order, req *
}
// 退款
err = v.payRefund(ctx, order)
err = v.payRefund(ctx, tx, order)
if err != nil {
return err
}
@ -3193,7 +3199,7 @@ func (v *Vas) refundZoneMoment(ctx *gin.Context, order *dbstruct.Order, req *vas
}
// 退款
err = v.payRefund(ctx, order)
err = v.payRefund(ctx, tx, order)
if err != nil {
return err
}
@ -3429,7 +3435,7 @@ func (v *Vas) refundZoneSuperfanship(ctx *gin.Context, order *dbstruct.Order, re
}
// 退款
err = v.payRefund(ctx, order)
err = v.payRefund(ctx, tx, order)
if err != nil {
return err
}
@ -3652,7 +3658,7 @@ func (v *Vas) refundCoinContactWechat(ctx *gin.Context, order *dbstruct.CoinOrde
return nil
}
func (v *Vas) payRefund(ctx *gin.Context, order *dbstruct.Order) error {
func (v *Vas) payRefund(ctx *gin.Context, tx *sqlx.Tx, order *dbstruct.Order) error {
var (
orderId = order.GetID()
)
@ -3679,6 +3685,12 @@ func (v *Vas) payRefund(ctx *gin.Context, order *dbstruct.Order) error {
logger.Error("wxpayCli.RefundOne fail, orderId: %v, resp: %v, err: %v", orderId, util.ToJson(resp), err)
return err
}
case vasproto.PayTypeCoin:
err := v.store.IncCoins(ctx, tx, order.GetMid(), order.GetPayAmount())
if err != nil {
logger.Error("coin.RefundOne fail, orderId: %v, err: %v", orderId, err)
return err
}
}
return nil
}

View File

@ -291,7 +291,10 @@ func (v *Vas) UnlockZoneMoment(ctx *gin.Context, tx *sqlx.Tx, order *dbstruct.Or
}
// 计算收入
totalDias := int64(float64(order.GetPayAmount()) / 100.0 * 10.0)
var totalDias = int64(float64(order.GetPayAmount()) / 100.0 * 10.0)
if order.GetPayType() == vasproto.PayTypeCoin {
totalDias = order.GetPayAmount()
}
incomeList, err := v.calcAndUpdateIncome(ctx, tx, order.GetUid(), mid, order.GetDid(), orderId, order.GetProductId(), totalDias, dbstruct.CHSTypeIncomeZoneStreamer)
if err != nil {
logger.Error("calcAndUpdateIncome fail, order: %v, err: %v", util.ToJson(order), err)
@ -371,7 +374,10 @@ func (v *Vas) UnlockZoneAdmission(ctx *gin.Context, tx *sqlx.Tx, order *dbstruct
}
// 计算收入
totalDias := int64(float64(order.GetPayAmount()) / 100.0 * 10.0)
var totalDias = int64(float64(order.GetPayAmount()) / 100.0 * 10.0)
if order.GetPayType() == vasproto.PayTypeCoin {
totalDias = order.GetPayAmount()
}
incomeList, err := v.calcAndUpdateIncome(ctx, tx, order.GetUid(), mid, order.GetDid(), orderId, order.GetProductId(), totalDias, dbstruct.CHSTypeIncomeZoneStreamer)
if err != nil {
logger.Error("calcAndUpdateIncome fail, order: %v, err: %v", util.ToJson(order), err)
@ -421,7 +427,10 @@ func (v *Vas) UnlockZoneSuperfanship(ctx *gin.Context, tx *sqlx.Tx, order *dbstr
}
// 计算收入
totalDias := int64(float64(order.GetPayAmount()) / 100.0 * 10.0)
var totalDias = int64(float64(order.GetPayAmount()) / 100.0 * 10.0)
if order.GetPayType() == vasproto.PayTypeCoin {
totalDias = order.GetPayAmount()
}
incomeList, err := v.calcAndUpdateIncome(ctx, tx, order.GetUid(), mid, order.GetDid(), orderId, order.GetProductId(), totalDias, dbstruct.CHSTypeIncomeZoneStreamer)
if err != nil {
logger.Error("calcAndUpdateIncome fail, order: %v, err: %v", util.ToJson(order), err)

View File

@ -1021,6 +1021,7 @@ func (s *Service) GetMembershipProductList(ctx *gin.Context, req *vasproto.GetMe
ec = errcode.ErrCodeVasSrvFail
return
}
product.RealCoinPrice = product.GetRealPriceCoin()
data = &vasproto.GetMembershipProductListData{
Product: product,
}

View File

@ -1843,6 +1843,7 @@ func (s *Service) utilFillZoneMomentsWithApiVOInfo(ctx *gin.Context, list []*dbs
// 7.填充所有信息
for _, vo := range volist {
vo.ZoneMoment.CoinPrice = vo.ZoneMoment.GetCoinPrice()
zid := vo.ZoneMoment.GetZid()
@ -1886,6 +1887,7 @@ func (s *Service) utilFillZoneMomentsWithApiVOInfo(ctx *gin.Context, list []*dbs
// 铁粉价格
if zv, ok := zvMap[zid]; ok {
vo.IronfanshipPrice = zv.IronfanshipPrice
vo.IronfanshipCoinPrice = zv.GetIronfanshipCoinPrice()
vo.IsSuperfanshipEnabled = int64(zv.IsSuperfanshipEnabled)
}
}

View File

@ -18,6 +18,7 @@ import (
"service/library/mycrypto"
"service/library/payclients/applepaycli"
"strconv"
"strings"
"github.com/gin-gonic/gin"
)
@ -317,6 +318,14 @@ func (s *Service) chListCharge(ctx *gin.Context, chList []*dbstruct.ConsumeHisto
item.Desc = "解锁空间超粉退款"
item.Change = fmt.Sprintf("+%.1f元", float64(util.AbsInt64(chDB.GetChange()))/100.0)
}
if strings.Contains(chDB.GetTypeId(), ":_:pay_type=coin") && strings.Contains(item.Change, "元") {
oldChange := item.Change
newChange := ""
if len(item.Change) > 0 {
newChange += oldChange[:1]
}
newChange += fmt.Sprintf("%d金币", chDB.GetChange())
}
list = append(list, item)
}
@ -1090,6 +1099,8 @@ func (s *Service) ApplepayCallback(ctx *gin.Context, notify applepaycli.Applepay
mid, _ = strconv.ParseInt(event.AppUserID, 10, 64)
)
switch event.Type {
case applepaycli.NotifyTypeNonRenewingPurchase:
// 验证用户
acnt, _ := _DefaultAccount.GetAccountMapByMids(ctx, []int64{mid})
if _, ok := acnt[mid]; !ok {
@ -1126,6 +1137,7 @@ func (s *Service) ApplepayCallback(ctx *gin.Context, notify applepaycli.Applepay
logger.Error("PayCallback fail, param: %v, err: %v", payCallbackParam, err)
return err
}
}
return nil
}

View File

@ -190,3 +190,7 @@ func VerisonCompare(ver1 string, ver2 string) (bool, error) {
}
return false, nil
}
func RoundUp(num float64) int64 {
return int64(math.Ceil(num))
}

7
bizcommon/util/x_test.go Normal file
View File

@ -0,0 +1,7 @@
package util
import "testing"
func TestRound(t *testing.T) {
Round()
}

View File

@ -1,5 +1,7 @@
package dbstruct
import "service/bizcommon/util"
// 商品id
const (
ProductIdOpCoin = "op_coin" // op充值的金币
@ -50,6 +52,13 @@ var ProductIdDescMap = map[string]string{
ProductIdH5ZoneSuperfanship: "解锁超粉",
}
var CoinPayValidProductIdMap = map[string]bool{
ProductIdMembership: true,
ProductIdH5ZoneMoment: true,
ProductIdH5ZoneAdmission: true,
ProductIdH5ZoneSuperfanship: true,
}
// 商品类型
const (
ProductTypeCoins = "coins" // 商品类型:金币
@ -98,5 +107,5 @@ type Product struct {
}
func (p Product) GetRealPriceCoin() int64 {
return p.RealPrice / 10
return util.RoundUp(float64(p.RealPrice) / 10.0)
}

View File

@ -1,6 +1,9 @@
package dbstruct
import "math"
import (
"math"
"service/bizcommon/util"
)
// 用户增值信息
const (
@ -122,6 +125,18 @@ func (p ZoneVas) GetSuperfanshipDurationDesc() string {
}
}
func (p ZoneVas) GetAdmissionCoinPrice() int64 {
return util.RoundUp(float64(p.AdmissionPrice) / 10.0)
}
func (p ZoneVas) GetIronfanshipCoinPrice() int64 {
return util.RoundUp(float64(p.IronfanshipPrice) / 10.0)
}
func (p ZoneVas) GetSuperfanshipCoinPrice() int64 {
return util.RoundUp(float64(p.SuperfanshipPrice) / 10.0)
}
// 空间动态价格
type ZoneMomentPrice struct {
MomentId int64 `json:"id" bson:"_id"` // 动态id

View File

@ -1,5 +1,7 @@
package dbstruct
import "service/bizcommon/util"
type ZoneMoment struct {
Id *int64 `json:"id" bson:"_id"` // 私密圈动态表id
Mid *int64 `json:"mid" bson:"mid"` // 用户表id
@ -117,3 +119,7 @@ func (p *ZoneMoment) GetPaidText() string {
}
return ""
}
func (p *ZoneMoment) GetCoinPrice() int64 {
return util.RoundUp(float64(p.CoinPrice) / 10.0)
}

View File

@ -1,5 +1,9 @@
package applepaycli
const (
NotifyTypeNonRenewingPurchase = "NON_RENEWING_PURCHASE" // 非续费型消费
)
type Event struct {
EventTimestampMs int64 `json:"event_timestamp_ms"`
ProductID string `json:"product_id"`

View File

@ -26,6 +26,15 @@ type C struct {
}
func main() {
numbers := []float64{12.9, 99.9}
for _, number := range numbers {
rounded := util.RoundUp(number)
fmt.Printf("%.1f -> %d\n", number, rounded)
}
return
c := C{
A: &A{Mid: 111},
B: &B{Mid: 222},