修复账号禁用及队列场次状态规则
问题与需求:后台禁用员工后旧会话仍可继续访问;实时队列跨天误读昨日场次;项目暂停后需禁止取号但允许叫号。 修复思路:账号权限变更时撤销会话并同步前端登录态;实时查询统一按项目时区当天场次过滤;拆分取号与叫号的状态校验,并补充前后端及 PostgreSQL 回归测试。
This commit is contained in:
@@ -69,9 +69,7 @@ func (s *Server) queueSnapshot(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, mapNotFound(err, "PROJECT_NOT_FOUND", "项目不存在"))
|
||||
return
|
||||
}
|
||||
var session model.QueueSession
|
||||
err := s.db.WithContext(r.Context()).Where("project_id = ? AND status IN ?", projectID, []string{"RUNNING", "PAUSED"}).
|
||||
Order("business_date DESC").First(&session).Error
|
||||
session, err := s.currentQueueSession(s.db.WithContext(r.Context()), project)
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
writeJSON(w, http.StatusOK, map[string]any{
|
||||
"project": projectView(project), "session": nil, "revision": 0,
|
||||
@@ -447,7 +445,7 @@ func (s *Server) callNext(w http.ResponseWriter, r *http.Request) {
|
||||
responseCode := http.StatusOK
|
||||
var revision int64
|
||||
err = s.db.WithContext(r.Context()).Transaction(func(tx *gorm.DB) error {
|
||||
project, session, err := s.lockRunningProjectAndSession(tx, projectID)
|
||||
project, session, err := s.lockCallableProjectAndSession(tx, projectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -715,25 +713,31 @@ func (s *Server) transitionTicket(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *Server) lockRunningProjectAndSession(tx *gorm.DB, projectID string) (model.Project, model.QueueSession, error) {
|
||||
return s.lockProjectAndSession(tx, projectID, false)
|
||||
}
|
||||
|
||||
func (s *Server) lockCallableProjectAndSession(tx *gorm.DB, projectID string) (model.Project, model.QueueSession, error) {
|
||||
return s.lockProjectAndSession(tx, projectID, true)
|
||||
}
|
||||
|
||||
func (s *Server) lockProjectAndSession(tx *gorm.DB, projectID string, allowPaused bool) (model.Project, model.QueueSession, error) {
|
||||
var project model.Project
|
||||
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&project, "id = ?", projectID).Error; err != nil {
|
||||
return project, model.QueueSession{}, mapNotFound(err, "PROJECT_NOT_FOUND", "项目不存在")
|
||||
}
|
||||
if project.Status != model.ProjectRunning {
|
||||
if project.Status != model.ProjectRunning && (!allowPaused || project.Status != model.ProjectPaused) {
|
||||
return project, model.QueueSession{}, &apiError{Status: http.StatusConflict, Code: "PROJECT_NOT_RUNNING", Message: "项目当前未运行,不能写入队列"}
|
||||
}
|
||||
location, err := time.LoadLocation(project.Timezone)
|
||||
businessDate, err := s.businessDateFor(project)
|
||||
if err != nil {
|
||||
return project, model.QueueSession{}, fmt.Errorf("invalid project timezone: %w", err)
|
||||
return project, model.QueueSession{}, err
|
||||
}
|
||||
businessDate := s.now().In(location).Format("2006-01-02")
|
||||
var session model.QueueSession
|
||||
err = tx.Clauses(clause.Locking{Strength: "UPDATE"}).Where("project_id = ? AND business_date = ?", projectID, businessDate).First(&session).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
now := s.now()
|
||||
date, _ := time.ParseInLocation("2006-01-02", businessDate, location)
|
||||
session = model.QueueSession{
|
||||
ID: uuid.NewString(), ProjectID: projectID, BusinessDate: date, Status: "RUNNING",
|
||||
ID: uuid.NewString(), ProjectID: projectID, BusinessDate: businessDate, Status: "RUNNING",
|
||||
NextTicketNumber: 1, Revision: 0, OpenedAt: now, CreatedAt: now, UpdatedAt: now,
|
||||
}
|
||||
if err := tx.Create(&session).Error; err != nil {
|
||||
@@ -744,7 +748,7 @@ func (s *Server) lockRunningProjectAndSession(tx *gorm.DB, projectID string) (mo
|
||||
if err != nil {
|
||||
return project, session, err
|
||||
}
|
||||
if session.Status != "RUNNING" {
|
||||
if session.Status != "RUNNING" && (!allowPaused || session.Status != "PAUSED") {
|
||||
return project, session, &apiError{Status: http.StatusConflict, Code: "QUEUE_NOT_RUNNING", Message: "队列当前未运行"}
|
||||
}
|
||||
return project, session, nil
|
||||
|
||||
Reference in New Issue
Block a user