feat: 任务改用采集采购独立序号 (#172)
This commit is contained in:
@@ -5,11 +5,71 @@ import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"cmautobuy/admin/model"
|
||||
)
|
||||
|
||||
const (
|
||||
collectTaskIDPrefix = "cj"
|
||||
purchaseTaskIDPrefix = "cg"
|
||||
)
|
||||
|
||||
// NextTaskID 在当前事务内分配下一条任务业务单号。
|
||||
//
|
||||
// 采集和采购分别递增;更新序列表后再读取同一行,依赖事务行锁保证并发不重复。
|
||||
// 调用方必须把分配和任务 INSERT 放在同一个事务里,失败回滚时不会消耗序号。
|
||||
func NextTaskID(q Execer, taskType model.TaskType) (string, error) {
|
||||
prefix, ok := taskIDPrefix(taskType)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("不支持为任务类型 %q 分配编号", taskType)
|
||||
}
|
||||
result, err := q.Exec(`UPDATE task_sequences SET current_value=current_value+1 WHERE task_type=?`, taskType)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("递增 %s 任务序号失败: %w", taskType, err)
|
||||
}
|
||||
affected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("读取 %s 任务序号更新结果失败: %w", taskType, err)
|
||||
}
|
||||
if affected != 1 {
|
||||
return "", fmt.Errorf("%s 任务序列表缺失,请先完成数据库迁移", taskType)
|
||||
}
|
||||
var number int64
|
||||
if err := q.QueryRow(`SELECT current_value FROM task_sequences WHERE task_type=?`, taskType).Scan(&number); err != nil {
|
||||
return "", fmt.Errorf("读取 %s 任务序号失败: %w", taskType, err)
|
||||
}
|
||||
if number <= 0 {
|
||||
return "", fmt.Errorf("%s 任务序号不正确: %d", taskType, number)
|
||||
}
|
||||
return prefix + strconv.FormatInt(number, 10), nil
|
||||
}
|
||||
|
||||
func taskIDPrefix(taskType model.TaskType) (string, bool) {
|
||||
switch taskType {
|
||||
case model.TaskCollect:
|
||||
return collectTaskIDPrefix, true
|
||||
case model.TaskPurchase:
|
||||
return purchaseTaskIDPrefix, true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
func parseTaskIDNumber(taskType model.TaskType, taskID string) (int64, bool) {
|
||||
prefix, ok := taskIDPrefix(taskType)
|
||||
if !ok || !strings.HasPrefix(taskID, prefix) || len(taskID) == len(prefix) {
|
||||
return 0, false
|
||||
}
|
||||
numberText := taskID[len(prefix):]
|
||||
if numberText[0] == '0' {
|
||||
return 0, false
|
||||
}
|
||||
number, err := strconv.ParseInt(numberText, 10, 64)
|
||||
return number, err == nil && number > 0
|
||||
}
|
||||
|
||||
// ClaimNextTask 为指定客户端领取一个任务。
|
||||
//
|
||||
// 没有可领的任务时返回 (nil, nil) —— 调用方据此返回 204。
|
||||
|
||||
Reference in New Issue
Block a user