feat(admin): 账号区域标识回填
This commit is contained in:
parent
34bce0f5df
commit
64585261c4
|
|
@ -55,6 +55,7 @@ def _scrub_user_payload(user: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
"name": user.get("service_department_name"),
|
"name": user.get("service_department_name"),
|
||||||
"code": user.get("service_department_code"),
|
"code": user.get("service_department_code"),
|
||||||
"region_id": user.get("service_department_region_id"),
|
"region_id": user.get("service_department_region_id"),
|
||||||
|
"region_name": user.get("service_department_region_name"),
|
||||||
"parent_id": user.get("service_department_parent_id"),
|
"parent_id": user.get("service_department_parent_id"),
|
||||||
"phone": user.get("service_department_phone"),
|
"phone": user.get("service_department_phone"),
|
||||||
"role": user.get("department_role"),
|
"role": user.get("department_role"),
|
||||||
|
|
|
||||||
|
|
@ -275,11 +275,23 @@ def admin_create_user():
|
||||||
return jsonify({"success": False, "message": "用户名和密码均不能为空"}), 400
|
return jsonify({"success": False, "message": "用户名和密码均不能为空"}), 400
|
||||||
parent_department_id = (payload.get("parent_department_id") or "").strip() or None
|
parent_department_id = (payload.get("parent_department_id") or "").strip() or None
|
||||||
service_department_id = (payload.get("service_department_id") or "").strip() or None
|
service_department_id = (payload.get("service_department_id") or "").strip() or None
|
||||||
|
region_id = (payload.get("region_id") or "").strip() or None
|
||||||
department_phone = (payload.get("department_phone") or "").strip() or None
|
department_phone = (payload.get("department_phone") or "").strip() or None
|
||||||
|
|
||||||
# 如果未显式绑定部门,则为该用户创建一个同名单位,并按父级决定层级
|
# 如果未显式绑定部门,则为该用户创建一个同名单位,并按父级决定层级
|
||||||
created_department: Optional[Dict[str, Any]] = None
|
created_department: Optional[Dict[str, Any]] = None
|
||||||
if not service_department_id:
|
if not service_department_id:
|
||||||
|
# 未显式指定区域时,继承父级部门的区域
|
||||||
|
if not region_id and parent_department_id:
|
||||||
|
try:
|
||||||
|
parent_dept = next(
|
||||||
|
(dept for dept in list_service_departments() if str(dept.get("id")) == parent_department_id),
|
||||||
|
None
|
||||||
|
)
|
||||||
|
if parent_dept:
|
||||||
|
region_id = parent_dept.get("region_id")
|
||||||
|
except Exception:
|
||||||
|
region_id = None
|
||||||
try:
|
try:
|
||||||
dept_name = (payload.get("display_name") or username).strip() or username
|
dept_name = (payload.get("display_name") or username).strip() or username
|
||||||
dept_code = username.upper()
|
dept_code = username.upper()
|
||||||
|
|
@ -288,6 +300,7 @@ def admin_create_user():
|
||||||
code=dept_code,
|
code=dept_code,
|
||||||
phone=department_phone,
|
phone=department_phone,
|
||||||
parent_id=parent_department_id,
|
parent_id=parent_department_id,
|
||||||
|
region_id=region_id,
|
||||||
)
|
)
|
||||||
service_department_id = created_department.get("id")
|
service_department_id = created_department.get("id")
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
|
@ -303,6 +316,7 @@ def admin_create_user():
|
||||||
service_department_id=service_department_id,
|
service_department_id=service_department_id,
|
||||||
department_role=payload.get("department_role"),
|
department_role=payload.get("department_role"),
|
||||||
parent_department_id=parent_department_id,
|
parent_department_id=parent_department_id,
|
||||||
|
service_department_region_id=region_id,
|
||||||
service_department_phone=department_phone,
|
service_department_phone=department_phone,
|
||||||
)
|
)
|
||||||
return jsonify({"success": True, "data": {"user": user, "department": created_department}})
|
return jsonify({"success": True, "data": {"user": user, "department": created_department}})
|
||||||
|
|
@ -508,6 +522,16 @@ def admin_create_service_department():
|
||||||
"description": payload.get("description"),
|
"description": payload.get("description"),
|
||||||
"grade": grade,
|
"grade": grade,
|
||||||
}
|
}
|
||||||
|
if not kwargs["region_id"] and kwargs["parent_id"]:
|
||||||
|
try:
|
||||||
|
parent_dept = next(
|
||||||
|
(dept for dept in list_service_departments() if str(dept.get("id")) == kwargs["parent_id"]),
|
||||||
|
None
|
||||||
|
)
|
||||||
|
if parent_dept:
|
||||||
|
kwargs["region_id"] = parent_dept.get("region_id")
|
||||||
|
except Exception:
|
||||||
|
kwargs["region_id"] = None
|
||||||
try:
|
try:
|
||||||
department = create_service_department(name, code=code_token, **kwargs)
|
department = create_service_department(name, code=code_token, **kwargs)
|
||||||
department_id = department.get("id")
|
department_id = department.get("id")
|
||||||
|
|
|
||||||
|
|
@ -279,6 +279,7 @@ def _public_user_payload(user: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
"phone": user.get("service_department_phone"),
|
"phone": user.get("service_department_phone"),
|
||||||
"parent_id": user.get("service_department_parent_id"),
|
"parent_id": user.get("service_department_parent_id"),
|
||||||
"region_id": user.get("service_department_region_id"),
|
"region_id": user.get("service_department_region_id"),
|
||||||
|
"region_name": user.get("service_department_region_name"),
|
||||||
"role": user.get("department_role"),
|
"role": user.get("department_role"),
|
||||||
}
|
}
|
||||||
created_at = user.get("created_at")
|
created_at = user.get("created_at")
|
||||||
|
|
@ -322,9 +323,11 @@ def get_user_by_username(username: str) -> Optional[Dict[str, Any]]:
|
||||||
sd.code AS service_department_code,
|
sd.code AS service_department_code,
|
||||||
sd.phone AS service_department_phone,
|
sd.phone AS service_department_phone,
|
||||||
sd.parent_id AS service_department_parent_id,
|
sd.parent_id AS service_department_parent_id,
|
||||||
sd.region_id AS service_department_region_id
|
sd.region_id AS service_department_region_id,
|
||||||
|
r.name AS service_department_region_name
|
||||||
FROM auth_users au
|
FROM auth_users au
|
||||||
LEFT JOIN service_departments sd ON sd.id = au.service_department_id
|
LEFT JOIN service_departments sd ON sd.id = au.service_department_id
|
||||||
|
LEFT JOIN regions r ON r.id = sd.region_id
|
||||||
WHERE au.username = %s
|
WHERE au.username = %s
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
""",
|
""",
|
||||||
|
|
@ -359,9 +362,11 @@ def get_user_by_id(user_id: str) -> Optional[Dict[str, Any]]:
|
||||||
sd.code AS service_department_code,
|
sd.code AS service_department_code,
|
||||||
sd.phone AS service_department_phone,
|
sd.phone AS service_department_phone,
|
||||||
sd.parent_id AS service_department_parent_id,
|
sd.parent_id AS service_department_parent_id,
|
||||||
sd.region_id AS service_department_region_id
|
sd.region_id AS service_department_region_id,
|
||||||
|
r.name AS service_department_region_name
|
||||||
FROM auth_users au
|
FROM auth_users au
|
||||||
LEFT JOIN service_departments sd ON sd.id = au.service_department_id
|
LEFT JOIN service_departments sd ON sd.id = au.service_department_id
|
||||||
|
LEFT JOIN regions r ON r.id = sd.region_id
|
||||||
WHERE au.id = %s
|
WHERE au.id = %s
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
""",
|
""",
|
||||||
|
|
@ -394,9 +399,11 @@ def list_users(include_inactive: bool = False) -> List[Dict[str, Any]]:
|
||||||
sd.code AS service_department_code,
|
sd.code AS service_department_code,
|
||||||
sd.phone AS service_department_phone,
|
sd.phone AS service_department_phone,
|
||||||
sd.parent_id AS service_department_parent_id,
|
sd.parent_id AS service_department_parent_id,
|
||||||
sd.region_id AS service_department_region_id
|
sd.region_id AS service_department_region_id,
|
||||||
|
r.name AS service_department_region_name
|
||||||
FROM auth_users au
|
FROM auth_users au
|
||||||
LEFT JOIN service_departments sd ON sd.id = au.service_department_id
|
LEFT JOIN service_departments sd ON sd.id = au.service_department_id
|
||||||
|
LEFT JOIN regions r ON r.id = sd.region_id
|
||||||
{where_clause}
|
{where_clause}
|
||||||
ORDER BY au.created_at DESC
|
ORDER BY au.created_at DESC
|
||||||
"""
|
"""
|
||||||
|
|
@ -419,6 +426,7 @@ def create_user(
|
||||||
service_department_id: Optional[str] = None,
|
service_department_id: Optional[str] = None,
|
||||||
department_role: Optional[str] = None,
|
department_role: Optional[str] = None,
|
||||||
parent_department_id: Optional[str] = None,
|
parent_department_id: Optional[str] = None,
|
||||||
|
service_department_region_id: Optional[str] = None,
|
||||||
service_department_phone: Optional[str] = None,
|
service_department_phone: Optional[str] = None,
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
username_clean = (username or "").strip().lower()
|
username_clean = (username or "").strip().lower()
|
||||||
|
|
@ -436,6 +444,7 @@ def create_user(
|
||||||
code=dept_code,
|
code=dept_code,
|
||||||
phone=(service_department_phone or "").strip() or None,
|
phone=(service_department_phone or "").strip() or None,
|
||||||
parent_id=(parent_department_id or "").strip() or None,
|
parent_id=(parent_department_id or "").strip() or None,
|
||||||
|
region_id=(service_department_region_id or "").strip() or None,
|
||||||
)
|
)
|
||||||
dept_token = created.get("id")
|
dept_token = created.get("id")
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
|
|
||||||
|
|
@ -1185,6 +1185,7 @@
|
||||||
<th>用户名</th>
|
<th>用户名</th>
|
||||||
<th>显示名</th>
|
<th>显示名</th>
|
||||||
<th>部门</th>
|
<th>部门</th>
|
||||||
|
<th>区域</th>
|
||||||
<th>角色</th>
|
<th>角色</th>
|
||||||
<th>创建时间</th>
|
<th>创建时间</th>
|
||||||
<th>操作</th>
|
<th>操作</th>
|
||||||
|
|
@ -1214,6 +1215,11 @@
|
||||||
<label>单位电话(可选)
|
<label>单位电话(可选)
|
||||||
<input type="text" name="department_phone" placeholder="用于自动创建的单位联系电话">
|
<input type="text" name="department_phone" placeholder="用于自动创建的单位联系电话">
|
||||||
</label>
|
</label>
|
||||||
|
<label>所属区域(可选)
|
||||||
|
<select id="userCreateRegion" class="form-select" name="region_id">
|
||||||
|
<option value="">不选择区域(默认继承上级区域)</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
<label>上级单位(可选,不选则创建顶级市级单位)
|
<label>上级单位(可选,不选则创建顶级市级单位)
|
||||||
<select id="userCreateParent" class="form-select">
|
<select id="userCreateParent" class="form-select">
|
||||||
<option value="">不选择上级(顶级单位)</option>
|
<option value="">不选择上级(顶级单位)</option>
|
||||||
|
|
@ -1400,6 +1406,7 @@ const rootDeptsEl = document.getElementById('rootDepts');
|
||||||
let state = {
|
let state = {
|
||||||
users: [],
|
users: [],
|
||||||
departments: [],
|
departments: [],
|
||||||
|
regions: [],
|
||||||
themes: [],
|
themes: [],
|
||||||
templateMeta: {},
|
templateMeta: {},
|
||||||
userFilter: {
|
userFilter: {
|
||||||
|
|
@ -1482,7 +1489,17 @@ async function loadCurrentUser() {
|
||||||
document.getElementById('currentUserName').textContent = user.display_name || user.username || '未知管理员';
|
document.getElementById('currentUserName').textContent = user.display_name || user.username || '未知管理员';
|
||||||
document.getElementById('currentUserRole').textContent = user.role || 'admin';
|
document.getElementById('currentUserRole').textContent = user.role || 'admin';
|
||||||
const dept = user.department;
|
const dept = user.department;
|
||||||
document.getElementById('currentUserDept').textContent = dept ? `${dept.name || ''}${dept.code ? ' · ' + dept.code : ''}` : '未绑定部门';
|
const deptPieces = [];
|
||||||
|
if (dept) {
|
||||||
|
if (dept.name) deptPieces.push(dept.name);
|
||||||
|
if (dept.code) deptPieces.push(dept.code);
|
||||||
|
if (dept.region_name) {
|
||||||
|
deptPieces.push(dept.region_name);
|
||||||
|
} else if (dept.region_id) {
|
||||||
|
deptPieces.push(dept.region_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.getElementById('currentUserDept').textContent = dept ? (deptPieces.join(' · ') || '未绑定部门') : '未绑定部门';
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('认证失败:', err);
|
console.error('认证失败:', err);
|
||||||
// 认证失败时重定向到登录页面
|
// 认证失败时重定向到登录页面
|
||||||
|
|
@ -1502,6 +1519,7 @@ function renderDepartmentOptions() {
|
||||||
deptParentSelect.innerHTML = parentOptions.join('');
|
deptParentSelect.innerHTML = parentOptions.join('');
|
||||||
}
|
}
|
||||||
renderUserCreateParentSelector();
|
renderUserCreateParentSelector();
|
||||||
|
renderUserCreateRegionSelector();
|
||||||
if (userEditDept) {
|
if (userEditDept) {
|
||||||
userEditDept.innerHTML = serviceOptions.join('');
|
userEditDept.innerHTML = serviceOptions.join('');
|
||||||
}
|
}
|
||||||
|
|
@ -1520,6 +1538,37 @@ function renderUserCreateParentSelector() {
|
||||||
parentSelect.innerHTML = options.join('');
|
parentSelect.innerHTML = options.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildRegionOptions(selectedId = '', includeBlank = true) {
|
||||||
|
const options = [];
|
||||||
|
if (includeBlank) {
|
||||||
|
options.push('<option value="">不选择区域(继承上级或稍后再设)</option>');
|
||||||
|
}
|
||||||
|
let hasSelected = false;
|
||||||
|
(state.regions || []).forEach(region => {
|
||||||
|
const value = region.id || '';
|
||||||
|
const name = region.name || value || '未命名区域';
|
||||||
|
const selected = String(selectedId || '') === String(value) ? 'selected' : '';
|
||||||
|
if (selected) {
|
||||||
|
hasSelected = true;
|
||||||
|
}
|
||||||
|
options.push(`<option value="${value}" ${selected}>${name}</option>`);
|
||||||
|
});
|
||||||
|
if (selectedId && !hasSelected && !options.find(opt => opt.includes(`value="${selectedId}"`))) {
|
||||||
|
options.push(`<option value="${selectedId}" selected>${selectedId}</option>`);
|
||||||
|
}
|
||||||
|
if (!options.length) {
|
||||||
|
options.push('<option value="">暂无区域数据</option>');
|
||||||
|
}
|
||||||
|
return options.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderUserCreateRegionSelector() {
|
||||||
|
const select = document.getElementById('userCreateRegion');
|
||||||
|
if (!select) return;
|
||||||
|
const current = select.value;
|
||||||
|
select.innerHTML = buildRegionOptions(current, true);
|
||||||
|
}
|
||||||
|
|
||||||
function renderRoleOptions() {
|
function renderRoleOptions() {
|
||||||
const roles = new Set(DEFAULT_ROLE_ORDER);
|
const roles = new Set(DEFAULT_ROLE_ORDER);
|
||||||
state.users.forEach(user => {
|
state.users.forEach(user => {
|
||||||
|
|
@ -1548,7 +1597,8 @@ function applyUserFilters(users) {
|
||||||
const roleFilter = state.userFilter.role || '';
|
const roleFilter = state.userFilter.role || '';
|
||||||
return users.filter(user => {
|
return users.filter(user => {
|
||||||
const deptName = user.department ? (user.department.name || '') : '';
|
const deptName = user.department ? (user.department.name || '') : '';
|
||||||
const text = `${user.username || ''} ${user.display_name || ''} ${deptName}`.toLowerCase();
|
const regionName = user.department ? (user.department.region_name || user.department.region_id || '') : '';
|
||||||
|
const text = `${user.username || ''} ${user.display_name || ''} ${deptName} ${regionName}`.toLowerCase();
|
||||||
const matchKeyword = !keyword || text.includes(keyword);
|
const matchKeyword = !keyword || text.includes(keyword);
|
||||||
const matchRole = !roleFilter || user.role === roleFilter;
|
const matchRole = !roleFilter || user.role === roleFilter;
|
||||||
return matchKeyword && matchRole;
|
return matchKeyword && matchRole;
|
||||||
|
|
@ -1559,16 +1609,18 @@ function renderUserTable() {
|
||||||
if (!userTableBody) return;
|
if (!userTableBody) return;
|
||||||
const filtered = applyUserFilters(state.users);
|
const filtered = applyUserFilters(state.users);
|
||||||
if (!filtered.length) {
|
if (!filtered.length) {
|
||||||
userTableBody.innerHTML = `<tr><td colspan="6" style="text-align:center;color:#6b7280;padding:14px 0;">暂无用户,点击右上角“创建账号”开始添加</td></tr>`;
|
userTableBody.innerHTML = `<tr><td colspan="7" style="text-align:center;color:#6b7280;padding:14px 0;">暂无用户,点击右上角“创建账号”开始添加</td></tr>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
userTableBody.innerHTML = filtered.map(user => {
|
userTableBody.innerHTML = filtered.map(user => {
|
||||||
const dept = user.department ? user.department.name : '—';
|
const dept = user.department ? user.department.name : '—';
|
||||||
|
const region = user.department ? (user.department.region_name || user.department.region_id || '—') : '—';
|
||||||
const isActive = activeUserId && String(user.id) === String(activeUserId);
|
const isActive = activeUserId && String(user.id) === String(activeUserId);
|
||||||
return `<tr data-id="${user.id}" class="${isActive ? 'active-row' : ''}">
|
return `<tr data-id="${user.id}" class="${isActive ? 'active-row' : ''}">
|
||||||
<td>${user.username}</td>
|
<td>${user.username}</td>
|
||||||
<td>${user.display_name || '—'}</td>
|
<td>${user.display_name || '—'}</td>
|
||||||
<td>${dept}</td>
|
<td>${dept}</td>
|
||||||
|
<td>${region}</td>
|
||||||
<td><span class="pill">${getRoleLabel(user.role)}</span></td>
|
<td><span class="pill">${getRoleLabel(user.role)}</span></td>
|
||||||
<td>${formatDate(user.created_at)}</td>
|
<td>${formatDate(user.created_at)}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -1634,6 +1686,12 @@ async function refreshUsers(options = {}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function refreshRegions() {
|
||||||
|
const data = await fetchJSON(`${API_BASE}/admin/regions`, {method: 'GET'});
|
||||||
|
state.regions = data.data.regions || [];
|
||||||
|
renderUserCreateRegionSelector();
|
||||||
|
}
|
||||||
|
|
||||||
async function refreshDepartments() {
|
async function refreshDepartments() {
|
||||||
const data = await fetchJSON(`${API_BASE}/admin/service-departments`, {method: 'GET'});
|
const data = await fetchJSON(`${API_BASE}/admin/service-departments`, {method: 'GET'});
|
||||||
state.departments = data.data.departments || [];
|
state.departments = data.data.departments || [];
|
||||||
|
|
@ -1676,12 +1734,14 @@ function fillUserDrawer(user) {
|
||||||
if (userSummaryBox) {
|
if (userSummaryBox) {
|
||||||
const dept = user.department ? `${user.department.name || ''}${user.department.code ? ' · ' + user.department.code : ''}` : '未绑定';
|
const dept = user.department ? `${user.department.name || ''}${user.department.code ? ' · ' + user.department.code : ''}` : '未绑定';
|
||||||
const deptPhone = user.department ? (user.department.phone || '—') : '—';
|
const deptPhone = user.department ? (user.department.phone || '—') : '—';
|
||||||
|
const region = user.department ? (user.department.region_name || user.department.region_id || '—') : '—';
|
||||||
userSummaryBox.innerHTML = `
|
userSummaryBox.innerHTML = `
|
||||||
<div class="summary-grid">
|
<div class="summary-grid">
|
||||||
<div><div class="label">登录账号</div><div class="value">${user.username || '—'}</div></div>
|
<div><div class="label">登录账号</div><div class="value">${user.username || '—'}</div></div>
|
||||||
<div><div class="label">显示名</div><div class="value">${user.display_name || '—'}</div></div>
|
<div><div class="label">显示名</div><div class="value">${user.display_name || '—'}</div></div>
|
||||||
<div><div class="label">角色</div><div class="value"><span class="pill">${getRoleLabel(user.role)}</span></div></div>
|
<div><div class="label">角色</div><div class="value"><span class="pill">${getRoleLabel(user.role)}</span></div></div>
|
||||||
<div><div class="label">绑定部门</div><div class="value">${dept}</div></div>
|
<div><div class="label">绑定部门</div><div class="value">${dept}</div></div>
|
||||||
|
<div><div class="label">所属区域</div><div class="value">${region}</div></div>
|
||||||
<div><div class="label">单位电话</div><div class="value">${deptPhone}</div></div>
|
<div><div class="label">单位电话</div><div class="value">${deptPhone}</div></div>
|
||||||
<div><div class="label">创建时间</div><div class="value">${formatDate(user.created_at)}</div></div>
|
<div><div class="label">创建时间</div><div class="value">${formatDate(user.created_at)}</div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1778,13 +1838,25 @@ if (userCreateForm) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
const form = evt.target;
|
const form = evt.target;
|
||||||
const parentSelect = document.getElementById('userCreateParent');
|
const parentSelect = document.getElementById('userCreateParent');
|
||||||
|
const regionSelect = document.getElementById('userCreateRegion');
|
||||||
const parentDepartmentId = parentSelect ? (parentSelect.value || '') : '';
|
const parentDepartmentId = parentSelect ? (parentSelect.value || '') : '';
|
||||||
|
let regionId = regionSelect ? regionSelect.value : '';
|
||||||
|
if (!regionId && parentDepartmentId) {
|
||||||
|
const parentDept = state.departments.find(dept => String(dept.id) === String(parentDepartmentId));
|
||||||
|
if (parentDept) {
|
||||||
|
regionId = parentDept.region_id || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!regionId && !parentDepartmentId) {
|
||||||
|
showMessage('请选择所属区域,或指定上级单位继承区域', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
const payload = {
|
const payload = {
|
||||||
username: form.username.value.trim(),
|
username: form.username.value.trim(),
|
||||||
password: form.password.value.trim(),
|
password: form.password.value.trim(),
|
||||||
display_name: form.display_name.value.trim(),
|
display_name: form.display_name.value.trim(),
|
||||||
parent_department_id: parentDepartmentId || null,
|
parent_department_id: parentDepartmentId || null,
|
||||||
|
region_id: regionId || null,
|
||||||
department_phone: (form.department_phone.value || '').trim()
|
department_phone: (form.department_phone.value || '').trim()
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
|
|
@ -1799,6 +1871,9 @@ if (userCreateForm) {
|
||||||
if (parentSelect) {
|
if (parentSelect) {
|
||||||
parentSelect.value = '';
|
parentSelect.value = '';
|
||||||
}
|
}
|
||||||
|
if (regionSelect) {
|
||||||
|
regionSelect.value = '';
|
||||||
|
}
|
||||||
form.department_phone.value = '';
|
form.department_phone.value = '';
|
||||||
switchUserSubtab('user-list-panel');
|
switchUserSubtab('user-list-panel');
|
||||||
await refreshDepartments();
|
await refreshDepartments();
|
||||||
|
|
@ -1807,6 +1882,18 @@ if (userCreateForm) {
|
||||||
showMessage(err.message, 'error');
|
showMessage(err.message, 'error');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const parentSelect = document.getElementById('userCreateParent');
|
||||||
|
const regionSelect = document.getElementById('userCreateRegion');
|
||||||
|
if (parentSelect && regionSelect) {
|
||||||
|
parentSelect.addEventListener('change', () => {
|
||||||
|
if (regionSelect.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const parentDept = state.departments.find(dept => String(dept.id) === String(parentSelect.value || ''));
|
||||||
|
regionSelect.value = parentDept ? (parentDept.region_id || '') : '';
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userEditForm) {
|
if (userEditForm) {
|
||||||
|
|
@ -2084,6 +2171,7 @@ function flattenTree(nodes, level = 0, result = [], parentId = null) {
|
||||||
name: node.name || '未知部门',
|
name: node.name || '未知部门',
|
||||||
code: node.code || '',
|
code: node.code || '',
|
||||||
region_name: node.region_name || '',
|
region_name: node.region_name || '',
|
||||||
|
region_id: node.region_id || '',
|
||||||
level,
|
level,
|
||||||
node
|
node
|
||||||
};
|
};
|
||||||
|
|
@ -2556,6 +2644,7 @@ document.getElementById('downloadTemplateBtn').addEventListener('click', () => {
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
await loadCurrentUser();
|
await loadCurrentUser();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
refreshRegions(),
|
||||||
refreshUsers(),
|
refreshUsers(),
|
||||||
refreshDepartments(),
|
refreshDepartments(),
|
||||||
refreshThemes(),
|
refreshThemes(),
|
||||||
|
|
@ -2634,6 +2723,7 @@ function showAddChildModal(parentNode) {
|
||||||
name: formData.get('name'),
|
name: formData.get('name'),
|
||||||
code: formData.get('code'),
|
code: formData.get('code'),
|
||||||
phone: formData.get('phone'),
|
phone: formData.get('phone'),
|
||||||
|
region_id: formData.get('region_id'),
|
||||||
parent_id: parentNode.id,
|
parent_id: parentNode.id,
|
||||||
description: formData.get('description'),
|
description: formData.get('description'),
|
||||||
grade: autoGrade // 自动计算,无需手动选择
|
grade: autoGrade // 自动计算,无需手动选择
|
||||||
|
|
@ -2662,6 +2752,12 @@ function showAddChildModal(parentNode) {
|
||||||
<label>联系电话
|
<label>联系电话
|
||||||
<input type="text" name="phone" placeholder="座机或手机号">
|
<input type="text" name="phone" placeholder="座机或手机号">
|
||||||
</label>
|
</label>
|
||||||
|
<label>所属区域
|
||||||
|
<select name="region_id">
|
||||||
|
${buildRegionOptions(parentNode.region_id || '', true)}
|
||||||
|
</select>
|
||||||
|
<small style="color: #6b7280; font-size: 12px;">不选择则默认继承上级区域</small>
|
||||||
|
</label>
|
||||||
<label>备注
|
<label>备注
|
||||||
<textarea name="description" rows="2" placeholder="可填写简要职责"></textarea>
|
<textarea name="description" rows="2" placeholder="可填写简要职责"></textarea>
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -2676,6 +2772,7 @@ function showEditModal(nodeData) {
|
||||||
return {
|
return {
|
||||||
name: formData.get('name'),
|
name: formData.get('name'),
|
||||||
phone: formData.get('phone'),
|
phone: formData.get('phone'),
|
||||||
|
region_id: formData.get('region_id'),
|
||||||
description: formData.get('description')
|
description: formData.get('description')
|
||||||
// 编辑时不修改grade,grade根据层级自动计算
|
// 编辑时不修改grade,grade根据层级自动计算
|
||||||
};
|
};
|
||||||
|
|
@ -2702,6 +2799,11 @@ function showEditModal(nodeData) {
|
||||||
<label>联系电话
|
<label>联系电话
|
||||||
<input type="text" name="phone" value="${nodeData.phone || ''}">
|
<input type="text" name="phone" value="${nodeData.phone || ''}">
|
||||||
</label>
|
</label>
|
||||||
|
<label>所属区域
|
||||||
|
<select name="region_id">
|
||||||
|
${buildRegionOptions(nodeData.region_id || '', true)}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
<label>备注
|
<label>备注
|
||||||
<textarea name="description" rows="2">${nodeData.description || ''}</textarea>
|
<textarea name="description" rows="2">${nodeData.description || ''}</textarea>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue