feat: 累积功能变更 — 聊天集成、租户管理、小程序更新、ETL 增强、迁移脚本
包含多个会话的累积代码变更: - backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔 - admin-web: ETL 状态页、任务管理、调度配置、登录优化 - miniprogram: 看板页面、聊天集成、UI 组件、导航更新 - etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强 - tenant-admin: 项目初始化 - db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8) - packages/shared: 枚举和工具函数更新 - tools: 数据库工具、报表生成、健康检查 - docs: PRD/架构/部署/合约文档更新 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
117
apps/backend/app/schemas/tenant_users.py
Normal file
117
apps/backend/app/schemas/tenant_users.py
Normal file
@@ -0,0 +1,117 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
租户管理后台 — 用户审核 + 用户管理 Pydantic Schema。
|
||||
|
||||
覆盖:申请列表、关联建议、审核通过/拒绝、用户列表、编辑、绑定、角色列表、人员候选。
|
||||
|
||||
需求: 3.2, 4.1
|
||||
|
||||
AI_CHANGELOG
|
||||
- 2026-03-23 17:00:00 | Prompt: P20260323-164500(审核弹窗改造)| Direct cause:新增 roles + site-staff 端点需要响应 Schema | Summary:新增 RoleItem(角色列表项)+ StaffCandidate(人员候选项,source 区分 assistant/staff)| Verify:后端 /roles 和 /site-staff 返回正确 JSON 结构
|
||||
- 2026-03-24 | Prompt: 用户管理绑定功能改造 | Direct cause:UserEditRequest 需要同时携带角色+绑定字段 | Summary:UserEditRequest 扩展 assistant_id/staff_id 字段,支持角色+绑定合并提交 | Verify:PATCH /users/{id} 接受 assistantId/staffId 参数
|
||||
- 2026-03-24 | Prompt: 审核弹窗头像昵称+排版优化 | Direct cause:ApplicationListItem 缺少 avatar_url | Summary:新增 avatar_url 字段 | Verify:GET /applications 返回 avatarUrl
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from app.schemas.base import CamelModel
|
||||
|
||||
|
||||
# ── 用户申请审核 ──────────────────────────────────────────
|
||||
|
||||
|
||||
class ApplicationListItem(CamelModel):
|
||||
"""申请列表项。"""
|
||||
id: int
|
||||
user_id: int
|
||||
nickname: str | None = None
|
||||
avatar_url: str | None = None
|
||||
phone: str | None = None
|
||||
site_code: str | None = None
|
||||
applied_role_text: str | None = None
|
||||
employee_number: str | None = None
|
||||
created_at: str | None = None
|
||||
status: str # pending / approved / rejected
|
||||
|
||||
|
||||
class MatchSuggestion(CamelModel):
|
||||
"""关联匹配建议。"""
|
||||
assistant_id: int | None = None
|
||||
staff_id: int | None = None
|
||||
name: str
|
||||
number: str | None = None
|
||||
source_table: str # v_dim_assistant / v_dim_staff
|
||||
|
||||
|
||||
class ApproveRequest(CamelModel):
|
||||
"""审核通过请求。"""
|
||||
role: str = Field(..., min_length=1, description="分配角色(coach/staff/head_coach/manager)")
|
||||
assistant_id: int | None = Field(None, description="关联助教 ID")
|
||||
staff_id: int | None = Field(None, description="关联员工 ID")
|
||||
|
||||
|
||||
class RejectRequest(CamelModel):
|
||||
"""审核拒绝请求。"""
|
||||
reason: str = Field(..., min_length=1, description="拒绝原因")
|
||||
|
||||
|
||||
# ── 用户管理 ──────────────────────────────────────────────
|
||||
|
||||
|
||||
class UserListItem(CamelModel):
|
||||
"""用户列表项。"""
|
||||
id: int
|
||||
nickname: str | None = None
|
||||
role: str | None = None # 角色中文名(显示用)
|
||||
role_code: str | None = None # 角色 code(提交用)
|
||||
assistant_id: int | None = None # 当前绑定的助教 ID
|
||||
staff_id: int | None = None # 当前绑定的员工 ID
|
||||
assistant_name: str | None = None
|
||||
site_name: str | None = None
|
||||
site_id: int | None = None
|
||||
status: str # approved / disabled
|
||||
|
||||
|
||||
class UserEditRequest(CamelModel):
|
||||
"""用户编辑请求(合并角色+绑定)。
|
||||
|
||||
角色与绑定互斥:coach 只能绑 assistant_id,其他角色只能绑 staff_id。
|
||||
换角色时后端自动清除旧绑定。staffBinding="none" 表示解绑。
|
||||
"""
|
||||
role: str | None = Field(None, description="新角色 code(coach/staff/head_coach/manager)")
|
||||
site_id: int | None = Field(None, description="新门店 ID")
|
||||
assistant_id: int | None = Field(None, description="关联助教 ID(仅 coach 角色)")
|
||||
staff_id: int | None = Field(None, description="关联员工 ID(仅非 coach 角色)")
|
||||
# CHANGE 2026-03-23 | 移除 status 字段:租户不能禁用用户,只能移除店铺关系
|
||||
# CHANGE 2026-03-24 | 合并绑定字段:角色+绑定同一请求提交,换角色自动清除旧绑定
|
||||
|
||||
|
||||
class UserBindingRequest(CamelModel):
|
||||
"""用户绑定修改请求。"""
|
||||
assistant_id: int | None = Field(None, description="关联助教 ID")
|
||||
staff_id: int | None = Field(None, description="关联员工 ID")
|
||||
|
||||
|
||||
# ── 角色 + 人员候选 ──────────────────────────────────────
|
||||
# [CHANGE P20260323-164500] intent: 审核弹窗角色动态化 + 人员联动所需的响应 Schema
|
||||
# assumptions: StaffCandidate.source 区分 assistant/staff,前端据此构造 staffBinding 值
|
||||
|
||||
|
||||
class RoleItem(CamelModel):
|
||||
"""角色列表项(从 auth.roles 动态读取)。"""
|
||||
id: int
|
||||
code: str
|
||||
name: str
|
||||
description: str | None = None
|
||||
|
||||
|
||||
class StaffCandidate(CamelModel):
|
||||
"""人员候选项(审核弹窗关联下拉用)。"""
|
||||
id: int = Field(..., description="assistant_id 或 staff_id")
|
||||
identity_label: str | None = Field(None, description="身份角色(level / staff_identity 的原始值)")
|
||||
name: str = Field(..., description="姓名")
|
||||
mobile: str | None = Field(None, description="手机号")
|
||||
entry_time: str | None = Field(None, description="入职时间")
|
||||
source: str = Field(..., description="assistant / staff")
|
||||
Reference in New Issue
Block a user