feat: 添加授权码状态计算逻辑并优化查询条件
This commit is contained in:
1 parent
b3ca90017b
commit
b8430c5b7d
3 files changed
+84
-24
No files matched your search
@@ -17,6 +17,36 @@ GET /api/v1/authorization-codes
|
||||
- `sort` - 排序字段 (created_at/updated_at/code)
|
||||
- `order` - 排序方向 (asc/desc)
|
||||
|
||||
**实现说明**
|
||||
|
||||
由于 `status` 是虚拟字段,需要在 SQL 查询中动态计算并筛选:
|
||||
|
||||
```sql
|
||||
-- 状态计算逻辑
|
||||
SELECT *,
|
||||
CASE
|
||||
WHEN is_locked = true THEN 'locked'
|
||||
WHEN end_date < NOW() THEN 'expired'
|
||||
WHEN start_date <= NOW() AND end_date >= NOW() THEN 'normal'
|
||||
ELSE 'expired'
|
||||
END AS status
|
||||
FROM authorization_codes
|
||||
WHERE 1=1
|
||||
-- status 参数筛选
|
||||
AND (
|
||||
(:status = 'locked' AND is_locked = true) OR
|
||||
(:status = 'expired' AND is_locked = false AND end_date < NOW()) OR
|
||||
(:status = 'normal' AND is_locked = false AND start_date <= NOW() AND end_date >= NOW()) OR
|
||||
:status IS NULL
|
||||
)
|
||||
-- 其他筛选条件
|
||||
AND (:customer_id IS NULL OR customer_id = :customer_id)
|
||||
AND (:start_date IS NULL OR created_at >= :start_date)
|
||||
AND (:end_date IS NULL OR created_at <= :end_date)
|
||||
ORDER BY created_at DESC
|
||||
LIMIT :page_size OFFSET :offset;
|
||||
```
|
||||
|
||||
**响应**
|
||||
```json
|
||||
{
|
||||
|
||||
@@ -44,6 +44,17 @@
|
||||
|
||||
### 状态管理属性
|
||||
- (虚字段-不出现在表中)`status` - 授权状态 (normal正常/locked已锁定/expired已过期)
|
||||
- **SQL 计算逻辑**:
|
||||
```sql
|
||||
CASE
|
||||
WHEN is_locked = true THEN 'locked'
|
||||
WHEN end_date < NOW() THEN 'expired'
|
||||
WHEN start_date <= NOW() AND end_date >= NOW() THEN 'normal'
|
||||
ELSE 'expired'
|
||||
END AS status
|
||||
```
|
||||
- **优先级**: locked > expired > normal
|
||||
- **筛选实现**: 在 WHERE 子句中使用相同逻辑进行条件判断
|
||||
- `is_locked` - 是否被锁定 (布尔字段)
|
||||
- `lock_reason` - 锁定原因 (自定义文本输入)
|
||||
- `locked_at` - 锁定时间
|
||||
|
||||
@@ -2,9 +2,9 @@ package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"license-manager/internal/models"
|
||||
"math"
|
||||
"time"
|
||||
"license-manager/internal/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -58,11 +58,17 @@ func (r *authorizationCodeRepository) GetAuthorizationCodeList(ctx context.Conte
|
||||
order = "desc"
|
||||
}
|
||||
|
||||
// 构建查询
|
||||
// 构建查询,包含状态计算
|
||||
query := r.db.WithContext(ctx).Table("authorization_codes ac").
|
||||
Select(`ac.id, ac.code, ac.customer_id, c.customer_name,
|
||||
ac.start_date, ac.end_date, ac.max_activations,
|
||||
ac.deployment_type, ac.is_locked, ac.description, ac.created_at`).
|
||||
ac.deployment_type, ac.is_locked, ac.description, ac.created_at,
|
||||
CASE
|
||||
WHEN ac.is_locked = true THEN 'locked'
|
||||
WHEN ac.end_date < NOW() THEN 'expired'
|
||||
WHEN ac.start_date <= NOW() AND ac.end_date >= NOW() THEN 'normal'
|
||||
ELSE 'expired'
|
||||
END AS status`).
|
||||
Joins("LEFT JOIN customers c ON ac.customer_id = c.id AND c.deleted_at IS NULL")
|
||||
|
||||
// 添加筛选条件
|
||||
@@ -70,7 +76,18 @@ func (r *authorizationCodeRepository) GetAuthorizationCodeList(ctx context.Conte
|
||||
query = query.Where("ac.customer_id = ?", req.CustomerID)
|
||||
}
|
||||
|
||||
// 状态筛选需要在应用层处理,因为status是计算字段
|
||||
// 状态筛选 - 在 SQL 层面处理
|
||||
if req.Status != "" {
|
||||
switch req.Status {
|
||||
case "locked":
|
||||
query = query.Where("ac.is_locked = true")
|
||||
case "expired":
|
||||
query = query.Where("ac.is_locked = false AND ac.end_date < NOW()")
|
||||
case "normal":
|
||||
query = query.Where("ac.is_locked = false AND ac.start_date <= NOW() AND ac.end_date >= NOW()")
|
||||
}
|
||||
}
|
||||
|
||||
if req.StartDate != "" {
|
||||
query = query.Where("ac.created_at >= ?", req.StartDate)
|
||||
}
|
||||
@@ -97,6 +114,7 @@ func (r *authorizationCodeRepository) GetAuthorizationCodeList(ctx context.Conte
|
||||
IsLocked bool `json:"is_locked"`
|
||||
Description *string `json:"description"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
Status string `json:"status"` // 添加状态字段
|
||||
}
|
||||
|
||||
offset := (page - 1) * pageSize
|
||||
@@ -112,20 +130,21 @@ func (r *authorizationCodeRepository) GetAuthorizationCodeList(ctx context.Conte
|
||||
if result.CustomerName != nil {
|
||||
customerName = *result.CustomerName
|
||||
}
|
||||
|
||||
|
||||
list[i] = models.AuthorizationCodeListItem{
|
||||
ID: result.ID,
|
||||
Code: result.Code,
|
||||
CustomerID: result.CustomerID,
|
||||
CustomerName: customerName,
|
||||
StartDate: result.StartDate,
|
||||
EndDate: result.EndDate,
|
||||
MaxActivations: result.MaxActivations,
|
||||
CurrentActivations: 0, // TODO: 从licenses表统计
|
||||
DeploymentType: result.DeploymentType,
|
||||
IsLocked: result.IsLocked,
|
||||
Description: result.Description,
|
||||
CreatedAt: result.CreatedAt,
|
||||
ID: result.ID,
|
||||
Code: result.Code,
|
||||
CustomerID: result.CustomerID,
|
||||
CustomerName: customerName,
|
||||
Status: result.Status, // 使用 SQL 计算的状态
|
||||
StartDate: result.StartDate,
|
||||
EndDate: result.EndDate,
|
||||
MaxActivations: result.MaxActivations,
|
||||
CurrentActivations: 0, // TODO: 从licenses表统计
|
||||
DeploymentType: result.DeploymentType,
|
||||
IsLocked: result.IsLocked,
|
||||
Description: result.Description,
|
||||
CreatedAt: result.CreatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,12 +243,12 @@ func (r *authorizationCodeRepository) GetAuthorizationChangeList(ctx context.Con
|
||||
offset := (req.Page - 1) * req.PageSize
|
||||
|
||||
var changes []struct {
|
||||
ID string `json:"id"`
|
||||
ChangeType string `json:"change_type"`
|
||||
OperatorID string `json:"operator_id"`
|
||||
OperatorName *string `json:"operator_name"`
|
||||
Reason *string `json:"reason"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ID string `json:"id"`
|
||||
ChangeType string `json:"change_type"`
|
||||
OperatorID string `json:"operator_id"`
|
||||
OperatorName *string `json:"operator_name"`
|
||||
Reason *string `json:"reason"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
if err := query.Order(orderBy).Limit(req.PageSize).Offset(offset).Scan(&changes).Error; err != nil {
|
||||
@@ -264,4 +283,4 @@ func (r *authorizationCodeRepository) GetAuthorizationChangeList(ctx context.Con
|
||||
PageSize: req.PageSize,
|
||||
TotalPages: totalPages,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user