| | |
| | | } |
| | | |
| | | /** |
| | | * 按微信 openid 查询本地 APP 用户。 |
| | | * 按微信 openid 查询本地 APP 用户,重复脏数据场景优先返回启用且已绑定手机号的账号。 |
| | | */ |
| | | private AppUser findUserByWechatOpenid(String openid) { |
| | | return userMapper.selectOne(new LambdaQueryWrapper<AppUser>() |
| | | .eq(AppUser::getWechatOpenid, openid) |
| | | .eq(AppUser::getDeleted, 0) |
| | | .last("limit 1")); |
| | | .last("ORDER BY CASE WHEN status = 1 THEN 0 ELSE 1 END, " |
| | | + "CASE WHEN phone IS NOT NULL AND TRIM(phone) <> '' THEN 0 ELSE 1 END, " |
| | | + "updated_at DESC, id DESC LIMIT 1")); |
| | | } |
| | | |
| | | /** |
| | | * 按苹果 subject 查询本地 APP 用户。 |
| | | * 按苹果 subject 查询本地 APP 用户,重复脏数据场景优先返回启用且已绑定手机号的账号。 |
| | | */ |
| | | private AppUser findUserByAppleSubject(String subject) { |
| | | return userMapper.selectOne(new LambdaQueryWrapper<AppUser>() |
| | | .eq(AppUser::getAppleIdentitySubject, subject) |
| | | .eq(AppUser::getDeleted, 0) |
| | | .last("limit 1")); |
| | | .last("ORDER BY CASE WHEN status = 1 THEN 0 ELSE 1 END, " |
| | | + "CASE WHEN phone IS NOT NULL AND TRIM(phone) <> '' THEN 0 ELSE 1 END, " |
| | | + "updated_at DESC, id DESC LIMIT 1")); |
| | | } |
| | | |
| | | /** |
| | |
| | | private String orderNo; |
| | | private String giftName; |
| | | private String giftCover; |
| | | private String nickname; |
| | | private Integer status; |
| | | private Integer count; |
| | | private Boolean canConfirmReceived; |
| | |
| | | item.setOrderNo(trimToEmpty(row.getOrderNo())); |
| | | item.setGiftName(trimToEmpty(row.getGiftName())); |
| | | item.setGiftCover(trimToEmpty(row.getGiftCover())); |
| | | item.setNickname(trimToEmpty(row.getNickname())); |
| | | item.setActivityPeriodText(buildActivityPeriodText(row.getActivityStartAt(), row.getActivityEndAt())); |
| | | item.setStatus(row.getStatus()); |
| | | item.setStatusText(resolveExchangeStatusText(row.getStatus())); |
| | |
| | | private String orderNo; |
| | | private String giftName; |
| | | private String giftCover; |
| | | private String nickname; |
| | | private String activityPeriodText; |
| | | private Integer status; |
| | | private String statusText; |
| | |
| | | |
| | | import cn.dev33.satoken.stp.SaTokenInfo; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.tcm.training.admin.app.auth.dto.AppWechatLoginRequest; |
| | | import com.tcm.training.admin.app.auth.service.AppAuthSessionService; |
| | | import com.tcm.training.admin.app.auth.vo.AppLoginResponse; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 合并后软删除第三方临时账号,避免产生重复用户。 |
| | | * 合并后清空第三方票据并逻辑删除临时账号,避免同一 openid 或苹果 subject 命中多个账号。 |
| | | */ |
| | | private void disableMergedTemporaryUser(AppUser currentUser) { |
| | | currentUser.setStatus(0); |
| | | currentUser.setDeleted(1); |
| | | userMapper.updateById(currentUser); |
| | | userMapper.update(null, new LambdaUpdateWrapper<AppUser>() |
| | | .eq(AppUser::getId, currentUser.getId()) |
| | | .set(AppUser::getStatus, 0) |
| | | .set(AppUser::getWechatOpenid, null) |
| | | .set(AppUser::getWechatNickname, null) |
| | | .set(AppUser::getWechatAvatar, null) |
| | | .set(AppUser::getWechatBoundAt, null) |
| | | .set(AppUser::getAppleUserIdentifier, null) |
| | | .set(AppUser::getAppleIdentitySubject, null) |
| | | .set(AppUser::getAppleBoundAt, null) |
| | | .set(AppUser::getDeleted, 1)); |
| | | } |
| | | |
| | | /** |
| | |
| | | private AppShareBoundUserItemVO toBoundUserItem(AppUser user) { |
| | | AppShareBoundUserItemVO item = new AppShareBoundUserItemVO(); |
| | | item.setId(user.getId()); |
| | | item.setNickname(resolveNickname(user)); |
| | | item.setNickname(resolveBoundUserPhone(user)); |
| | | item.setAvatar(resolveAvatar(user)); |
| | | item.setRegisteredAt(resolveRegisteredAt(user)); |
| | | return item; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 优先使用昵称,没有时回退手机号。 |
| | | * 绑定用户列表按业务要求直接在昵称字段展示完整手机号。 |
| | | */ |
| | | private String resolveNickname(AppUser user) { |
| | | String nickname = trimToNull(user == null ? null : user.getNickname()); |
| | | if (nickname != null) { |
| | | return nickname; |
| | | } |
| | | String wechatNickname = trimToNull(user == null ? null : user.getWechatNickname()); |
| | | if (wechatNickname != null) { |
| | | return wechatNickname; |
| | | } |
| | | private String resolveBoundUserPhone(AppUser user) { |
| | | return trimToEmpty(user == null ? null : user.getPhone()); |
| | | } |
| | | |
| | |
| | | o.order_no AS orderNo, |
| | | o.gift_name AS giftName, |
| | | o.gift_cover AS giftCover, |
| | | MAX(COALESCE(NULLIF(TRIM(u.phone), ''), NULLIF(TRIM(i.user_phone), ''))) AS nickname, |
| | | o.status, |
| | | COUNT(i.id) AS count, |
| | | CASE WHEN o.status = 1 THEN TRUE ELSE FALSE END AS canConfirmReceived, |
| | |
| | | i.id, |
| | | i.order_id AS orderId, |
| | | u.id AS patientId, |
| | | COALESCE(NULLIF(TRIM(u.nickname), ''), NULLIF(TRIM(i.user_nickname), ''), NULLIF(TRIM(u.phone), ''), '用户') AS patientName, |
| | | COALESCE(NULLIF(TRIM(u.phone), ''), NULLIF(TRIM(i.user_phone), ''), '用户') AS patientName, |
| | | COALESCE(NULLIF(TRIM(u.phone), ''), NULLIF(TRIM(i.user_phone), '')) AS patientPhone, |
| | | i.settled_points AS settledPoints, |
| | | i.status, |