diff --git a/backend/app/api/admin.py b/backend/app/api/admin.py
index ec6ae0aa..0332c39e 100644
--- a/backend/app/api/admin.py
+++ b/backend/app/api/admin.py
@@ -253,6 +253,8 @@ class UserCreateBody(BaseModel):
supervisor_user_id: Optional[str] = Field(None, alias="supervisorUserId")
email: Optional[str] = Field("", alias="email")
phone_no: Optional[str] = Field("", alias="phoneNo")
+ hire_date: Optional[str] = Field(None, alias="hireDate")
+ probation_months: Optional[int] = Field(None, alias="probationMonths")
sex: Optional[str] = Field("0", alias="sex")
avatar: Optional[str] = Field(None, alias="avatar")
status: Optional[str] = Field("1", alias="status")
@@ -269,6 +271,8 @@ class UserUpdateBody(BaseModel):
supervisor_user_id: Optional[str] = Field(None, alias="supervisorUserId")
email: Optional[str] = Field(None, alias="email")
phone_no: Optional[str] = Field(None, alias="phoneNo")
+ hire_date: Optional[str] = Field(None, alias="hireDate")
+ probation_months: Optional[int] = Field(None, alias="probationMonths")
sex: Optional[str] = Field(None, alias="sex")
avatar: Optional[str] = Field(None, alias="avatar")
status: Optional[str] = Field(None, alias="status")
@@ -378,6 +382,8 @@ async def create_user(
supervisor_user_id=body.supervisor_user_id,
email=body.email,
phone_no=body.phone_no,
+ hire_date=body.hire_date,
+ probation_months=body.probation_months,
sex=body.sex,
avatar=body.avatar,
status=body.status,
@@ -402,23 +408,26 @@ async def update_user(
):
try:
payload: dict[str, Any] = body.model_dump(exclude_unset=True, by_alias=False)
- obj = user_svc.update_user(
- db,
- user_id,
- nick_name=payload.get("nick_name"),
- dept_id=payload.get("dept_id"),
- supervisor_user_id=payload.get("supervisor_user_id"),
- email=payload.get("email"),
- phone_no=payload.get("phone_no"),
- sex=payload.get("sex"),
- avatar=payload.get("avatar"),
- status=payload.get("status"),
- order_num=payload.get("order_num"),
- remark=payload.get("remark"),
- user_id_updater=user.get("user_id"),
- role_ids=payload.get("role_ids"),
- post_ids=payload.get("post_ids"),
- )
+ update_kwargs: dict[str, Any] = {
+ "nick_name": payload.get("nick_name"),
+ "dept_id": payload.get("dept_id"),
+ "supervisor_user_id": payload.get("supervisor_user_id"),
+ "email": payload.get("email"),
+ "phone_no": payload.get("phone_no"),
+ "sex": payload.get("sex"),
+ "avatar": payload.get("avatar"),
+ "status": payload.get("status"),
+ "order_num": payload.get("order_num"),
+ "remark": payload.get("remark"),
+ "user_id_updater": user.get("user_id"),
+ "role_ids": payload.get("role_ids"),
+ "post_ids": payload.get("post_ids"),
+ }
+ if "hire_date" in payload:
+ update_kwargs["hire_date"] = payload.get("hire_date")
+ if "probation_months" in payload:
+ update_kwargs["probation_months"] = payload.get("probation_months")
+ obj = user_svc.update_user(db, user_id, **update_kwargs)
return success_response(user_svc._row_to_dict(obj), message="更新成功")
except ValueError as e:
return error_response(400, str(e))
diff --git a/backend/app/api/public.py b/backend/app/api/public.py
index 92d09704..30b40382 100644
--- a/backend/app/api/public.py
+++ b/backend/app/api/public.py
@@ -59,6 +59,8 @@ def _build_user_info_payload(user: SysUser, web_role: str, role_names: list = No
"realName": user.nick_name,
"phone": phone,
"email": (getattr(user, "email", None) or "").strip() or None,
+ "hireDate": user.hire_date.strftime("%Y-%m-%d") if getattr(user, "hire_date", None) else None,
+ "probationMonths": getattr(user, "probation_months", None),
"sex": getattr(user, "sex", None) or "0",
"remark": (getattr(user, "remark", None) or "").strip() or None,
"role": web_role,
diff --git a/backend/app/crud/user.py b/backend/app/crud/user.py
index 512a789e..60c9e37c 100644
--- a/backend/app/crud/user.py
+++ b/backend/app/crud/user.py
@@ -2,8 +2,8 @@
from __future__ import annotations
import math
-from datetime import datetime
-from typing import Any, Dict, List, Optional, Tuple
+from datetime import date, datetime
+from typing import Any, Dict, List, Optional, Tuple, Union
import bcrypt
from sqlalchemy import and_, func, or_
@@ -44,6 +44,10 @@ def _row_to_dict(u: SysUser, dept_name: str = "") -> Dict[str, Any]:
"nickName": u.nick_name,
"email": u.email or "",
"phoneNo": u.phone_no or "",
+ "hireDate": u.hire_date.strftime("%Y-%m-%d") if getattr(u, "hire_date", None) else "",
+ "probationMonths": (
+ u.probation_months if getattr(u, "probation_months", None) is not None else None
+ ),
"sex": u.sex or "0",
"avatar": u.avatar or "",
"status": u.status,
@@ -285,6 +289,17 @@ def _replace_associations(
))
+def _parse_hire_date(value: Optional[Union[str, date]]) -> Optional[date]:
+ if value is None or value == "":
+ return None
+ if isinstance(value, date) and not isinstance(value, datetime):
+ return value
+ s = str(value).strip()
+ if not s:
+ return None
+ return datetime.strptime(s[:10], "%Y-%m-%d").date()
+
+
def create_user(
db: Session,
*,
@@ -294,6 +309,8 @@ def create_user(
dept_id: Optional[str] = None,
email: str = "",
phone_no: str = "",
+ hire_date: Optional[Union[str, date]] = None,
+ probation_months: Optional[int] = None,
sex: str = "0",
avatar: Optional[str] = None,
status: str = "1",
@@ -323,6 +340,8 @@ def create_user(
nick_name=nn,
email=(email or "").strip(),
phone_no=(phone_no or "").strip(),
+ hire_date=_parse_hire_date(hire_date),
+ probation_months=probation_months,
sex=sex or "0",
avatar=avatar,
password=_hash_password(pw),
@@ -354,6 +373,8 @@ def update_user(
dept_id: Optional[str] = None,
email: Optional[str] = None,
phone_no: Optional[str] = None,
+ hire_date: Any = ...,
+ probation_months: Any = ...,
sex: Optional[str] = None,
avatar: Optional[str] = None,
status: Optional[str] = None,
@@ -378,6 +399,13 @@ def update_user(
obj.email = (email or "").strip()
if phone_no is not None:
obj.phone_no = (phone_no or "").strip()
+ if hire_date is not ...:
+ obj.hire_date = _parse_hire_date(hire_date)
+ if probation_months is not ...:
+ if probation_months is None or probation_months == "":
+ obj.probation_months = None
+ else:
+ obj.probation_months = int(probation_months)
if sex is not None:
obj.sex = sex
if avatar is not None:
diff --git a/backend/app/models/models.py b/backend/app/models/models.py
index fe6ad256..e9fe5dd6 100644
--- a/backend/app/models/models.py
+++ b/backend/app/models/models.py
@@ -31,6 +31,8 @@ class SysUser(Base):
nick_name = Column(String(30), nullable=False, comment="用户名")
email = Column(String(50), nullable=False, default="", comment="用户邮箱")
phone_no = Column(String(11), nullable=False, default="", comment="手机号码")
+ hire_date = Column(Date, nullable=True, comment="入职日期")
+ probation_months = Column(Integer, nullable=True, comment="试用期月数")
sex = Column(CHAR(1), nullable=True, default="0", comment="用户性别")
avatar = Column(String(512), nullable=True, comment="头像")
password = Column("password", String(100), nullable=False, default="", comment="密码")
diff --git a/docs/sql/sys_user_hire_probation.sql b/docs/sql/sys_user_hire_probation.sql
new file mode 100644
index 00000000..746e0775
--- /dev/null
+++ b/docs/sql/sys_user_hire_probation.sql
@@ -0,0 +1,5 @@
+-- docs/sql/sys_user_hire_probation.sql
+-- 用户表补齐入职日期、试用期月数(转正套件主数据)
+ALTER TABLE `sys_user`
+ ADD COLUMN `hire_date` date DEFAULT NULL COMMENT '入职日期' AFTER `phone_no`,
+ ADD COLUMN `probation_months` int(11) DEFAULT NULL COMMENT '试用期月数' AFTER `hire_date`;
diff --git a/web-admin/src/api/admin.ts b/web-admin/src/api/admin.ts
index 39afbb07..3ab9218e 100644
--- a/web-admin/src/api/admin.ts
+++ b/web-admin/src/api/admin.ts
@@ -132,6 +132,8 @@ export function fetchCreateUser(data: {
supervisorUserId?: string
email?: string
phoneNo?: string
+ hireDate?: string
+ probationMonths?: number | null
sex?: string
avatar?: string
status?: string
@@ -155,6 +157,8 @@ export function fetchUpdateUser(
supervisorUserId: string
email: string
phoneNo: string
+ hireDate: string | null
+ probationMonths: number | null
sex: string
avatar: string
status: string
diff --git a/web-admin/src/types/api.d.ts b/web-admin/src/types/api.d.ts
index d07ee70a..fd5d39f8 100644
--- a/web-admin/src/types/api.d.ts
+++ b/web-admin/src/types/api.d.ts
@@ -43,6 +43,8 @@ declare namespace Api {
nickName: string
email: string
phoneNo: string
+ hireDate?: string
+ probationMonths?: number | null
sex: string
avatar: string
status: string
diff --git a/web-admin/src/views/system/user/index.vue b/web-admin/src/views/system/user/index.vue
index f8dffbfe..a9e22c83 100644
--- a/web-admin/src/views/system/user/index.vue
+++ b/web-admin/src/views/system/user/index.vue
@@ -313,6 +313,27 @@
+
+
+
+
+
+
@@ -479,6 +500,8 @@
supervisorUserId: '' as string,
email: '',
phoneNo: '',
+ hireDate: '' as string,
+ probationMonths: null as number | null,
sex: '0',
avatar: '',
status: '1',
@@ -584,6 +607,8 @@
formData.supervisorUserId = ''
formData.email = ''
formData.phoneNo = ''
+ formData.hireDate = ''
+ formData.probationMonths = null
formData.sex = '0'
formData.avatar = ''
formData.status = '1'
@@ -618,6 +643,11 @@
formData.supervisorUserId = detail.supervisorUserId || ''
formData.email = detail.email || ''
formData.phoneNo = detail.phoneNo || ''
+ formData.hireDate = detail.hireDate || ''
+ formData.probationMonths =
+ detail.probationMonths === null || detail.probationMonths === undefined
+ ? null
+ : Number(detail.probationMonths)
formData.sex = detail.sex || '0'
formData.avatar = detail.avatar || ''
formData.status = detail.status || '1'
@@ -651,6 +681,8 @@
supervisorUserId: formData.supervisorUserId || '',
email: formData.email?.trim() || undefined,
phoneNo: formData.phoneNo?.trim() || undefined,
+ hireDate: formData.hireDate || null,
+ probationMonths: formData.probationMonths,
sex: formData.sex,
status: formData.status,
orderNum: formData.orderNum,
@@ -666,6 +698,8 @@
supervisorUserId: formData.supervisorUserId || undefined,
email: formData.email?.trim() || undefined,
phoneNo: formData.phoneNo?.trim() || undefined,
+ hireDate: formData.hireDate || undefined,
+ probationMonths: formData.probationMonths ?? undefined,
sex: formData.sex,
status: formData.status,
orderNum: formData.orderNum,
@@ -769,6 +803,14 @@
{ label: '所属组织', value: formatUserDeptDisplay(row) },
{ label: '手机号', value: row.phoneNo },
{ label: '邮箱', value: row.email },
+ { label: '入职日期', value: row.hireDate || '—' },
+ {
+ label: '试用期',
+ value:
+ row.probationMonths === null || row.probationMonths === undefined
+ ? '—'
+ : `${row.probationMonths} 个月`
+ },
{
label: '性别',
value: