Merge branch 'feat-cjy-taskBench' into dev

This commit is contained in:
cjy 2025-10-22 12:46:45 +08:00
commit 947651ea3f
2 changed files with 90 additions and 58 deletions

View File

@ -41,31 +41,34 @@ func RunInitialTaskBalanceSync() error {
return nil
}
// 直接获取所有BundleBalance记录进行同步不再依赖GetValidArtistList的严格过滤
var bundleBalances []model.BundleBalance
if err := app.ModuleClients.BundleDB.Find(&bundleBalances).Error; err != nil {
// 获取当前有效(未过期且已支付)的艺人及其最新订单
validArtists, err := GetValidArtistList()
if err != nil {
return err
}
if len(bundleBalances) == 0 {
_ = app.ModuleClients.TaskBenchDB.Create(&model.TaskSyncStatus{
SyncKey: model.InitialSyncKey,
ExecutedAt: time.Now(),
Remark: "skipped: no bundle_balance records found",
}).Error
fmt.Println(validArtists)
if len(validArtists) == 0 {
// 不写入已执行标记,留待后续有数据时再次执行
fmt.Println("无数据更新")
return nil
}
// 构造待插入的 TaskBalance 列表
tasks := make([]model.TaskBalance, 0, len(bundleBalances))
skippedCount := 0
tasks := make([]model.TaskBalance, 0, len(validArtists))
for _, a := range validArtists {
// 根据 user_id + order_uuid 获取 BundleBalance 明细
var bb model.BundleBalance
if err := app.ModuleClients.BundleDB.Where("user_id = ? AND order_uuid = ?", a.UserID, a.OrderUUID).First(&bb).Error; err != nil {
// 若未查到则跳过该条
if err == gorm.ErrRecordNotFound {
continue
}
return err
}
for _, bb := range bundleBalances {
subNum, telNum, err := fetchIdentityForBundle(&bb)
if err != nil {
// 无法获取身份信息则跳过该条,但记录跳过数量
fmt.Println("跳过 BundleBalance ID:", bb.ID, "错误:", err)
skippedCount++
// 无法获取身份信息则跳过该条
continue
}
@ -82,7 +85,7 @@ func RunInitialTaskBalanceSync() error {
tasks = append(tasks, tb)
}
// 原子写入:插入 TaskBalance + 插入标记
// 原子写入:插入 TaskBalance + 插入标记(确保有插入才写标记)
tx := app.ModuleClients.TaskBenchDB.Begin()
defer func() {
if r := recover(); r != nil {
@ -90,23 +93,20 @@ func RunInitialTaskBalanceSync() error {
}
}()
if len(tasks) > 0 {
if err := tx.Create(&tasks).Error; err != nil {
tx.Rollback()
return err
}
if len(tasks) == 0 {
// 没有可插入的数据,不写标记,直接返回
tx.Rollback()
return nil
}
// 记录同步结果
remark := "initial sync executed"
if skippedCount > 0 {
remark = fmt.Sprintf("initial sync executed with %d records skipped due to missing identity info", skippedCount)
if err := tx.Create(&tasks).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Create(&model.TaskSyncStatus{
SyncKey: model.InitialSyncKey,
ExecutedAt: time.Now(),
Remark: remark,
Remark: "initial sync executed",
}).Error; err != nil {
tx.Rollback()
return err
@ -159,33 +159,27 @@ func SyncTaskBalanceFromBundleBalance(bb model.BundleBalance) error {
// fetchIdentityForBundle 根据 BundleBalance 拿到 sub_num 与 tel_num
func fetchIdentityForBundle(bb *model.BundleBalance) (string, string, error) {
// tel_num 来自 micro-account.user
var telNum string
type userRow struct {
Tel string
}
var ur userRow
if err := app.ModuleClients.BundleDB.Table("`micro-account`.`user`").Unscoped().
Select("tel_num").Where("id = ?", bb.UserId).Scan(&telNum).Error; err != nil {
Select("tel_num AS tel").Where("id = ?", bb.UserId).Limit(1).Scan(&ur).Error; err != nil {
return "", "", err
}
// customer_num 来自 bundle_order_records按 order_uuid
// 添加容错机制如果order_uuid为空或查询失败使用user_id作为备用方案
var customerNum string
if bb.OrderUUID != "" {
type orderRow struct {
Customer string `gorm:"column:customer_num"`
}
var or orderRow
if err := app.ModuleClients.BundleDB.Table("bundle_order_records").
Select("customer_num").Where("uuid = ?", bb.OrderUUID).First(&or).Error; err != nil {
// 如果查询失败如记录不存在使用user_id作为备用customer_num
customerNum = fmt.Sprintf("user_%d", bb.UserId)
} else {
customerNum = or.Customer
}
} else {
// 如果order_uuid为空使用user_id作为备用customer_num
customerNum = fmt.Sprintf("user_%d", bb.UserId)
type orderRow struct {
Customer string
}
return customerNum, telNum, nil
var or orderRow
if bb.OrderUUID == "" {
return "", "", errors.New("bundle order_uuid missing")
}
if err := app.ModuleClients.BundleDB.Table("bundle_order_records").
Select("customer_num AS customer").Where("uuid = ?", bb.OrderUUID).Limit(1).Scan(&or).Error; err != nil {
return "", "", err
}
return or.Customer, ur.Tel, nil
}
// UpdateTaskBalance 每月批量更新任务余额

View File

@ -1,10 +1,12 @@
package dao
import (
"fmt"
"micro-bundle/internal/model"
"micro-bundle/pkg/app"
commonErr "micro-bundle/pkg/err"
"time"
"strings"
"github.com/google/uuid"
"gorm.io/gorm"
@ -1071,7 +1073,7 @@ func GetTaskAssignRecordsList(req *TaskAssignRecordsQueryRequest) ([]*model.Task
}
// GetValidArtistList 查询套餐状态为有效中的艺人数据列表
// 根据BundleOrderRecords表查询过期时间大于当前时间且状态为已支付的艺人详细信息
// 根据BundleOrderRecords表查询过期时间大于当前时间且状态为已支付,同时已激活的艺人详细信息
func GetValidArtistList() ([]ValidArtistInfo, error) {
// 构建子查询,获取每个用户的最新订单记录
subQuery := app.ModuleClients.BundleDB.Table("bundle_order_records as bor1").
@ -1083,7 +1085,7 @@ func GetValidArtistList() ([]ValidArtistInfo, error) {
) bor2 ON bor1.customer_id = bor2.customer_id AND bor1.created_at = bor2.max_created_time`)
// 主查询,关联用户表和实名信息表
session := app.ModuleClients.BundleDB.Table("`micro-account`.`user` AS u").
session := app.ModuleClients.BundleDB.Table("`micro-account`.`user` AS u").Unscoped().
Select(`u.id as user_id, bor.customer_num, rn.name as user_name,
u.tel_num as user_phone_number, bor.bundle_name, bor.expiration_time,
bor.status, bor.uuid as order_uuid,
@ -1098,11 +1100,14 @@ func GetValidArtistList() ([]ValidArtistInfo, error) {
bb.expansion_packs_number`).
Joins("LEFT JOIN `micro-account`.real_name rn ON u.real_name_id = rn.id").
Joins("LEFT JOIN (?) as bor ON bor.customer_id = u.id", subQuery).
Joins("LEFT JOIN bundle_balance bb ON u.id = bb.user_id AND bb.order_uuid = bor.uuid").
Joins("LEFT JOIN fiee_bundle.bundle_balance bb ON u.id = bb.user_id AND bb.order_uuid = bor.uuid").
Joins("LEFT JOIN bundle_activate bc ON bc.user_id = u.id").
Where("rn.name IS NOT NULL").
Where("u.deleted_at = 0").
Where("bor.expiration_time > ?", time.Now().Format("2006-01-02 15:04:05")).
Where("bor.status = ?", 2). // 2:已签已支付
Where("bor.deleted_at IS NULL").
Where("bb.expired_at > ?", time.Now()).
Where("bc.activate = ?", 2).
Where("bb.month = ?", time.Now().Format("2006-01")).
Order("bor.expiration_time desc")
var data []ValidArtistInfo
@ -1111,6 +1116,7 @@ func GetValidArtistList() ([]ValidArtistInfo, error) {
return nil, commonErr.ReturnError(err, "查询有效艺人失败", "查询有效艺人失败: ")
}
fmt.Println(data)
return data, nil
}
@ -1182,11 +1188,14 @@ func GetPendingTaskList(req *TaskQueryRequest, validArtist []ValidArtistInfo) ([
return nil, 0, commonErr.ReturnError(err, "查询待指派任务记录失败", "查询待指派任务记录失败: ")
}
// 统计总数(分页前)
total := int64(len(tmList))
// 构建已存在的 sub_num 集合,用于补充缺失的有效艺人
existingSubNums := make(map[string]struct{}, len(tmList))
for _, t := range tmList {
existingSubNums[t.SubNum] = struct{}{}
}
// 映射为响应结构(基础字段)
resp := make([]*TaskQueryResponse, 0, len(tmList))
resp := make([]*TaskQueryResponse, 0, len(tmList)+len(validArtist))
for _, t := range tmList {
resp = append(resp, &TaskQueryResponse{
SubNum: t.SubNum,
@ -1197,5 +1206,34 @@ func GetPendingTaskList(req *TaskQueryRequest, validArtist []ValidArtistInfo) ([
})
}
// 追加:对在 TaskManagement 中不存在的有效艺人构建基础记录
for _, a := range validArtist {
if a.CustomerNum == "" {
continue
}
if _, ok := existingSubNums[a.CustomerNum]; ok {
continue
}
// 关键词过滤(与查询条件保持一致)
if req.Keyword != "" {
kw := strings.ToLower(req.Keyword)
if !(strings.Contains(strings.ToLower(a.CustomerNum), kw) ||
strings.Contains(strings.ToLower(a.UserPhoneNumber), kw) ||
strings.Contains(strings.ToLower(a.UserName), kw)) {
continue
}
}
resp = append(resp, &TaskQueryResponse{
SubNum: a.CustomerNum,
TelNum: a.UserPhoneNumber,
ArtistName: a.UserName,
LastTaskAssignee: "",
TaskAssigneeNum: "",
})
}
// 统计总数(分页前)
total := int64(len(resp))
return resp, total, nil
}