Browse Source

feat(factory): 添加部门成员管理功能

- 新增 AccessDeptListMembersRequest DTO 类用于查询部门成员列表
- 创建 AccessDeptMemberController 控制器实现部门成员的增删改查接口
- 添加 AccessDeptMemberDeleteRequest 和 AccessDeptMemberSaveRequest DTO 类
- 实现 AccessDeptMemberService 接口定义部门成员管理业务方法
- 提供 AccessDeptMemberServiceImpl 服务实现类包含完整的业务逻辑
- 扩展 SiteMapper 数据访问接口添加部门成员相关操作方法
- 在 SiteMapper.xml 中实现新增的部门成员管理 SQL 映射语句
- 添加部门成员验证逻辑包括上级关系检查和循环引用防护
- 实现部门成员的保存、更新、删除和查询功能
master
qiankanghui 2 months ago
parent
commit
815369ca82
  1. 54
      src/main/java/com/xujie/modules/factory/controller/AccessDeptMemberController.java
  2. 17
      src/main/java/com/xujie/modules/factory/dao/SiteMapper.java
  3. 39
      src/main/java/com/xujie/modules/factory/entity/dto/AccessDeptListMembersRequest.java
  4. 48
      src/main/java/com/xujie/modules/factory/entity/dto/AccessDeptMemberDeleteRequest.java
  5. 75
      src/main/java/com/xujie/modules/factory/entity/dto/AccessDeptMemberSaveRequest.java
  6. 21
      src/main/java/com/xujie/modules/factory/entity/dto/UserAccessDeptQueryRequest.java
  7. 22
      src/main/java/com/xujie/modules/factory/service/AccessDeptMemberService.java
  8. 170
      src/main/java/com/xujie/modules/factory/service/impl/AccessDeptMemberServiceImpl.java
  9. 37
      src/main/java/com/xujie/modules/sys/entity/SysDepartmentEntity.java
  10. 75
      src/main/resources/mapper/factory/SiteMapper.xml
  11. 2
      src/main/resources/mapper/sys/SysDepartmentMapper.xml

54
src/main/java/com/xujie/modules/factory/controller/AccessDeptMemberController.java

@ -0,0 +1,54 @@
package com.xujie.modules.factory.controller;
import com.xujie.common.utils.R;
import com.xujie.modules.factory.entity.dto.AccessDeptListMembersRequest;
import com.xujie.modules.factory.entity.dto.AccessDeptMemberDeleteRequest;
import com.xujie.modules.factory.entity.dto.AccessDeptMemberSaveRequest;
import com.xujie.modules.factory.entity.dto.UserAccessDeptQueryRequest;
import com.xujie.modules.factory.service.AccessDeptMemberService;
import com.xujie.modules.sys.entity.SysDepartmentEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequestMapping("/site/accessDept")
@RestController
public class AccessDeptMemberController {
@Autowired
private AccessDeptMemberService accessDeptMemberService;
@PostMapping("/listMembers")
public R listMembers(@RequestBody AccessDeptListMembersRequest request) {
List<SysDepartmentEntity> list = accessDeptMemberService.listMembers(request);
return R.ok().put("list", list);
}
@PostMapping("/saveMember")
public R saveMember(@RequestBody AccessDeptMemberSaveRequest request) {
accessDeptMemberService.saveMember(request);
return R.ok();
}
@PostMapping("/updateMember")
public R updateMember(@RequestBody AccessDeptMemberSaveRequest request) {
accessDeptMemberService.updateMember(request);
return R.ok();
}
@PostMapping("/deleteMember")
public R deleteMember(@RequestBody AccessDeptMemberDeleteRequest request) {
accessDeptMemberService.deleteMember(request);
return R.ok();
}
@PostMapping("/listByUsername")
public R listByUsername(@RequestBody UserAccessDeptQueryRequest request) {
List<SysDepartmentEntity> list = accessDeptMemberService.listByUsername(request);
return R.ok().put("list", list);
}
}

17
src/main/java/com/xujie/modules/factory/dao/SiteMapper.java

@ -85,4 +85,21 @@ public interface SiteMapper extends BaseMapper<Site> {
List<EmpyDept> getEmpyDeptList(EmpyDept data);
List<SiteVo> getSite2(SiteVo data);
List<SysDepartmentEntity> listAccessDeptMembers(SysDepartmentEntity deptKey);
void insertAccessDeptMember(SysDepartmentEntity row);
void updateAccessDeptMember(SysDepartmentEntity row);
int countDirectReportsInDept(SysDepartmentEntity row);
void deleteAccessDeptMember(SysDepartmentEntity row);
List<SysDepartmentEntity> listAccessDeptByUsername(SysDepartmentEntity query);
int countMemberInDept(SysDepartmentEntity row);
String selectSuperiorUsernameInDept(SysDepartmentEntity row);
}

39
src/main/java/com/xujie/modules/factory/entity/dto/AccessDeptListMembersRequest.java

@ -0,0 +1,39 @@
package com.xujie.modules.factory.entity.dto;
import java.io.Serializable;
/**
* 查询某部门下的成员列表
*/
public class AccessDeptListMembersRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String site;
private String buNo;
private String departmentId;
public String getSite() {
return site;
}
public void setSite(String site) {
this.site = site;
}
public String getBuNo() {
return buNo;
}
public void setBuNo(String buNo) {
this.buNo = buNo;
}
public String getDepartmentId() {
return departmentId;
}
public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}
}

48
src/main/java/com/xujie/modules/factory/entity/dto/AccessDeptMemberDeleteRequest.java

@ -0,0 +1,48 @@
package com.xujie.modules.factory.entity.dto;
import java.io.Serializable;
/**
* 从部门移除成员
*/
public class AccessDeptMemberDeleteRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String site;
private String buNo;
private String departmentId;
private String username;
public String getSite() {
return site;
}
public void setSite(String site) {
this.site = site;
}
public String getBuNo() {
return buNo;
}
public void setBuNo(String buNo) {
this.buNo = buNo;
}
public String getDepartmentId() {
return departmentId;
}
public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}

75
src/main/java/com/xujie/modules/factory/entity/dto/AccessDeptMemberSaveRequest.java

@ -0,0 +1,75 @@
package com.xujie.modules.factory.entity.dto;
import java.io.Serializable;
/**
* 新增或更新部门成员
*/
public class AccessDeptMemberSaveRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String site;
private String buNo;
private String departmentId;
private String username;
private String jobTitle;
private String deptManagerFlag;
private String superiorUsername;
public String getSite() {
return site;
}
public void setSite(String site) {
this.site = site;
}
public String getBuNo() {
return buNo;
}
public void setBuNo(String buNo) {
this.buNo = buNo;
}
public String getDepartmentId() {
return departmentId;
}
public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getJobTitle() {
return jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
public String getDeptManagerFlag() {
return deptManagerFlag;
}
public void setDeptManagerFlag(String deptManagerFlag) {
this.deptManagerFlag = deptManagerFlag;
}
public String getSuperiorUsername() {
return superiorUsername;
}
public void setSuperiorUsername(String superiorUsername) {
this.superiorUsername = superiorUsername;
}
}

21
src/main/java/com/xujie/modules/factory/entity/dto/UserAccessDeptQueryRequest.java

@ -0,0 +1,21 @@
package com.xujie.modules.factory.entity.dto;
import java.io.Serializable;
/**
* 按用户查询其全部 Access_dept 记录
*/
public class UserAccessDeptQueryRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}

22
src/main/java/com/xujie/modules/factory/service/AccessDeptMemberService.java

@ -0,0 +1,22 @@
package com.xujie.modules.factory.service;
import com.xujie.modules.factory.entity.dto.AccessDeptListMembersRequest;
import com.xujie.modules.factory.entity.dto.AccessDeptMemberDeleteRequest;
import com.xujie.modules.factory.entity.dto.AccessDeptMemberSaveRequest;
import com.xujie.modules.factory.entity.dto.UserAccessDeptQueryRequest;
import com.xujie.modules.sys.entity.SysDepartmentEntity;
import java.util.List;
public interface AccessDeptMemberService {
List<SysDepartmentEntity> listMembers(AccessDeptListMembersRequest request);
void saveMember(AccessDeptMemberSaveRequest request);
void updateMember(AccessDeptMemberSaveRequest request);
void deleteMember(AccessDeptMemberDeleteRequest request);
List<SysDepartmentEntity> listByUsername(UserAccessDeptQueryRequest request);
}

170
src/main/java/com/xujie/modules/factory/service/impl/AccessDeptMemberServiceImpl.java

@ -0,0 +1,170 @@
package com.xujie.modules.factory.service.impl;
import com.xujie.modules.factory.dao.SiteMapper;
import com.xujie.modules.factory.entity.dto.AccessDeptListMembersRequest;
import com.xujie.modules.factory.entity.dto.AccessDeptMemberDeleteRequest;
import com.xujie.modules.factory.entity.dto.AccessDeptMemberSaveRequest;
import com.xujie.modules.factory.entity.dto.UserAccessDeptQueryRequest;
import com.xujie.modules.factory.service.AccessDeptMemberService;
import com.xujie.modules.sys.entity.SysDepartmentEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@Service
public class AccessDeptMemberServiceImpl implements AccessDeptMemberService {
@Autowired
private SiteMapper siteMapper;
@Override
public List<SysDepartmentEntity> listMembers(AccessDeptListMembersRequest request) {
requireDeptKey(request.getSite(), request.getBuNo(), request.getDepartmentId());
SysDepartmentEntity key = new SysDepartmentEntity();
key.setSite(trimToNull(request.getSite()));
key.setBuNo(trimToNull(request.getBuNo()));
key.setDepartmentId(trimToNull(request.getDepartmentId()));
List<SysDepartmentEntity> list = siteMapper.listAccessDeptMembers(key);
return list != null ? list : new ArrayList<>();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveMember(AccessDeptMemberSaveRequest request) {
requireDeptKey(request.getSite(), request.getBuNo(), request.getDepartmentId());
String username = trimToNull(request.getUsername());
if (username == null) {
throw new RuntimeException("账号不能为空");
}
SysDepartmentEntity row = toEntity(request);
SysDepartmentEntity exists = siteMapper.selectDeptByUserName(row);
if (exists != null) {
throw new RuntimeException("该用户已在本部门中");
}
validateSuperiorChain(row.getSite(), row.getBuNo(), row.getDepartmentId(), username, row.getSuperiorUsername());
siteMapper.insertAccessDeptMember(row);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateMember(AccessDeptMemberSaveRequest request) {
requireDeptKey(request.getSite(), request.getBuNo(), request.getDepartmentId());
String username = trimToNull(request.getUsername());
if (username == null) {
throw new RuntimeException("账号不能为空");
}
SysDepartmentEntity row = toEntity(request);
SysDepartmentEntity exists = siteMapper.selectDeptByUserName(row);
if (exists == null) {
throw new RuntimeException("成员不存在");
}
validateSuperiorChain(row.getSite(), row.getBuNo(), row.getDepartmentId(), username, row.getSuperiorUsername());
siteMapper.updateAccessDeptMember(row);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteMember(AccessDeptMemberDeleteRequest request) {
requireDeptKey(request.getSite(), request.getBuNo(), request.getDepartmentId());
String username = trimToNull(request.getUsername());
if (username == null) {
throw new RuntimeException("账号不能为空");
}
SysDepartmentEntity row = new SysDepartmentEntity();
row.setSite(trimToNull(request.getSite()));
row.setBuNo(trimToNull(request.getBuNo()));
row.setDepartmentId(trimToNull(request.getDepartmentId()));
row.setUsername(username);
int subs = siteMapper.countDirectReportsInDept(row);
if (subs > 0) {
throw new RuntimeException("存在以该用户为上级的人员,请先调整其上级后再删除");
}
siteMapper.deleteAccessDeptMember(row);
}
@Override
public List<SysDepartmentEntity> listByUsername(UserAccessDeptQueryRequest request) {
String username = trimToNull(request.getUsername());
if (username == null) {
return new ArrayList<>();
}
SysDepartmentEntity q = new SysDepartmentEntity();
q.setUsername(username);
List<SysDepartmentEntity> list = siteMapper.listAccessDeptByUsername(q);
return list != null ? list : new ArrayList<>();
}
private static void requireDeptKey(String site, String buNo, String departmentId) {
if (StringUtils.isAnyBlank(site, buNo, departmentId)) {
throw new RuntimeException("工厂、BU、部门不能为空");
}
}
private SysDepartmentEntity toEntity(AccessDeptMemberSaveRequest request) {
SysDepartmentEntity row = new SysDepartmentEntity();
row.setSite(trimToNull(request.getSite()));
row.setBuNo(trimToNull(request.getBuNo()));
row.setDepartmentId(trimToNull(request.getDepartmentId()));
row.setUsername(trimToNull(request.getUsername()));
row.setJobTitle(trimToNull(request.getJobTitle()));
row.setDeptManagerFlag(normalizeManagerFlag(request.getDeptManagerFlag()));
row.setSuperiorUsername(trimToNull(request.getSuperiorUsername()));
return row;
}
private static String normalizeManagerFlag(String flag) {
if (StringUtils.isBlank(flag)) {
return "N";
}
String f = flag.trim();
if ("Y".equalsIgnoreCase(f) || "1".equals(f) || "true".equalsIgnoreCase(f)) {
return "Y";
}
return "N";
}
private static String trimToNull(String s) {
if (s == null) {
return null;
}
String t = s.trim();
return t.isEmpty() ? null : t;
}
private void validateSuperiorChain(String site, String buNo, String deptId, String memberUsername, String superiorUsername) {
if (StringUtils.isBlank(superiorUsername)) {
return;
}
String sup = superiorUsername.trim();
if (sup.equalsIgnoreCase(memberUsername)) {
throw new RuntimeException("上级不能是自己");
}
SysDepartmentEntity check = new SysDepartmentEntity();
check.setSite(site);
check.setBuNo(buNo);
check.setDepartmentId(deptId);
check.setUsername(sup);
if (siteMapper.countMemberInDept(check) == 0) {
throw new RuntimeException("上级必须是本部门已有成员");
}
String current = sup;
for (int i = 0; i < 64; i++) {
if (current != null && current.equalsIgnoreCase(memberUsername)) {
throw new RuntimeException("上级关系不能形成环路");
}
if (current == null) {
break;
}
check.setUsername(current);
String next = siteMapper.selectSuperiorUsernameInDept(check);
if (StringUtils.isBlank(next)) {
break;
}
current = next.trim();
}
}
}

37
src/main/java/com/xujie/modules/sys/entity/SysDepartmentEntity.java

@ -43,8 +43,45 @@ public class SysDepartmentEntity extends QueryPage {
*/
private String buDesc;
/**
* 部门内职称Access_dept.job_title
*/
private String jobTitle;
/**
* 是否部门经理 Y/NAccess_dept.dept_manager_flag
*/
private String deptManagerFlag;
/**
* 同部门内直属上级账号Access_dept.superior_username
*/
private String superiorUsername;
private List<SysDepartmentEntity> deptList;
public String getJobTitle() {
return jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
public String getDeptManagerFlag() {
return deptManagerFlag;
}
public void setDeptManagerFlag(String deptManagerFlag) {
this.deptManagerFlag = deptManagerFlag;
}
public String getSuperiorUsername() {
return superiorUsername;
}
public void setSuperiorUsername(String superiorUsername) {
this.superiorUsername = superiorUsername;
}
public List<SysDepartmentEntity> getDeptList() {
return deptList;
}

75
src/main/resources/mapper/factory/SiteMapper.xml

@ -454,4 +454,77 @@
</if>
</where>
</select>
</mapper>
<!-- 部门成员列表(部门人员维护页下表) -->
<select id="listAccessDeptMembers" resultType="SysDepartmentEntity" parameterType="SysDepartmentEntity">
SELECT
ad.site,
ad.bu_no,
dbo.get_bu_desc(ad.site, ad.bu_no) AS buDesc,
ad.department_id,
ISNULL(d.department_name, '') AS department_name,
ad.username,
ad.job_title AS jobTitle,
ad.dept_manager_flag AS deptManagerFlag,
ad.superior_username AS superiorUsername
FROM Access_dept ad
LEFT JOIN sys_department d ON d.site = ad.site AND d.bu_no = ad.bu_no AND d.department_id = ad.department_id
WHERE ad.site = #{site} AND ad.bu_no = #{buNo} AND ad.department_id = #{departmentId}
ORDER BY ad.username
</select>
<insert id="insertAccessDeptMember" parameterType="SysDepartmentEntity">
INSERT INTO Access_dept (site, bu_no, department_id, username, job_title, dept_manager_flag, superior_username)
VALUES (#{site}, #{buNo}, #{departmentId}, #{username}, #{jobTitle}, #{deptManagerFlag}, #{superiorUsername})
</insert>
<update id="updateAccessDeptMember" parameterType="SysDepartmentEntity">
UPDATE Access_dept
SET job_title = #{jobTitle},
dept_manager_flag = #{deptManagerFlag},
superior_username = #{superiorUsername}
WHERE site = #{site} AND bu_no = #{buNo} AND department_id = #{departmentId} AND username = #{username}
</update>
<select id="countDirectReportsInDept" resultType="int" parameterType="SysDepartmentEntity">
SELECT COUNT(1)
FROM Access_dept
WHERE site = #{site} AND bu_no = #{buNo} AND department_id = #{departmentId}
AND superior_username = #{username}
</select>
<delete id="deleteAccessDeptMember" parameterType="SysDepartmentEntity">
DELETE FROM Access_dept
WHERE site = #{site} AND bu_no = #{buNo} AND department_id = #{departmentId} AND username = #{username}
</delete>
<!-- 某用户全部 Access_dept 行(用户管理-查看部门) -->
<select id="listAccessDeptByUsername" resultType="SysDepartmentEntity" parameterType="SysDepartmentEntity">
SELECT
ad.site,
ad.bu_no,
dbo.get_bu_desc(ad.site, ad.bu_no) AS buDesc,
ad.department_id,
ISNULL(d.department_name, '') AS department_name,
ad.username,
ad.job_title AS jobTitle,
ad.dept_manager_flag AS deptManagerFlag,
ad.superior_username AS superiorUsername
FROM Access_dept ad
LEFT JOIN sys_department d ON d.site = ad.site AND d.bu_no = ad.bu_no AND d.department_id = ad.department_id
WHERE ad.username = #{username}
ORDER BY ad.site, ad.bu_no, ad.department_id
</select>
<select id="selectSuperiorUsernameInDept" resultType="java.lang.String" parameterType="SysDepartmentEntity">
SELECT superior_username
FROM Access_dept
WHERE site = #{site} AND bu_no = #{buNo} AND department_id = #{departmentId} AND username = #{username}
</select>
<select id="countMemberInDept" resultType="int" parameterType="SysDepartmentEntity">
SELECT COUNT(1)
FROM Access_dept
WHERE site = #{site} AND bu_no = #{buNo} AND department_id = #{departmentId} AND username = #{username}
</select>
</mapper>

2
src/main/resources/mapper/sys/SysDepartmentMapper.xml

@ -26,6 +26,8 @@
AND department_name like '%' + #{query.departmentName} + '%'
</if>
</where>
order by department_id
</select>
<!-- 查询部门是否已存在 -->

Loading…
Cancel
Save