From 93de43267e1663031fe5dc2f5ae40d128a182a76 Mon Sep 17 00:00:00 2001
From: doum <doum>
Date: 星期四, 18 六月 2026 17:24:51 +0800
Subject: [PATCH] 新增智能电表、空调管理

---
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwCustomerH5AuthServiceImpl.java |  252 +++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 216 insertions(+), 36 deletions(-)

diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwCustomerH5AuthServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwCustomerH5AuthServiceImpl.java
index 59d02f7..3d0b5fd 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwCustomerH5AuthServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwCustomerH5AuthServiceImpl.java
@@ -12,6 +12,7 @@
 import com.doumee.dao.business.model.Member;
 import com.doumee.dao.business.model.YwCustomer;
 import com.doumee.dao.system.dto.LoginPhoneDTO;
+import com.doumee.service.business.SmsEmailService;
 import com.doumee.service.business.YwCustomerH5AuthService;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -30,22 +31,37 @@
     private MemberMapper memberMapper;
     @Autowired
     private JwtTokenUtil jwtTokenUtil;
+    @Autowired
+    private SmsEmailService smsEmailService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public String loginByPhone(LoginPhoneDTO dto) {
-        YwCustomer customer = findActiveByPhone(dto.getPhone());
-        bindOpenId(customer, dto.getOpenid());
-        touchLogin(customer);
-        return jwtTokenUtil.generateToken(toLoginUserInfo(customer));
+        smsEmailService.validateCode(dto.getCode(), dto.getPhone());
+        CustomerMemberContext ctx = resolveByPhone(dto.getPhone());
+        if (ctx == null || ctx.customer == null) {
+            throw new BusinessException(ResponseStatus.ACCOUNT_INCORRECT.getCode(), "鍟嗘埛涓嶅瓨鍦ㄦ垨鏈敞鍐�");
+        }
+        assertCustomerEnabled(ctx.customer);
+        if (ctx.member != null) {
+            assertMemberEnabled(ctx.member);
+            bindMemberOpenId(ctx.member, dto.getOpenid());
+            touchMemberLogin(ctx.member);
+        }
+        touchLogin(ctx.customer);
+        return jwtTokenUtil.generateToken(toLoginUserInfo(ctx.customer, ctx.member));
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public String loginByCustomerId(Integer customerId) {
         YwCustomer customer = requireActiveCustomer(customerId);
+        Member member = resolveDefaultMember(customer);
         touchLogin(customer);
-        return jwtTokenUtil.generateToken(toLoginUserInfo(customer));
+        if (member != null) {
+            touchMemberLogin(member);
+        }
+        return jwtTokenUtil.generateToken(toLoginUserInfo(customer, member));
     }
 
     @Override
@@ -54,58 +70,97 @@
         if (StringUtils.isBlank(openId)) {
             return null;
         }
+        String trimmed = openId.trim();
+        Member member = findActiveCustomerMemberByOpenId(trimmed);
+        if (member != null) {
+            YwCustomer customer = loadCustomerByMember(member);
+            if (customer != null) {
+                assertCustomerEnabled(customer);
+                assertMemberEnabled(member);
+                touchMemberLogin(member);
+                touchLogin(customer);
+                return jwtTokenUtil.generateToken(toLoginUserInfo(customer, member));
+            }
+        }
         YwCustomer customer = ywCustomerMapper.selectOne(new QueryWrapper<YwCustomer>().lambda()
                 .eq(YwCustomer::getIsdeleted, Constants.ZERO)
-                .eq(YwCustomer::getOpenid, openId.trim())
+                .eq(YwCustomer::getOpenid, trimmed)
                 .last(" limit 1 "));
         if (customer == null) {
             return null;
         }
         assertCustomerEnabled(customer);
+        Member defaultMember = resolveDefaultMember(customer);
+        if (defaultMember != null && StringUtils.isBlank(defaultMember.getOpenid())) {
+            bindMemberOpenId(defaultMember, trimmed);
+            touchMemberLogin(defaultMember);
+        }
         touchLogin(customer);
-        return jwtTokenUtil.generateToken(toLoginUserInfo(customer));
+        return jwtTokenUtil.generateToken(toLoginUserInfo(customer, defaultMember));
     }
 
     @Override
-    public LoginUserInfo buildLoginUserInfo(Integer customerId) {
-        return toLoginUserInfo(requireActiveCustomer(customerId));
+    public LoginUserInfo buildLoginUserInfo(Integer customerId, Integer memberId) {
+        YwCustomer customer = requireActiveCustomer(customerId);
+        Member member = resolveMemberForCustomer(customer, memberId);
+        return toLoginUserInfo(customer, member);
     }
 
     @Override
     public void assertActiveCustomerByPhone(String phone) {
-        findActiveByPhone(phone);
+        CustomerMemberContext ctx = resolveByPhone(phone);
+        if (ctx == null || ctx.customer == null) {
+            throw new BusinessException(ResponseStatus.ACCOUNT_INCORRECT.getCode(), "鍟嗘埛涓嶅瓨鍦ㄦ垨鏈敞鍐�");
+        }
+        assertCustomerEnabled(ctx.customer);
+        if (ctx.member != null) {
+            assertMemberEnabled(ctx.member);
+        }
     }
 
-    private YwCustomer findActiveByPhone(String phone) {
+    private CustomerMemberContext resolveByPhone(String phone) {
         if (StringUtils.isBlank(phone)) {
             throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鎵嬫満鍙蜂笉鑳戒负绌�");
         }
-        YwCustomer customer = findCustomerByPhone(phone.trim());
-        if (customer == null) {
-            throw new BusinessException(ResponseStatus.ACCOUNT_INCORRECT.getCode(), "鍟嗘埛涓嶅瓨鍦ㄦ垨鏈敞鍐�");
+        String trimmed = phone.trim();
+        Member member = findActiveCustomerMemberByPhone(trimmed);
+        if (member != null) {
+            YwCustomer customer = loadCustomerByMember(member);
+            if (customer != null) {
+                return new CustomerMemberContext(customer, member);
+            }
         }
-        assertCustomerEnabled(customer);
-        return customer;
-    }
-
-    /**
-     * 鍟嗘埛鎵嬫満鍙凤細浼樺厛 yw_customer.phone锛屽惁鍒欏尮閰嶈仈绯讳汉 member.phone
-     */
-    private YwCustomer findCustomerByPhone(String phone) {
         YwCustomer byCustomerPhone = ywCustomerMapper.selectOne(new QueryWrapper<YwCustomer>().lambda()
                 .eq(YwCustomer::getIsdeleted, Constants.ZERO)
-                .eq(YwCustomer::getPhone, phone)
+                .eq(YwCustomer::getPhone, trimmed)
                 .last(" limit 1 "));
         if (byCustomerPhone != null) {
-            return byCustomerPhone;
+            return new CustomerMemberContext(byCustomerPhone, resolveDefaultMember(byCustomerPhone));
         }
-        Member member = memberMapper.selectOne(new QueryWrapper<Member>().lambda()
+        return null;
+    }
+
+    private Member findActiveCustomerMemberByPhone(String phone) {
+        return memberMapper.selectOne(new QueryWrapper<Member>().lambda()
                 .eq(Member::getIsdeleted, Constants.ZERO)
                 .eq(Member::getType, Constants.memberType.customer)
                 .eq(Member::getPhone, phone)
                 .isNotNull(Member::getCustomerId)
                 .orderByDesc(Member::getId)
                 .last(" limit 1 "));
+    }
+
+    private Member findActiveCustomerMemberByOpenId(String openId) {
+        return memberMapper.selectOne(new QueryWrapper<Member>().lambda()
+                .eq(Member::getIsdeleted, Constants.ZERO)
+                .eq(Member::getType, Constants.memberType.customer)
+                .eq(Member::getOpenid, openId)
+                .isNotNull(Member::getCustomerId)
+                .orderByDesc(Member::getId)
+                .last(" limit 1 "));
+    }
+
+    private YwCustomer loadCustomerByMember(Member member) {
         if (member == null || member.getCustomerId() == null) {
             return null;
         }
@@ -120,6 +175,48 @@
                 .eq(YwCustomer::getIsdeleted, Constants.ZERO)
                 .eq(YwCustomer::getMemberId, member.getId())
                 .last(" limit 1 "));
+    }
+
+    private Member resolveDefaultMember(YwCustomer customer) {
+        if (customer.getMemberId() != null) {
+            Member member = memberMapper.selectById(customer.getMemberId());
+            if (isActiveCustomerMember(member)) {
+                return member;
+            }
+        }
+        return memberMapper.selectOne(new QueryWrapper<Member>().lambda()
+                .eq(Member::getIsdeleted, Constants.ZERO)
+                .eq(Member::getType, Constants.memberType.customer)
+                .eq(Member::getCustomerId, customer.getId())
+                .orderByAsc(Member::getId)
+                .last(" limit 1 "));
+    }
+
+    private Member resolveMemberForCustomer(YwCustomer customer, Integer memberId) {
+        if (memberId != null) {
+            Member member = memberMapper.selectById(memberId);
+            if (member != null && isMemberBelongsToCustomer(member, customer)) {
+                assertMemberEnabled(member);
+                return member;
+            }
+        }
+        return resolveDefaultMember(customer);
+    }
+
+    private boolean isMemberBelongsToCustomer(Member member, YwCustomer customer) {
+        if (!isActiveCustomerMember(member)) {
+            return false;
+        }
+        if (member.getCustomerId() != null && Constants.equalsInteger(member.getCustomerId(), customer.getId())) {
+            return true;
+        }
+        return customer.getMemberId() != null && Constants.equalsInteger(customer.getMemberId(), member.getId());
+    }
+
+    private boolean isActiveCustomerMember(Member member) {
+        return member != null
+                && Constants.equalsInteger(member.getIsdeleted(), Constants.ZERO)
+                && Constants.equalsInteger(member.getType(), Constants.memberType.customer);
     }
 
     private YwCustomer requireActiveCustomer(Integer customerId) {
@@ -140,15 +237,32 @@
         }
     }
 
-    private void bindOpenId(YwCustomer customer, String openid) {
-        if (StringUtils.isBlank(openid)) {
+    private void assertMemberEnabled(Member member) {
+        if (member.getStatus() != null && Constants.equalsInteger(member.getStatus(), Constants.ONE)) {
+            throw new BusinessException(ResponseStatus.NO_ALLOW_LOGIN.getCode(), "浜哄憳璐﹀彿宸茬鐢�");
+        }
+    }
+
+    private void bindMemberOpenId(Member member, String openid) {
+        if (member == null || StringUtils.isBlank(openid)) {
             return;
         }
-        ywCustomerMapper.update(null, new UpdateWrapper<YwCustomer>().lambda()
-                .set(YwCustomer::getOpenid, null)
-                .eq(YwCustomer::getOpenid, openid.trim())
-                .ne(YwCustomer::getId, customer.getId()));
-        customer.setOpenid(openid.trim());
+        String trimmed = openid.trim();
+        memberMapper.update(null, new UpdateWrapper<Member>().lambda()
+                .set(Member::getOpenid, null)
+                .eq(Member::getOpenid, trimmed)
+                .ne(Member::getId, member.getId()));
+        member.setOpenid(trimmed);
+        member.setEditDate(new Date());
+        memberMapper.updateById(member);
+    }
+
+    private void touchMemberLogin(Member member) {
+        if (member == null) {
+            return;
+        }
+        member.setEditDate(new Date());
+        memberMapper.updateById(member);
     }
 
     private void touchLogin(YwCustomer customer) {
@@ -159,18 +273,43 @@
         ywCustomerMapper.updateById(customer);
     }
 
-    private LoginUserInfo toLoginUserInfo(YwCustomer customer) {
+    private LoginUserInfo toLoginUserInfo(YwCustomer customer, Member member) {
         LoginUserInfo loginUserInfo = new LoginUserInfo();
         loginUserInfo.setCustomerId(customer.getId());
         loginUserInfo.setId(customer.getId());
         loginUserInfo.setH5UserType(LoginUserInfo.H5_USER_CUSTOMER);
-        loginUserInfo.setRealname(customer.getName());
-        loginUserInfo.setMobile(resolveLoginMobile(customer));
-        loginUserInfo.setUsername("customer_" + customer.getId());
+        loginUserInfo.setCustomerName(customer.getName());
+        if (member != null) {
+            loginUserInfo.setMemberId(member.getId());
+            loginUserInfo.setMemberName(member.getName());
+            loginUserInfo.setMobile(member.getPhone());
+        } else {
+            loginUserInfo.setMobile(resolveLoginMobile(customer));
+        }
+        String displayName = buildDisplayName(customer.getName(), member != null ? member.getName() : null);
+        loginUserInfo.setDisplayName(displayName);
+        loginUserInfo.setRealname(displayName);
+        loginUserInfo.setUsername("customer_" + customer.getId()
+                + "_member_" + (member != null ? member.getId() : 0));
         loginUserInfo.setSource(LoginUserInfo.SOURCE_H5_CUSTOMER);
         loginUserInfo.setRoles(Collections.singletonList("h5_customer"));
         loginUserInfo.setPermissions(Collections.emptyList());
         return loginUserInfo;
+    }
+
+    private String buildDisplayName(String customerName, String memberName) {
+        String customer = StringUtils.trimToEmpty(customerName);
+        String member = StringUtils.trimToEmpty(memberName);
+        if (StringUtils.isBlank(customer) && StringUtils.isBlank(member)) {
+            return "";
+        }
+        if (StringUtils.isBlank(member)) {
+            return customer;
+        }
+        if (StringUtils.isBlank(customer)) {
+            return member;
+        }
+        return customer + "-" + member;
     }
 
     private String resolveLoginMobile(YwCustomer customer) {
@@ -185,4 +324,45 @@
         }
         return customer.getPhone();
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void logout(LoginUserInfo user, String token) {
+        if (user == null) {
+            jwtTokenUtil.invalidateToken(token);
+            return;
+        }
+        String memberOpenId = null;
+        if (user.getMemberId() != null) {
+            Member member = memberMapper.selectById(user.getMemberId());
+            if (member != null) {
+                memberOpenId = member.getOpenid();
+                if (StringUtils.isNotBlank(memberOpenId)) {
+                    memberMapper.update(null, new UpdateWrapper<Member>().lambda()
+                            .set(Member::getOpenid, null)
+                            .eq(Member::getId, member.getId()));
+                }
+            }
+        }
+        if (user.getCustomerId() != null) {
+            YwCustomer customer = ywCustomerMapper.selectById(user.getCustomerId());
+            if (customer != null && StringUtils.isNotBlank(customer.getOpenid())
+                    && (memberOpenId == null || StringUtils.equals(customer.getOpenid(), memberOpenId))) {
+                ywCustomerMapper.update(null, new UpdateWrapper<YwCustomer>().lambda()
+                        .set(YwCustomer::getOpenid, null)
+                        .eq(YwCustomer::getId, customer.getId()));
+            }
+        }
+        jwtTokenUtil.invalidateToken(token);
+    }
+
+    private static class CustomerMemberContext {
+        private final YwCustomer customer;
+        private final Member member;
+
+        private CustomerMemberContext(YwCustomer customer, Member member) {
+            this.customer = customer;
+            this.member = member;
+        }
+    }
 }

--
Gitblit v1.9.3