feat: 迁移 Admin Repository 到 MySQL 8 (#79)

This commit is contained in:
chengma
2026-08-10 02:21:31 +08:00
parent 05793e48b3
commit 13cfced80d
29 changed files with 390 additions and 240 deletions
+20 -17
View File
@@ -55,14 +55,14 @@ func UpsertClient(q Execer, c model.Client, explicit bool) error {
pdd_package, capabilities,
last_seen_at, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(client_id) DO UPDATE SET
ON DUPLICATE KEY UPDATE
name = CASE WHEN ? THEN ? ELSE clients.name END,
device_address = excluded.device_address,
platform = excluded.platform,
pdd_package = excluded.pdd_package,
capabilities = excluded.capabilities,
last_seen_at = excluded.last_seen_at,
updated_at = excluded.updated_at`,
device_address = VALUES(device_address),
platform = VALUES(platform),
pdd_package = VALUES(pdd_package),
capabilities = VALUES(capabilities),
last_seen_at = VALUES(last_seen_at),
updated_at = VALUES(updated_at)`,
c.ClientID, insertName, c.DeviceAddress, c.Platform,
c.PddPackage, c.Capabilities, now, now, now,
updateName, name)
@@ -155,8 +155,11 @@ func listClientsForUserPage(db *sql.DB, keyword, visibleUserID string, limit, of
query := `SELECT c.client_id, c.name, c.device_address, c.platform, c.pdd_package,
c.capabilities, c.last_seen_at, c.created_at, c.updated_at,
a.user_id, u.username` + clientListFrom + where +
` ORDER BY c.last_seen_at DESC, c.client_id LIMIT ? OFFSET ?`
args = append(args, limit, offset)
` ORDER BY c.last_seen_at DESC, c.client_id`
if limit >= 0 {
query += ` LIMIT ? OFFSET ?`
args = append(args, limit, offset)
}
rows, err := db.Query(query, args...)
if err != nil {
@@ -216,16 +219,16 @@ func ListClientsForUserPage(db *sql.DB, keyword, visibleUserID string, limit, of
}
// CountOnlineClientsForUser 统计同一筛选和权限范围内的在线客户端。
// julianday 解析失败会得到 NULL,自然按离线处理,与 model.Client.IsOnline 一致。
// last_seen_at 统一以 UTC RFC3339 保存,固定宽度字符串的字典序就是时间顺序。
func CountOnlineClientsForUser(db *sql.DB, keyword, visibleUserID, cutoffISO string) (int, error) {
where, args := clientListFilter(keyword, visibleUserID)
args = append(args, cutoffISO)
var online int
query := `SELECT COUNT(*)` + clientListFrom + where
if where == "" {
query += ` WHERE julianday(c.last_seen_at) > julianday(?)`
query += ` WHERE c.last_seen_at > ?`
} else {
query += ` AND julianday(c.last_seen_at) > julianday(?)`
query += ` AND c.last_seen_at > ?`
}
if err := db.QueryRow(query, args...).Scan(&online); err != nil {
return 0, fmt.Errorf("统计在线客户端失败: %w", err)
@@ -262,13 +265,13 @@ func AssignClient(db *sql.DB, assignment model.ClientUserAssignment) (bool, bool
return false, false, fmt.Errorf("开始绑定客户端事务失败: %w", err)
}
defer tx.Rollback()
var exists int
if err := tx.QueryRow(`SELECT COUNT(*) FROM clients WHERE client_id = ?`, assignment.ClientID).Scan(&exists); err != nil {
var lockedClientID string
if err := tx.QueryRow(`SELECT client_id FROM clients WHERE client_id = ? FOR UPDATE`, assignment.ClientID).Scan(&lockedClientID); errors.Is(err, sql.ErrNoRows) {
return false, false, ErrClientNotFound
} else if err != nil {
return false, false, fmt.Errorf("检查客户端失败: %w", err)
}
if exists == 0 {
return false, false, ErrClientNotFound
}
var exists int
if err := tx.QueryRow(`SELECT COUNT(*) FROM users WHERE user_id = ? AND role = ? AND status = ?`,
assignment.UserID, model.RolePurchaser, model.UserActive).Scan(&exists); err != nil {
return false, false, fmt.Errorf("检查采购员失败: %w", err)