diff --git a/fjrcloud-module-community/pom.xml b/fjrcloud-module-community/pom.xml
index 65f2a4a..bbe5022 100644
--- a/fjrcloud-module-community/pom.xml
+++ b/fjrcloud-module-community/pom.xml
@@ -27,6 +27,11 @@
fjrcloud-module-infra
${revision}
+
+ com.fjrcloud.boot
+ fjrcloud-module-member
+ ${revision}
+
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
new file mode 100644
index 0000000..2e5b7ad
--- /dev/null
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/HouseController.java
@@ -0,0 +1,142 @@
+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.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.dal.dataobject.house.HouseDO;
+import com.fjrcloud.community.module.community.service.house.HouseService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import static com.fjrcloud.community.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static com.fjrcloud.community.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - 房屋信息主")
+@RestController
+@RequestMapping("/community/house")
+@Validated
+public class HouseController {
+
+ @Resource
+ private HouseService houseService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建房屋信息主")
+ @PreAuthorize("@ss.hasPermission('community:house:create')")
+ public CommonResult createHouse(@Valid @RequestBody HouseSaveReqVO createReqVO) {
+ return success(houseService.createHouse(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新房屋信息主")
+ @PreAuthorize("@ss.hasPermission('community:house:update')")
+ public CommonResult updateHouse(@Valid @RequestBody HouseSaveReqVO updateReqVO) {
+ houseService.updateHouse(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除房屋信息主")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('community:house:delete')")
+ public CommonResult deleteHouse(@RequestParam("id") Long id) {
+ houseService.deleteHouse(id);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete-list")
+ @Parameter(name = "ids", description = "编号", required = true)
+ @Operation(summary = "批量删除房屋信息主")
+ @PreAuthorize("@ss.hasPermission('community:house:delete')")
+ public CommonResult deleteHouseList(@RequestParam("ids") List ids) {
+ houseService.deleteHouseListByIds(ids);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得房屋信息主")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('community:house:query')")
+ public CommonResult getHouse(@RequestParam("id") Long id) {
+ HouseDO house = houseService.getHouse(id);
+ return success(BeanUtils.toBean(house, HouseRespVO.class));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得房屋信息主分页")
+ @PreAuthorize("@ss.hasPermission('community:house:query')")
+ public CommonResult> getHousePage(@Valid HousePageReqVO pageReqVO) {
+ PageResult pageResult = houseService.getHousePage(pageReqVO);
+ return success(BeanUtils.toBean(pageResult, HouseRespVO.class));
+ }
+
+ @GetMapping("/export-excel")
+ @Operation(summary = "导出房屋信息主 Excel")
+ @PreAuthorize("@ss.hasPermission('community:house:export')")
+ @ApiAccessLog(operateType = EXPORT)
+ public void exportHouseExcel(@Valid HousePageReqVO pageReqVO,
+ HttpServletResponse response) throws IOException {
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+ List list = houseService.getHousePage(pageReqVO).getList();
+ // 导出 Excel
+ ExcelUtils.write(response, "房屋信息主.xls", "数据", HouseRespVO.class,
+ BeanUtils.toBean(list, HouseRespVO.class));
+ }
+
+ @GetMapping("/get-import-template")
+ @Operation(summary = "获得导入房屋模板")
+ public void importTemplate(HttpServletResponse response) throws IOException {
+ // 手动创建导出 demo
+ List list = Arrays.asList(
+ HouseImportExcelVO.builder()
+ .communityName("阳光小区")
+ .buildingNo("1号楼")
+ .unitNo("1单元")
+ .roomNo("101")
+ .ownerName("张三")
+ .ownerPhone("13800138000")
+ .build(),
+ HouseImportExcelVO.builder()
+ .communityName("阳光小区")
+ .buildingNo("1号楼")
+ .unitNo("1单元")
+ .roomNo("102")
+ .ownerName("李四")
+ .ownerPhone("13800138001")
+ .build()
+ );
+ // 输出
+ ExcelUtils.write(response, "房屋导入模板.xls", "房屋列表", HouseImportExcelVO.class, list);
+ }
+
+ @PostMapping("/import")
+ @Operation(summary = "导入房屋")
+ @Parameters({
+ @Parameter(name = "file", description = "Excel 文件", required = true),
+ @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 {
+ List list = ExcelUtils.read(file, HouseImportExcelVO.class);
+ return success(houseService.importHouseList(list, updateSupport));
+ }
+
+}
\ No newline at end of file
diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseImportExcelVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseImportExcelVO.java
new file mode 100644
index 0000000..25ec8fc
--- /dev/null
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseImportExcelVO.java
@@ -0,0 +1,41 @@
+package com.fjrcloud.community.module.community.controller.admin.house.vo;
+
+import cn.idev.excel.annotation.ExcelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * 房屋信息导入 Excel VO
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class HouseImportExcelVO {
+
+ @ExcelProperty("小区名称")
+ private String communityName;
+
+ @ExcelProperty("楼号")
+ private String buildingNo;
+
+ @ExcelProperty("单元号")
+ private String unitNo;
+
+ @ExcelProperty("门牌号")
+ private String roomNo;
+
+ @ExcelProperty("产权面积(㎡)")
+ private BigDecimal propertyArea;
+
+ @ExcelProperty("业主姓名")
+ private String ownerName;
+
+ @ExcelProperty("业主手机号")
+ private String ownerPhone;
+
+}
diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseImportRespVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseImportRespVO.java
new file mode 100644
index 0000000..3fddeda
--- /dev/null
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseImportRespVO.java
@@ -0,0 +1,24 @@
+package com.fjrcloud.community.module.community.controller.admin.house.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Schema(description = "管理后台 - 房屋导入 Response VO")
+@Data
+@Builder
+public class HouseImportRespVO {
+
+ @Schema(description = "创建成功的房屋编号数组", requiredMode = Schema.RequiredMode.REQUIRED)
+ private List createHouses;
+
+ @Schema(description = "更新成功的房屋编号数组", requiredMode = Schema.RequiredMode.REQUIRED)
+ private List updateHouses;
+
+ @Schema(description = "导入失败的房屋集合,key 为房屋标识,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
+ private Map failureHouses;
+
+}
diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HousePageReqVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HousePageReqVO.java
new file mode 100644
index 0000000..c5fa882
--- /dev/null
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HousePageReqVO.java
@@ -0,0 +1,48 @@
+package com.fjrcloud.community.module.community.controller.admin.house.vo;
+
+import com.fjrcloud.community.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+import static com.fjrcloud.community.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 房屋信息主分页 Request VO")
+@Data
+public class HousePageReqVO extends PageParam {
+
+ @Schema(description = "小区ID", example = "21615")
+ private Long communityId;
+
+ @Schema(description = "小区名称", example = "李四")
+ private String communityName;
+
+ @Schema(description = "楼号")
+ private String buildingNo;
+
+ @Schema(description = "单元号")
+ private String unitNo;
+
+ @Schema(description = "门牌号")
+ private String roomNo;
+
+ @Schema(description = "产权面积(㎡)")
+ private BigDecimal propertyArea;
+
+ @Schema(description = "业主ID", example = "9301")
+ private Long memberId;
+
+ @Schema(description = "业主姓名", example = "王五")
+ private String ownerName;
+
+ @Schema(description = "业主手机号")
+ private String ownerPhone;
+
+ @Schema(description = "创建时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] createTime;
+
+}
\ No newline at end of file
diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseRespVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseRespVO.java
new file mode 100644
index 0000000..ffe00cc
--- /dev/null
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseRespVO.java
@@ -0,0 +1,60 @@
+package com.fjrcloud.community.module.community.controller.admin.house.vo;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 房屋信息主 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class HouseRespVO {
+
+ @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "25483")
+ @ExcelProperty("主键ID")
+ private Long id;
+
+ @Schema(description = "小区ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "21615")
+ @ExcelProperty("小区ID")
+ private Long communityId;
+
+ @Schema(description = "小区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
+ @ExcelProperty("小区名称")
+ private String communityName;
+
+ @Schema(description = "楼号", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("楼号")
+ private String buildingNo;
+
+ @Schema(description = "单元号", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("单元号")
+ private String unitNo;
+
+ @Schema(description = "门牌号", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("门牌号")
+ private String roomNo;
+
+ @Schema(description = "产权面积(㎡)")
+ @ExcelProperty("产权面积(㎡)")
+ private BigDecimal propertyArea;
+
+ @Schema(description = "业主ID", example = "9301")
+ @ExcelProperty("业主ID")
+ private Long memberId;
+
+ @Schema(description = "业主姓名", example = "王五")
+ @ExcelProperty("业主姓名")
+ private String ownerName;
+
+ @Schema(description = "业主手机号")
+ @ExcelProperty("业主手机号")
+ private String ownerPhone;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ @ExcelProperty("创建时间")
+ private LocalDateTime createTime;
+
+}
\ No newline at end of file
diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseSaveReqVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseSaveReqVO.java
new file mode 100644
index 0000000..aed7026
--- /dev/null
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/admin/house/vo/HouseSaveReqVO.java
@@ -0,0 +1,49 @@
+package com.fjrcloud.community.module.community.controller.admin.house.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+@Schema(description = "管理后台 - 房屋信息主新增/修改 Request VO")
+@Data
+public class HouseSaveReqVO {
+
+ @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "25483")
+ private Long id;
+
+ @Schema(description = "小区ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "21615")
+ @NotNull(message = "小区ID不能为空")
+ private Long communityId;
+
+ @Schema(description = "小区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
+ @NotEmpty(message = "小区名称不能为空")
+ private String communityName;
+
+ @Schema(description = "楼号", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotEmpty(message = "楼号不能为空")
+ private String buildingNo;
+
+ @Schema(description = "单元号", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotEmpty(message = "单元号不能为空")
+ private String unitNo;
+
+ @Schema(description = "门牌号", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotEmpty(message = "门牌号不能为空")
+ private String roomNo;
+
+ @Schema(description = "产权面积(㎡)")
+ private BigDecimal propertyArea;
+
+ @Schema(description = "业主ID", example = "9301")
+ private Long memberId;
+
+ @Schema(description = "业主姓名", example = "王五")
+ private String ownerName;
+
+ @Schema(description = "业主手机号")
+ private String ownerPhone;
+
+}
\ No newline at end of file
diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/house/HouseDO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/house/HouseDO.java
new file mode 100644
index 0000000..e11896a
--- /dev/null
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/dataobject/house/HouseDO.java
@@ -0,0 +1,69 @@
+package com.fjrcloud.community.module.community.dal.dataobject.house;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fjrcloud.community.framework.mybatis.core.dataobject.BaseDO;
+import lombok.*;
+
+import java.math.BigDecimal;
+
+/**
+ * 房屋信息主 DO
+ *
+ * @author zzy
+ */
+@TableName("comm_house")
+@KeySequence("comm_house_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class HouseDO extends BaseDO {
+
+ /**
+ * 主键ID
+ */
+ @TableId
+ private Long id;
+ /**
+ * 小区ID
+ */
+ private Long communityId;
+ /**
+ * 小区名称
+ */
+ private String communityName;
+ /**
+ * 楼号
+ */
+ private String buildingNo;
+ /**
+ * 单元号
+ */
+ private String unitNo;
+ /**
+ * 门牌号
+ */
+ private String roomNo;
+ /**
+ * 产权面积(㎡)
+ */
+ private BigDecimal propertyArea;
+ /**
+ * 业主ID
+ */
+ private Long memberId;
+ /**
+ * 业主姓名
+ */
+ private String ownerName;
+ /**
+ * 业主手机号
+ */
+ private String ownerPhone;
+
+
+}
\ No newline at end of file
diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/house/HouseMapper.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/house/HouseMapper.java
new file mode 100644
index 0000000..a05cd7c
--- /dev/null
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/house/HouseMapper.java
@@ -0,0 +1,33 @@
+package com.fjrcloud.community.module.community.dal.mysql.house;
+
+import com.fjrcloud.community.framework.common.pojo.PageResult;
+import com.fjrcloud.community.framework.mybatis.core.mapper.BaseMapperX;
+import com.fjrcloud.community.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.fjrcloud.community.module.community.controller.admin.house.vo.HousePageReqVO;
+import com.fjrcloud.community.module.community.dal.dataobject.house.HouseDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 房屋信息主 Mapper
+ *
+ * @author zzy
+ */
+@Mapper
+public interface HouseMapper extends BaseMapperX {
+
+ default PageResult selectPage(HousePageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .eqIfPresent(HouseDO::getCommunityId, reqVO.getCommunityId())
+ .likeIfPresent(HouseDO::getCommunityName, reqVO.getCommunityName())
+ .eqIfPresent(HouseDO::getBuildingNo, reqVO.getBuildingNo())
+ .eqIfPresent(HouseDO::getUnitNo, reqVO.getUnitNo())
+ .eqIfPresent(HouseDO::getRoomNo, reqVO.getRoomNo())
+ .eqIfPresent(HouseDO::getPropertyArea, reqVO.getPropertyArea())
+ .eqIfPresent(HouseDO::getMemberId, reqVO.getMemberId())
+ .likeIfPresent(HouseDO::getOwnerName, reqVO.getOwnerName())
+ .eqIfPresent(HouseDO::getOwnerPhone, reqVO.getOwnerPhone())
+ .betweenIfPresent(HouseDO::getCreateTime, reqVO.getCreateTime())
+ .orderByDesc(HouseDO::getId));
+ }
+
+}
\ No newline at end of file
diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/enums/ErrorCodeConstants.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/enums/ErrorCodeConstants.java
index c3a090f..a329cef 100644
--- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/enums/ErrorCodeConstants.java
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/enums/ErrorCodeConstants.java
@@ -10,4 +10,9 @@ import com.fjrcloud.community.framework.common.exception.ErrorCode;
public interface ErrorCodeConstants {
ErrorCode COMMUNITY_NOT_EXISTS = new ErrorCode(2_001_000_001, "小区信息主表(comm_community)不存在");
+
+ ErrorCode HOUSE_NOT_EXISTS = new ErrorCode(2_001_001_001, "房屋信息主不存在");
+
+ ErrorCode HOUSE_IMPORT_LIST_IS_EMPTY = new ErrorCode(2_001_001_002, "导入房屋数据不能为空!");
+
}
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
new file mode 100644
index 0000000..2606260
--- /dev/null
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/house/HouseService.java
@@ -0,0 +1,74 @@
+package com.fjrcloud.community.module.community.service.house;
+
+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;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 房屋信息主 Service 接口
+ *
+ * @author zzy
+ */
+public interface HouseService {
+
+ /**
+ * 创建房屋信息主
+ *
+ * @param createReqVO 创建信息
+ * @return 编号
+ */
+ Long createHouse(@Valid HouseSaveReqVO createReqVO);
+
+ /**
+ * 更新房屋信息主
+ *
+ * @param updateReqVO 更新信息
+ */
+ void updateHouse(@Valid HouseSaveReqVO updateReqVO);
+
+ /**
+ * 删除房屋信息主
+ *
+ * @param id 编号
+ */
+ void deleteHouse(Long id);
+
+ /**
+ * 批量删除房屋信息主
+ *
+ * @param ids 编号
+ */
+ void deleteHouseListByIds(List ids);
+
+ /**
+ * 获得房屋信息主
+ *
+ * @param id 编号
+ * @return 房屋信息主
+ */
+ HouseDO getHouse(Long id);
+
+ /**
+ * 获得房屋信息主分页
+ *
+ * @param pageReqVO 分页查询
+ * @return 房屋信息主分页
+ */
+ PageResult getHousePage(HousePageReqVO pageReqVO);
+
+ /**
+ * 批量导入房屋
+ *
+ * @param importHouses 导入房屋列表
+ * @param isUpdateSupport 是否支持更新
+ * @return 导入结果
+ */
+ HouseImportRespVO 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
new file mode 100644
index 0000000..4c07c34
--- /dev/null
+++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/house/HouseServiceImpl.java
@@ -0,0 +1,229 @@
+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.PageResult;
+import com.fjrcloud.community.framework.common.util.object.BeanUtils;
+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;
+import com.fjrcloud.community.module.community.dal.dataobject.house.HouseDO;
+import com.fjrcloud.community.module.community.dal.mysql.community.CommunityMapper;
+import com.fjrcloud.community.module.community.dal.mysql.house.HouseMapper;
+import com.fjrcloud.community.module.member.dal.dataobject.user.MemberUserDO;
+import com.fjrcloud.community.module.member.dal.mysql.user.MemberUserMapper;
+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.concurrent.atomic.AtomicInteger;
+
+import static com.fjrcloud.community.framework.common.exception.util.ServiceExceptionUtil.exception;
+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;
+
+/**
+ * 房屋信息主 Service 实现类
+ *
+ * @author zzy
+ */
+@Service
+@Validated
+public class HouseServiceImpl implements HouseService {
+
+ @Resource
+ private HouseMapper houseMapper;
+
+ @Resource
+ private CommunityMapper communityMapper;
+
+ @Resource
+ private MemberUserMapper memberUserMapper;
+
+ @Override
+ public Long createHouse(HouseSaveReqVO createReqVO) {
+ // 插入
+ HouseDO house = BeanUtils.toBean(createReqVO, HouseDO.class);
+ houseMapper.insert(house);
+
+ // 返回
+ return house.getId();
+ }
+
+ @Override
+ public void updateHouse(HouseSaveReqVO updateReqVO) {
+ // 校验存在
+ validateHouseExists(updateReqVO.getId());
+ // 更新
+ HouseDO updateObj = BeanUtils.toBean(updateReqVO, HouseDO.class);
+ houseMapper.updateById(updateObj);
+ }
+
+ @Override
+ public void deleteHouse(Long id) {
+ // 校验存在
+ validateHouseExists(id);
+ // 删除
+ houseMapper.deleteById(id);
+ }
+
+ @Override
+ public void deleteHouseListByIds(List ids) {
+ // 删除
+ houseMapper.deleteByIds(ids);
+ }
+
+
+ private void validateHouseExists(Long id) {
+ if (houseMapper.selectById(id) == null) {
+ throw exception(HOUSE_NOT_EXISTS);
+ }
+ }
+
+ @Override
+ public HouseDO getHouse(Long id) {
+ return houseMapper.selectById(id);
+ }
+
+ @Override
+ public PageResult getHousePage(HousePageReqVO pageReqVO) {
+ return houseMapper.selectPage(pageReqVO);
+ }
+
+ @Override
+ public HouseImportRespVO 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();
+
+ AtomicInteger index = new AtomicInteger(1);
+ importHouses.forEach(importHouse -> {
+ int currentIndex = index.getAndIncrement();
+
+ // 2.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());
+ return;
+ }
+
+ // 2.2 根据小区名称匹配小区ID
+ Long communityId = findCommunityIdByName(importHouse.getCommunityName());
+ if (communityId == null) {
+ String houseIdentifier = importHouse.getBuildingNo() + "-" + importHouse.getUnitNo() + "-" + importHouse.getRoomNo();
+ respVO.getFailureHouses().put(houseIdentifier, "小区【" + importHouse.getCommunityName() + "】不存在");
+ return;
+ }
+
+ // 2.3 根据业主手机号匹配业主ID
+ Long memberId = null;
+ if (StrUtil.isNotBlank(importHouse.getOwnerPhone())) {
+ MemberUserDO memberUser = memberUserMapper.selectByMobile(importHouse.getOwnerPhone());
+ if (memberUser != null) {
+ memberId = memberUser.getId();
+ }
+ }
+
+ // 2.4 判断房屋是否已存在(通过小区ID+楼号+单元号+门牌号唯一标识)
+ HouseDO existHouse = findExistHouse(communityId, importHouse);
+
+ // 2.5 如果不存在,进行插入
+ 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);
+ return;
+ }
+
+ // 2.6 如果存在,判断是否允许更新
+ if (!isUpdateSupport) {
+ String houseIdentifier = importHouse.getBuildingNo() + "-" + importHouse.getUnitNo() + "-" + importHouse.getRoomNo();
+ respVO.getFailureHouses().put(houseIdentifier, "房屋已存在,且不支持更新");
+ return;
+ }
+
+ // 2.7 更新已有房屋
+ 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);
+ });
+
+ return respVO;
+ }
+
+ /**
+ * 校验导入的房屋数据
+ *
+ * @param importHouse 导入的房屋数据
+ * @param currentIndex 当前行号
+ */
+ private void validateImportHouse(HouseImportExcelVO importHouse, int currentIndex) {
+ if (StrUtil.isBlank(importHouse.getCommunityName())) {
+ throw new IllegalArgumentException("第 " + currentIndex + " 行:小区名称不能为空");
+ }
+ if (StrUtil.isBlank(importHouse.getBuildingNo())) {
+ throw new IllegalArgumentException("第 " + currentIndex + " 行:楼号不能为空");
+ }
+ if (StrUtil.isBlank(importHouse.getUnitNo())) {
+ throw new IllegalArgumentException("第 " + currentIndex + " 行:单元号不能为空");
+ }
+ if (StrUtil.isBlank(importHouse.getRoomNo())) {
+ throw new IllegalArgumentException("第 " + currentIndex + " 行:门牌号不能为空");
+ }
+ }
+
+ /**
+ * 根据小区名称查找小区ID
+ *
+ * @param communityName 小区名称
+ * @return 小区ID,未找到返回null
+ */
+ private Long findCommunityIdByName(String communityName) {
+ CommunityDO community = communityMapper.selectOne(CommunityDO::getCommunityName, communityName);
+ return community != null ? community.getId() : null;
+ }
+
+ /**
+ * 查找已存在的房屋
+ *
+ * @param communityId 小区ID
+ * @param importHouse 导入的房屋数据
+ * @return 已存在的房屋
+ */
+ private HouseDO findExistHouse(Long communityId, HouseImportExcelVO importHouse) {
+ // 通过小区ID+楼号+单元号+门牌号查找已存在的房屋
+ List houses = houseMapper.selectList(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper()
+ .eq(HouseDO::getCommunityId, communityId)
+ .eq(HouseDO::getBuildingNo, importHouse.getBuildingNo())
+ .eq(HouseDO::getUnitNo, importHouse.getUnitNo())
+ .eq(HouseDO::getRoomNo, importHouse.getRoomNo())
+ .last("LIMIT 1"));
+
+ return CollUtil.isNotEmpty(houses) ? houses.get(0) : null;
+ }
+
+}
\ No newline at end of file
diff --git a/fjrcloud-module-community/src/main/resources/mapper/house/HouseMapper.xml b/fjrcloud-module-community/src/main/resources/mapper/house/HouseMapper.xml
new file mode 100644
index 0000000..27e00cd
--- /dev/null
+++ b/fjrcloud-module-community/src/main/resources/mapper/house/HouseMapper.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
\ No newline at end of file