feat(): 新增消防队伍成员管理功能

dev
lishiwei 2026-07-09 18:05:28 +08:00
parent d0424faa28
commit 8ac39be8d1
13 changed files with 554 additions and 0 deletions

View File

@ -0,0 +1,63 @@
package com.zcloud.zcGbsServicer.web;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.zcGbsServicer.api.FireBrigadeMemberServiceI;
import com.zcloud.zcGbsServicer.dto.FireBrigadeMemberAddCmd;
import com.zcloud.zcGbsServicer.dto.FireBrigadeMemberPageQry;
import com.zcloud.zcGbsServicer.dto.FireBrigadeMemberUpdateCmd;
import com.zcloud.zcGbsServicer.dto.clientobject.FireBrigadeMemberCO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api(tags = "消防队伍成员")
@RestController
@AllArgsConstructor
@RequestMapping("/${application.gateway}/fireBrigade/member")
public class FireBrigadeMemberController {
private final FireBrigadeMemberServiceI fireBrigadeMemberService;
@ApiOperation("分页查询")
@PostMapping("/list")
public PageResponse<FireBrigadeMemberCO> list(@RequestBody FireBrigadeMemberPageQry qry) {
return fireBrigadeMemberService.listPage(qry);
}
@ApiOperation("新增")
@PostMapping("/save")
public SingleResponse<FireBrigadeMemberCO> save(@Validated @RequestBody FireBrigadeMemberAddCmd cmd) {
return fireBrigadeMemberService.add(cmd);
}
@ApiOperation("编辑")
@PutMapping("/edit")
public Response edit(@Validated @RequestBody FireBrigadeMemberUpdateCmd cmd) {
fireBrigadeMemberService.edit(cmd);
return Response.buildSuccess();
}
@ApiOperation("详情")
@GetMapping("/{id}")
public SingleResponse<FireBrigadeMemberCO> get(@PathVariable Long id) {
return SingleResponse.of(fireBrigadeMemberService.get(id));
}
@ApiOperation("删除")
@DeleteMapping("/{id}")
public Response remove(@PathVariable Long id) {
fireBrigadeMemberService.remove(id);
return Response.buildSuccess();
}
@ApiOperation("批量删除")
@DeleteMapping("/ids")
public Response removeBatch(@RequestParam Long[] ids) {
fireBrigadeMemberService.removeBatch(ids);
return Response.buildSuccess();
}
}

View File

@ -0,0 +1,18 @@
package com.zcloud.zcGbsServicer.command.convertor;
import com.zcloud.zcGbsServicer.dto.clientobject.FireBrigadeMemberCO;
import com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeUserDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import java.util.List;
@Mapper(componentModel = "spring")
public interface FireBrigadeMemberCoConvertor {
@Mapping(source = "fireBrigadeId", target = "fireBrigadeBizId")
List<FireBrigadeMemberCO> converDOsToCOs(List<FireBrigadeUserDO> fireBrigadeUserDOs);
@Mapping(source = "fireBrigadeId", target = "fireBrigadeBizId")
FireBrigadeMemberCO converDOToCO(FireBrigadeUserDO fireBrigadeUserDO);
}

View File

@ -0,0 +1,42 @@
package com.zcloud.zcGbsServicer.service;
import com.alibaba.cola.dto.MultiResponse;
import com.zcloud.gbscommon.zclouduser.facade.ZcloudUserFacade;
import com.zcloud.gbscommon.zclouduser.response.ZcloudUserCo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
@Component
public class FireAlarmUserResolver {
@DubboReference(check = false)
private ZcloudUserFacade zcloudUserFacade;
public Map<Long, ZcloudUserCo> getUserMap(Collection<Long> userIds) {
if (userIds == null || userIds.isEmpty()) {
return Collections.emptyMap();
}
MultiResponse<ZcloudUserCo> response;
try {
response = zcloudUserFacade.listByUserIds(userIds);
}
catch (Exception ex) {
return Collections.emptyMap();
}
if (response == null || response.getData() == null || response.getData().isEmpty()) {
return Collections.emptyMap();
}
Map<Long, ZcloudUserCo> userMap = new LinkedHashMap<>();
for (ZcloudUserCo user : response.getData()) {
if (user != null && user.getId() != null) {
userMap.put(user.getId(), user);
}
}
return userMap;
}
}

View File

@ -0,0 +1,212 @@
package com.zcloud.zcGbsServicer.service;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.zcloud.gbscommon.zclouduser.response.ZcloudUserCo;
import com.zcloud.zcGbsServicer.api.FireBrigadeMemberServiceI;
import com.zcloud.zcGbsServicer.command.convertor.FireBrigadeMemberCoConvertor;
import com.zcloud.zcGbsServicer.dto.FireBrigadeMemberAddCmd;
import com.zcloud.zcGbsServicer.dto.FireBrigadeMemberPageQry;
import com.zcloud.zcGbsServicer.dto.FireBrigadeMemberUpdateCmd;
import com.zcloud.zcGbsServicer.dto.clientobject.FireBrigadeMemberCO;
import com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeDO;
import com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeUserDO;
import com.zcloud.zcGbsServicer.persistence.repository.FireBrigadeRepository;
import com.zcloud.zcGbsServicer.persistence.repository.FireBrigadeUserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class FireBrigadeMemberServiceImpl extends FireAlarmServiceSupport implements FireBrigadeMemberServiceI {
private final FireBrigadeRepository fireBrigadeRepository;
private final FireBrigadeUserRepository fireBrigadeUserRepository;
private final FireAlarmUserResolver fireAlarmUserResolver;
private final FireBrigadeMemberCoConvertor fireBrigadeMemberCoConvertor;
@Override
public PageResponse<FireBrigadeMemberCO> listPage(FireBrigadeMemberPageQry qry) {
FireBrigadeDO brigade = getBrigade(qry.getFireBrigadeId());
List<FireBrigadeUserDO> relations = fireBrigadeUserRepository.listByFireBrigadeId(brigade.getFireBrigadeId());
Map<Long, ZcloudUserCo> userMap = getUserMap(relations);
List<FireBrigadeMemberCO> data = relations
.stream()
.map(item -> buildCO(item, brigade, userMap))
.filter(item -> StrUtil.isBlank(qry.getName()) || StrUtil.containsIgnoreCase(item.getUserName(), qry.getName().trim()))
.collect(Collectors.toList());
int pageSize = qry.getPageSize() <= 0 ? data.size() : qry.getPageSize();
int pageIndex = qry.getPageIndex() <= 0 ? 1 : qry.getPageIndex();
int fromIndex = Math.min((pageIndex - 1) * pageSize, data.size());
int toIndex = Math.min(fromIndex + pageSize, data.size());
return PageResponse.of(data.subList(fromIndex, toIndex), data.size(), pageSize, pageIndex);
}
@Override
@Transactional(rollbackFor = Exception.class)
public SingleResponse<FireBrigadeMemberCO> add(FireBrigadeMemberAddCmd cmd) {
FireBrigadeDO brigade = getBrigade(cmd.getFireBrigadeId());
Long userId = parseUserId(cmd.getUserId());
if (userId == null) {
throw new BizException("用户ID不能为空");
}
if (fireBrigadeUserRepository.existsRelation(brigade.getFireBrigadeId(), userId, null)) {
throw new BizException("消防队员已存在");
}
FireBrigadeUserDO relation = new FireBrigadeUserDO();
relation.setId(nextId());
relation.setFireBrigadeUserId(nextBizId());
relation.setFireBrigadeId(brigade.getFireBrigadeId());
relation.setUserId(userId);
fillMemberSnapshot(relation, cmd);
fillCreateAudit(relation);
fireBrigadeUserRepository.save(relation);
return SingleResponse.of(buildCO(relation, brigade, fireAlarmUserResolver.getUserMap(Collections.singleton(userId))));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void edit(FireBrigadeMemberUpdateCmd cmd) {
FireBrigadeUserDO relation = fireBrigadeUserRepository.getById(cmd.getId());
if (relation == null) {
throw new BizException("消防队员不存在");
}
FireBrigadeDO brigade = getBrigade(cmd.getFireBrigadeId());
Long userId = parseUserId(cmd.getUserId());
if (userId == null) {
throw new BizException("用户ID不能为空");
}
if (fireBrigadeUserRepository.existsRelation(brigade.getFireBrigadeId(), userId, relation.getId())) {
throw new BizException("消防队员已存在");
}
relation.setFireBrigadeId(brigade.getFireBrigadeId());
relation.setUserId(userId);
fillMemberSnapshot(relation, cmd);
fillUpdateAudit(relation);
fireBrigadeUserRepository.updateById(relation);
}
@Override
public FireBrigadeMemberCO get(Long id) {
FireBrigadeUserDO relation = fireBrigadeUserRepository.getById(id);
if (relation == null) {
throw new BizException("消防队员不存在");
}
FireBrigadeDO brigade = fireBrigadeRepository.getByFireBrigadeId(relation.getFireBrigadeId());
FireBrigadeDO actualBrigade = brigade == null ? new FireBrigadeDO() : brigade;
if (actualBrigade.getFireBrigadeId() == null) {
actualBrigade.setId(null);
actualBrigade.setFireBrigadeId(relation.getFireBrigadeId());
}
return buildCO(relation, actualBrigade, fireAlarmUserResolver.getUserMap(Collections.singleton(relation.getUserId())));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void remove(Long id) {
FireBrigadeUserDO relation = fireBrigadeUserRepository.getById(id);
if (relation == null) {
throw new BizException("消防队员不存在");
}
checkLeaderRelation(relation);
fireBrigadeUserRepository.removeById(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void removeBatch(Long[] ids) {
if (ids == null || ids.length == 0) {
return;
}
for (Long id : ids) {
FireBrigadeUserDO relation = fireBrigadeUserRepository.getById(id);
if (relation != null) {
checkLeaderRelation(relation);
}
}
fireBrigadeUserRepository.removeByIds(java.util.Arrays.asList(ids));
}
private FireBrigadeDO getBrigade(Long id) {
FireBrigadeDO brigade = fireBrigadeRepository.getById(id);
if (brigade == null) {
throw new BizException("消防队伍不存在");
}
return brigade;
}
private void checkLeaderRelation(FireBrigadeUserDO relation) {
FireBrigadeDO brigade = fireBrigadeRepository.getByFireBrigadeId(relation.getFireBrigadeId());
if (brigade != null && brigade.getLeaderUserId() != null && brigade.getLeaderUserId().equals(relation.getUserId())) {
throw new BizException("负责人未更换前,不能删除该成员");
}
}
private FireBrigadeMemberCO buildCO(FireBrigadeUserDO relation, FireBrigadeDO brigade, Map<Long, ZcloudUserCo> userMap) {
FireBrigadeMemberCO co = fireBrigadeMemberCoConvertor.converDOToCO(relation);
ZcloudUserCo user = relation.getUserId() == null ? null : userMap.get(relation.getUserId());
co.setFireBrigadeId(brigade.getId());
co.setUserId(relation.getUserId() == null ? null : String.valueOf(relation.getUserId()));
co.setUserName(selectText(user == null ? null : user.getName(), co.getUserName()));
co.setIdNo(selectText(user == null ? null : user.getUserIdCard(), co.getIdNo()));
co.setPhone(selectText(user == null ? null : user.getPhone(), co.getPhone()));
co.setDutyName(selectText(user == null ? null : user.getPostName(), co.getDutyName()));
co.setOrgName(selectText(user == null ? null : user.getDepartmentName(), co.getOrgName()));
if (brigade.getLeaderUserId() != null && brigade.getLeaderUserId().equals(relation.getUserId())) {
co.setRoleCode(1);
}
return co;
}
private void fillMemberSnapshot(FireBrigadeUserDO relation, FireBrigadeMemberAddCmd cmd) {
relation.setUserName(cmd.getName());
relation.setGender(cmd.getGender());
relation.setIdNo(cmd.getIdNo());
relation.setPhone(cmd.getPhone());
relation.setDutyName(cmd.getDuty());
relation.setOrgName(cmd.getOrg());
}
private String selectText(String preferred, String fallback) {
return StrUtil.isNotBlank(preferred) ? preferred : fallback;
}
private Long parseUserId(String userId) {
if (StrUtil.isBlank(userId)) {
return null;
}
try {
return Long.valueOf(userId.trim());
}
catch (NumberFormatException ex) {
return null;
}
}
private Map<Long, ZcloudUserCo> getUserMap(List<FireBrigadeUserDO> relations) {
Set<Long> userIds = relations.stream()
.map(FireBrigadeUserDO::getUserId)
.filter(java.util.Objects::nonNull)
.collect(Collectors.toSet());
return fireAlarmUserResolver.getUserMap(userIds);
}
private long nextId() {
return IdUtil.getSnowflake(1, 1).nextId();
}
private String nextBizId() {
return UUID.randomUUID().toString().replace("-", "");
}
}

View File

@ -0,0 +1,23 @@
package com.zcloud.zcGbsServicer.api;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.zcGbsServicer.dto.FireBrigadeMemberAddCmd;
import com.zcloud.zcGbsServicer.dto.FireBrigadeMemberPageQry;
import com.zcloud.zcGbsServicer.dto.FireBrigadeMemberUpdateCmd;
import com.zcloud.zcGbsServicer.dto.clientobject.FireBrigadeMemberCO;
public interface FireBrigadeMemberServiceI {
PageResponse<FireBrigadeMemberCO> listPage(FireBrigadeMemberPageQry qry);
SingleResponse<FireBrigadeMemberCO> add(FireBrigadeMemberAddCmd cmd);
void edit(FireBrigadeMemberUpdateCmd cmd);
FireBrigadeMemberCO get(Long id);
void remove(Long id);
void removeBatch(Long[] ids);
}

View File

@ -0,0 +1,42 @@
package com.zcloud.zcGbsServicer.dto;
import com.alibaba.cola.dto.Command;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class FireBrigadeMemberAddCmd extends Command {
@NotNull
@ApiModelProperty("消防队伍ID")
private Long fireBrigadeId;
@ApiModelProperty("用户ID")
private String userId;
@NotBlank
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty("性别")
private String gender;
@ApiModelProperty("身份证号")
private String idNo;
@NotBlank
@ApiModelProperty("联系电话")
private String phone;
@ApiModelProperty("职务")
private String duty;
@ApiModelProperty("所属机构")
private String org;
@ApiModelProperty("角色编码")
private Integer roleCode;
}

View File

@ -0,0 +1,18 @@
package com.zcloud.zcGbsServicer.dto;
import com.alibaba.cola.dto.PageQuery;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class FireBrigadeMemberPageQry extends PageQuery {
@NotNull
@ApiModelProperty("消防队伍ID")
private Long fireBrigadeId;
@ApiModelProperty("姓名")
private String name;
}

View File

@ -0,0 +1,14 @@
package com.zcloud.zcGbsServicer.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class FireBrigadeMemberUpdateCmd extends FireBrigadeMemberAddCmd {
@NotNull
@ApiModelProperty("主键ID")
private Long id;
}

View File

@ -0,0 +1,30 @@
package com.zcloud.zcGbsServicer.dto.clientobject;
import com.alibaba.cola.dto.ClientObject;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class FireBrigadeMemberCO extends ClientObject {
private Long id;
private String fireBrigadeUserId;
private Long fireBrigadeId;
private String fireBrigadeBizId;
private String userId;
@JsonProperty("name")
private String userName;
private String gender;
private String idNo;
private String phone;
@JsonProperty("duty")
private String dutyName;
@JsonProperty("org")
private String orgName;
private Integer roleCode;
}

View File

@ -0,0 +1,22 @@
package com.zcloud.zcGbsServicer.persistence.dataobject;
import com.baomidou.mybatisplus.annotation.TableName;
import com.jjb.saas.framework.repository.basedo.BaseDO;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("fire_brigade_user")
public class FireBrigadeUserDO extends BaseDO {
private String fireBrigadeUserId;
private String fireBrigadeId;
private Long userId;
private String userName;
private String gender;
private String idNo;
private String phone;
private String dutyName;
private String orgName;
}

View File

@ -0,0 +1,9 @@
package com.zcloud.zcGbsServicer.persistence.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeUserDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface FireBrigadeUserMapper extends BaseMapper<FireBrigadeUserDO> {
}

View File

@ -0,0 +1,15 @@
package com.zcloud.zcGbsServicer.persistence.repository;
import com.jjb.saas.framework.repository.repo.BaseRepository;
import com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeUserDO;
import java.util.List;
public interface FireBrigadeUserRepository extends BaseRepository<FireBrigadeUserDO> {
List<FireBrigadeUserDO> listByFireBrigadeId(String fireBrigadeId);
List<FireBrigadeUserDO> listByUserId(Long userId);
boolean existsRelation(String fireBrigadeId, Long userId, Long excludeId);
}

View File

@ -0,0 +1,46 @@
package com.zcloud.zcGbsServicer.persistence.repository.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl;
import com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeUserDO;
import com.zcloud.zcGbsServicer.persistence.mapper.FireBrigadeUserMapper;
import com.zcloud.zcGbsServicer.persistence.repository.FireBrigadeUserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class FireBrigadeUserRepositoryImpl extends BaseRepositoryImpl<FireBrigadeUserMapper, FireBrigadeUserDO> implements FireBrigadeUserRepository {
@Override
public List<FireBrigadeUserDO> listByFireBrigadeId(String fireBrigadeId) {
return this.list(new LambdaQueryWrapper<FireBrigadeUserDO>()
.eq(FireBrigadeUserDO::getFireBrigadeId, fireBrigadeId)
.eq(FireBrigadeUserDO::getTenantId, AuthContext.getTenantId())
.eq(FireBrigadeUserDO::getDeleteEnum, "FALSE"));
}
@Override
public List<FireBrigadeUserDO> listByUserId(Long userId) {
return this.list(new LambdaQueryWrapper<FireBrigadeUserDO>()
.eq(FireBrigadeUserDO::getUserId, userId)
.eq(FireBrigadeUserDO::getTenantId, AuthContext.getTenantId())
.eq(FireBrigadeUserDO::getDeleteEnum, "FALSE"));
}
@Override
public boolean existsRelation(String fireBrigadeId, Long userId, Long excludeId) {
LambdaQueryWrapper<FireBrigadeUserDO> wrapper = new LambdaQueryWrapper<FireBrigadeUserDO>()
.eq(FireBrigadeUserDO::getFireBrigadeId, fireBrigadeId)
.eq(FireBrigadeUserDO::getUserId, userId)
.eq(FireBrigadeUserDO::getTenantId, AuthContext.getTenantId())
.eq(FireBrigadeUserDO::getDeleteEnum, "FALSE");
if (excludeId != null) {
wrapper.ne(FireBrigadeUserDO::getId, excludeId);
}
return this.count(wrapper) > 0;
}
}