修复部门设置负责人失败的问题
- 前端:允许选择所有用户作为部门负责人,不限于该部门成员 - 前端:修复leaderId和parentId的类型兼容性问题 - 后端:添加leaderId有效性验证,防止设置不存在的用户
This commit is contained in:
parent
ec6a0d1838
commit
6df38c4f89
@ -28,7 +28,6 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 部门管理Service
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DepartmentService {
|
||||
@ -106,6 +105,14 @@ public class DepartmentService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public DepartmentOverviewVO createDepartment(DepartmentCreateRequest request) {
|
||||
validateDeptType(request.getDeptType());
|
||||
|
||||
// 验证负责人ID是否有效
|
||||
if (request.getLeaderId() != null && request.getLeaderId() > 0) {
|
||||
User leader = userMapper.selectById(request.getLeaderId());
|
||||
if (leader == null) {
|
||||
throw new BusinessException("指定的负责人不存在");
|
||||
}
|
||||
}
|
||||
|
||||
Department department = new Department();
|
||||
department.setDeptName(request.getDeptName());
|
||||
@ -179,6 +186,13 @@ public class DepartmentService {
|
||||
// 但由于无法判断字段是否存在,我们采用:如果leaderId不为null,则更新
|
||||
if (request.getLeaderId() != null) {
|
||||
Long leaderId = request.getLeaderId();
|
||||
// 验证负责人ID是否有效(0表示清除,大于0需要验证)
|
||||
if (leaderId > 0) {
|
||||
User leader = userMapper.selectById(leaderId);
|
||||
if (leader == null) {
|
||||
throw new BusinessException("指定的负责人不存在");
|
||||
}
|
||||
}
|
||||
existDept.setLeaderId(leaderId == 0 ? null : leaderId);
|
||||
} else if (request.getDeptName() != null) {
|
||||
// 如果其他字段被更新(说明这是完整的更新请求),且leaderId为null,则清除负责人
|
||||
@ -211,42 +225,20 @@ public class DepartmentService {
|
||||
existDept.setOverLimitAction(request.getOverLimitAction());
|
||||
}
|
||||
|
||||
try {
|
||||
departmentMapper.updateById(existDept);
|
||||
log.info("更新部门成功: id={}, deptName={}", id, existDept.getDeptName());
|
||||
} catch (Exception e) {
|
||||
log.error("更新部门失败: id={}, error={}", id, e.getMessage(), e);
|
||||
throw new BusinessException("更新部门失败: " + e.getMessage());
|
||||
}
|
||||
departmentMapper.updateById(existDept);
|
||||
|
||||
// 同步积分池
|
||||
try {
|
||||
teamScorePoolService.upsertPool(existDept.getId(), existDept.getDeptName());
|
||||
log.info("同步积分池成功: deptId={}, deptName={}", existDept.getId(), existDept.getDeptName());
|
||||
} catch (Exception e) {
|
||||
log.error("同步积分池失败: deptId={}, error={}", existDept.getId(), e.getMessage(), e);
|
||||
throw new BusinessException("同步积分池失败: " + e.getMessage());
|
||||
}
|
||||
|
||||
// 更新积分池限制配置(仅需求部门)
|
||||
teamScorePoolService.upsertPool(existDept.getId(), existDept.getDeptName());
|
||||
if ("demand".equals(existDept.getDeptType()) &&
|
||||
(request.getLimitEnabled() != null || request.getLimitPeriod() != null ||
|
||||
request.getPeriodLimit() != null || request.getAlertThreshold() != null)) {
|
||||
try {
|
||||
teamScorePoolService.updateLimitConfig(
|
||||
existDept.getId(),
|
||||
request.getLimitEnabled(),
|
||||
request.getLimitPeriod(),
|
||||
request.getPeriodLimit(),
|
||||
request.getAlertThreshold()
|
||||
);
|
||||
log.info("更新积分池限制配置成功: deptId={}, limitEnabled={}, limitPeriod={}, periodLimit={}, alertThreshold={}",
|
||||
existDept.getId(), request.getLimitEnabled(), request.getLimitPeriod(),
|
||||
request.getPeriodLimit(), request.getAlertThreshold());
|
||||
} catch (Exception e) {
|
||||
log.error("更新积分池限制配置失败: deptId={}, error={}", existDept.getId(), e.getMessage(), e);
|
||||
throw new BusinessException("更新积分池限制配置失败: " + e.getMessage());
|
||||
}
|
||||
teamScorePoolService.updateLimitConfig(
|
||||
existDept.getId(),
|
||||
request.getLimitEnabled(),
|
||||
request.getLimitPeriod(),
|
||||
request.getPeriodLimit(),
|
||||
request.getAlertThreshold()
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@ -1118,7 +1118,7 @@
|
||||
</a-form-item>
|
||||
<a-form-item label="部门负责人">
|
||||
<a-select
|
||||
v-model:value="formData.department.leaderId"
|
||||
v-model:value="departmentLeaderId"
|
||||
placeholder="请选择部门负责人"
|
||||
allow-clear
|
||||
show-search
|
||||
@ -1134,7 +1134,7 @@
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="上级部门">
|
||||
<a-select v-model:value="formData.department.parentId" placeholder="请选择上级部门" allow-clear>
|
||||
<a-select v-model:value="departmentParentId" placeholder="请选择上级部门" allow-clear>
|
||||
<a-select-option :value="0">顶级部门</a-select-option>
|
||||
<a-select-option
|
||||
v-for="dept in departments.filter(d => !editingItem || d.id !== editingItem.id)"
|
||||
@ -1367,7 +1367,7 @@ interface DepartmentForm {
|
||||
deptCode?: string
|
||||
deptType: DeptType
|
||||
parentId?: number | null
|
||||
leaderId?: number | null
|
||||
leaderId?: number | null | undefined
|
||||
description?: string
|
||||
sortOrder?: number
|
||||
status?: number
|
||||
@ -1477,7 +1477,7 @@ const defaultDepartmentForm = (): DepartmentForm => ({
|
||||
deptCode: '',
|
||||
deptType: 'demand',
|
||||
parentId: 0,
|
||||
leaderId: null,
|
||||
leaderId: undefined,
|
||||
description: '',
|
||||
sortOrder: 0,
|
||||
status: 1,
|
||||
@ -1521,18 +1521,13 @@ const unassignedUsers = computed(() => {
|
||||
|
||||
// 过滤出当前部门的用户(用于负责人选择)
|
||||
const departmentUsers = computed(() => {
|
||||
// 如果是编辑部门,只显示该部门的用户
|
||||
if (editingItem.value?.id) {
|
||||
const deptId = editingItem.value.id
|
||||
const users = usersByDept.value[deptId] || []
|
||||
return users.slice().sort((a, b) => {
|
||||
const nameA = a.realName || a.username || ''
|
||||
const nameB = b.realName || b.username || ''
|
||||
return nameA.localeCompare(nameB)
|
||||
})
|
||||
}
|
||||
// 如果是新建部门,显示未分配部门的用户
|
||||
return unassignedUsers.value
|
||||
// 部门负责人应该可以选择任何用户,不限制于该部门的成员
|
||||
// 返回所有用户的排序列表
|
||||
return allUsers.value.slice().sort((a, b) => {
|
||||
const nameA = a.realName || a.username || ''
|
||||
const nameB = b.realName || b.username || ''
|
||||
return nameA.localeCompare(nameB)
|
||||
})
|
||||
})
|
||||
|
||||
const hasUserData = computed(() => {
|
||||
@ -1949,7 +1944,7 @@ const showDepartmentModal = async (item?: DepartmentOverview) => {
|
||||
deptCode: item.deptCode,
|
||||
deptType: item.deptType,
|
||||
parentId: item.parentId ?? 0,
|
||||
leaderId: item.leaderId ?? null,
|
||||
leaderId: item.leaderId ?? undefined,
|
||||
description: item.description,
|
||||
sortOrder: item.sortOrder ?? 0,
|
||||
status: item.status ?? 1,
|
||||
@ -2128,6 +2123,17 @@ const saveCategory = async () => {
|
||||
const isDemandDept = computed(() => formData.department.deptType === 'demand')
|
||||
const isReceivingDept = computed(() => formData.department.deptType === 'receiving')
|
||||
|
||||
// Computed属性用于处理leaderId和parentId的null到undefined的转换,以兼容a-select
|
||||
const departmentLeaderId = computed({
|
||||
get: () => formData.department.leaderId ?? undefined,
|
||||
set: (val) => { formData.department.leaderId = val ?? undefined }
|
||||
})
|
||||
|
||||
const departmentParentId = computed({
|
||||
get: () => formData.department.parentId ?? undefined,
|
||||
set: (val) => { formData.department.parentId = val ?? undefined }
|
||||
})
|
||||
|
||||
const buildDepartmentPayload = (includeInitial: boolean): DepartmentPayload => {
|
||||
const payload: DepartmentPayload = {
|
||||
deptName: formData.department.deptName,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user