diff --git a/fjrcloud-framework/fjrcloud-common/src/main/java/com/fjrcloud/community/framework/common/pojo/ImportResultRespVO.java b/fjrcloud-framework/fjrcloud-common/src/main/java/com/fjrcloud/community/framework/common/pojo/ImportResultRespVO.java new file mode 100644 index 0000000..ca9bbda --- /dev/null +++ b/fjrcloud-framework/fjrcloud-common/src/main/java/com/fjrcloud/community/framework/common/pojo/ImportResultRespVO.java @@ -0,0 +1,27 @@ +package com.fjrcloud.community.framework.common.pojo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Schema(description = "通用 - 导入结果 Response VO") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ImportResultRespVO { + + @Schema(description = "创建成功数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + private Integer createCount; + + @Schema(description = "更新成功数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") + private Integer updateCount; + + @Schema(description = "导入失败的错误信息列表", requiredMode = Schema.RequiredMode.REQUIRED) + private List failureMessages; + +} diff --git a/fjrcloud-framework/fjrcloud-spring-boot-starter-biz-tenant/src/main/java/com/fjrcloud/community/framework/tenant/core/security/TenantSecurityWebFilter.java b/fjrcloud-framework/fjrcloud-spring-boot-starter-biz-tenant/src/main/java/com/fjrcloud/community/framework/tenant/core/security/TenantSecurityWebFilter.java index c6f91a1..e972987 100644 --- a/fjrcloud-framework/fjrcloud-spring-boot-starter-biz-tenant/src/main/java/com/fjrcloud/community/framework/tenant/core/security/TenantSecurityWebFilter.java +++ b/fjrcloud-framework/fjrcloud-spring-boot-starter-biz-tenant/src/main/java/com/fjrcloud/community/framework/tenant/core/security/TenantSecurityWebFilter.java @@ -34,6 +34,11 @@ import java.util.Set; @Slf4j public class TenantSecurityWebFilter extends ApiRequestFilter { + /** + * 系统租户编号(超级管理员) + */ + public static final Long SYSTEM_TENANT_ID = 1L; + private final TenantProperties tenantProperties; /** @@ -83,16 +88,23 @@ public class TenantSecurityWebFilter extends ApiRequestFilter { } } + // 2. 超级管理员(系统租户)默认忽略租户隔离,可查询所有数据 + if (SYSTEM_TENANT_ID.equals(tenantId)) { + TenantContextHolder.setIgnore(true); + log.debug("[doFilterInternal][超级管理员访问,忽略租户隔离] URL({}/{})", request.getRequestURI(), request.getMethod()); + } + // 如果非允许忽略租户的 URL,则校验租户是否合法 if (!isIgnoreUrl(request)) { - // 2. 如果请求未带租户的编号,不允许访问。 + // 3. 如果请求未带租户的编号,不允许访问。 if (tenantId == null) { log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod()); ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "请求的租户标识未传递,请进行排查")); return; } - // 3. 校验租户是合法,例如说被禁用、到期 + // 4. 校验租户是合法,例如说被禁用、到期 + // 注意:超级管理员已设置忽略租户,此处不会被拦截 try { tenantFrameworkService.validTenant(tenantId); } catch (Throwable ex) { diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/community/CommunityController.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/community/CommunityController.java index 84c0ddd..2727a7e 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/community/CommunityController.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/community/CommunityController.java @@ -2,6 +2,7 @@ package com.fjrcloud.community.module.community.controller.admin.community; import com.fjrcloud.community.framework.apilog.core.annotation.ApiAccessLog; import com.fjrcloud.community.framework.common.pojo.CommonResult; +import com.fjrcloud.community.framework.common.pojo.ImportResultRespVO; import com.fjrcloud.community.framework.common.pojo.PageParam; import com.fjrcloud.community.framework.common.pojo.PageResult; import com.fjrcloud.community.framework.common.util.object.BeanUtils; @@ -136,10 +137,18 @@ public class CommunityController { @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") }) @PreAuthorize("@ss.hasPermission('community:community:import')") - public CommonResult importExcel(@RequestParam("file") MultipartFile file, - @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { + public CommonResult importExcel(@RequestParam("file") MultipartFile file, + @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { List list = ExcelUtils.read(file, CommunityImportExcelVO.class); return success(communityService.importCommunityList(list, updateSupport)); } + @GetMapping("/simple-list") + @Operation(summary = "获取小区精简列表") + @PreAuthorize("@ss.hasPermission('community:community:query')") + public CommonResult> getCommunitySimpleList() { + List list = communityService.getCommunitySimpleList(); + return success(list); + } + } \ No newline at end of file diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/community/vo/CommunitySimpleRespVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/community/vo/CommunitySimpleRespVO.java new file mode 100644 index 0000000..0b1c922 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/community/vo/CommunitySimpleRespVO.java @@ -0,0 +1,22 @@ +package com.fjrcloud.community.module.community.controller.admin.community.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Schema(description = "管理后台 - 小区精简信息 Response VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class CommunitySimpleRespVO { + + @Schema(description = "小区编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "小区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "阳光小区") + private String communityName; + +} diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/HouseController.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/HouseController.java index 2e5b7ad..9348f0c 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/HouseController.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/HouseController.java @@ -2,11 +2,15 @@ package com.fjrcloud.community.module.community.controller.admin.house; import com.fjrcloud.community.framework.apilog.core.annotation.ApiAccessLog; import com.fjrcloud.community.framework.common.pojo.CommonResult; +import com.fjrcloud.community.framework.common.pojo.ImportResultRespVO; import com.fjrcloud.community.framework.common.pojo.PageParam; import com.fjrcloud.community.framework.common.pojo.PageResult; import com.fjrcloud.community.framework.common.util.object.BeanUtils; import com.fjrcloud.community.framework.excel.core.util.ExcelUtils; -import com.fjrcloud.community.module.community.controller.admin.house.vo.*; +import com.fjrcloud.community.module.community.controller.admin.house.vo.HouseImportExcelVO; +import com.fjrcloud.community.module.community.controller.admin.house.vo.HousePageReqVO; +import com.fjrcloud.community.module.community.controller.admin.house.vo.HouseRespVO; +import com.fjrcloud.community.module.community.controller.admin.house.vo.HouseSaveReqVO; import com.fjrcloud.community.module.community.dal.dataobject.house.HouseDO; import com.fjrcloud.community.module.community.service.house.HouseService; import io.swagger.v3.oas.annotations.Operation; @@ -133,8 +137,8 @@ public class HouseController { @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") }) @PreAuthorize("@ss.hasPermission('community:house:import')") - public CommonResult importExcel(@RequestParam("file") MultipartFile file, - @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { + public CommonResult importExcel(@RequestParam("file") MultipartFile file, + @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { List list = ExcelUtils.read(file, HouseImportExcelVO.class); return success(houseService.importHouseList(list, updateSupport)); } diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/community/CommunityService.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/community/CommunityService.java index 0670249..23f3960 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/community/CommunityService.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/community/CommunityService.java @@ -1,10 +1,11 @@ package com.fjrcloud.community.module.community.service.community; +import com.fjrcloud.community.framework.common.pojo.ImportResultRespVO; import com.fjrcloud.community.framework.common.pojo.PageResult; import com.fjrcloud.community.module.community.controller.admin.community.vo.CommunityImportExcelVO; -import com.fjrcloud.community.module.community.controller.admin.community.vo.CommunityImportRespVO; import com.fjrcloud.community.module.community.controller.admin.community.vo.CommunityPageReqVO; import com.fjrcloud.community.module.community.controller.admin.community.vo.CommunitySaveReqVO; +import com.fjrcloud.community.module.community.controller.admin.community.vo.CommunitySimpleRespVO; import com.fjrcloud.community.module.community.dal.dataobject.community.CommunityDO; import javax.validation.Valid; @@ -69,6 +70,13 @@ public interface CommunityService { * @param isUpdateSupport 是否支持更新 * @return 导入结果 */ - CommunityImportRespVO importCommunityList(List importCommunities, boolean isUpdateSupport); + ImportResultRespVO importCommunityList(List importCommunities, boolean isUpdateSupport); + + /** + * 获取小区精简列表 + * + * @return 小区精简列表 + */ + List getCommunitySimpleList(); } \ No newline at end of file diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/community/CommunityServiceImpl.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/community/CommunityServiceImpl.java index e156336..6ccf597 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/community/CommunityServiceImpl.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/community/CommunityServiceImpl.java @@ -3,14 +3,15 @@ package com.fjrcloud.community.module.community.service.community; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.fjrcloud.community.framework.common.enums.CommonStatusEnum; +import com.fjrcloud.community.framework.common.pojo.ImportResultRespVO; import com.fjrcloud.community.framework.common.pojo.PageResult; import com.fjrcloud.community.framework.common.util.object.BeanUtils; import com.fjrcloud.community.framework.tenant.core.context.TenantContextHolder; import com.fjrcloud.community.framework.tenant.core.util.TenantUtils; import com.fjrcloud.community.module.community.controller.admin.community.vo.CommunityImportExcelVO; -import com.fjrcloud.community.module.community.controller.admin.community.vo.CommunityImportRespVO; import com.fjrcloud.community.module.community.controller.admin.community.vo.CommunityPageReqVO; import com.fjrcloud.community.module.community.controller.admin.community.vo.CommunitySaveReqVO; +import com.fjrcloud.community.module.community.controller.admin.community.vo.CommunitySimpleRespVO; import com.fjrcloud.community.module.community.dal.dataobject.community.CommunityDO; import com.fjrcloud.community.module.community.dal.mysql.community.CommunityMapper; import com.fjrcloud.community.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO; @@ -21,11 +22,14 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; import static com.fjrcloud.community.framework.common.exception.util.ServiceExceptionUtil.exception; +import static com.fjrcloud.community.framework.tenant.core.security.TenantSecurityWebFilter.SYSTEM_TENANT_ID; import static com.fjrcloud.community.module.community.enums.ErrorCodeConstants.COMMUNITY_IMPORT_LIST_IS_EMPTY; import static com.fjrcloud.community.module.community.enums.ErrorCodeConstants.COMMUNITY_NOT_EXISTS; @@ -199,43 +203,61 @@ public class CommunityServiceImpl implements CommunityService { } @Override - public CommunityImportRespVO importCommunityList(List importCommunities, boolean isUpdateSupport) { + public ImportResultRespVO importCommunityList(List importCommunities, boolean isUpdateSupport) { // 1. 参数校验 if (CollUtil.isEmpty(importCommunities)) { throw exception(COMMUNITY_IMPORT_LIST_IS_EMPTY); } - // 2. 遍历,逐个创建 or 更新 - CommunityImportRespVO respVO = CommunityImportRespVO.builder() - .createCommunityNames(new ArrayList<>()) - .updateCommunityNames(new ArrayList<>()) - .failureCommunities(new LinkedHashMap<>()) - .build(); + // 2. 校验导入数据中是否存在重复的小区名称 + Map communityNameCount = importCommunities.stream() + .filter(c -> StrUtil.isNotBlank(c.getCommunityName())) + .collect(Collectors.groupingBy(CommunityImportExcelVO::getCommunityName, Collectors.counting())); + + Set duplicateNames = communityNameCount.entrySet().stream() + .filter(entry -> entry.getValue() > 1) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + + // 3. 遍历,逐个创建 or 更新 + List failureMessages = new ArrayList<>(); + AtomicInteger createCount = new AtomicInteger(0); + AtomicInteger updateCount = new AtomicInteger(0); AtomicInteger index = new AtomicInteger(1); + boolean isSystemAdmin = SYSTEM_TENANT_ID.equals(TenantContextHolder.getTenantId()); + importCommunities.forEach(importCommunity -> { int currentIndex = index.getAndIncrement(); + String communityName = importCommunity.getCommunityName(); - // 2.1 校验必填字段 + // 3.1 校验必填字段 try { validateImportCommunity(importCommunity, currentIndex); } catch (Exception ex) { - respVO.getFailureCommunities().put(importCommunity.getCommunityName() != null ? importCommunity.getCommunityName() : "第 " + currentIndex + " 行", ex.getMessage()); + String key = StrUtil.isNotBlank(communityName) ? communityName : "第 " + currentIndex + " 行"; + failureMessages.add(key + ": " + ex.getMessage()); return; } - // 2.2 转换 Boolean 值 + // 3.2 校验导入数据中是否有重复的小区名称 + if (duplicateNames.contains(communityName)) { + failureMessages.add(communityName + ": 导入数据中存在重复的小区名称"); + return; + } + + // 3.3 转换 Boolean 值 Boolean visitAudit = convertBoolean(importCommunity.getVisitAuditStr()); Boolean gateAudit = convertBoolean(importCommunity.getGateAuditStr()); - // 2.3 判断小区是否已存在 - CommunityDO existCommunity = findCommunityByName(importCommunity.getCommunityName()); + // 3.4 判断小区是否已存在 + CommunityDO existCommunity = findCommunityByName(communityName); - // 2.4 如果不存在,进行插入 + // 3.5 如果不存在,进行插入 if (existCommunity == null) { try { CommunitySaveReqVO createReqVO = new CommunitySaveReqVO(); - createReqVO.setCommunityName(importCommunity.getCommunityName()); + createReqVO.setCommunityName(communityName); createReqVO.setStreetName(importCommunity.getStreetName()); createReqVO.setDistrictName(importCommunity.getDistrictName()); createReqVO.setCommunityAddress(importCommunity.getCommunityAddress()); @@ -248,24 +270,24 @@ public class CommunityServiceImpl implements CommunityService { createReqVO.setGateAudit(gateAudit); createCommunity(createReqVO); - respVO.getCreateCommunityNames().add(importCommunity.getCommunityName()); + createCount.incrementAndGet(); } catch (Exception e) { - respVO.getFailureCommunities().put(importCommunity.getCommunityName(), e.getMessage()); + failureMessages.add(communityName + ": " + e.getMessage()); } return; } - // 2.5 如果存在,判断是否允许更新 + // 3.6 如果存在,判断是否允许更新 if (!isUpdateSupport) { - respVO.getFailureCommunities().put(importCommunity.getCommunityName(), "小区已存在,且不支持更新"); + failureMessages.add(communityName + ": 小区已存在,且不支持更新"); return; } - // 2.6 更新已有小区 + // 3.7 更新已有小区 try { CommunitySaveReqVO updateReqVO = new CommunitySaveReqVO(); updateReqVO.setId(existCommunity.getId()); - updateReqVO.setCommunityName(importCommunity.getCommunityName()); + updateReqVO.setCommunityName(communityName); updateReqVO.setStreetName(importCommunity.getStreetName()); updateReqVO.setDistrictName(importCommunity.getDistrictName()); updateReqVO.setCommunityAddress(importCommunity.getCommunityAddress()); @@ -275,14 +297,23 @@ public class CommunityServiceImpl implements CommunityService { updateReqVO.setVisitAudit(visitAudit); updateReqVO.setGateAudit(gateAudit); - updateCommunity(updateReqVO); - respVO.getUpdateCommunityNames().add(importCommunity.getCommunityName()); + // 超管更新时,临时切换到该小区的租户上下文执行更新 + if (isSystemAdmin) { + TenantUtils.execute(existCommunity.getId(), () -> updateCommunity(updateReqVO)); + } else { + updateCommunity(updateReqVO); + } + updateCount.incrementAndGet(); } catch (Exception e) { - respVO.getFailureCommunities().put(importCommunity.getCommunityName(), e.getMessage()); + failureMessages.add(communityName + ": " + e.getMessage()); } }); - return respVO; + return ImportResultRespVO.builder() + .createCount(createCount.get()) + .updateCount(updateCount.get()) + .failureMessages(failureMessages) + .build(); } /** @@ -330,16 +361,34 @@ public class CommunityServiceImpl implements CommunityService { } /** - * 查找已存在的小区 + * 获取小区精简列表 */ private CommunityDO findCommunityByName(String communityName) { // 超管查询时忽略租户隔离 if (Long.valueOf(1).equals(TenantContextHolder.getTenantId())) { return TenantUtils.executeIgnore(() -> - communityMapper.selectOne(CommunityDO::getCommunityName, communityName) + communityMapper.selectOne(CommunityDO::getCommunityName, communityName) ); } return communityMapper.selectOne(CommunityDO::getCommunityName, communityName); } + @Override + public List getCommunitySimpleList() { + List communities; + // 超管查询时忽略租户隔离,返回所有小区 + if (Long.valueOf(1).equals(TenantContextHolder.getTenantId())) { + communities = TenantUtils.executeIgnore(() -> communityMapper.selectList()); + } else { + // 租户管理员查询时,框架自动加上 tenant_id 条件 + communities = communityMapper.selectList(); + } + return communities.stream() + .map(community -> CommunitySimpleRespVO.builder() + .id(community.getId()) + .communityName(community.getCommunityName()) + .build()) + .collect(Collectors.toList()); + } + } \ No newline at end of file diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/house/HouseService.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/house/HouseService.java index 2606260..db82e9b 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/house/HouseService.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/house/HouseService.java @@ -1,8 +1,8 @@ package com.fjrcloud.community.module.community.service.house; +import com.fjrcloud.community.framework.common.pojo.ImportResultRespVO; import com.fjrcloud.community.framework.common.pojo.PageResult; import com.fjrcloud.community.module.community.controller.admin.house.vo.HouseImportExcelVO; -import com.fjrcloud.community.module.community.controller.admin.house.vo.HouseImportRespVO; import com.fjrcloud.community.module.community.controller.admin.house.vo.HousePageReqVO; import com.fjrcloud.community.module.community.controller.admin.house.vo.HouseSaveReqVO; import com.fjrcloud.community.module.community.dal.dataobject.house.HouseDO; @@ -69,6 +69,6 @@ public interface HouseService { * @param isUpdateSupport 是否支持更新 * @return 导入结果 */ - HouseImportRespVO importHouseList(List importHouses, boolean isUpdateSupport); + ImportResultRespVO importHouseList(List importHouses, boolean isUpdateSupport); } \ No newline at end of file diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/house/HouseServiceImpl.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/house/HouseServiceImpl.java index 4c07c34..7521a6f 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/house/HouseServiceImpl.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/house/HouseServiceImpl.java @@ -2,10 +2,12 @@ package com.fjrcloud.community.module.community.service.house; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; +import com.fjrcloud.community.framework.common.pojo.ImportResultRespVO; import com.fjrcloud.community.framework.common.pojo.PageResult; import com.fjrcloud.community.framework.common.util.object.BeanUtils; +import com.fjrcloud.community.framework.tenant.core.context.TenantContextHolder; +import com.fjrcloud.community.framework.tenant.core.util.TenantUtils; import com.fjrcloud.community.module.community.controller.admin.house.vo.HouseImportExcelVO; -import com.fjrcloud.community.module.community.controller.admin.house.vo.HouseImportRespVO; import com.fjrcloud.community.module.community.controller.admin.house.vo.HousePageReqVO; import com.fjrcloud.community.module.community.controller.admin.house.vo.HouseSaveReqVO; import com.fjrcloud.community.module.community.dal.dataobject.community.CommunityDO; @@ -18,12 +20,12 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; import static com.fjrcloud.community.framework.common.exception.util.ServiceExceptionUtil.exception; +import static com.fjrcloud.community.framework.tenant.core.security.TenantSecurityWebFilter.SYSTEM_TENANT_ID; import static com.fjrcloud.community.module.community.enums.ErrorCodeConstants.HOUSE_IMPORT_LIST_IS_EMPTY; import static com.fjrcloud.community.module.community.enums.ErrorCodeConstants.HOUSE_NOT_EXISTS; @@ -73,10 +75,10 @@ public class HouseServiceImpl implements HouseService { } @Override - public void deleteHouseListByIds(List ids) { + public void deleteHouseListByIds(List ids) { // 删除 houseMapper.deleteByIds(ids); - } + } private void validateHouseExists(Long id) { @@ -96,83 +98,128 @@ public class HouseServiceImpl implements HouseService { } @Override - public HouseImportRespVO importHouseList(List importHouses, boolean isUpdateSupport) { + public ImportResultRespVO importHouseList(List importHouses, boolean isUpdateSupport) { // 1. 参数校验 if (CollUtil.isEmpty(importHouses)) { throw exception(HOUSE_IMPORT_LIST_IS_EMPTY); } - // 2. 遍历,逐个创建 or 更新 - HouseImportRespVO respVO = HouseImportRespVO.builder() - .createHouses(new ArrayList<>()) - .updateHouses(new ArrayList<>()) - .failureHouses(new LinkedHashMap<>()) - .build(); + // 2. 校验导入数据中是否存在重复的房屋标识(小区名称 + 楼号 + 单元号 + 门牌号) + Map houseIdentifierCount = new LinkedHashMap<>(); + for (HouseImportExcelVO house : importHouses) { + if (StrUtil.isNotBlank(house.getCommunityName()) + && StrUtil.isNotBlank(house.getBuildingNo()) + && StrUtil.isNotBlank(house.getUnitNo()) + && StrUtil.isNotBlank(house.getRoomNo())) { + String identifier = house.getCommunityName() + "|" + house.getBuildingNo() + "-" + house.getUnitNo() + "-" + house.getRoomNo(); + houseIdentifierCount.put(identifier, houseIdentifierCount.getOrDefault(identifier, 0L) + 1); + } + } + Set duplicateIdentifiers = houseIdentifierCount.entrySet().stream() + .filter(entry -> entry.getValue() > 1) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + + // 3. 遍历,逐个创建 or 更新 + List failureMessages = new ArrayList<>(); + AtomicInteger createCount = new AtomicInteger(0); + AtomicInteger updateCount = new AtomicInteger(0); + AtomicInteger index = new AtomicInteger(1); + boolean isSystemAdmin = SYSTEM_TENANT_ID.equals(TenantContextHolder.getTenantId()); + importHouses.forEach(importHouse -> { int currentIndex = index.getAndIncrement(); - - // 2.1 校验必填字段 + String houseIdentifier = importHouse.getBuildingNo() + "-" + importHouse.getUnitNo() + "-" + importHouse.getRoomNo(); + String fullIdentifier = importHouse.getCommunityName() + "|" + houseIdentifier; + + // 3.1 校验必填字段 try { validateImportHouse(importHouse, currentIndex); } catch (Exception ex) { - String key = StrUtil.isNotBlank(importHouse.getRoomNo()) - ? importHouse.getBuildingNo() + "-" + importHouse.getUnitNo() + "-" + importHouse.getRoomNo() - : "第 " + currentIndex + " 行"; - respVO.getFailureHouses().put(key, ex.getMessage()); + String key = StrUtil.isNotBlank(houseIdentifier) ? houseIdentifier : "第 " + currentIndex + " 行"; + failureMessages.add(key + ": " + ex.getMessage()); return; } - // 2.2 根据小区名称匹配小区ID + // 3.2 校验导入数据中是否有重复的房屋标识 + if (duplicateIdentifiers.contains(fullIdentifier)) { + failureMessages.add(houseIdentifier + ": 导入数据中存在重复的房屋"); + return; + } + + // 3.3 根据小区名称匹配小区ID Long communityId = findCommunityIdByName(importHouse.getCommunityName()); if (communityId == null) { - String houseIdentifier = importHouse.getBuildingNo() + "-" + importHouse.getUnitNo() + "-" + importHouse.getRoomNo(); - respVO.getFailureHouses().put(houseIdentifier, "小区【" + importHouse.getCommunityName() + "】不存在"); + failureMessages.add(houseIdentifier + ": 小区【" + importHouse.getCommunityName() + "】不存在"); return; } - // 2.3 根据业主手机号匹配业主ID + // 3.4 根据业主手机号匹配业主ID Long memberId = null; if (StrUtil.isNotBlank(importHouse.getOwnerPhone())) { - MemberUserDO memberUser = memberUserMapper.selectByMobile(importHouse.getOwnerPhone()); - if (memberUser != null) { - memberId = memberUser.getId(); + // 如果是超管,临时切换到该小区租户上下文查询业主 + if (isSystemAdmin) { + memberId = TenantUtils.execute(communityId, () -> { + MemberUserDO memberUser = memberUserMapper.selectByMobile(importHouse.getOwnerPhone()); + return memberUser != null ? memberUser.getId() : null; + }); + } else { + MemberUserDO memberUser = memberUserMapper.selectByMobile(importHouse.getOwnerPhone()); + if (memberUser != null) { + memberId = memberUser.getId(); + } } } - // 2.4 判断房屋是否已存在(通过小区ID+楼号+单元号+门牌号唯一标识) + // 3.5 判断房屋是否已存在(通过小区ID+楼号+单元号+门牌号唯一标识) HouseDO existHouse = findExistHouse(communityId, importHouse); - - // 2.5 如果不存在,进行插入 + + // 3.6 如果不存在,进行插入 if (existHouse == null) { HouseDO newHouse = BeanUtils.toBean(importHouse, HouseDO.class); newHouse.setCommunityId(communityId); newHouse.setMemberId(memberId); - houseMapper.insert(newHouse); - String houseIdentifier = importHouse.getBuildingNo() + "-" + importHouse.getUnitNo() + "-" + importHouse.getRoomNo(); - respVO.getCreateHouses().add(houseIdentifier); + + // 超管操作时,临时切换到该小区的租户上下文执行插入 + if (isSystemAdmin) { + TenantUtils.execute(communityId, () -> houseMapper.insert(newHouse)); + } else { + houseMapper.insert(newHouse); + } + + createCount.incrementAndGet(); return; } - - // 2.6 如果存在,判断是否允许更新 + + // 3.7 如果存在,判断是否允许更新 if (!isUpdateSupport) { - String houseIdentifier = importHouse.getBuildingNo() + "-" + importHouse.getUnitNo() + "-" + importHouse.getRoomNo(); - respVO.getFailureHouses().put(houseIdentifier, "房屋已存在,且不支持更新"); + failureMessages.add(houseIdentifier + ": 房屋已存在,且不支持更新"); return; } - - // 2.7 更新已有房屋 + + // 3.8 更新已有房屋 HouseDO updateHouse = BeanUtils.toBean(importHouse, HouseDO.class); updateHouse.setId(existHouse.getId()); updateHouse.setCommunityId(communityId); updateHouse.setMemberId(memberId); - houseMapper.updateById(updateHouse); - String houseIdentifier = importHouse.getBuildingNo() + "-" + importHouse.getUnitNo() + "-" + importHouse.getRoomNo(); - respVO.getUpdateHouses().add(houseIdentifier); + + // 超管操作时,临时切换到该小区的租户上下文执行更新 + if (isSystemAdmin) { + TenantUtils.execute(communityId, () -> houseMapper.updateById(updateHouse)); + } else { + houseMapper.updateById(updateHouse); + } + + updateCount.incrementAndGet(); }); - - return respVO; + + return ImportResultRespVO.builder() + .createCount(createCount.get()) + .updateCount(updateCount.get()) + .failureMessages(failureMessages) + .build(); } /** @@ -222,7 +269,7 @@ public class HouseServiceImpl implements HouseService { .eq(HouseDO::getUnitNo, importHouse.getUnitNo()) .eq(HouseDO::getRoomNo, importHouse.getRoomNo()) .last("LIMIT 1")); - + return CollUtil.isNotEmpty(houses) ? houses.get(0) : null; }