Bläddra i källkod

add 积分释放 的后续逻辑

tags/v3.9.1
DengBiao 2 år sedan
förälder
incheckning
43ffc138bf
13 ändrade filer med 824 tillägg och 11 borttagningar
  1. +157
    -0
      db/db_integral_release_interposition_user_amount.go
  2. +157
    -0
      db/db_integral_release_interposition_user_flow.go
  3. +157
    -0
      db/db_integral_release_interposition_user_records.go
  4. +18
    -0
      db/model/integral_release_interposition_user_amount.go
  5. +23
    -0
      db/model/integral_release_interposition_user_flow.go
  6. +12
    -0
      enum/fin_user_flow.go
  7. +2
    -1
      md/app_redis_key.go
  8. +8
    -8
      md/block_star_chain.go
  9. +42
    -0
      md/fin_user_flow.go
  10. +88
    -1
      rule/integral_release_settlement.go
  11. +135
    -0
      svc/svc_deal_user_amount.go
  12. +1
    -1
      svc/svc_redis_mutex_lock.go
  13. +24
    -0
      svc/svc_redis_mutex_lock_for_amount.go

+ 157
- 0
db/db_integral_release_interposition_user_amount.go Visa fil

@@ -0,0 +1,157 @@
package db

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model"
zhios_order_relate_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils"
zhios_order_relate_logx "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/logx"
"errors"
"fmt"
"reflect"
"xorm.io/xorm"
)

// BatchSelectIntegralReleaseInterpositionUserAmounts 批量查询数据 TODO::和下面的方法重复了,建议采用下面的 `IntegralReleaseInterpositionUserAmountFindByParams` 方法
func BatchSelectIntegralReleaseInterpositionUserAmounts(Db *xorm.Engine, params map[string]interface{}) (*[]model.IntegralReleaseInterpositionUserAmount, error) {
var IntegralReleaseInterpositionUserAmountData []model.IntegralReleaseInterpositionUserAmount
if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).
Find(&IntegralReleaseInterpositionUserAmountData); err != nil {
return nil, zhios_order_relate_logx.Warn(err)
}
return &IntegralReleaseInterpositionUserAmountData, nil
}

// IntegralReleaseInterpositionUserAmountInsert 插入单条数据
func IntegralReleaseInterpositionUserAmountInsert(session *xorm.Session, IntegralReleaseInterpositionUserAmount *model.IntegralReleaseInterpositionUserAmount) (int, error) {
_, err := session.InsertOne(IntegralReleaseInterpositionUserAmount)
if err != nil {
return 0, err
}
return IntegralReleaseInterpositionUserAmount.Id, nil
}

// BatchAddIntegralReleaseInterpositionUserAmounts 批量新增数据
func BatchAddIntegralReleaseInterpositionUserAmounts(Db *xorm.Engine, IntegralReleaseInterpositionUserAmountData []*model.IntegralReleaseInterpositionUserAmount) (int64, error) {
affected, err := Db.Insert(IntegralReleaseInterpositionUserAmountData)
if err != nil {
return 0, err
}
return affected, nil
}

func GetIntegralReleaseInterpositionUserAmountCount(Db *xorm.Engine) int {
var IntegralReleaseInterpositionUserAmount model.IntegralReleaseInterpositionUserAmount
session := Db.Where("")
count, err := session.Count(&IntegralReleaseInterpositionUserAmount)
if err != nil {
return 0
}
return int(count)
}

// IntegralReleaseInterpositionUserAmountDelete 删除记录
func IntegralReleaseInterpositionUserAmountDelete(Db *xorm.Engine, id interface{}) (int64, error) {
if reflect.TypeOf(id).Kind() == reflect.Slice {
return Db.In("id", id).Delete(model.IntegralReleaseInterpositionUserAmount{})
} else {
return Db.Where("id = ?", id).Delete(model.IntegralReleaseInterpositionUserAmount{})
}
}

// IntegralReleaseInterpositionUserAmountUpdate 更新记录
func IntegralReleaseInterpositionUserAmountUpdate(session *xorm.Session, id interface{}, IntegralReleaseInterpositionUserAmount *model.IntegralReleaseInterpositionUserAmount, forceColums ...string) (int64, error) {
var (
affected int64
err error
)
if forceColums != nil {
affected, err = session.Where("id=?", id).Cols(forceColums...).Update(IntegralReleaseInterpositionUserAmount)
} else {
affected, err = session.Where("id=?", id).Update(IntegralReleaseInterpositionUserAmount)
}
if err != nil {
return 0, err
}
return affected, nil
}

// IntegralReleaseInterpositionUserAmountGetOneByParams 通过传入的参数查询数据(单条)
func IntegralReleaseInterpositionUserAmountGetOneByParams(session *xorm.Session, coinId int, params map[string]interface{}) (*model.IntegralReleaseInterpositionUserAmount, error) {
var m model.IntegralReleaseInterpositionUserAmount
var query = fmt.Sprintf("%s =?", params["key"])
has, err := session.Where(query, params["value"]).And("coin_id =?", coinId).Get(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
if has == false {
return nil, errors.New("未查询到相应的 integral_release_interposition_user_amount 记录")
}
return &m, nil
}

// IntegralReleaseInterpositionUserAmountFindByParams 通过传入的参数查询数据(多条)
func IntegralReleaseInterpositionUserAmountFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.IntegralReleaseInterpositionUserAmount, error) {
var m []model.IntegralReleaseInterpositionUserAmount
if params["value"] == nil {
return nil, errors.New("参数有误")
}
if params["key"] == nil {
//查询全部数据
err := Db.Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
} else {
if reflect.TypeOf(params["value"]).Kind() == reflect.Slice {
//指定In查询
if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Find(&m); err != nil {
return nil, zhios_order_relate_logx.Warn(err)
}
return &m, nil
} else {
var query = fmt.Sprintf("%s =?", params["key"])
err := Db.Where(query, params["value"]).Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
}

}
}

func IntegralReleaseInterpositionUserAmountFindByParamsByPage(Db *xorm.Engine, params map[string]interface{}, page, pageSize int) (*[]model.IntegralReleaseInterpositionUserAmount, error) {
var m []model.IntegralReleaseInterpositionUserAmount
if params["value"] == nil {
return nil, errors.New("参数有误")
}
if page == 0 && pageSize == 0 {
page = 1
pageSize = 10
}

if params["key"] == nil {
//查询全部数据
err := Db.Limit(pageSize, (page-1)*pageSize).Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
} else {
if reflect.TypeOf(params["value"]).Kind() == reflect.Slice {
//指定In查询
if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m); err != nil {
return nil, zhios_order_relate_logx.Warn(err)
}
return &m, nil
} else {
var query = fmt.Sprintf("%s =?", params["key"])
err := Db.Where(query, params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
}

}
}

+ 157
- 0
db/db_integral_release_interposition_user_flow.go Visa fil

@@ -0,0 +1,157 @@
package db

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model"
zhios_order_relate_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils"
zhios_order_relate_logx "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/logx"
"errors"
"fmt"
"reflect"
"xorm.io/xorm"
)

// BatchSelectIntegralReleaseInterpositionUserFlows 批量查询数据 TODO::和下面的方法重复了,建议采用下面的 `IntegralReleaseInterpositionUserFlowFindByParams` 方法
func BatchSelectIntegralReleaseInterpositionUserFlows(Db *xorm.Engine, params map[string]interface{}) (*[]model.IntegralReleaseInterpositionUserFlow, error) {
var IntegralReleaseInterpositionUserFlowData []model.IntegralReleaseInterpositionUserFlow
if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).
Find(&IntegralReleaseInterpositionUserFlowData); err != nil {
return nil, zhios_order_relate_logx.Warn(err)
}
return &IntegralReleaseInterpositionUserFlowData, nil
}

// IntegralReleaseInterpositionUserFlowInsert 插入单条数据
func IntegralReleaseInterpositionUserFlowInsert(session *xorm.Session, IntegralReleaseInterpositionUserFlow *model.IntegralReleaseInterpositionUserFlow) (int, error) {
_, err := session.InsertOne(IntegralReleaseInterpositionUserFlow)
if err != nil {
return 0, err
}
return IntegralReleaseInterpositionUserFlow.Id, nil
}

// BatchAddIntegralReleaseInterpositionUserFlows 批量新增数据
func BatchAddIntegralReleaseInterpositionUserFlows(Db *xorm.Engine, IntegralReleaseInterpositionUserFlowData []*model.IntegralReleaseInterpositionUserFlow) (int64, error) {
affected, err := Db.Insert(IntegralReleaseInterpositionUserFlowData)
if err != nil {
return 0, err
}
return affected, nil
}

func GetIntegralReleaseInterpositionUserFlowCount(Db *xorm.Engine) int {
var IntegralReleaseInterpositionUserFlow model.IntegralReleaseInterpositionUserFlow
session := Db.Where("")
count, err := session.Count(&IntegralReleaseInterpositionUserFlow)
if err != nil {
return 0
}
return int(count)
}

// IntegralReleaseInterpositionUserFlowDelete 删除记录
func IntegralReleaseInterpositionUserFlowDelete(Db *xorm.Engine, id interface{}) (int64, error) {
if reflect.TypeOf(id).Kind() == reflect.Slice {
return Db.In("id", id).Delete(model.IntegralReleaseInterpositionUserFlow{})
} else {
return Db.Where("id = ?", id).Delete(model.IntegralReleaseInterpositionUserFlow{})
}
}

// IntegralReleaseInterpositionUserFlowUpdate 更新记录
func IntegralReleaseInterpositionUserFlowUpdate(session *xorm.Session, id interface{}, IntegralReleaseInterpositionUserFlow *model.IntegralReleaseInterpositionUserFlow, forceColums ...string) (int64, error) {
var (
affected int64
err error
)
if forceColums != nil {
affected, err = session.Where("id=?", id).Cols(forceColums...).Update(IntegralReleaseInterpositionUserFlow)
} else {
affected, err = session.Where("id=?", id).Update(IntegralReleaseInterpositionUserFlow)
}
if err != nil {
return 0, err
}
return affected, nil
}

// IntegralReleaseInterpositionUserFlowGetOneByParams 通过传入的参数查询数据(单条)
func IntegralReleaseInterpositionUserFlowGetOneByParams(session *xorm.Session, params map[string]interface{}) (*model.IntegralReleaseInterpositionUserFlow, error) {
var m model.IntegralReleaseInterpositionUserFlow
var query = fmt.Sprintf("%s =?", params["key"])
has, err := session.Where(query, params["value"]).Get(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
if has == false {
return nil, errors.New("未查询到相应的 block_star_chain 记录")
}
return &m, nil
}

// IntegralReleaseInterpositionUserFlowFindByParams 通过传入的参数查询数据(多条)
func IntegralReleaseInterpositionUserFlowFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.IntegralReleaseInterpositionUserFlow, error) {
var m []model.IntegralReleaseInterpositionUserFlow
if params["value"] == nil {
return nil, errors.New("参数有误")
}
if params["key"] == nil {
//查询全部数据
err := Db.Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
} else {
if reflect.TypeOf(params["value"]).Kind() == reflect.Slice {
//指定In查询
if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Find(&m); err != nil {
return nil, zhios_order_relate_logx.Warn(err)
}
return &m, nil
} else {
var query = fmt.Sprintf("%s =?", params["key"])
err := Db.Where(query, params["value"]).Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
}

}
}

func IntegralReleaseInterpositionUserFlowFindByParamsByPage(Db *xorm.Engine, params map[string]interface{}, page, pageSize int) (*[]model.IntegralReleaseInterpositionUserFlow, error) {
var m []model.IntegralReleaseInterpositionUserFlow
if params["value"] == nil {
return nil, errors.New("参数有误")
}
if page == 0 && pageSize == 0 {
page = 1
pageSize = 10
}

if params["key"] == nil {
//查询全部数据
err := Db.Limit(pageSize, (page-1)*pageSize).Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
} else {
if reflect.TypeOf(params["value"]).Kind() == reflect.Slice {
//指定In查询
if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m); err != nil {
return nil, zhios_order_relate_logx.Warn(err)
}
return &m, nil
} else {
var query = fmt.Sprintf("%s =?", params["key"])
err := Db.Where(query, params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
}

}
}

+ 157
- 0
db/db_integral_release_interposition_user_records.go Visa fil

@@ -0,0 +1,157 @@
package db

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model"
zhios_order_relate_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils"
zhios_order_relate_logx "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/logx"
"errors"
"fmt"
"reflect"
"xorm.io/xorm"
)

// BatchSelectIntegralReleaseInterpositionUserRecords 批量查询数据 TODO::和下面的方法重复了,建议采用下面的 `IntegralReleaseInterpositionUserRecordsFindByParams` 方法
func BatchSelectIntegralReleaseInterpositionUserRecords(Db *xorm.Engine, params map[string]interface{}) (*[]model.IntegralReleaseInterpositionUserRecords, error) {
var IntegralReleaseInterpositionUserRecordsData []model.IntegralReleaseInterpositionUserRecords
if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).
Find(&IntegralReleaseInterpositionUserRecordsData); err != nil {
return nil, zhios_order_relate_logx.Warn(err)
}
return &IntegralReleaseInterpositionUserRecordsData, nil
}

// IntegralReleaseInterpositionUserRecordsInsert 插入单条数据
func IntegralReleaseInterpositionUserRecordsInsert(Db *xorm.Engine, IntegralReleaseInterpositionUserRecords *model.IntegralReleaseInterpositionUserRecords) (int, error) {
_, err := Db.InsertOne(IntegralReleaseInterpositionUserRecords)
if err != nil {
return 0, err
}
return IntegralReleaseInterpositionUserRecords.Id, nil
}

// BatchAddIntegralReleaseInterpositionUserRecords 批量新增数据
func BatchAddIntegralReleaseInterpositionUserRecords(Db *xorm.Engine, IntegralReleaseInterpositionUserRecordsData []*model.IntegralReleaseInterpositionUserRecords) (int64, error) {
affected, err := Db.Insert(IntegralReleaseInterpositionUserRecordsData)
if err != nil {
return 0, err
}
return affected, nil
}

func GetIntegralReleaseInterpositionUserRecordsCount(Db *xorm.Engine) int {
var IntegralReleaseInterpositionUserRecords model.IntegralReleaseInterpositionUserRecords
session := Db.Where("")
count, err := session.Count(&IntegralReleaseInterpositionUserRecords)
if err != nil {
return 0
}
return int(count)
}

// IntegralReleaseInterpositionUserRecordsDelete 删除记录
func IntegralReleaseInterpositionUserRecordsDelete(Db *xorm.Engine, id interface{}) (int64, error) {
if reflect.TypeOf(id).Kind() == reflect.Slice {
return Db.In("id", id).Delete(model.IntegralReleaseInterpositionUserRecords{})
} else {
return Db.Where("id = ?", id).Delete(model.IntegralReleaseInterpositionUserRecords{})
}
}

// IntegralReleaseInterpositionUserRecordsUpdate 更新记录
func IntegralReleaseInterpositionUserRecordsUpdate(session *xorm.Session, id interface{}, IntegralReleaseInterpositionUserRecords *model.IntegralReleaseInterpositionUserRecords, forceColums ...string) (int64, error) {
var (
affected int64
err error
)
if forceColums != nil {
affected, err = session.Where("id=?", id).Cols(forceColums...).Update(IntegralReleaseInterpositionUserRecords)
} else {
affected, err = session.Where("id=?", id).Update(IntegralReleaseInterpositionUserRecords)
}
if err != nil {
return 0, err
}
return affected, nil
}

// IntegralReleaseInterpositionUserRecordsGetOneByParams 通过传入的参数查询数据(单条)
func IntegralReleaseInterpositionUserRecordsGetOneByParams(session *xorm.Session, params map[string]interface{}) (*model.IntegralReleaseInterpositionUserRecords, error) {
var m model.IntegralReleaseInterpositionUserRecords
var query = fmt.Sprintf("%s =?", params["key"])
has, err := session.Where(query, params["value"]).Get(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
if has == false {
return nil, errors.New("未查询到相应的 block_star_chain 记录")
}
return &m, nil
}

// IntegralReleaseInterpositionUserRecordsFindByParams 通过传入的参数查询数据(多条)
func IntegralReleaseInterpositionUserRecordsFindByParams(Db *xorm.Engine, params map[string]interface{}) (*[]model.IntegralReleaseInterpositionUserRecords, error) {
var m []model.IntegralReleaseInterpositionUserRecords
if params["value"] == nil {
return nil, errors.New("参数有误")
}
if params["key"] == nil {
//查询全部数据
err := Db.Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
} else {
if reflect.TypeOf(params["value"]).Kind() == reflect.Slice {
//指定In查询
if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Find(&m); err != nil {
return nil, zhios_order_relate_logx.Warn(err)
}
return &m, nil
} else {
var query = fmt.Sprintf("%s =?", params["key"])
err := Db.Where(query, params["value"]).Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
}

}
}

func IntegralReleaseInterpositionUserRecordsFindByParamsByPage(Db *xorm.Engine, params map[string]interface{}, page, pageSize int) (*[]model.IntegralReleaseInterpositionUserRecords, error) {
var m []model.IntegralReleaseInterpositionUserRecords
if params["value"] == nil {
return nil, errors.New("参数有误")
}
if page == 0 && pageSize == 0 {
page = 1
pageSize = 10
}

if params["key"] == nil {
//查询全部数据
err := Db.Limit(pageSize, (page-1)*pageSize).Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
} else {
if reflect.TypeOf(params["value"]).Kind() == reflect.Slice {
//指定In查询
if err := Db.In(zhios_order_relate_utils.AnyToString(params["key"]), params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m); err != nil {
return nil, zhios_order_relate_logx.Warn(err)
}
return &m, nil
} else {
var query = fmt.Sprintf("%s =?", params["key"])
err := Db.Where(query, params["value"]).Limit(pageSize, (page-1)*pageSize).Find(&m)
if err != nil {
return nil, zhios_order_relate_logx.Error(err)
}
return &m, nil
}

}
}

+ 18
- 0
db/model/integral_release_interposition_user_amount.go Visa fil

@@ -0,0 +1,18 @@
package model

import (
"time"
)

type IntegralReleaseInterpositionUserAmount struct {
Id int `json:"id" xorm:"not null pk autoincr comment('主键id') INT(11)"`
Uid int `json:"uid" xorm:"not null default 0 comment('用户uid') INT(11)"`
CoinId int `json:"coin_id" xorm:"not null default 0 comment('虚拟币id(若为0则为 余额)') INT(11)"`
TotalAmount string `json:"total_amount" xorm:"not null default 0.0000 comment('累计金额') DECIMAL(10,4)"`
WaiteAmount string `json:"waite_amount" xorm:"not null default 0.0000 comment('待释放金额') DECIMAL(10,4)"`
AlreadyAmount string `json:"already_amount" xorm:"not null default 0.0000 comment('已释放金额') DECIMAL(10,4)"`
State int `json:"state" xorm:"not null default 1 comment('状态(1:正常 2:冻结(停止释放))') TINYINT(3)"`
Ext string `json:"ext" xorm:"TEXT"`
CreateAt time.Time `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' comment('创建时间') TIMESTAMP"`
UpdateAt time.Time `json:"update_at" xorm:"default 'CURRENT_TIMESTAMP' comment('更新时间') TIMESTAMP"`
}

+ 23
- 0
db/model/integral_release_interposition_user_flow.go Visa fil

@@ -0,0 +1,23 @@
package model

import (
"time"
)

type IntegralReleaseInterpositionUserFlow struct {
Id int `json:"id" xorm:"not null pk autoincr comment('主键id') INT(11)"`
Uid int `json:"uid" xorm:"not null default 0 comment('用户uid') INT(11)"`
CoinId int `json:"coin_id" xorm:"not null default 0 comment('虚拟币id(若为0则为 余额)') INT(11)"`
OrdId string `json:"ord_id" xorm:"not null default '' comment('订单id') VARCHAR(100)"`
Kind int `json:"kind" xorm:"not null default 1 comment('种类(1:流入 2:流出)') TINYINT(1)"`
Amount string `json:"amount" xorm:"not null default 0.0000 comment('金额') DECIMAL(10,4)"`
BeforeTotalAmount string `json:"before_total_amount" xorm:"not null default 0.0000 comment('累计金额-之前') DECIMAL(10,4)"`
AfterTotalAmount string `json:"after_total_amount" xorm:"not null default 0.0000 comment('累计金额-之后') DECIMAL(10,4)"`
BeforeAlreadyAmount string `json:"before_already_amount" xorm:"not null default 0.0000 comment('已释放金额-之前') DECIMAL(10,4)"`
AfterAlreadyAmount string `json:"after_already_amount" xorm:"not null default 0.0000 comment('已释放金额-之后') DECIMAL(10,4)"`
BeforeWaiteAmount string `json:"before_waite_amount" xorm:"not null default 0.0000 comment('待释放金额-之前') DECIMAL(10,4)"`
AfterWaiteAmount string `json:"after_waite_amount" xorm:"not null default 0.0000 comment('待释放金额-之后') DECIMAL(10,4)"`
Date string `json:"date" xorm:"not null default '0000-00-00' comment('释放日期') VARCHAR(50)"`
CreateAt time.Time `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' comment('创建时间') TIMESTAMP"`
UpdateAt time.Time `json:"update_at" xorm:"default 'CURRENT_TIMESTAMP' comment('更新时间') TIMESTAMP"`
}

+ 12
- 0
enum/fin_user_flow.go Visa fil

@@ -0,0 +1,12 @@
package enum

import "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/md"

func FinUserFlowOrderActionString(kind int) string {
switch kind {
case md.IntegralReleaseServiceRevenueOrderTypeForFinUserFlow:
return "integral_release_service_revenue"
default:
return "unknown"
}
}

+ 2
- 1
md/app_redis_key.go Visa fil

@@ -7,7 +7,8 @@ const (
PlanRewardCfgCacheKey = "%s:plan_reward_cfg"
UnionSetCacheCfg = "%s:union_set_cfg:%s" // 联盟设置缓存key

UserFinValidUpdateLock = "%s:user_fin_valid_update_lock:%s" // 用户余额更新锁(能拿到锁才能更新余额)
UserFinValidUpdateLock = "%s:user_fin_valid_update_lock:%s" // 用户余额更新锁(能拿到锁才能更新余额)
UserVirtualAmountUpdateLock = "%s:user_virtual_amount_update_lock:%s" // 用户虚拟币更新锁(能拿到锁才能更新余额)

WithdrawApplyQueueListKey = "withdraw_apply_queue" // 提现队列



+ 8
- 8
md/block_star_chain.go Visa fil

@@ -42,10 +42,10 @@ const (
BlockGreenChainTransactionAndDestroyTitleForUserVirtualCoinFlow = "绿色积分-交易(销毁贡献值)"
BlockGreenChainAdminDestroyTitleForUserVirtualCoinFlow = "绿色积分-管理员销毁"

IntegralReleaseRedCoinGrantByOrdTitleForUserVirtualCoinFlow = "积分兑换-红积分发放(订单)"
IntegralReleaseRedCoinGrantBySignInTitleForUserVirtualCoinFlow = "积分兑换-红积分发放(签到)"
IntegralReleaseGreenCoinGrantByOrdTitleForUserVirtualCoinFlow = "积分兑换-绿积分发放(订单)"
IntegralReleaseGreenCoinGrantBySignInTitleForUserVirtualCoinFlow = "积分兑换-红积分发放(签到)"
IntegralReleaseRedCoinGrantByOrdTitleForUserVirtualCoinFlow = "积分释放-红积分发放(订单)"
IntegralReleaseRedCoinGrantBySignInTitleForUserVirtualCoinFlow = "积分释放-红积分发放(签到)"
IntegralReleaseGreenCoinGrantByOrdTitleForUserVirtualCoinFlow = "积分释放-绿积分发放(订单)"
IntegralReleaseGreenCoinGrantBySignInTitleForUserVirtualCoinFlow = "积分释放-红积分发放(签到)"
)

const (
@@ -80,10 +80,10 @@ const (
BlockGreenChainTransactionAndDestroyTransferTypeForUserVirtualCoinFlow = 133 // 绿色积分-交易(销毁贡献值)
BlockGreenChainAdminDestroyTransferTypeForUserVirtualCoinFlow = 134 // 绿色积分-管理员销毁

IntegralReleaseRedCoinGrantByOrdTransferTypeForUserVirtualCoinFlow = 135 // 积分兑换-红积分发放(订单)
IntegralReleaseRedCoinGrantBySignInTransferTypeForUserVirtualCoinFlow = 136 // 积分兑换-红积分发放(签到)
IntegralReleaseGreenCoinGrantByOrdTransferTypeForUserVirtualCoinFlow = 137 // 积分兑换-绿积分发放(订单)
IntegralReleaseGreenCoinGrantBySignInTransferTypeForUserVirtualCoinFlow = 138 // 积分兑换-绿积分发放(签到)
IntegralReleaseRedCoinGrantByOrdTransferTypeForUserVirtualCoinFlow = 135 // 积分释放-红积分发放(订单)
IntegralReleaseRedCoinGrantBySignInTransferTypeForUserVirtualCoinFlow = 136 // 积分释放-红积分发放(签到)
IntegralReleaseGreenCoinGrantByOrdTransferTypeForUserVirtualCoinFlow = 137 // 积分释放-绿积分发放(订单)
IntegralReleaseGreenCoinGrantBySignInTransferTypeForUserVirtualCoinFlow = 138 // 积分释放-绿积分发放(签到)
)

const DealUserCoinRequestIdPrefix = "%s:block_star_chain_deal_user_coin:%d:uid:%d"


+ 42
- 0
md/fin_user_flow.go Visa fil

@@ -0,0 +1,42 @@
package md

const (
FinUserFlowDirectionIncome = 1 //流水 - 收入
FinUserFlowDirectionExpenditure = 2 //流水 - 支出
)

const (
FinUserFlowRedisDataBase = 0
FinUserFlowRedisKey = "%s:fin_user_flow:%d:user:%d"
)

const (
IntegralReleaseServiceRevenueTitleForFinUserFlow = "积分释放-服务收益"
)

const (
IntegralReleaseServiceRevenueOrderTypeForFinUserFlow = 50 // 积分释放-服务收益
)

const DealUserAmountRequestIdPrefix = "%s:deal_user_amount:%d"
const UserAmountRedisKey = "%s:user_amount:%d"

type DealIntegralReleaseInterpositionUserAmountReq struct {
Kind string `json:"kind"`
Mid string `json:"mid"`
OrdId string `json:"ord_id"`
CoinId int `json:"coin_id"`
Uid int `json:"uid"`
Amount float64 `json:"amount"`
}

type DealUserAmount struct {
Kind string `json:"kind"`
Mid string `json:"mid"`
Title string `json:"title"`
OrderType string `json:"order_type"`
OrdAction int `json:"ord_action"`
OrdId string `json:"ord_id"`
Uid int `json:"uid"`
Amount float64 `json:"amount"`
}

+ 88
- 1
rule/integral_release_settlement.go Visa fil

@@ -3,6 +3,7 @@ package rule
import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db"
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model"
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/enum"
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/md"
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/svc"
zhios_order_relate_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils"
@@ -78,7 +79,7 @@ func DailySettlementIntegralRelease(engine *xorm.Engine, mid string, isTask bool

//2、查询所有 `integral_release_user_with_ord` 记录
integralReleaseUserWithOrds, err := db.IntegralReleaseUserWithOrdFindByParams(session, map[string]interface{}{
"key": "state",
"key": "state",
"value": 1,
})
for _, ord := range *integralReleaseUserWithOrds {
@@ -268,3 +269,89 @@ func DealUserCoinForIntegralRelease(session *xorm.Session, req md.DealUserCoinRe

return nil
}

// DealIntegralReleaseInterpositionUserAmount 处理间推用户服务收益
func DealIntegralReleaseInterpositionUserAmount(session *xorm.Session, req md.DealIntegralReleaseInterpositionUserAmountReq) (err error) {
if req.Amount < 0 {
req.Amount = 0
}

//1、计算&&组装数据
now := time.Now()
userAmount, err := db.IntegralReleaseInterpositionUserAmountGetOneByParams(session, req.CoinId, map[string]interface{}{
"key": "uid",
"value": req.Uid,
})
if err != nil {
return err
}
totalAmountValue := decimal.NewFromFloat(zhios_order_relate_utils.StrToFloat64(userAmount.TotalAmount))
waiteAmountValue := decimal.NewFromFloat(zhios_order_relate_utils.StrToFloat64(userAmount.WaiteAmount))
alreadyAmountValue := decimal.NewFromFloat(zhios_order_relate_utils.StrToFloat64(userAmount.AlreadyAmount))
amountValue := decimal.NewFromFloat(req.Amount).RoundFloor(4)

var integralReleaseInterpositionUserFlow = model.IntegralReleaseInterpositionUserFlow{
Uid: req.Uid,
CoinId: req.CoinId,
OrdId: req.OrdId,
Amount: amountValue.String(),
Date: "",
CreateAt: now,
UpdateAt: now,
}
if req.Kind == "add" {
integralReleaseInterpositionUserFlow.Kind = 1
integralReleaseInterpositionUserFlow.BeforeTotalAmount = totalAmountValue.String()
integralReleaseInterpositionUserFlow.AfterTotalAmount = totalAmountValue.Add(amountValue).String()
integralReleaseInterpositionUserFlow.BeforeWaiteAmount = waiteAmountValue.String()
integralReleaseInterpositionUserFlow.AfterAlreadyAmount = waiteAmountValue.Add(amountValue).String()
integralReleaseInterpositionUserFlow.BeforeAlreadyAmount = alreadyAmountValue.String()
integralReleaseInterpositionUserFlow.AfterAlreadyAmount = alreadyAmountValue.String()
} else if req.Kind == "sub" {
integralReleaseInterpositionUserFlow.Kind = 1
integralReleaseInterpositionUserFlow.BeforeTotalAmount = totalAmountValue.String()
integralReleaseInterpositionUserFlow.AfterTotalAmount = totalAmountValue.String()
integralReleaseInterpositionUserFlow.BeforeWaiteAmount = waiteAmountValue.String()
integralReleaseInterpositionUserFlow.AfterAlreadyAmount = waiteAmountValue.Sub(amountValue).String()
integralReleaseInterpositionUserFlow.BeforeAlreadyAmount = alreadyAmountValue.String()
integralReleaseInterpositionUserFlow.AfterAlreadyAmount = alreadyAmountValue.Add(amountValue).String()
integralReleaseInterpositionUserFlow.Date = now.Format("2006-01-02")
//TODO::判断增加用户 余额 or 虚拟币积分
if req.CoinId == 0 {
orderType := enum.FinUserFlowOrderActionString(md.IntegralReleaseServiceRevenueOrderTypeForFinUserFlow)
var dealUserAmount = md.DealUserAmount{
Kind: req.Kind,
Mid: req.Mid,
Title: md.IntegralReleaseServiceRevenueTitleForFinUserFlow,
OrderType: orderType,
OrdAction: md.IntegralReleaseServiceRevenueOrderTypeForFinUserFlow,
OrdId: req.OrdId,
Uid: req.Uid,
Amount: req.Amount,
}
err = svc.DealUserAmount(session, dealUserAmount)
if err != nil {
return err
}
}
} else {
err = errors.New("错误的kind类型")
return err
}

//2、插入 `integral_release_interposition_user_flow` 记录
_, err = db.IntegralReleaseInterpositionUserFlowInsert(session, &integralReleaseInterpositionUserFlow)
if err != nil {
return err
}

//3、修改 `integral_release_interposition_user_amount` 的相关 amount 值
updateAffected, _ := db.IntegralReleaseInterpositionUserAmountUpdate(session, userAmount.Id, userAmount)
if err != nil {
return err
}
if updateAffected == 0 {
return errors.New("更新 integral_release_interposition_user_flow 记录失败")
}
return nil
}

+ 135
- 0
svc/svc_deal_user_amount.go Visa fil

@@ -0,0 +1,135 @@
package svc

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db"
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/db/model"
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/md"
zhios_order_relate_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils"
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/cache"
zhios_order_relate_logx "code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/utils/logx"
"errors"
"fmt"
"github.com/shopspring/decimal"
"strconv"
"time"
"xorm.io/xorm"
)

// DealUserAmount 处理给用户余额
func DealUserAmount(session *xorm.Session, req md.DealUserAmount) (err error) {
if req.Amount < 0 {
req.Amount = 0
}
//1、分布式锁阻拦
requestIdPrefix := fmt.Sprintf(md.DealUserAmountRequestIdPrefix, req.Mid, req.Uid)
cb, err := HandleBalanceDistributedLockForAmount(req.Mid, strconv.Itoa(req.Uid), requestIdPrefix)
if err != nil {
return err
}
if cb != nil {
defer cb() // 释放锁
}

//2、计算&&组装数据
now := time.Now()
userAmount, err := GetUserAmount(session, req.Mid, req.Uid)
if err != nil {
return err
}
userAmountValue := decimal.NewFromFloat(zhios_order_relate_utils.StrToFloat64(userAmount))
amountValue := decimal.NewFromFloat(req.Amount).RoundFloor(4)

var finUserFlow = model.FinUserFlow{
Uid: req.Uid,
Amount: "",
BeforeAmount: userAmount,
OrdType: req.OrderType,
OrdId: req.OrdId,
OrdTitle: req.Title,
OrdAction: req.OrdAction,
OrdTime: int(now.Unix()),
State: 1,
CreateAt: now,
UpdateAt: now,
}
if req.Kind == "add" {
finUserFlow.Type = 0
finUserFlow.AfterAmount = userAmountValue.Add(amountValue).RoundFloor(4).String()
} else if req.Kind == "sub" {
finUserFlow.Type = 1
finUserFlow.AfterAmount = userAmountValue.Sub(amountValue).RoundFloor(4).String()
} else {
err = errors.New("错误的kind类型")
return err
}
if zhios_order_relate_utils.StrToFloat64(finUserFlow.AfterAmount) < 0 {
zhios_order_relate_utils.FilePutContents("user_amount_not", zhios_order_relate_utils.SerializeStr(map[string]interface{}{
"uid": finUserFlow.Uid,
"amount": finUserFlow.Amount,
"before_amount": finUserFlow.BeforeAmount,
"title": finUserFlow.OrdTitle,
"mid": req.Mid,
}))
return errors.New("用户余额不足")
}

//3、插入 `user_virtual_coin_flow` 记录
affected, err := session.Insert(&finUserFlow)
if affected == 0 || err != nil {
_ = zhios_order_relate_logx.Warn(err)
return err
}

//4、修改 `user_profile`的fin_valid值 && 及缓存
err = SetCacheUserAmount(session, req.Mid, finUserFlow.AfterAmount, req.Uid, true)
if err != nil {
return err
}

return nil
}

// GetUserAmount 获取用户余额
func GetUserAmount(session *xorm.Session, masterId string, uid int) (amount string, err error) {
redisKey := fmt.Sprintf(md.UserAmountRedisKey, masterId, uid)
amount, err = cache.GetString(redisKey)
if err != nil {
if err.Error() == "redigo: nil returned" {
userAmount, err := db.UserProfileFindByIDWithSession(session, uid)
if err != nil {
return amount, err
}
if userAmount == nil {
amount = "0"
} else {
amount = userAmount.FinValid
}
//将获取到的余额值缓存至redis
_ = SetCacheUserAmount(session, masterId, amount, uid, false)
return amount, nil
}
return amount, err
}
return amount, nil
}

// SetCacheUserAmount 设置缓存的用户余额
func SetCacheUserAmount(session *xorm.Session, masterId, amount string, uid int, isUpdateDb bool) error {
redisKey := fmt.Sprintf(md.UserAmountRedisKey, masterId, uid)
if isUpdateDb {
_, err := session.Where("uid=?", uid).Update(model.UserProfile{
Uid: uid,
FinValid: amount,
})
if err != nil {
return err
}
}
//_, err := cache.Set(redisKey, int64(utils.StrToFloat64(amount)))
//TODO::默认缓存1小时 (先调整为 2 min)
_, err := cache.SetEx(redisKey, zhios_order_relate_utils.StrToFloat64(amount), 60*2)
if err != nil {
return err
}
return nil
}

+ 1
- 1
svc/svc_redis_mutex_lock.go Visa fil

@@ -69,7 +69,7 @@ func GetDistributedLockRequestId(prefix string) string {
// HandleDistributedLock 处理余额更新时获取锁和释放锁 如果加锁成功,使用语句 ` defer cb() ` 释放锁
func HandleDistributedLock(masterId, uid, requestIdPrefix string) (cb func(), err error) {
// 获取余额更新锁
balanceLockKey := fmt.Sprintf(md.UserFinValidUpdateLock, masterId, uid)
balanceLockKey := fmt.Sprintf(md.UserVirtualAmountUpdateLock, masterId, uid)
requestId := GetDistributedLockRequestId(requestIdPrefix)
balanceLockOk := TryGetDistributedLock(balanceLockKey, requestId, true)
if !balanceLockOk {


+ 24
- 0
svc/svc_redis_mutex_lock_for_amount.go Visa fil

@@ -0,0 +1,24 @@
package svc

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_order_relate_rule.git/md"
"errors"
"fmt"
)

// HandleBalanceDistributedLockForAmount 处理余额更新时获取锁和释放锁 如果加锁成功,使用语句 ` defer cb() ` 释放锁
func HandleBalanceDistributedLockForAmount(masterId, uid, requestIdPrefix string) (cb func(), err error) {
// 获取余额更新锁
balanceLockKey := fmt.Sprintf(md.UserFinValidUpdateLock, masterId, uid)
requestId := GetDistributedLockRequestId(requestIdPrefix)
balanceLockOk := TryGetDistributedLock(balanceLockKey, requestId, true)
if !balanceLockOk {
return nil, errors.New("系统繁忙,请稍后再试")
}

cb = func() {
_, _ = ReleaseDistributedLock(balanceLockKey, requestId)
}

return cb, nil
}

Laddar…
Avbryt
Spara