From f09fdeb42ffcc2d9a59ae759219363465a923aa2 Mon Sep 17 00:00:00 2001 From: zzy Date: Tue, 21 Apr 2026 23:27:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BC=9A=E5=91=98=E6=88=BF?= =?UTF-8?q?=E5=B1=8B=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../memberhouse/AppMemberHouseController.java | 62 +++++++++ .../memberhouse/vo/AppMemberHouseRespVO.java | 40 ++++++ .../vo/AppMemberHouseSaveReqVO.java | 64 ++++++++++ .../vo/AppMemberRelationRespVO.java | 34 +++++ .../mysql/memberhouse/MemberHouseMapper.java | 15 +++ .../memberhouse/MemberHouseService.java | 43 ++++++- .../memberhouse/MemberHouseServiceImpl.java | 119 ++++++++++++++++++ 7 files changed, 371 insertions(+), 6 deletions(-) create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/AppMemberHouseController.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberHouseRespVO.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberHouseSaveReqVO.java create mode 100644 fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberRelationRespVO.java diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/AppMemberHouseController.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/AppMemberHouseController.java new file mode 100644 index 0000000..0535772 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/AppMemberHouseController.java @@ -0,0 +1,62 @@ +package com.fjrcloud.community.module.community.controller.app.memberhouse; + +import com.fjrcloud.community.framework.common.pojo.CommonResult; +import com.fjrcloud.community.framework.security.core.util.SecurityFrameworkUtils; +import com.fjrcloud.community.module.community.controller.app.memberhouse.vo.AppMemberHouseRespVO; +import com.fjrcloud.community.module.community.controller.app.memberhouse.vo.AppMemberHouseSaveReqVO; +import com.fjrcloud.community.module.community.controller.app.memberhouse.vo.AppMemberRelationRespVO; +import com.fjrcloud.community.module.community.service.memberhouse.MemberHouseService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +import static com.fjrcloud.community.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户APP - 业主认证") +@RestController +@RequestMapping("/community/member-house") +@Validated +@Slf4j +public class AppMemberHouseController { + + @Resource + private MemberHouseService memberHouseService; + + @PostMapping("/create") + @Operation(summary = "创建业主认证") + public CommonResult createMemberHouse(@Valid @RequestBody AppMemberHouseSaveReqVO createReqVO) { + Long memberId = SecurityFrameworkUtils.getLoginUserId(); + return success(memberHouseService.createMemberHouseForApp(memberId, createReqVO)); + } + + @GetMapping("/my-list") + @Operation(summary = "获取我的房屋认证列表") + public CommonResult> getMyHouseList() { + Long memberId = SecurityFrameworkUtils.getLoginUserId(); + return success(memberHouseService.getMemberHouseListByMemberId(memberId)); + } + + @GetMapping("/relation-list") + @Operation(summary = "获取房屋关联人员列表") + @Parameter(name = "houseId", description = "房屋ID", required = true, example = "1") + public CommonResult> getRelationList( + @RequestParam("houseId") Long houseId) { + return success(memberHouseService.getRelationListByHouseId(houseId)); + } + + @DeleteMapping("/unbind") + @Operation(summary = "解除绑定") + @Parameter(name = "id", description = "认证记录ID", required = true, example = "1") + public CommonResult unbindMemberHouse(@RequestParam("id") Long id) { + memberHouseService.unbindMemberHouse(id); + return success(true); + } + +} \ No newline at end of file diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberHouseRespVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberHouseRespVO.java new file mode 100644 index 0000000..02dee70 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberHouseRespVO.java @@ -0,0 +1,40 @@ +package com.fjrcloud.community.module.community.controller.app.memberhouse.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "用户APP - 业主认证房屋列表项 Response VO") +@Data +public class AppMemberHouseRespVO { + + @Schema(description = "主键ID", example = "1") + private Long id; + + @Schema(description = "小区ID", example = "1") + private Long communityId; + + @Schema(description = "小区名称", example = "融侨馨苑") + private String communityName; + + @Schema(description = "房屋id", example = "1") + private Long houseId; + + @Schema(description = "楼号", example = "12号楼") + private String buildingNo; + + @Schema(description = "单元号", example = "1单元") + private String unitNo; + + @Schema(description = "门牌号", example = "701") + private String roomNo; + + @Schema(description = "认证状态(0-待审核,1-已认证,2-驳回)", example = "0") + private Integer status; + + @Schema(description = "驳回原因", example = "证件信息不清晰") + private String rejectReason; + + @Schema(description = "关联人员数量", example = "3") + private Integer relationCount; + +} \ No newline at end of file diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberHouseSaveReqVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberHouseSaveReqVO.java new file mode 100644 index 0000000..5547f56 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberHouseSaveReqVO.java @@ -0,0 +1,64 @@ +package com.fjrcloud.community.module.community.controller.app.memberhouse.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.time.LocalDate; + +@Schema(description = "用户APP - 业主认证信息新增 Request VO") +@Data +public class AppMemberHouseSaveReqVO { + + @Schema(description = "小区ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15661") + @NotNull(message = "小区ID不能为空") + private Long communityId; + + @Schema(description = "小区名称", example = "融侨馨苑") + private String communityName; + + @Schema(description = "房屋id", requiredMode = Schema.RequiredMode.REQUIRED, example = "15336") + @NotNull(message = "房屋id不能为空") + private Long houseId; + + @Schema(description = "楼号", example = "12号楼") + private String buildingNo; + + @Schema(description = "单元号", example = "1单元") + private String unitNo; + + @Schema(description = "门牌号", example = "701") + private String roomNo; + + @Schema(description = "是否产权人(false-否,true-是)", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "是否产权人不能为空") + private Boolean isOwner; + + @Schema(description = "与产权人关系", example = "配偶") + private String relationType; + + @Schema(description = "姓名", example = "张三") + private String name; + + @Schema(description = "手机号", example = "13800138000") + private String mobile; + + @Schema(description = "证件类型", example = "1") + private String idType; + + @Schema(description = "证件号", example = "110101199001011234") + private String idNumber; + + @Schema(description = "性别(0-未知,1-男,2-女)", example = "1") + private Integer sex; + + @Schema(description = "出生日期", example = "1990-01-01") + private LocalDate birthday; + + @Schema(description = "附件URL", example = "https://www.fjrcloud.cn/attachment.jpg") + private String attachmentUrl; + + @Schema(description = "人脸照片URL", example = "https://www.fjrcloud.cn/face.jpg") + private String facePhotoUrl; + +} \ No newline at end of file diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberRelationRespVO.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberRelationRespVO.java new file mode 100644 index 0000000..45620b4 --- /dev/null +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/controller/app/memberhouse/vo/AppMemberRelationRespVO.java @@ -0,0 +1,34 @@ +package com.fjrcloud.community.module.community.controller.app.memberhouse.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "用户APP - 关联人员 Response VO") +@Data +public class AppMemberRelationRespVO { + + @Schema(description = "主键ID", example = "1") + private Long id; + + @Schema(description = "会员ID", example = "100") + private Long memberId; + + @Schema(description = "姓名", example = "王德福") + private String name; + + @Schema(description = "手机号", example = "13800138000") + private String mobile; + + @Schema(description = "是否产权人(0-否,1-是)", example = "true") + private Boolean isOwner; + + @Schema(description = "与产权人关系", example = "本人") + private String relationType; + + @Schema(description = "关系描述", example = "业主") + private String relationDesc; + + @Schema(description = "人脸照片URL", example = "https://www.fjrcloud.cn/face.jpg") + private String facePhotoUrl; + +} \ No newline at end of file diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/memberhouse/MemberHouseMapper.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/memberhouse/MemberHouseMapper.java index 5540408..2277f3d 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/memberhouse/MemberHouseMapper.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/dal/mysql/memberhouse/MemberHouseMapper.java @@ -35,4 +35,19 @@ public interface MemberHouseMapper extends BaseMapperX { .eq(MemberHouseDO::getMobile, mobile)); } + default List selectListByMemberId(Long memberId) { + return selectList(new LambdaQueryWrapperX() + .eq(MemberHouseDO::getMemberId, memberId) + .orderByDesc(MemberHouseDO::getStatus) + .orderByDesc(MemberHouseDO::getId)); + } + + default List selectListByHouseId(Long houseId) { + return selectList(new LambdaQueryWrapperX() + .eq(MemberHouseDO::getHouseId, houseId) + .eq(MemberHouseDO::getStatus, 1) + .orderByDesc(MemberHouseDO::getIsOwner) + .orderByDesc(MemberHouseDO::getId)); + } + } \ No newline at end of file diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/memberhouse/MemberHouseService.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/memberhouse/MemberHouseService.java index 8bc360e..0bac10c 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/memberhouse/MemberHouseService.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/memberhouse/MemberHouseService.java @@ -3,6 +3,9 @@ package com.fjrcloud.community.module.community.service.memberhouse; import com.fjrcloud.community.framework.common.pojo.PageResult; import com.fjrcloud.community.module.community.controller.admin.memberhouse.vo.MemberHousePageReqVO; import com.fjrcloud.community.module.community.controller.admin.memberhouse.vo.MemberHouseSaveReqVO; +import com.fjrcloud.community.module.community.controller.app.memberhouse.vo.AppMemberHouseRespVO; +import com.fjrcloud.community.module.community.controller.app.memberhouse.vo.AppMemberHouseSaveReqVO; +import com.fjrcloud.community.module.community.controller.app.memberhouse.vo.AppMemberRelationRespVO; import com.fjrcloud.community.module.community.dal.dataobject.memberhouse.MemberHouseDO; import javax.validation.Valid; @@ -60,25 +63,53 @@ public interface MemberHouseService { */ PageResult getMemberHousePage(MemberHousePageReqVO pageReqVO); + /** + * 根据会员ID获取房屋认证列表 + * + * @param memberId 会员ID + * @return 房屋认证列表 + */ + List getMemberHouseListByMemberId(Long memberId); + + /** + * 根据房屋ID获取关联人员列表 + * + * @param houseId 房屋ID + * @return 关联人员列表 + */ + List getRelationListByHouseId(Long houseId); + /** * 审核业主认证 * - * @param id 认证 ID - * @param status 审核状态(1-通过,2-驳回) - * @param rejectReason 驳回原因(仅驳回时必填) + * @param id 编号 + * @param status 审核状态 + * @param rejectReason 驳回原因 */ void auditMemberHouse(Long id, Integer status, String rejectReason); /** - * 解除绑定(删除认证记录) + * 解除绑定 * - * @param id 认证 ID + * @param id 编号 */ void unbindMemberHouse(Long id); /** - * 校验认证是否存在 + * 校验业主认证信息是否存在 + * + * @param id 编号 + * @return 业主认证信息 */ MemberHouseDO validateMemberHouseExists(Long id); + /** + * App端创建业主认证信息 + * + * @param memberId 会员ID + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createMemberHouseForApp(Long memberId, @Valid AppMemberHouseSaveReqVO createReqVO); + } \ No newline at end of file diff --git a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/memberhouse/MemberHouseServiceImpl.java b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/memberhouse/MemberHouseServiceImpl.java index 9f06126..0af9ca1 100644 --- a/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/memberhouse/MemberHouseServiceImpl.java +++ b/fjrcloud-module-community/src/main/java/com/fjrcloud/community/module/community/service/memberhouse/MemberHouseServiceImpl.java @@ -7,6 +7,9 @@ import com.fjrcloud.community.framework.common.util.object.BeanUtils; import com.fjrcloud.community.framework.security.core.util.SecurityFrameworkUtils; import com.fjrcloud.community.module.community.controller.admin.memberhouse.vo.MemberHousePageReqVO; import com.fjrcloud.community.module.community.controller.admin.memberhouse.vo.MemberHouseSaveReqVO; +import com.fjrcloud.community.module.community.controller.app.memberhouse.vo.AppMemberHouseRespVO; +import com.fjrcloud.community.module.community.controller.app.memberhouse.vo.AppMemberHouseSaveReqVO; +import com.fjrcloud.community.module.community.controller.app.memberhouse.vo.AppMemberRelationRespVO; import com.fjrcloud.community.module.community.dal.dataobject.memberhouse.MemberHouseDO; import com.fjrcloud.community.module.community.dal.mysql.memberhouse.MemberHouseMapper; import com.fjrcloud.community.module.community.service.community.CommunityService; @@ -20,6 +23,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.List; +import java.util.stream.Collectors; import static com.fjrcloud.community.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.fjrcloud.community.module.community.enums.ErrorCodeConstants.*; @@ -180,4 +184,119 @@ public class MemberHouseServiceImpl implements MemberHouseService { return memberHouseMapper.selectPage(pageReqVO); } + @Override + public List getMemberHouseListByMemberId(Long memberId) { + // 1. 查询该会员的所有房屋认证记录 + List houseList = memberHouseMapper.selectListByMemberId(memberId); + if (CollUtil.isEmpty(houseList)) { + return CollUtil.newArrayList(); + } + + // 2. 按照小区+房屋进行分组,每个房屋只保留最新的一条记录 + return houseList.stream() + .collect(Collectors.groupingBy( + house -> house.getCommunityId() + "_" + house.getBuildingNo() + "_" + house.getUnitNo() + "_" + house.getRoomNo(), + Collectors.maxBy((h1, h2) -> { + // 优先按状态排序:已认证(1) > 待审核(0) > 驳回(2) + int statusCompare = compareStatus(h1.getStatus(), h2.getStatus()); + if (statusCompare != 0) { + return statusCompare; + } + // 状态相同则按ID降序 + return h1.getId().compareTo(h2.getId()); + }) + )) + .values().stream() + .filter(java.util.Optional::isPresent) + .map(java.util.Optional::get) + .map(house -> { + AppMemberHouseRespVO respVO = BeanUtils.toBean(house, AppMemberHouseRespVO.class); + // 查询该房屋的关联人员数量(只统计已认证的) + List relationList = memberHouseMapper.selectListByHouseId(house.getHouseId()); + respVO.setRelationCount(relationList.size()); + return respVO; + }) + .collect(Collectors.toList()); + } + + @Override + public List getRelationListByHouseId(Long houseId) { + // 1. 查询该房屋的所有已认证人员 + List houseList = memberHouseMapper.selectListByHouseId(houseId); + if (CollUtil.isEmpty(houseList)) { + return CollUtil.newArrayList(); + } + + // 2. 转换为响应VO + return houseList.stream().map(house -> { + AppMemberRelationRespVO respVO = BeanUtils.toBean(house, AppMemberRelationRespVO.class); + // 设置关系描述 + respVO.setRelationDesc(buildRelationDesc(house.getIsOwner(), house.getRelationType())); + return respVO; + }).collect(Collectors.toList()); + } + + /** + * 构建关系描述 + * + * @param isOwner 是否产权人 + * @param relationType 关系类型 + * @return 关系描述 + */ + private String buildRelationDesc(Boolean isOwner, String relationType) { + if (Boolean.TRUE.equals(isOwner)) { + return "业主"; + } + if (StrUtil.isNotBlank(relationType)) { + return relationType; + } + return "家属"; + } + + /** + * 比较认证状态优先级 + * + * @param status1 状态1 + * @param status2 状态2 + * @return 比较结果 + */ + private int compareStatus(Integer status1, Integer status2) { + if (status1 == null || status2 == null) { + return 0; + } + // 已认证(1) > 待审核(0) > 驳回(2) + int priority1 = status1 == 1 ? 3 : (status1 == 0 ? 2 : 1); + int priority2 = status2 == 1 ? 3 : (status2 == 0 ? 2 : 1); + return Integer.compare(priority2, priority1); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createMemberHouseForApp(Long memberId, AppMemberHouseSaveReqVO createReqVO) { + // 1. 校验小区是否存在 + if (communityService.getCommunity(createReqVO.getCommunityId()) == null) { + throw exception(COMMUNITY_NOT_EXISTS); + } + + // 2. 校验重复认证:同一小区、同一房屋、同一手机号不能重复认证 + List existList = memberHouseMapper.selectListByCommunityAndRoom( + createReqVO.getCommunityId(), + createReqVO.getBuildingNo(), + createReqVO.getUnitNo(), + createReqVO.getRoomNo(), + createReqVO.getMobile()); + if (CollUtil.isNotEmpty(existList)) { + throw exception(MEMBER_HOUSE_EXISTS); + } + + // 3. 插入数据,默认状态为待审核 (0) + MemberHouseDO memberHouse = BeanUtils.toBean(createReqVO, MemberHouseDO.class); + memberHouse.setMemberId(memberId); + memberHouse.setStatus(0); + memberHouse.setTenantId(createReqVO.getCommunityId()); + memberHouseMapper.insert(memberHouse); + + return memberHouse.getId(); + } + } \ No newline at end of file