package service import ( "errors" "github.com/gin-gonic/gin" "go.uber.org/zap" "gorm.io/gorm" "log" "sfbase/global" "sfis/db" "sfis/lock" "sfis/model" "sfis/model/response" "strconv" "strings" "sync" "time" ) func UserProduct(productIds, appId, startTime, endTime string, leftNum, costModel, interfaceStatus, callTimesLimitDay, dataNumOneTimes, tradeMoney, buyType int, c *gin.Context) { //取出用户锁 lock.MainLock.Lock() userLock := lock.UserLockMap[appId] lock.MainLock.Unlock() userLock.Lock() defer userLock.Unlock() productIdsArr := strings.Split(productIds, ",") if len(productIdsArr) > 0 { var errs error for _, v := range productIdsArr { productId, _ := strconv.Atoi(v) userProduct := &model.UserProduct{} userProduct.AppID = appId userProduct.StartAt, _ = time.ParseInLocation("2006-01-02 15:04:05", startTime, time.Local) userProduct.EndAt, _ = time.ParseInLocation("2006-01-02 15:04:05", endTime, time.Local) userProduct.LeftNum = leftNum userProduct.CostModel = costModel userProduct.InterfaceStatus = interfaceStatus userProduct.CallTimesLimitDay = callTimesLimitDay userProduct.DataNumLimitOneTimes = dataNumOneTimes userProduct.ProductID = productId userProductInfo := model.UserProduct{} product := model.Product{} //查询产品信息,获取购买时候产品单价、试用次数 err := db.GetSFISDB().Where("id = ?", productId).Find(&product).Error if err != nil { response.FailWithMessage("查询产品信息出错", c) return } historyUnitPrice := product.UnitPrice err = db.GetSFISDB().Where("product_id = ? and app_id = ?", productId, appId).Find(&userProductInfo).Error if err != nil { response.FailWithMessage("查询用户产品信息出错", c) return } //已选择过该产品--更新用户产品信息 if userProductInfo.ID != 0 { before := userProductInfo.LeftNum after := userProductInfo.LeftNum + leftNum userProductId := userProductInfo.ID errs = db.GetSFISDB().Transaction(func(tx *gorm.DB) error { //更新用户产品信息 userProduct.LeftNum = userProductInfo.LeftNum + leftNum userProduct.UpdateAt = time.Now() log.Println(userProduct.UpdateAt, "++++++++++++++++++++") err := tx.Exec("update user_product set left_num = ?, start_at = ?,end_at = ?,cost_model = ?,interface_status = ?,call_times_limit_day=?,data_num_limit_one_times=? where product_id = ? and app_id = ?", after, startTime, endTime, costModel, interfaceStatus, callTimesLimitDay, dataNumOneTimes, productId, appId).Error if err != nil { log.Printf("appID:[%s],productId:[%d] update user_product error:[%v]", appId, productId, err) tx.Rollback() return err } //生成购买产品记录 //扣费类型为扣余额,user_buy_record中tradeMoney金额为0 rechargeAmount := 0 if costModel == 0 { rechargeAmount = tradeMoney } 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, userProductId, before, after, rechargeAmount, buyType, historyUnitPrice).Error if err != nil { log.Printf("appID:[%s],productId[%d],trade_money:[%d] execute insert into user_buy_record error:[%v]", appId, productId, tradeMoney, err) tx.Rollback() return err } //扣费类型是扣余额,充值用户余额 if costModel == 1 { userAccount := model.UserAccount{} err = tx.First(&userAccount, model.UserAccount{AppID: appId}).Error if err != nil { log.Printf("appID:[%s],productId[%d],trade_money:[%d] execute find user_account error:[%v]", appId, productId, tradeMoney, err) tx.Rollback() return err } moneyBefore := userAccount.Money moneyAfter := userAccount.Money + tradeMoney //充值 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, tradeMoney).Error if err != nil { log.Printf("appID:[%s],trade_money:[%d] execute insert into user_money_record error:[%v]", appId, tradeMoney, err) tx.Rollback() return err } } return nil }) } else { //用户没有购买过改产品 errs = db.GetSFISDB().Transaction(func(tx *gorm.DB) error { //扣费类型为扣余额,user_buy_record中tradeMoney金额为0 rechargeAmount := 0 //第一次购买产品赠送试用量 testNum := product.TestNum remark := "" if costModel == 0 { rechargeAmount = tradeMoney leftNum += testNum } else if costModel == 1 { //扣余额,把赠送量转化成金额 freeMoney := testNum * product.UnitPrice tradeMoney += freeMoney remark = "充值金额为:" + strconv.Itoa(tradeMoney) + "赠送金额为:" + strconv.Itoa(freeMoney) } userProduct.LeftNum = leftNum //生用户产品 err := tx.Create(userProduct).Error if err != nil { log.Printf("appID:[%s],productId:[%d] insert user_product error:[%v]", appId, productId, err) tx.Rollback() return tx.Error } userProductId := userProduct.ID //生成购买产品记录 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, userProductId, 0, leftNum, rechargeAmount, buyType, historyUnitPrice).Error if err != nil { log.Printf("appID:[%s],productId[%d],trade_money:[%d] execute insert into user_buy_record error:[%v]", appId, productId, tradeMoney, err) tx.Rollback() return err } //扣费类型是扣余额,充值用户余额 if costModel == 1 { //第一次购买产品赠送免费次数 userAccount := model.UserAccount{} err = tx.First(&userAccount, model.UserAccount{AppID: appId}).Error if err != nil { log.Printf("appID:[%s],productId[%d],trade_money:[%d] execute find user_account error:[%v]", appId, productId, tradeMoney, err) tx.Rollback() return err } moneyBefore := userAccount.Money moneyAfter := userAccount.Money + tradeMoney //充值 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,remark) values (?,?,?,?,?)", appId, moneyBefore, moneyAfter, tradeMoney, remark).Error if err != nil { log.Printf("appID:[%s],trade_money:[%d] execute insert into user_money_record error:[%v]", appId, tradeMoney, err) tx.Rollback() return err } } return nil }) } } if errs == nil { response.Ok(c) return } else { response.FailWithMessage("购买产品失败", c) return } } response.FailWithMessage("缺少参数", c) } func UserProductList(appId string, c *gin.Context) { userProduct := []model.UserProduct{} err := db.GetSFISDB().Where("app_id = ? and ", appId).Find(&userProduct).Error if err != nil { log.Printf("appID:[%s] find into user_product error:[%v]", appId, err) response.FailWithMessage("查询出错", c) } else { response.OkWithData(userProduct, c) } } //创建用户 func CreateUser(user model.User) (model.User, error) { var tempUser []model.User // 判断用户名是否重复 db.GetSFISDB().Where("name = ?", user.Name).Find(&tempUser) if len(tempUser) > 0 { global.Logger.Error("userCreate Error", zap.Any("user", user), zap.Any("error", "用户名已存在")) return user, errors.New("用户名已存在") } // 判断手机号是否重复 var tempUser_ []model.User db.GetSFISDB().Where("phone = ?", user.Phone).Find(&tempUser_) if len(tempUser_) > 0 { global.Logger.Error("userCreate Error", zap.Any("user", user), zap.Any("error", "手机号已存在")) return user, errors.New("手机号已存在") } errs := db.GetSFISDB().Transaction(func(tx *gorm.DB) error { // 新增用户 err := tx.Create(&user).Error if err != nil { global.Logger.Error("userCreate Error", zap.Any("user", user), zap.Any("error", err)) tx.Rollback() return err } // 初始化用户账户 userAccount := model.UserAccount{AppID: user.AppID, Money: 0} err = tx.Create(&userAccount).Error if err != nil { global.Logger.Error("userAccountInit Error", zap.Any("user", user), zap.Any("userAccount", userAccount), zap.Any("error", err)) tx.Rollback() return err } return nil }) if errs != nil { global.Logger.Error("userCreate Error", zap.Any("user", user), zap.Any("error", errs)) return user, errors.New("创建失败") } else { global.Logger.Info("userCreate Success", zap.Any("user", user)) // 生全局内存锁 lock.MainLock.Lock() lock.UserLockMap[user.AppID] = &sync.Mutex{} lock.MainLock.Unlock() return user, nil } }