bilibili-backup/app/admin/main/growup/service/offlineactivity.go
2019-04-22 02:59:20 +00:00

780 lines
23 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"context"
"encoding/json"
"fmt"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
"go-common/app/admin/main/growup/conf"
"go-common/app/admin/main/growup/dao"
"go-common/app/admin/main/growup/dao/shell"
"go-common/app/admin/main/growup/model/offlineactivity"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/http/blademaster"
"io/ioutil"
"math/rand"
"sort"
"strconv"
"strings"
"time"
)
const (
uploadFilePath = "/data/uploadfiles/"
dateFmt = "20060102"
exportMaxCount = 1000
)
func (s *Service) offlineactivityCheckSendDbProc() {
defer func() {
if r := recover(); r != nil {
r = errors.WithStack(r.(error))
log.Error("write stat data Runtime error caught, try recover: %+v", r)
go s.offlineactivityCheckSendDbProc()
}
}()
var timer = time.NewTicker(60 * time.Second)
for {
select {
case <-timer.C:
case <-s.chanCheckDb:
}
s.checkResultNotSendingOrder()
}
}
func (s *Service) offlineactivityCheckShellOrderProc() {
defer func() {
if r := recover(); r != nil {
r = errors.WithStack(r.(error))
log.Error("write stat data Runtime error caught, try recover: %+v", r)
go s.offlineactivityCheckShellOrderProc()
}
}()
var timer = time.NewTimer(10 * time.Second)
var timerStart = false
var resultIds []int64
for {
select {
case orderID := <-s.chanCheckShellOrder:
var all = []*offlineactivity.OfflineActivityResult{orderID}
for {
drain:
for {
select {
case orderID := <-s.chanCheckShellOrder:
all = append(all, orderID)
if len(all) >= 100 {
break drain
}
default:
break drain
}
}
s.checkShellOrder(context.Background(), all)
if len(all) < 100 {
break
}
all = nil
}
case resultID := <-s.chanCheckActivity:
if !timerStart {
timer.Reset(10 * time.Second)
timerStart = true
}
resultIds = append(resultIds, resultID)
case <-timer.C:
// 去检查对应活动的状态
timerStart = false
var ids []int64
ids = append(ids, resultIds...)
s.checkActivityState(context.Background(), ids)
// clear map
resultIds = nil
}
}
}
//PreAddOfflineActivity just test add resutl
func (s *Service) PreAddOfflineActivity(ctx context.Context, arg *offlineactivity.AddActivityArg) (res *offlineactivity.PreAddActivityResult, err error) {
if arg == nil {
return
}
res = new(offlineactivity.PreAddActivityResult)
var bonusList = arg.BonusList
var hasBonus = false
res.BonusType = arg.BonusType
for _, bonus := range bonusList {
if bonus.TotalMoney <= 0 {
err = fmt.Errorf("bonus money < 0, money=%f", bonus.TotalMoney)
log.Error(err.Error())
return
}
res.TotalMoney += bonus.TotalMoney
if bonus.Filename != "" {
var fullpath = uploadFilePath + bonus.Filename
var filecontent []byte
filecontent, err = ioutil.ReadFile(fullpath)
if err != nil {
log.Error("read file fail, path=%s", fullpath)
return
}
bonus.Mids = string(filecontent)
bonus.MidList = dao.ParseMidsFromString(bonus.Mids)
bonus.MemberCount = int64(len(bonus.MidList))
if bonus.MemberCount == 0 {
log.Warn("no mid for this bonus, bonusmoney=%d", bonus.TotalMoney)
continue
}
} else {
bonus.MidList = dao.ParseMidsFromString(bonus.Mids)
bonus.MemberCount = int64(len(bonus.MidList))
if bonus.MemberCount == 0 {
log.Warn("no mid for this bonus, bonusmoney=%d", bonus.TotalMoney)
continue
}
}
res.MemberCount += bonus.MemberCount
hasBonus = true
}
// 如果一个bonus都没有则什么也不做
if !hasBonus {
log.Error("no bonus")
err = fmt.Errorf("没有获奖人员信息/解析文件失败(请上传csv/txt等文本格式文件)")
return
}
return
}
//AddOfflineActivity add offline activity
func (s *Service) AddOfflineActivity(ctx context.Context, arg *offlineactivity.AddActivityArg) (res *offlineactivity.AddActivityResult, err error) {
if arg == nil {
return
}
var bonusList = arg.BonusList
var hasBonus = false
var bc = ctx.(*blademaster.Context)
var cookie, _ = bc.Request.Cookie("username")
if cookie != nil {
arg.Creator = cookie.Value
}
for _, bonus := range bonusList {
if bonus.TotalMoney <= 0 {
err = fmt.Errorf("bonus money < 0, money=%f", bonus.TotalMoney)
log.Error(err.Error())
return
}
if bonus.Filename != "" {
var fullpath = uploadFilePath + bonus.Filename
var filecontent []byte
filecontent, err = ioutil.ReadFile(fullpath)
if err != nil {
log.Error("read file fail, path=%s", fullpath)
return
}
bonus.Mids = string(filecontent)
} else {
bonus.MidList = dao.ParseMidsFromString(bonus.Mids)
bonus.MemberCount = int64(len(bonus.MidList))
if bonus.MemberCount == 0 {
log.Warn("no mid for this bonus, bonusmoney=%d", bonus.TotalMoney)
continue
}
}
hasBonus = true
}
// 如果一个bonus都没有则什么也不做
if !hasBonus {
log.Error("no bonus")
err = fmt.Errorf("no bonus info")
return
}
go func() {
err = s.dao.OfflineActivityAddActivity(context.Background(), arg)
if err != nil {
log.Error("offline add fail")
return
}
log.Info("offline add ok")
if len(s.chanCheckDb) == 0 {
s.chanCheckDb <- 1
}
}()
return
}
//ShellCallback shell callback
func (s *Service) ShellCallback(ctx context.Context, arg *shell.OrderCallbackParam) (err error) {
if arg == nil {
log.Error("arg is nil")
return ecode.RequestErr
}
var result = shell.OrderCallbackJSON{}
if err = json.Unmarshal([]byte(arg.MsgContent), &result); err != nil {
log.Error("msgid=%s, unmarshal msg content fail, err=%s, msgcontent=%s", err, arg.MsgID, string(arg.MsgContent))
return
}
log.Info("order id=%s, handle shell callback, status=%s", result.ThirdOrderNo, result.Status)
if result.CustomerID != conf.Conf.ShellConf.CustomID {
log.Error("order id=%s, customerid not the same, give=%s, expect=%s", result.ThirdOrderNo, result.CustomerID, conf.Conf.ShellConf.CustomID)
return
}
orderInfo, err := s.dao.ShellCallbackUpdate(ctx, &result, arg.MsgID)
if err == nil {
s.queueToUpdateActivityState(orderInfo.ResultID)
}
return
}
//OfflineActivityQueryActivity query activity
func (s *Service) OfflineActivityQueryActivity(ctx context.Context, arg *offlineactivity.QueryActivityByIDArg) (res *offlineactivity.QueryActivityResult, err error) {
var db = s.dao.OfflineActivityGetDB()
// make sure it's valid
var limit, offset = arg.CheckPageValidation()
if arg.ExportFormat() != "" {
limit = exportMaxCount
}
var now = time.Now()
if arg.FromDate == "" {
arg.FromDate = now.AddDate(0, -1, 0).Format(dateFmt)
}
if arg.ToDate == "" {
arg.ToDate = now.Format(dateFmt)
}
// 1.查询 OfflineActivityInfo 与 OfflineActivityBonus 数据,然后聚合
var activityList []*offlineactivity.OfflineActivityInfo
var total = 1
if arg.ID != 0 {
if err = db.Where("id=?", arg.ID).Find(&activityList).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("fail to get from db, err=%s", err)
return
}
total = len(activityList)
} else {
if arg.FromDate == "" || arg.ToDate == "" {
log.Error("request error, fromdate or todate is nill")
err = ecode.RequestErr
return
}
var todate, e = time.Parse(dateFmt, arg.ToDate)
err = e
if err != nil {
log.Error("todate format err, todate=%s, err=%s", arg.ToDate, err)
return
}
todate = todate.AddDate(0, 0, 1)
var todatestr = todate.Format(dateFmt)
if err = db.Table(offlineactivity.TableOfflineActivityInfo).Where("ctime>=? and ctime<=?", arg.FromDate, todatestr).Count(&total).Error; err != nil {
log.Error("fail to get from db, err=%s", err)
return
}
if err = db.Where("ctime>=? and ctime<=?", arg.FromDate, todatestr).Order("id desc").Offset(offset).Limit(limit).Find(&activityList).Error; err != nil {
log.Error("fail to get from db, err=%s", err)
return
}
}
var activityIDs []int64
for _, v := range activityList {
activityIDs = append(activityIDs, v.ID)
}
if len(activityList) == 0 {
log.Warn("0 activity list")
return
}
// 查询bonus info
var bonusList []*offlineactivity.OfflineActivityBonus
if err = db.Where("activity_id in (?)", activityIDs).Find(&bonusList).Error; err != nil {
log.Error("fail to get from db, err=%s", err)
return
}
res = new(offlineactivity.QueryActivityResult)
var activityMap = make(map[int64]*offlineactivity.QueryActivityInfo, len(activityList))
for _, v := range activityList {
var info = new(offlineactivity.QueryActivityInfo)
info.CopyFromActivityDB(v)
activityMap[info.ID] = info
}
for _, v := range bonusList {
var info, _ = activityMap[v.ActivityID]
if info == nil {
continue
}
info.TotalMoney += offlineactivity.GetMoneyFromDb(v.TotalMoney)
info.MemberCount += v.MemberCount
}
for _, v := range activityList {
if info, ok := activityMap[v.ID]; ok {
res.Result = append(res.Result, info)
}
}
res.PageResult = arg.ToPageResult(total)
return
}
// OfflineActivityQueryUpBonusSummary query up bonus info
func (s *Service) OfflineActivityQueryUpBonusSummary(ctx context.Context, arg *offlineactivity.QueryUpBonusByMidArg) (res *offlineactivity.QueryUpBonusByMidResult, err error) {
var limit, offset = arg.CheckPageValidation()
if arg.ExportFormat() != "" {
limit = exportMaxCount
}
// 查询所有的 result for mid
// 区分已结算、未结算
// 已结算= 成功, 未结算= 初始、发送、等待
upResult, total, err := s.dao.OfflineActivityGetUpBonusResult(ctx, true, limit, offset, "mid=?", arg.Mid)
if err != nil {
log.Error("get from up result fail, err=%s", err)
return
}
res = new(offlineactivity.QueryUpBonusByMidResult)
res.PageResult = arg.ToPageResult(total)
var bonusMap = make(map[int64]*offlineactivity.UpSummaryBonusInfo)
for _, v := range upResult {
var bonusInfo, ok = bonusMap[v.Mid]
if !ok {
bonusInfo = &offlineactivity.UpSummaryBonusInfo{
Mid: v.Mid,
}
bonusMap[v.Mid] = bonusInfo
}
switch offlineactivity.ActivityState(v.State) {
case offlineactivity.ActivityStateSucess:
bonusInfo.BilledMoney += offlineactivity.GetMoneyFromDb(v.BonusMoney)
if bonusInfo.TmpBillTime < v.MTime {
bonusInfo.TmpBillTime = v.MTime
}
case offlineactivity.ActivityStateInit, offlineactivity.ActivityStateSending, offlineactivity.ActivityStateWaitResult:
bonusInfo.UnbilledMoney += offlineactivity.GetMoneyFromDb(v.BonusMoney)
}
}
for _, v := range bonusMap {
v.Finish()
res.Result = append(res.Result, v)
}
return
}
//OfflineActivityQueryUpBonusByActivity get bonus info group by activity
func (s *Service) OfflineActivityQueryUpBonusByActivity(ctx context.Context, arg *offlineactivity.QueryUpBonusByMidArg) (res *offlineactivity.QueryUpBonusByActivityResult, err error) {
var limit, offset = arg.CheckPageValidation()
if arg.ExportFormat() != "" {
limit = exportMaxCount
}
// 查询所有的 result for mid
// 区分已结算、未结算
// 已结算= 成功, 未结算= 初始、发送、等待
upResult, total, err := s.dao.OfflineActivityGetUpBonusByActivityResult(ctx, limit, offset, arg.Mid)
if err != nil {
log.Error("get from up result fail, err=%s", err)
return
}
res = new(offlineactivity.QueryUpBonusByActivityResult)
res.PageResult = arg.ToPageResult(total)
// [mid][activity_id], 按Activity做聚合
var bonusMap = make(map[int64]map[int64]*offlineactivity.UpSummaryBonusInfo)
for _, v := range upResult {
var bonusActivityMap, ok = bonusMap[v.Mid]
if !ok {
bonusActivityMap = make(map[int64]*offlineactivity.UpSummaryBonusInfo)
bonusMap[v.Mid] = bonusActivityMap
}
bonusInfo, ok := bonusActivityMap[v.ActivityID]
if !ok {
bonusInfo = &offlineactivity.UpSummaryBonusInfo{
Mid: v.Mid,
ActivityID: v.ActivityID,
}
bonusActivityMap[v.ActivityID] = bonusInfo
}
var bonusMoney = offlineactivity.GetMoneyFromDb(v.BonusMoney)
switch offlineactivity.ActivityState(v.State) {
case offlineactivity.ActivityStateSucess:
bonusInfo.BilledMoney += bonusMoney
if bonusInfo.TmpBillTime < v.MTime {
bonusInfo.TmpBillTime = v.MTime
}
bonusInfo.TotalBonusMoney += bonusMoney
case offlineactivity.ActivityStateInit, offlineactivity.ActivityStateSending, offlineactivity.ActivityStateWaitResult:
bonusInfo.UnbilledMoney += bonusMoney
bonusInfo.TotalBonusMoney += bonusMoney
}
}
for _, activityMap := range bonusMap {
for _, v := range activityMap {
v.Finish()
res.Result = append(res.Result, v)
}
}
return
}
//OfflineActivityQueryActivityByMonth activity by month
func (s *Service) OfflineActivityQueryActivityByMonth(ctx context.Context, arg *offlineactivity.QueryActvityMonthArg) (res *offlineactivity.QueryActivityMonthResult, err error) {
var db = s.dao.OfflineActivityGetDB()
var bonusInfo []*offlineactivity.OfflineActivityBonus
var limit, offset = 100, 0
var lastCount = limit
for limit == lastCount {
var bonusInfoTmp []*offlineactivity.OfflineActivityBonus
if err = db.Find(&bonusInfoTmp).Error; err != nil {
log.Error("get from db fail, err=%s", err)
return
}
bonusInfo = append(bonusInfo, bonusInfoTmp...)
lastCount = len(bonusInfoTmp)
offset += lastCount
}
var now = time.Now()
var dateStr = now.Format(dateFmt)
var monthDataMap = make(map[string]*offlineactivity.ActivityMonthInfo)
for _, v := range bonusInfo {
var date = v.CTime.Time().Format("200601")
var monthData, ok = monthDataMap[date]
if !ok {
monthData = &offlineactivity.ActivityMonthInfo{
CreateTime: date,
}
monthDataMap[date] = monthData
monthData.GenerateDay = dateStr
}
monthData.AddBonus(v)
}
var monthInfoS []*offlineactivity.ActivityMonthInfo
for _, v := range monthDataMap {
monthInfoS = append(monthInfoS, v)
v.Finish()
}
sort.Slice(monthInfoS, func(i, j int) bool {
return monthInfoS[i].CreateTime > monthInfoS[j].CreateTime
})
var lastIndex = len(monthInfoS) - 1
if lastIndex >= 0 {
monthInfoS[lastIndex].TotalMoneyAccumulate = monthInfoS[lastIndex].TotalBonusMoneyMonth
}
for i := len(monthInfoS) - 1; i > 0; i-- {
monthInfoS[i-1].TotalMoneyAccumulate = monthInfoS[i].TotalMoneyAccumulate + monthInfoS[i-1].TotalBonusMoneyMonth
}
res = new(offlineactivity.QueryActivityMonthResult)
res.Result = monthInfoS
return
}
/*
查询对应的activity_result表state=0 && bonus_type = 1 && ctime <= 86400
for each item state=0 and activity_id = ? limit 100
if 没有order_id
生成order_id写入数据库, result表与shellorder表
写入成功,记录等待发送
if 有order id
// 说明已经经历过上一步但是发送失败那么加入到检查order id的队列
记录等待发送
批量进行发送-> shell
if 发送成功
更新所有的item状态 -> 1
else if 失败:
错误码是8002999997->order_id有重复
更新所有的item order id = '',等待重试
*/
func (s *Service) checkResultNotSendingOrder() {
var db, err = gorm.Open("mysql", conf.Conf.ORM.Growup.DSN)
if err != nil {
log.Error("open db fail, dsn=%s", conf.Conf.ORM.Growup.DSN)
return
}
defer db.Close()
db.LogMode(false)
// 查询对应的activity_result表state=0 && bonus_type = 1 && diff(ctime) <= 86400
var minTime = time.Now().Add(-time.Hour * 24)
var limit = 100
var lastCount = limit
var lastID int64
for limit == lastCount {
var needSendResult = make([]*offlineactivity.OfflineActivityResult, limit)
if err = db.Select("id, mid, bonus_money, order_id, activity_id, bonus_id").
Where("state=0 and bonus_type=1 and ctime>=? and id>?", minTime, lastID).Limit(limit).
Find(&needSendResult).Error; err != nil {
log.Error("get result fail, err=%s", err)
return
}
lastCount = len(needSendResult)
var now = time.Now()
var sendRequestResult []*offlineactivity.OfflineActivityResult
for _, activityResult := range needSendResult {
if activityResult.ID > lastID {
lastID = activityResult.ID
}
// if 没有order_id
if activityResult.OrderID == "" {
activityResult.OrderID = generateOrderID(activityResult, now)
if err = s.offlineActivityUpdateResultForSend(db, activityResult); err != nil {
log.Warn("fail update result, err=%s, will retry next time", err)
continue
}
log.Info("update result ok, mid=%d, activity_id=%d, order_id=%s", activityResult.Mid, activityResult.ActivityID, activityResult.OrderID)
sendRequestResult = append(sendRequestResult, activityResult)
} else {
// if 有order id
go func(res *offlineactivity.OfflineActivityResult) {
s.chanCheckShellOrder <- res
log.Info("order has id, need to check, order id=%s, mid=%d, activityid=%d, bonusid=%d",
res.OrderID, res.Mid, res.ActivityID, res.BonusID)
}(activityResult)
}
if len(sendRequestResult) >= 10 {
err = s.sendRequestAndUpdate(db, sendRequestResult)
if err != nil {
log.Error("send request err, err=%s", err)
} else {
log.Info("send to shell ok, length=%d", len(sendRequestResult))
}
sendRequestResult = nil
}
}
if len(sendRequestResult) > 0 {
err = s.sendRequestAndUpdate(db, sendRequestResult)
if err != nil {
log.Error("send request err, err=%s", err)
} else {
log.Info("send to shell ok, length=%d", len(sendRequestResult))
}
}
}
}
func (s *Service) sendRequestAndUpdate(db *gorm.DB, sendRequestResult []*offlineactivity.OfflineActivityResult) (err error) {
switch {
default:
var res *shell.OrderResponse
if res, err = s.sendShellOrder(context.Background(), sendRequestResult); err != nil || res == nil {
if err != nil {
log.Error("fail to send to shell order, err=%s", err)
}
break
}
var ids []int64
for _, v := range sendRequestResult {
ids = append(ids, v.ID)
}
// 需要区分是否返回 错误码是8002999997,表示有重复
if res.Errno == 8002999997 {
log.Error("fail to send request, err=%d, msg=%s重复", res.Errno, res.Msg)
// 将order id 更新为""
if err = db.Table(offlineactivity.TableOfflineActivityResult).Where("id in (?)", ids).
Update("order_id=''").Error; err != nil {
log.Error("fail to update order id for duplicate order, id=%v", ids)
break
}
return
} else if res.Errno != 0 {
log.Error("fail to send request, err=%d, msg=%s", res.Errno, res.Msg)
return
}
if err = db.Table(offlineactivity.TableOfflineActivityResult).Where("id in (?)", ids).
Update("state", offlineactivity.ActivityStateWaitResult).Error; err != nil {
log.Error("fail to update state, id=%v", ids)
break
}
log.Info("send request to shell order")
}
return
}
func generateOrderID(result *offlineactivity.OfflineActivityResult, tm time.Time) string {
var order = fmt.Sprintf("%s%04d%010d%04d", time.Now().Format("20060102150405"), (result.ActivityID*100+result.BonusID)%10000, result.Mid, rand.Int()%10000)
if len(order) > 32 {
order = order[:32]
}
return order
}
func (s *Service) offlineActivityUpdateResultForSend(db *gorm.DB, result *offlineactivity.OfflineActivityResult) (err error) {
if result == nil {
err = fmt.Errorf("nil pointer")
return
}
var tx = db.Begin()
defer func() {
if r := recover(); r != nil || err != nil {
tx.Rollback()
}
}()
// create
var query = tx.Select("order_id").Where("order_id=''").Save(result)
err = db.Error
if err != nil {
log.Error("err save offline result, err=%s", err)
return
}
if query.RowsAffected == 0 {
var msg = fmt.Sprintf("update order fail, it may already be sent, result_id=%d, mid=%d, activity_id=%d", result.ID, result.Mid, result.ActivityID)
log.Warn(msg)
err = fmt.Errorf(msg)
return
}
var shellOrder = offlineactivity.OfflineActivityShellOrder{
OrderID: result.OrderID,
ResultID: result.ID,
}
if err = tx.Save(&shellOrder).Error; err != nil {
log.Error("err insert offline shell order, err=%s", err)
return
}
return tx.Commit().Error
}
func (s *Service) sendShellOrder(ctx context.Context, needSendResult []*offlineactivity.OfflineActivityResult) (res *shell.OrderResponse, err error) {
if len(needSendResult) == 0 {
log.Warn("no need to send, len=0")
return
}
var nowtime = time.Now()
var now = time.Now().UnixNano() / int64(time.Millisecond)
var request = shell.OrderRequest{
ProductName: "活动奖励",
NotifyURL: conf.Conf.ShellConf.CallbackURL,
Rate: "1.0",
SignType: "MD5",
Timestamp: strconv.Itoa(int(beginOfDay(nowtime).UnixNano() / int64(time.Millisecond))),
}
for _, item := range needSendResult {
var money = fmt.Sprintf("%0.2f", float64(offlineactivity.GetMoneyFromDb(item.BonusMoney)))
var orderInfo = shell.OrderInfo{
Mid: item.Mid,
Brokerage: money,
ThirdCoin: money,
ThirdOrderNo: item.OrderID,
ThirdCtime: strconv.Itoa(int(now)),
}
request.Data = append(request.Data, orderInfo)
}
//log.Info("request=%+v", request)
res, err = s.shellClient.SendOrderRequest(ctx, &request)
if err != nil || res == nil {
log.Error("fail to send request, err=%s", err)
} else {
log.Info("send shell request, msg=%s, errno=%d", res.Msg, res.Errno)
}
return
}
/*
2.定单查询 - 查询定单的状态,
for each state=0 and 存在order id
去贝壳查询该定单状态
if 定单不存在
设置order id='', state=0 // 清除定单,等待重新发送
else if 定单成功
设置state=10
else if 定单失败
设置state=11
*/
// 最大不要超过100个订单
func (s *Service) checkShellOrder(ctx context.Context, values []*offlineactivity.OfflineActivityResult) (err error) {
if len(values) == 0 {
err = fmt.Errorf("values slice 0 length")
return
}
var orderMap = make(map[string]*offlineactivity.OfflineActivityResult, len(values))
var orderIds []string
for i, v := range values {
if i > 99 {
break
}
orderIds = append(orderIds, v.OrderID)
orderMap[v.OrderID] = v
}
var orderIDString = strings.Join(orderIds, ",")
var orderCheckRequest = shell.OrderCheckRequest{
Timestamp: time.Now().UnixNano() / int64(time.Millisecond),
ThirdOrderNos: orderIDString,
}
res, err := s.shellClient.SendCheckOrderRequest(ctx, &orderCheckRequest)
if err != nil {
log.Error("fail to check order, order id=%s, err=%s", orderIDString, err)
return
}
// 区分找到的订单和未找到的订单
// 订单找到,更新状态
for _, v := range res.Orders {
log.Info("order find, orderid=%s, current status=%s", v.ThirdOrderNo, v.Status)
// 删除已找到的订单
delete(orderMap, v.ThirdOrderNo)
var resultJSON = shell.OrderCallbackJSON{
Status: v.Status,
ThirdOrderNo: v.ThirdOrderNo,
Mid: v.Mid,
}
// 更新订单结果
var orderInfo, e = s.dao.ShellCallbackUpdate(ctx, &resultJSON, "checkorder")
if e == nil {
s.queueToUpdateActivityState(orderInfo.ID)
}
}
// 订单未找到,重新发送请求
var needSendRequest []*offlineactivity.OfflineActivityResult
for _, v := range orderMap {
needSendRequest = append(needSendRequest, v)
}
err = s.sendRequestAndUpdate(s.dao.OfflineActivityGetDB(), needSendRequest)
if err != nil {
log.Error("send order request fail, err=%s", err)
return
}
return
}
func (s *Service) checkActivityState(ctx context.Context, values []int64) (err error) {
if len(values) == 0 {
log.Warn("no activity need to check")
return
}
//
upResult, err := s.dao.OfflineActivityGetUpBonusResultSelect(ctx, "distinct(activity_id) as activity_id", "id in (?)", values)
for _, v := range upResult {
var _, e = s.dao.UpdateActivityState(ctx, v.ActivityID)
if e != nil {
log.Error("err when update activity state, err=%s", e)
}
}
return
}
func (s *Service) queueToUpdateActivityState(resultID int64) {
s.chanCheckActivity <- resultID
}
func beginOfDay(t time.Time) time.Time {
year, month, day := t.Date()
return time.Date(year, month, day, 0, 0, 0, 0, t.Location())
}