修复经理状态更新持久化
This commit is contained in:
parent
dd8dc489b7
commit
779d864e80
@ -107,8 +107,12 @@ func (h *Handler) UpdateManager(c *gin.Context) {
|
||||
response.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
statusDetail := ""
|
||||
if req.Status != nil && strings.TrimSpace(*req.Status) != "" {
|
||||
statusDetail = " status=" + strings.ToLower(strings.TrimSpace(*req.Status))
|
||||
}
|
||||
writeHostOrgAuditLog(c, h.audit, "update-manager", "manager_profiles", item.UserID,
|
||||
fmt.Sprintf("user_id=%d permissions_updated=true", item.UserID))
|
||||
fmt.Sprintf("user_id=%d permissions_updated=true%s", item.UserID, statusDetail))
|
||||
response.OK(c, item)
|
||||
}
|
||||
|
||||
|
||||
@ -652,8 +652,8 @@ func (r *Reader) CreateManagerProfile(ctx context.Context, userID int64, actorID
|
||||
return items[0], nil
|
||||
}
|
||||
|
||||
// UpdateManagerProfile 局部更新经理运营资料和经理中心权限。
|
||||
// 未传入的布尔权限不参与 SET,避免后台只编辑联系方式时把现有权限误恢复成默认值。
|
||||
// UpdateManagerProfile 局部更新经理运营资料、身份状态和经理中心权限。
|
||||
// 未传入的状态/布尔权限不参与 SET,避免后台只编辑联系方式时把现有开关误恢复成默认值。
|
||||
func (r *Reader) UpdateManagerProfile(ctx context.Context, userID int64, actorID int64, req updateManagerRequest) (*ManagerListItem, error) {
|
||||
if r == nil || r.db == nil {
|
||||
return nil, errUserDBNotConfigured()
|
||||
@ -671,6 +671,9 @@ func (r *Reader) UpdateManagerProfile(ctx context.Context, userID int64, actorID
|
||||
assignments = append(assignments, "contact_info = ?")
|
||||
args = append(args, contact)
|
||||
}
|
||||
if err := req.appendStatusAssignment(&assignments, &args); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.appendPermissionAssignments(&assignments, &args)
|
||||
args = append(args, appctx.FromContext(ctx), userID)
|
||||
// 权限更新只作用于已存在经理;RowsAffected=0 时返回 not found,避免 PUT 顺手创建新经理绕过创建审计。
|
||||
|
||||
87
server/admin/internal/modules/hostorg/reader_test.go
Normal file
87
server/admin/internal/modules/hostorg/reader_test.go
Normal file
@ -0,0 +1,87 @@
|
||||
package hostorg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"hyapp-admin-server/internal/appctx"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
)
|
||||
|
||||
func TestUpdateManagerProfilePersistsStatus(t *testing.T) {
|
||||
db, mock, err := sqlmock.New()
|
||||
if err != nil {
|
||||
t.Fatalf("new sqlmock: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
status := "disabled"
|
||||
reader := NewReader(db, nil, nil)
|
||||
ctx := appctx.WithContext(context.Background(), "lalu")
|
||||
|
||||
// 经理状态是 manager_profiles 的身份开关;PUT 传 status 时必须落到 UPDATE,否则前端刷新会重新读到旧状态。
|
||||
mock.ExpectExec(`(?s)UPDATE manager_profiles\s+SET updated_at_ms = \?, status = \?\s+WHERE app_code = \? AND user_id = \?`).
|
||||
WithArgs(sqlmock.AnyArg(), "disabled", "lalu", int64(1003)).
|
||||
WillReturnResult(sqlmock.NewResult(0, 1))
|
||||
mock.ExpectQuery(`(?s)SELECT COUNT\(DISTINCT mp\.user_id\).*FROM manager_profiles mp`).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(int64(1)))
|
||||
mock.ExpectQuery(`(?s)SELECT mp\.user_id, COALESCE\(manager\.current_display_user_id, ''\).*FROM manager_profiles mp`).
|
||||
WillReturnRows(managerListRows().
|
||||
AddRow(int64(1003), "1003", "manager", "avatar.png", int64(7), "西亚区", "disabled", "+63",
|
||||
true, true, true, true, true, true, true, true, true, true,
|
||||
int64(0), int64(0), int64(1710000000000), int64(1710000001000)))
|
||||
|
||||
item, err := reader.UpdateManagerProfile(ctx, 1003, 7, updateManagerRequest{Status: &status})
|
||||
if err != nil {
|
||||
t.Fatalf("update manager profile: %v", err)
|
||||
}
|
||||
if item.Status != "disabled" {
|
||||
t.Fatalf("manager status = %q, want disabled", item.Status)
|
||||
}
|
||||
if err := mock.ExpectationsWereMet(); err != nil {
|
||||
t.Fatalf("sql expectations: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateManagerProfileRejectsInvalidStatus(t *testing.T) {
|
||||
db, _, err := sqlmock.New()
|
||||
if err != nil {
|
||||
t.Fatalf("new sqlmock: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
status := "off"
|
||||
reader := NewReader(db, nil, nil)
|
||||
_, err = reader.UpdateManagerProfile(appctx.WithContext(context.Background(), "lalu"), 1003, 7, updateManagerRequest{Status: &status})
|
||||
if err == nil || err.Error() != "manager status is invalid" {
|
||||
t.Fatalf("invalid status error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func managerListRows() *sqlmock.Rows {
|
||||
return sqlmock.NewRows([]string{
|
||||
"user_id",
|
||||
"current_display_user_id",
|
||||
"username",
|
||||
"avatar",
|
||||
"region_id",
|
||||
"region_name",
|
||||
"status",
|
||||
"contact_info",
|
||||
"can_grant_avatar_frame",
|
||||
"can_grant_vehicle",
|
||||
"can_grant_badge",
|
||||
"can_grant_vip",
|
||||
"can_update_user_level",
|
||||
"can_add_bd_leader",
|
||||
"can_add_admin",
|
||||
"can_add_superadmin",
|
||||
"can_block_user",
|
||||
"can_transfer_user_country",
|
||||
"bd_leader_count",
|
||||
"last_invited_at_ms",
|
||||
"created_at_ms",
|
||||
"updated_at_ms",
|
||||
})
|
||||
}
|
||||
@ -83,6 +83,7 @@ type createManagerRequest struct {
|
||||
|
||||
type updateManagerRequest struct {
|
||||
Contact *string `json:"contact"`
|
||||
Status *string `json:"status"`
|
||||
CanGrantAvatarFrame *bool `json:"canGrantAvatarFrame"`
|
||||
CanGrantVehicle *bool `json:"canGrantVehicle"`
|
||||
CanGrantBadge *bool `json:"canGrantBadge"`
|
||||
@ -95,6 +96,23 @@ type updateManagerRequest struct {
|
||||
CanTransferCountry *bool `json:"canTransferUserCountry"`
|
||||
}
|
||||
|
||||
func (r updateManagerRequest) appendStatusAssignment(assignments *[]string, args *[]any) error {
|
||||
if r.Status == nil {
|
||||
return nil
|
||||
}
|
||||
status := strings.ToLower(strings.TrimSpace(*r.Status))
|
||||
if status == "" {
|
||||
return nil
|
||||
}
|
||||
if status != "active" && status != "disabled" {
|
||||
return fmt.Errorf("manager status is invalid")
|
||||
}
|
||||
// 经理状态属于 manager_profiles 自身身份开关;停用经理只关闭经理中心身份,不改用户主状态或其他 Host/BD 关系。
|
||||
*assignments = append(*assignments, "status = ?")
|
||||
*args = append(*args, status)
|
||||
return nil
|
||||
}
|
||||
|
||||
type managerPermissions struct {
|
||||
CanGrantAvatarFrame bool
|
||||
CanGrantVehicle bool
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user