Bläddra i källkod

feat(user): 添加用户数据恢复功能,补回被物理删除的用户信息

- 新增UserInfoMapper接口方法,查询订单和账户中存在但用户表缺失的用户数据
- 实现UserInfoService恢复方法,针对缺失用户重新插入用户记录
- 修改UserInfoServiceImpl,实现根据订单和账户数据恢复用户逻辑
- 在AppletHomeController添加测试接口调用恢复方法并记录恢复数量日志
- 调整UserInfoService的getUserInfoByPhone方法及更新用户信息逻辑
- 更新ResultCode中访问令牌失效提示文案为“暂未登录~”
wzq 4 veckor sedan
förälder
incheckning
502ea7abfb

+ 16 - 1
src/main/java/com/zsElectric/boot/business/controller/applet/AppletHomeController.java

@@ -5,6 +5,7 @@ import com.zsElectric.boot.business.model.entity.Advertising;
 import com.zsElectric.boot.business.model.query.AdvertisingQuery;
 import com.zsElectric.boot.business.model.vo.AdvertisingVO;
 import com.zsElectric.boot.business.service.AdvertisingService;
+import com.zsElectric.boot.business.service.UserInfoService;
 import com.zsElectric.boot.charging.service.ChargingReceptionService;
 import com.zsElectric.boot.common.constant.SystemConstants;
 import com.zsElectric.boot.common.util.electric.RequestParmsEntity;
@@ -20,12 +21,15 @@ import com.zsElectric.boot.business.service.AppletHomeService;
 import com.zsElectric.boot.core.web.PageResult;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 import java.math.BigDecimal;
 import java.util.List;
 
+@Slf4j
 @Tag(name = "小程序主页相关接口")
 @RestController
 @RequestMapping("/applet/v1/homePage")
@@ -55,7 +59,7 @@ public class AppletHomeController {
      * 首页地图模式-获取充电站列表(按距离排序)
      *
      * @param longitude 经度
-     * @param latitude 纬度
+     * @param latitude  纬度
      * @return 站点列表
      */
     @Operation(summary = "首页地图模式-获取充电站列表(按距离排序)")
@@ -98,4 +102,15 @@ public class AppletHomeController {
     public ResponseParmsEntity test(@RequestBody RequestParmsEntity requestDTO) throws Exception {
         return chargingReceptionService.chargeOrderResponse(requestDTO);
     }
+
+    @Autowired
+    private UserInfoService userInfoService;
+
+    @Operation(summary = "test2")
+    @PostMapping("/test2")
+    public void test2() throws Exception {
+        // 调用恢复方法
+        int restoredCount = userInfoService.restoreDeletedUsersByOrderAndAccount();
+        log.info("恢复用户数量:{}", restoredCount);
+    }
 }

+ 17 - 0
src/main/java/com/zsElectric/boot/business/mapper/UserInfoMapper.java

@@ -9,6 +9,8 @@ import com.zsElectric.boot.business.model.vo.applet.AppUserInfoVO;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * 个人用户信息Mapper接口
  *
@@ -28,4 +30,19 @@ public interface UserInfoMapper extends BaseMapper<UserInfo> {
     Page<UserInfoVO> getUserInfoPage(Page<UserInfoVO> page, UserInfoQuery queryParams);
 
     AppUserInfoVO getAppletUserInfo(@Param("userId") Long userId);
+
+    /**
+     * 查询在订单或账户中存在但UserInfo表中不存在的用户信息(用于恢复物理删除的数据)
+     *
+     * @return 需要恢复的用户信息列表
+     */
+    List<UserInfo> selectMissingUserInfoFromOrderAndAccount();
+
+    /**
+     * 插入恢复的用户信息(指定ID)
+     *
+     * @param userInfo 用户信息
+     * @return 插入的记录数
+     */
+    int insertUserInfoWithId(UserInfo userInfo);
 }

+ 18 - 1
src/main/java/com/zsElectric/boot/business/service/UserInfoService.java

@@ -59,11 +59,19 @@ public interface UserInfoService extends IService<UserInfo> {
     /**
      * 根据openid获取用户信息
      *
-     * @param openid 手机号
+     * @param openid openid
      * @return 用户信息,不存在返回null
      */
     UserInfo getUserInfoByOpenid(String openid);
 
+    /**
+     * 根据openid获取用户信息
+     *
+     * @param phone 手机号
+     * @return 用户信息,不存在返回null
+     */
+    UserInfo getUserInfoByPhone(String phone);
+
     /**
      * 根据手机号注册或更新用户(小程序用)
      * <p>
@@ -78,4 +86,13 @@ public interface UserInfoService extends IService<UserInfo> {
     AppUserInfoVO getAppletUserInfo();
 
     Boolean userBinding(Long userId, Long firmId);
+
+    /**
+     * 根据订单和账户数据恢复被物理删除的用户信息
+     * <p>
+     * 查找在 UserOrderInfo 或 UserAccount 中存在但在 UserInfo 中不存在的用户,并重新创建其数据
+     *
+     * @return 恢复的用户数量
+     */
+    int restoreDeletedUsersByOrderAndAccount();
 }

+ 1 - 0
src/main/java/com/zsElectric/boot/business/service/WFTOrderService.java

@@ -19,6 +19,7 @@ import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.validation.Valid;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 

+ 70 - 1
src/main/java/com/zsElectric/boot/business/service/impl/UserInfoServiceImpl.java

@@ -178,6 +178,23 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> i
         );
     }
 
+    /**
+     * 根据openid获取用户信息
+     *
+     * @param phone 手机号
+     * @return 用户信息,不存在返回null
+     */
+    @Override
+    public UserInfo getUserInfoByPhone(String phone) {
+        if (StrUtil.isBlank(phone)) {
+            return null;
+        }
+        return this.getOne(
+                new LambdaQueryWrapper<UserInfo>()
+                        .eq(UserInfo::getPhone, phone)
+        );
+    }
+
     /**
      * 根据手机号注册或更新用户(小程序用)
      * <p>
@@ -201,7 +218,7 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> i
             log.info("用户已存在,ID: {}, 手机号: {},openid: {}", existingUser.getId(), phone,openId);
             
             // 如果提供了phone且与现有phone不同,则更新
-            if (StrUtil.isNotBlank(phone) && !openId.equals(existingUser.getOpenid())) {
+            if (StrUtil.isNotBlank(phone) && !phone.equals(existingUser.getPhone())) {
                 log.info("更新用户phone,ID: {}", existingUser.getId());
                 existingUser.setPhone(phone);
                 this.updateById(existingUser);
@@ -210,6 +227,21 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> i
             return existingUser;
         }
 
+        UserInfo existingUser2 = getUserInfoByPhone(phone);
+
+        if (existingUser2 != null) {
+            log.info("用户已存在,ID: {}, 手机号: {},openid: {}", existingUser2.getId(), phone,openId);
+
+            // 如果提供了phone且与现有phone不同,则更新
+            if (StrUtil.isNotBlank(openId) && !openId.equals(existingUser2.getOpenid())) {
+                log.info("更新用户phone,ID: {}", existingUser2.getId());
+                existingUser2.setOpenid(openId);
+                this.updateById(existingUser2);
+            }
+
+            return existingUser2;
+        }
+
         // 用户不存在,创建新用户
         log.info("创建新用户,手机号: {}, openId: {}", phone, openId);
         UserInfo newUser = new UserInfo();
@@ -234,4 +266,41 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> i
         return newUser;
     }
 
+    /**
+     * 根据订单和账户数据恢复被物理删除的用户信息
+     * <p>
+     * 查找在 UserOrderInfo 或 UserAccount 中存在但在 UserInfo 中不存在的用户,并重新创建其数据
+     *
+     * @return 恢复的用户数量
+     */
+    @Override
+    public int restoreDeletedUsersByOrderAndAccount() {
+        // 查询在订单或账户中存在但UserInfo表中不存在的用户信息
+        List<UserInfo> missingUsers = this.baseMapper.selectMissingUserInfoFromOrderAndAccount();
+        
+        if (missingUsers == null || missingUsers.isEmpty()) {
+            log.info("没有需要恢复的用户数据");
+            return 0;
+        }
+        
+        log.info("找到 {} 个需要恢复的用户", missingUsers.size());
+        
+        int restoredCount = 0;
+        for (UserInfo userInfo : missingUsers) {
+            try {
+                // 插入恢复的用户信息
+                int inserted = this.baseMapper.insertUserInfoWithId(userInfo);
+                if (inserted > 0) {
+                    restoredCount++;
+                    log.info("成功恢复用户,ID: {}, openid: {}", userInfo.getId(), userInfo.getOpenid());
+                }
+            } catch (Exception e) {
+                log.error("恢复用户失败,ID: {}, 错误: {}", userInfo.getId(), e.getMessage());
+            }
+        }
+        
+        log.info("成功恢复 {} 个用户数据", restoredCount);
+        return restoredCount;
+    }
+
 }

+ 2 - 1
src/main/java/com/zsElectric/boot/core/web/ResultCode.java

@@ -68,7 +68,8 @@ public enum ResultCode implements IResultCode, Serializable {
     USER_FACE_RECOGNITION_FAILED("A0222", "用户面容识别失败"),
     USER_NOT_AUTHORIZED_THIRD_PARTY_LOGIN("A0223", "用户未获得第三方登录授权"),
 
-    ACCESS_TOKEN_INVALID("A0230", "访问令牌无效或已过期"),
+//    ACCESS_TOKEN_INVALID("A0230", "访问令牌无效或已过期"),
+    ACCESS_TOKEN_INVALID("A0230", "暂未登录~"),
     REFRESH_TOKEN_INVALID("A0231", "刷新令牌无效或已过期"),
 
     // 验证码错误

+ 29 - 0
src/main/resources/mapper/business/UserInfoMapper.xml

@@ -74,4 +74,33 @@
             AND ui.id = #{userId}
     </select>
 
+    <!-- 查询在订单或账户中存在但UserInfo表中不存在的用户信息(用于恢复物理删除的数据) -->
+    <select id="selectMissingUserInfoFromOrderAndAccount" resultType="com.zsElectric.boot.business.model.entity.UserInfo">
+        SELECT 
+            t.user_id AS id,
+            t.openid,
+            t.phone,
+            COALESCE(t.phone, CONCAT('用户_', t.user_id)) AS nick_name
+        FROM (
+            SELECT DISTINCT uoi.user_id, uoi.openid, NULL AS phone
+            FROM c_user_order_info uoi
+            WHERE uoi.is_deleted = 0
+            AND uoi.user_id IS NOT NULL
+            AND NOT EXISTS (SELECT 1 FROM c_user_info ui WHERE ui.id = uoi.user_id)
+            UNION
+            SELECT DISTINCT ua.user_id, NULL AS openid, NULL AS phone
+            FROM c_user_account ua
+            WHERE ua.is_deleted = 0
+            AND ua.user_id IS NOT NULL
+            AND NOT EXISTS (SELECT 1 FROM c_user_info ui WHERE ui.id = ua.user_id)
+        ) t
+        GROUP BY t.user_id
+    </select>
+
+    <!-- 插入恢复的用户信息(指定ID) -->
+    <insert id="insertUserInfoWithId">
+        INSERT INTO c_user_info (id, nick_name, phone, openid, create_time, update_time, is_deleted)
+        VALUES (#{id}, #{nickName}, #{phone}, #{openid}, NOW(), NOW(), 0)
+    </insert>
+
 </mapper>