feat(user): add hire_date and probation_months to sys_user and user admin

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-07-30 17:22:41 +08:00
1 parent b1b15da624
commit b22777fa2d
8 files changed
+113 -19

No files matched your search

+26 -17
View File
@@ -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))
+2
View File
@@ -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,
+30 -2
View File
@@ -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:
+2
View File
@@ -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="密码")
+5
View File
@@ -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`;
+4
View File
@@ -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
+2
View File
@@ -43,6 +43,8 @@ declare namespace Api {
nickName: string
email: string
phoneNo: string
hireDate?: string
probationMonths?: number | null
sex: string
avatar: string
status: string
+42
View File
@@ -313,6 +313,27 @@
<el-form-item label="邮箱">
<el-input v-model="formData.email" placeholder="可选" />
</el-form-item>
<el-form-item label="入职日期">
<el-date-picker
v-model="formData.hireDate"
type="date"
value-format="YYYY-MM-DD"
placeholder="可选"
class="w-full"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="试用期(月)">
<el-input-number
v-model="formData.probationMonths"
:min="0"
:precision="0"
controls-position="right"
placeholder="月数"
class="w-full"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="性别">
<el-select v-model="formData.sex" placeholder="请选择">
<el-option label="男" value="0" />
@@ -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: