xuzhiheng 4 роки тому
батько
коміт
acfbd772d8

+ 7 - 3
api/v1/userRecharge.go

@@ -3,6 +3,8 @@ package v1
 import (
 	"encoding/json"
 	"sfbase/global"
+	"sfis/service"
+	"strconv"
 
 	"github.com/gin-gonic/gin"
 	"go.uber.org/zap"
@@ -21,7 +23,7 @@ func RechargeApiRegister(router *gin.Engine) {
 //余额充值接口
 func moneyRecharge(c *gin.Context) {
 	appid := c.PostForm("appid")
-	money := c.PostForm("money")
+	money, _ := strconv.Atoi(c.PostForm("money"))
 	p := gin.H{
 		"appid": appid,
 		"money": money,
@@ -29,13 +31,14 @@ func moneyRecharge(c *gin.Context) {
 	bs, _ := json.Marshal(p)
 	param := string(bs)
 	global.Logger.Info("api moneyRecharge:", zap.Any("param:", param))
+	service.MoneyRecharge(appid, money, c)
 }
 
 //产品剩余量充值接口
 func productRecharge(c *gin.Context) {
 	appid := c.PostForm("appid")
-	productId := c.PostForm("productId")
-	rechargeNum := c.PostForm("rechargeNum")
+	productId, _ := strconv.Atoi(c.PostForm("productId"))
+	rechargeNum, _ := strconv.Atoi(c.PostForm("rechargeNum"))
 	endTime := c.PostForm("endTime")
 
 	p := gin.H{
@@ -47,4 +50,5 @@ func productRecharge(c *gin.Context) {
 	bs, _ := json.Marshal(p)
 	param := string(bs)
 	global.Logger.Info("api productRecharge:", zap.Any("param:", param))
+	service.ProductRecharge(appid, productId, rechargeNum, endTime, c)
 }

+ 20 - 14
model/user.go

@@ -1,5 +1,9 @@
 package model
 
+import (
+	"time"
+)
+
 type User struct {
 	BaseModel
 	Name        string `json:"name"`
@@ -24,11 +28,12 @@ func (p *UserAccount) TableName() string {
 }
 
 type UserMoneyRecord struct {
-	ID         int    `json:"id" gorm:"primaryKey"`
-	AppID      string `json:"app_id"`
-	Before     int    `json:"before"`
-	After      int    `json:"after"`
-	TradeMoney int    `json:"tarde_money"`
+	ID         int       `json:"id" gorm:"primaryKey"`
+	AppID      string    `json:"app_id"`
+	Before     int       `json:"before"`
+	After      int       `json:"after"`
+	TradeMoney int       `json:"tarde_money"`
+	CreateAt   time.Time `json:"-" gorm:"autoCreateTime"`
 }
 
 func (p *UserMoneyRecord) TableName() string {
@@ -36,15 +41,16 @@ func (p *UserMoneyRecord) TableName() string {
 }
 
 type UserBuyRecord struct {
-	ID               int    `json:"id" gorm:"primaryKey"`
-	AppID            string `json:"app_id"`
-	ProductId        int    `json:"product_id"`
-	UserProductId    int    `json:"user_product_id"`
-	Before           int    `json:"before"`
-	After            int    `json:"after"`
-	TradeMoney       int    `json:"tarde_money"`
-	BuyType          int    `json:"buy_type"`
-	HistoryUnitPrice int    `json:"history_unit_price"`
+	ID               int       `json:"id" gorm:"primaryKey"`
+	AppID            string    `json:"app_id"`
+	ProductId        int       `json:"product_id"`
+	UserProductId    int       `json:"user_product_id"`
+	Before           int       `json:"before"`
+	After            int       `json:"after"`
+	TradeMoney       int       `json:"tarde_money"`
+	BuyType          int       `json:"buy_type"`
+	HistoryUnitPrice int       `json:"history_unit_price"`
+	CreateAt         time.Time `json:"-" gorm:"autoCreateTime"`
 }
 
 func (p *UserBuyRecord) TableName() string {

+ 3 - 1
router/route.go

@@ -1,9 +1,10 @@
 package router
 
 import (
-	"github.com/gin-gonic/gin"
 	v1 "sfis/api/v1"
 	"sfis/manage/user"
+
+	"github.com/gin-gonic/gin"
 )
 
 func InitRouter(middleware ...gin.HandlerFunc) *gin.Engine {
@@ -15,6 +16,7 @@ func InitRouter(middleware ...gin.HandlerFunc) *gin.Engine {
 		})
 	})
 	v1.ProjectApiRegister(router)
+	v1.RechargeApiRegister(router)
 	user.DevUserManageRegister(router)
 	return router
 }

+ 114 - 0
service/userRecharge.go

@@ -0,0 +1,114 @@
+package service
+
+import (
+	"sfbase/global"
+	"sfis/db"
+	"sfis/lock"
+	"sfis/model"
+	"sfis/model/response"
+
+	"github.com/gin-gonic/gin"
+
+	"log"
+	"sfis/utils"
+	"time"
+
+	"go.uber.org/zap"
+	"gorm.io/gorm"
+)
+
+func MoneyRecharge(appid string, money int, context *gin.Context) {
+	//取出用户锁
+	lock.MainLock.Lock()
+	userLock := lock.UserLockMap[appid]
+	lock.MainLock.Unlock()
+	userLock.Lock()
+	defer userLock.Unlock()
+	//查用户当前余额
+	userAccount := &model.UserAccount{}
+	db.GetSFISDB().First(userAccount, &model.UserAccount{AppID: appid})
+	errs := db.GetSFISDB().Transaction(func(tx *gorm.DB) error {
+		moneyBefore := userAccount.Money
+		moneyAfter := userAccount.Money + money
+		//充值
+		err := tx.Exec("update user_account set money = ? WHERE `app_id` = ?", moneyAfter, appid).Error
+		if err != nil {
+			log.Printf("appID:[%s],money:[%d] execute cost user_account error:[%v]", appid, moneyAfter, err)
+			tx.Rollback()
+			return err
+		}
+		//生充值记录
+		err = tx.Exec("insert into user_money_record (app_id,`before`,`after`,trade_money) values (?,?,?,?)", appid, moneyBefore, moneyAfter, money).Error
+		if err != nil {
+			log.Printf("appID:[%s],trade_money:[%d] execute insert into user_money_record error:[%v]", appid, money, err)
+			tx.Rollback()
+			return err
+		}
+		return nil
+	})
+	if errs == nil {
+		response.Ok(context)
+	} else {
+		global.Logger.Error("数据库操作失败", zap.Any("error:", errs))
+		response.FailWithMessage("充值失败", context)
+	}
+}
+
+func ProductRecharge(appid string, productId, rechargeNum int, endTime string, context *gin.Context) {
+	//取出用户锁
+	lock.MainLock.Lock()
+	userLock := lock.UserLockMap[appid]
+	lock.MainLock.Unlock()
+	userLock.Lock()
+	defer userLock.Unlock()
+	endTimes := ""
+	if endTime != "" {
+		end := endTime + " 23:59:59"
+		loc, _ := time.LoadLocation("Local")
+		if ends, err := time.ParseInLocation("2006-01-02 15:04:05", end, loc); err == nil {
+			endTimes = ends.Local().Format("2006-01-02 15:04:05")
+		}
+	}
+	//查用户当前剩余量
+	userProduct := &model.UserProduct{}
+	db.GetSFISDB().First(userProduct, &model.UserProduct{AppID: appid, ProductID: productId})
+	product := &model.Product{}
+	if products, ok := utils.ProductCaches.Map.Load(productId); ok {
+		product = products.(*model.Product)
+	}
+	errs := db.GetSFISDB().Transaction(func(tx *gorm.DB) error {
+		before := userProduct.LeftNum
+		after := userProduct.LeftNum + rechargeNum
+		//充值
+		var err error
+		if endTimes != "" {
+			err = tx.Exec("update user_product set left_num = ?,end_at = ? WHERE `app_id` = ? and product_id = ?", after, endTimes, appid, productId).Error
+			if err != nil {
+				log.Printf("appID:[%s],left_num:[%d],endtime:[%s] execute cost user_product error:[%v]", appid, after, endTimes, err)
+				tx.Rollback()
+				return err
+			}
+		} else {
+			err = tx.Exec("update user_product set left_num = ? WHERE `app_id` = ? and product_id = ?", after, appid, productId).Error
+			if err != nil {
+				log.Printf("appID:[%s],left_num:[%d] execute cost user_product error:[%v]", appid, after, err)
+				tx.Rollback()
+				return err
+			}
+		}
+		//生充值记录
+		err = tx.Exec("insert into user_buy_record (app_id,product_id,user_product_id,`before`,`after`,trade_money,buy_type,history_unit_price) values (?,?,?,?,?,?,?,?)", appid, productId, userProduct.ID, before, after, product.UnitPrice*rechargeNum, 1, product.UnitPrice).Error
+		if err != nil {
+			log.Printf("appID:[%s],product_id:[%d],user_product_id:[%d],after:[%d],trade_money:[%d] execute insert into user_buy_record error:[%v]", appid, productId, userProduct.ID, after, product.UnitPrice*rechargeNum, err)
+			tx.Rollback()
+			return err
+		}
+		return nil
+	})
+	if errs == nil {
+		response.Ok(context)
+	} else {
+		global.Logger.Error("数据库操作失败", zap.Any("error:", errs))
+		response.FailWithMessage("充值失败", context)
+	}
+}

+ 47 - 0
test/userRecharge/userRecharge_test.go

@@ -0,0 +1,47 @@
+package userRecharge
+
+import (
+	"encoding/json"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"strings"
+	"testing"
+)
+
+var (
+	// apiurl = "http://127.0.0.1:8081/sfis/api/v1/user/moneyRecharge"
+	apiurl = "http://127.0.0.1:8081/sfis/api/v1/user/productRecharge"
+)
+
+func Test_Project(t *testing.T) {
+	getData()
+}
+
+func getData() {
+	data := post(apiurl, map[string]string{
+		"appid":       "sfGSVYRQMAAgkGBAUBJg4f",
+		"money":       "1000",
+		"productId":   "1000",
+		"rechargeNum": "100",
+		"endTime":     "2022-01-01",
+	})
+	log.Println(data)
+}
+
+func post(url string, form map[string]string) (data map[string]interface{}) {
+	str := ""
+	for k, v := range form {
+		str += "&" + k + "=" + v
+	}
+	log.Println(str)
+	res, err := http.Post(url, "application/x-www-form-urlencoded", strings.NewReader(str))
+	if err != nil {
+		log.Println("post err:", err.Error())
+	} else if res.Body != nil {
+		defer res.Body.Close()
+		bs, _ := ioutil.ReadAll(res.Body)
+		json.Unmarshal(bs, &data)
+	}
+	return
+}

+ 0 - 1
utils/cost_by_left_num.go

@@ -101,7 +101,6 @@ func after(productType int, dataLen int, userProduct *model.UserProduct, statusC
 				return err
 			}
 			//生订单
-			orderCode := utils.GenerateSimpleToken()
 			err = tx.Exec("insert into interface_order (order_code,app_id,user_product_id,`before`,`after`,cost_model,trade_num) values (?,?,?,?,?,?,?)", orderCode, appID, userProductID, orderBefore, orderAfter, 0, 1).Error
 			if err != nil {
 				log.Printf("appID:[%s],productID:[%d] execute insert into interface_order error:[%v]", appID, productID, err)