新增会员房屋管理

master
zzy 2026-04-21 23:27:38 +08:00
parent 325d782450
commit f09fdeb42f
7 changed files with 371 additions and 6 deletions

View File

@ -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<Long> createMemberHouse(@Valid @RequestBody AppMemberHouseSaveReqVO createReqVO) {
Long memberId = SecurityFrameworkUtils.getLoginUserId();
return success(memberHouseService.createMemberHouseForApp(memberId, createReqVO));
}
@GetMapping("/my-list")
@Operation(summary = "获取我的房屋认证列表")
public CommonResult<List<AppMemberHouseRespVO>> 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<List<AppMemberRelationRespVO>> 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<Boolean> unbindMemberHouse(@RequestParam("id") Long id) {
memberHouseService.unbindMemberHouse(id);
return success(true);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -35,4 +35,19 @@ public interface MemberHouseMapper extends BaseMapperX<MemberHouseDO> {
.eq(MemberHouseDO::getMobile, mobile)); .eq(MemberHouseDO::getMobile, mobile));
} }
default List<MemberHouseDO> selectListByMemberId(Long memberId) {
return selectList(new LambdaQueryWrapperX<MemberHouseDO>()
.eq(MemberHouseDO::getMemberId, memberId)
.orderByDesc(MemberHouseDO::getStatus)
.orderByDesc(MemberHouseDO::getId));
}
default List<MemberHouseDO> selectListByHouseId(Long houseId) {
return selectList(new LambdaQueryWrapperX<MemberHouseDO>()
.eq(MemberHouseDO::getHouseId, houseId)
.eq(MemberHouseDO::getStatus, 1)
.orderByDesc(MemberHouseDO::getIsOwner)
.orderByDesc(MemberHouseDO::getId));
}
} }

View File

@ -3,6 +3,9 @@ package com.fjrcloud.community.module.community.service.memberhouse;
import com.fjrcloud.community.framework.common.pojo.PageResult; 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.MemberHousePageReqVO;
import com.fjrcloud.community.module.community.controller.admin.memberhouse.vo.MemberHouseSaveReqVO; 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.dataobject.memberhouse.MemberHouseDO;
import javax.validation.Valid; import javax.validation.Valid;
@ -60,25 +63,53 @@ public interface MemberHouseService {
*/ */
PageResult<MemberHouseDO> getMemberHousePage(MemberHousePageReqVO pageReqVO); PageResult<MemberHouseDO> getMemberHousePage(MemberHousePageReqVO pageReqVO);
/**
* ID
*
* @param memberId ID
* @return
*/
List<AppMemberHouseRespVO> getMemberHouseListByMemberId(Long memberId);
/**
* ID
*
* @param houseId ID
* @return
*/
List<AppMemberRelationRespVO> getRelationListByHouseId(Long houseId);
/** /**
* *
* *
* @param id ID * @param id
* @param status 1-2- * @param status
* @param rejectReason * @param rejectReason
*/ */
void auditMemberHouse(Long id, Integer status, String rejectReason); void auditMemberHouse(Long id, Integer status, String rejectReason);
/** /**
* *
* *
* @param id ID * @param id
*/ */
void unbindMemberHouse(Long id); void unbindMemberHouse(Long id);
/** /**
* *
*
* @param id
* @return
*/ */
MemberHouseDO validateMemberHouseExists(Long id); MemberHouseDO validateMemberHouseExists(Long id);
/**
* App
*
* @param memberId ID
* @param createReqVO
* @return
*/
Long createMemberHouseForApp(Long memberId, @Valid AppMemberHouseSaveReqVO createReqVO);
} }

View File

@ -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.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.MemberHousePageReqVO;
import com.fjrcloud.community.module.community.controller.admin.memberhouse.vo.MemberHouseSaveReqVO; 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.dataobject.memberhouse.MemberHouseDO;
import com.fjrcloud.community.module.community.dal.mysql.memberhouse.MemberHouseMapper; import com.fjrcloud.community.module.community.dal.mysql.memberhouse.MemberHouseMapper;
import com.fjrcloud.community.module.community.service.community.CommunityService; import com.fjrcloud.community.module.community.service.community.CommunityService;
@ -20,6 +23,7 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; 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.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.fjrcloud.community.module.community.enums.ErrorCodeConstants.*; import static com.fjrcloud.community.module.community.enums.ErrorCodeConstants.*;
@ -180,4 +184,119 @@ public class MemberHouseServiceImpl implements MemberHouseService {
return memberHouseMapper.selectPage(pageReqVO); return memberHouseMapper.selectPage(pageReqVO);
} }
@Override
public List<AppMemberHouseRespVO> getMemberHouseListByMemberId(Long memberId) {
// 1. 查询该会员的所有房屋认证记录
List<MemberHouseDO> 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<MemberHouseDO> relationList = memberHouseMapper.selectListByHouseId(house.getHouseId());
respVO.setRelationCount(relationList.size());
return respVO;
})
.collect(Collectors.toList());
}
@Override
public List<AppMemberRelationRespVO> getRelationListByHouseId(Long houseId) {
// 1. 查询该房屋的所有已认证人员
List<MemberHouseDO> 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<MemberHouseDO> 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();
}
} }