[feat]:[FL-172][用户管理页面新增用户时邮箱放最后,且不要必填]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
chengkai3
2026-06-18 00:34:03 +08:00
parent e37ecac9af
commit 6519fee729
5 changed files with 35 additions and 21 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ class User(Base):
primary_key=True,
default=lambda: uuid4().hex,
)
email: Mapped[str] = mapped_column(String(255), unique=True, index=True)
email: Mapped[str | None] = mapped_column(String(255), unique=True, index=True, nullable=True)
username: Mapped[str] = mapped_column(
settings.user_username_column,
String(64),
+1 -1
View File
@@ -36,7 +36,7 @@ class UserPasswordResetRequest(BaseModel):
class UserCreateRequest(BaseModel):
user_id: str = Field(min_length=3, max_length=64)
email: str
email: str | None = None
username: str = Field(min_length=3, max_length=64)
password: str = Field(min_length=8, max_length=128)
+7 -4
View File
@@ -95,17 +95,20 @@ def create_user(
) -> UserPublic | None:
user_id = payload.user_id.strip()
# Build conditions for duplicate check
conditions = [User.id == user_id, User.username == payload.username]
if payload.email:
conditions.append(User.email == payload.email.lower())
duplicate = db.scalar(
select(User.id).where(
(User.id == user_id) | (User.email == payload.email.lower()) | (User.username == payload.username)
)
select(User.id).where(or_(*conditions))
)
if duplicate:
return None
user = User(
id=user_id,
email=payload.email.lower(),
email=payload.email.lower() if payload.email else None,
username=payload.username,
password_hash=hash_password(payload.password),
status="ENABLED",
+9
View File
@@ -0,0 +1,9 @@
-- Migration: Make user email column nullable
-- Date: 2026-06-18
-- Description: Modify users table to make email column nullable to support optional email during user creation
ALTER TABLE users ALTER COLUMN email DROP NOT NULL;
-- Notes:
-- This migration allows users to be created without an email address.
-- The email field remains unique when provided.
+17 -15
View File
@@ -39,7 +39,7 @@ type UserRolePayload = {
type CreateUserValues = {
user_id: string;
email: string;
email?: string;
username: string;
password: string;
};
@@ -323,20 +323,23 @@ export default function AdminUsersPage() {
const payload: CreateUserValues = {
user_id: values.user_id.trim(),
email: values.email.trim(),
username: values.username.trim(),
password: values.password,
};
if (values.email && values.email.trim()) {
payload.email = values.email.trim();
}
const candidateUserId = payload.user_id.toLowerCase();
const candidateEmail = payload.email.toLowerCase();
const candidateEmail = payload.email?.toLowerCase();
const candidateUsername = payload.username.toLowerCase();
if (existingUserIds.has(candidateUserId)) {
setError("用户 ID 已存在,请更换后重试");
return;
}
if (existingEmails.has(candidateEmail)) {
if (candidateEmail && existingEmails.has(candidateEmail)) {
setError("邮箱已存在,请更换后重试");
return;
}
@@ -796,17 +799,6 @@ export default function AdminUsersPage() {
<Input placeholder="例如 ck001" />
</Form.Item>
<Form.Item
label="邮箱"
name="email"
rules={[
{ required: true, message: "请输入邮箱" },
{ type: "email", message: "邮箱格式不正确" },
]}
>
<Input placeholder="请输入邮箱" />
</Form.Item>
<Form.Item
label="用户名"
name="username"
@@ -830,6 +822,16 @@ export default function AdminUsersPage() {
>
<Input.Password placeholder="至少 8 位" />
</Form.Item>
<Form.Item
label="邮箱"
name="email"
rules={[
{ type: "email", message: "邮箱格式不正确" },
]}
>
<Input placeholder="请输入邮箱(可选)" />
</Form.Item>
</Form>
</Modal>