feat: 迁移 Admin Repository 到 MySQL 8 (#79)
This commit is contained in:
+20
-17
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user