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

dev
lishiwei 2026-07-09 17:49:36 +08:00
parent 1bc6d62f4c
commit d0424faa28
13 changed files with 542 additions and 0 deletions

View File

@ -0,0 +1,56 @@
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.FireBrigadeServiceI;
import com.zcloud.zcGbsServicer.dto.FireBrigadeAddCmd;
import com.zcloud.zcGbsServicer.dto.FireBrigadePageQry;
import com.zcloud.zcGbsServicer.dto.FireBrigadeUpdateCmd;
import com.zcloud.zcGbsServicer.dto.clientobject.FireBrigadeCO;
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")
public class FireBrigadeController {
private final FireBrigadeServiceI fireBrigadeService;
@ApiOperation("分页查询")
@PostMapping("/list")
public PageResponse<FireBrigadeCO> list(@RequestBody FireBrigadePageQry qry) {
return fireBrigadeService.listPage(qry);
}
@ApiOperation("新增")
@PostMapping("/save")
public SingleResponse<FireBrigadeCO> save(@Validated @RequestBody FireBrigadeAddCmd cmd) {
return fireBrigadeService.add(cmd);
}
@ApiOperation("编辑")
@PutMapping("/edit")
public Response edit(@Validated @RequestBody FireBrigadeUpdateCmd cmd) {
fireBrigadeService.edit(cmd);
return Response.buildSuccess();
}
@ApiOperation("详情")
@GetMapping("/{id}")
public SingleResponse<FireBrigadeCO> get(@PathVariable Long id) {
return SingleResponse.of(fireBrigadeService.get(id));
}
@ApiOperation("删除")
@DeleteMapping("/{id}")
public Response remove(@PathVariable Long id) {
fireBrigadeService.remove(id);
return Response.buildSuccess();
}
}

View File

@ -0,0 +1,15 @@
package com.zcloud.zcGbsServicer.command.convertor;
import com.zcloud.zcGbsServicer.dto.clientobject.FireBrigadeCO;
import com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeDO;
import org.mapstruct.Mapper;
import java.util.List;
@Mapper(componentModel = "spring")
public interface FireBrigadeCoConvertor {
List<FireBrigadeCO> converDOsToCOs(List<FireBrigadeDO> fireBrigadeDOs);
FireBrigadeCO converDOToCO(FireBrigadeDO fireBrigadeDO);
}

View File

@ -0,0 +1,189 @@
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.FireBrigadeServiceI;
import com.zcloud.zcGbsServicer.command.convertor.FireBrigadeCoConvertor;
import com.zcloud.zcGbsServicer.dto.FireBrigadeAddCmd;
import com.zcloud.zcGbsServicer.dto.FireBrigadePageQry;
import com.zcloud.zcGbsServicer.dto.FireBrigadeUpdateCmd;
import com.zcloud.zcGbsServicer.dto.clientobject.FireBrigadeCO;
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.HashMap;
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 FireBrigadeServiceImpl extends FireAlarmServiceSupport implements FireBrigadeServiceI {
private final FireBrigadeRepository fireBrigadeRepository;
private final FireBrigadeUserRepository fireBrigadeUserRepository;
private final FireAlarmUserResolver fireAlarmUserResolver;
private final FireBrigadeCoConvertor fireBrigadeCoConvertor;
@Override
public PageResponse<FireBrigadeCO> listPage(FireBrigadePageQry qry) {
Map<String, Object> params = new HashMap<>();
params.put("pageIndex", qry.getPageIndex());
params.put("pageSize", qry.getPageSize());
params.put("brigadeName", qry.getName());
PageResponse<FireBrigadeDO> page = fireBrigadeRepository.listPage(params);
Map<Long, ZcloudUserCo> userMap = getLeaderUserMap(page.getData());
List<FireBrigadeCO> data = page.getData().stream().map(item -> buildCO(item, userMap)).collect(Collectors.toList());
return PageResponse.of(data, page.getTotalCount(), page.getPageSize(), page.getPageIndex());
}
@Override
@Transactional(rollbackFor = Exception.class)
public SingleResponse<FireBrigadeCO> add(FireBrigadeAddCmd cmd) {
if (fireBrigadeRepository.existsByBrigadeName(cmd.getName(), null)) {
throw new BizException("消防队伍名称已存在");
}
if (cmd.getLeaderUserId() == null) {
throw new BizException("负责人用户ID不能为空");
}
FireBrigadeDO brigade = new FireBrigadeDO();
brigade.setId(nextId());
brigade.setFireBrigadeId(nextBizId());
fillCreateAudit(brigade);
fillBrigade(brigade, cmd);
fireBrigadeRepository.save(brigade);
ensureLeaderRelation(brigade);
return SingleResponse.of(buildCO(brigade, getLeaderUserMap(Collections.singletonList(brigade))));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void edit(FireBrigadeUpdateCmd cmd) {
FireBrigadeDO brigade = fireBrigadeRepository.getById(cmd.getId());
if (brigade == null) {
throw new BizException("消防队伍不存在");
}
if (fireBrigadeRepository.existsByBrigadeName(cmd.getName(), cmd.getId())) {
throw new BizException("消防队伍名称已存在");
}
if (cmd.getLeaderUserId() == null) {
throw new BizException("负责人用户ID不能为空");
}
fillUpdateAudit(brigade);
fillBrigade(brigade, cmd);
fireBrigadeRepository.updateById(brigade);
ensureLeaderRelation(brigade);
}
@Override
public FireBrigadeCO get(Long id) {
FireBrigadeDO brigade = fireBrigadeRepository.getById(id);
if (brigade == null) {
throw new BizException("消防队伍不存在");
}
return buildCO(brigade, getLeaderUserMap(Collections.singletonList(brigade)));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void remove(Long id) {
FireBrigadeDO brigade = fireBrigadeRepository.getById(id);
if (brigade == null) {
throw new BizException("消防队伍不存在");
}
List<FireBrigadeUserDO> relations = fireBrigadeUserRepository.listByFireBrigadeId(brigade.getFireBrigadeId());
if (!relations.isEmpty()) {
fireBrigadeUserRepository.removeBatchByIds(relations.stream().map(FireBrigadeUserDO::getId).collect(Collectors.toList()));
}
fireBrigadeRepository.removeById(id);
}
private void fillBrigade(FireBrigadeDO brigade, FireBrigadeAddCmd cmd) {
brigade.setBrigadeName(cmd.getName());
brigade.setLeaderUserId(cmd.getLeaderUserId());
brigade.setLeaderName(cmd.getLeader());
brigade.setLeaderPhone(cmd.getLeaderPhone());
brigade.setLeaderDeptName(cmd.getLeaderDept());
brigade.setAddress(cmd.getAddress());
brigade.setDutyPhone(cmd.getDutyPhone());
brigade.setEstablishDate(cmd.getFounded());
brigade.setVehicleCount(cmd.getVehicles());
brigade.setBrigadeInfo(cmd.getDesc());
}
private void ensureLeaderRelation(FireBrigadeDO brigade) {
if (brigade.getLeaderUserId() == null) {
return;
}
List<FireBrigadeUserDO> relations = fireBrigadeUserRepository.listByFireBrigadeId(brigade.getFireBrigadeId());
FireBrigadeUserDO relation = relations.stream()
.filter(item -> brigade.getLeaderUserId().equals(item.getUserId()))
.findFirst()
.orElse(null);
if (relation == null) {
relation = new FireBrigadeUserDO();
relation.setId(nextId());
relation.setFireBrigadeUserId(nextBizId());
relation.setFireBrigadeId(brigade.getFireBrigadeId());
relation.setUserId(brigade.getLeaderUserId());
fillLeaderSnapshot(relation, brigade);
fillCreateAudit(relation);
fireBrigadeUserRepository.save(relation);
return;
}
fillLeaderSnapshot(relation, brigade);
fillUpdateAudit(relation);
fireBrigadeUserRepository.updateById(relation);
}
private void fillLeaderSnapshot(FireBrigadeUserDO relation, FireBrigadeDO brigade) {
relation.setUserName(brigade.getLeaderName());
relation.setPhone(brigade.getLeaderPhone());
relation.setDutyName("负责人");
relation.setOrgName(brigade.getLeaderDeptName());
}
private FireBrigadeCO buildCO(FireBrigadeDO brigade, Map<Long, ZcloudUserCo> userMap) {
FireBrigadeCO co = fireBrigadeCoConvertor.converDOToCO(brigade);
ZcloudUserCo leader = brigade.getLeaderUserId() == null ? null : userMap.get(brigade.getLeaderUserId());
co.setLeaderDeptName(selectText(leader == null ? null : leader.getDepartmentName(), co.getLeaderDeptName()));
co.setLeaderName(selectText(leader == null ? null : leader.getName(), co.getLeaderName()));
co.setLeaderPhone(selectText(leader == null ? null : leader.getPhone(), co.getLeaderPhone()));
co.setMemberCount(fireBrigadeUserRepository.listByFireBrigadeId(brigade.getFireBrigadeId()).size());
co.setOnline(Boolean.FALSE);
co.setOnlineText("未在线");
return co;
}
private String selectText(String preferred, String fallback) {
return StrUtil.isNotBlank(preferred) ? preferred : fallback;
}
private Map<Long, ZcloudUserCo> getLeaderUserMap(List<FireBrigadeDO> brigades) {
Set<Long> userIds = brigades.stream()
.map(FireBrigadeDO::getLeaderUserId)
.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,21 @@
package com.zcloud.zcGbsServicer.api;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.zcGbsServicer.dto.FireBrigadeAddCmd;
import com.zcloud.zcGbsServicer.dto.FireBrigadePageQry;
import com.zcloud.zcGbsServicer.dto.FireBrigadeUpdateCmd;
import com.zcloud.zcGbsServicer.dto.clientobject.FireBrigadeCO;
public interface FireBrigadeServiceI {
PageResponse<FireBrigadeCO> listPage(FireBrigadePageQry qry);
SingleResponse<FireBrigadeCO> add(FireBrigadeAddCmd cmd);
void edit(FireBrigadeUpdateCmd cmd);
FireBrigadeCO get(Long id);
void remove(Long id);
}

View File

@ -0,0 +1,51 @@
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;
import java.time.LocalDate;
@Data
public class FireBrigadeAddCmd extends Command {
@NotBlank
@ApiModelProperty("消防队伍名称")
private String name;
@ApiModelProperty("负责人部门")
private String leaderDept;
@ApiModelProperty("负责人用户ID")
private Long leaderUserId;
@NotBlank
@ApiModelProperty("负责人姓名")
private String leader;
@NotBlank
@ApiModelProperty("负责人电话")
private String leaderPhone;
@NotBlank
@ApiModelProperty("地址")
private String address;
@NotBlank
@ApiModelProperty("应急值班电话")
private String dutyPhone;
@NotNull
@ApiModelProperty("成立日期")
private LocalDate founded;
@NotNull
@ApiModelProperty("车辆数")
private Integer vehicles;
@NotBlank
@ApiModelProperty("队伍信息")
private String desc;
}

View File

@ -0,0 +1,12 @@
package com.zcloud.zcGbsServicer.dto;
import com.alibaba.cola.dto.PageQuery;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class FireBrigadePageQry extends PageQuery {
@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 FireBrigadeUpdateCmd extends FireBrigadeAddCmd {
@NotNull
@ApiModelProperty("主键ID")
private Long id;
}

View File

@ -0,0 +1,42 @@
package com.zcloud.zcGbsServicer.dto.clientobject;
import com.alibaba.cola.dto.ClientObject;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.time.LocalDate;
@Data
public class FireBrigadeCO extends ClientObject {
private Long id;
private String fireBrigadeId;
@JsonProperty("name")
private String brigadeName;
@JsonProperty("leaderDept")
private String leaderDeptName;
private Long leaderUserId;
@JsonProperty("leader")
private String leaderName;
private String leaderPhone;
private String address;
private String dutyPhone;
@JsonProperty("founded")
private LocalDate establishDate;
@JsonProperty("vehicles")
private Integer vehicleCount;
@JsonProperty("desc")
private String brigadeInfo;
private Integer memberCount;
private Boolean online;
private String onlineText;
}

View File

@ -0,0 +1,33 @@
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;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("fire_brigade")
public class FireBrigadeDO extends BaseDO {
private String fireBrigadeId;
private String brigadeName;
private Long leaderUserId;
private String leaderName;
private String leaderPhone;
private String leaderDeptName;
private String address;
private String dutyPhone;
private LocalDate establishDate;
private Integer vehicleCount;
private String brigadeInfo;
private String thirdDepartId;
private String thirdDepartName;
private String thirdParentDepartId;
private Integer thirdSyncStatus;
private String thirdSyncMsg;
private LocalDateTime thirdSyncTime;
}

View File

@ -0,0 +1,15 @@
package com.zcloud.zcGbsServicer.persistence.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface FireBrigadeMapper extends BaseMapper<FireBrigadeDO> {
IPage<FireBrigadeDO> selectPageSql(IPage<FireBrigadeDO> page,
@Param("brigadeName") String brigadeName,
@Param("tenantId") Long tenantId);
}

View File

@ -0,0 +1,16 @@
package com.zcloud.zcGbsServicer.persistence.repository;
import com.alibaba.cola.dto.PageResponse;
import com.jjb.saas.framework.repository.repo.BaseRepository;
import com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeDO;
import java.util.Map;
public interface FireBrigadeRepository extends BaseRepository<FireBrigadeDO> {
PageResponse<FireBrigadeDO> listPage(Map<String, Object> params);
boolean existsByBrigadeName(String brigadeName, Long excludeId);
FireBrigadeDO getByFireBrigadeId(String fireBrigadeId);
}

View File

@ -0,0 +1,56 @@
package com.zcloud.zcGbsServicer.persistence.repository.impl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.PageResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.framework.repository.common.PageHelper;
import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl;
import com.zcloud.gbscommon.utils.Query;
import com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeDO;
import com.zcloud.zcGbsServicer.persistence.mapper.FireBrigadeMapper;
import com.zcloud.zcGbsServicer.persistence.repository.FireBrigadeRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class FireBrigadeRepositoryImpl extends BaseRepositoryImpl<FireBrigadeMapper, FireBrigadeDO> implements FireBrigadeRepository {
private final FireBrigadeMapper fireBrigadeMapper;
@Override
public PageResponse<FireBrigadeDO> listPage(Map<String, Object> params) {
IPage<FireBrigadeDO> page = new Query<FireBrigadeDO>().getPage(params);
String brigadeName = params == null ? null : (String) params.get("brigadeName");
IPage<FireBrigadeDO> result = fireBrigadeMapper.selectPageSql(page, brigadeName, AuthContext.getTenantId());
return PageHelper.pageToResponse(result, result.getRecords());
}
@Override
public boolean existsByBrigadeName(String brigadeName, Long excludeId) {
if (StrUtil.isBlank(brigadeName)) {
return false;
}
LambdaQueryWrapper<FireBrigadeDO> wrapper = new LambdaQueryWrapper<FireBrigadeDO>()
.eq(FireBrigadeDO::getBrigadeName, brigadeName.trim())
.eq(FireBrigadeDO::getTenantId, AuthContext.getTenantId())
.eq(FireBrigadeDO::getDeleteEnum, "FALSE");
if (excludeId != null) {
wrapper.ne(FireBrigadeDO::getId, excludeId);
}
return this.count(wrapper) > 0;
}
@Override
public FireBrigadeDO getByFireBrigadeId(String fireBrigadeId) {
return this.getOne(new LambdaQueryWrapper<FireBrigadeDO>()
.eq(FireBrigadeDO::getFireBrigadeId, fireBrigadeId)
.eq(FireBrigadeDO::getTenantId, AuthContext.getTenantId())
.eq(FireBrigadeDO::getDeleteEnum, "FALSE")
.last("limit 1"));
}
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zcloud.zcGbsServicer.persistence.mapper.FireBrigadeMapper">
<select id="selectPageSql" resultType="com.zcloud.zcGbsServicer.persistence.dataobject.FireBrigadeDO">
SELECT *
FROM fire_brigade
<where>
delete_enum = 'FALSE'
<if test="tenantId != null">
AND tenant_id = #{tenantId}
</if>
<if test="brigadeName != null and brigadeName != ''">
AND brigade_name LIKE CONCAT('%', #{brigadeName}, '%')
</if>
</where>
ORDER BY create_time DESC
</select>
</mapper>