| | |
| | | import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; |
| | | import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.doumee.biz.system.OperationConfigBiz; |
| | | import com.doumee.biz.system.SystemDictDataBiz; |
| | | import com.doumee.config.jwt.JwtTokenUtil; |
| | | import com.doumee.config.wx.WxMiniConfig; |
| | |
| | | import com.doumee.core.model.PageWrap; |
| | | import com.doumee.core.utils.Utils; |
| | | import com.doumee.dao.business.MemberMapper; |
| | | import com.doumee.dao.business.CouponMapper; |
| | | import com.doumee.dao.business.MemberCouponMapper; |
| | | import com.doumee.dao.business.OrdersMapper; |
| | | import com.doumee.dao.business.ShopInfoMapper; |
| | | import com.doumee.dao.business.SmsrecordMapper; |
| | | import com.doumee.dao.business.model.Member; |
| | | import com.doumee.dao.business.model.Coupon; |
| | | import com.doumee.dao.business.model.MemberCoupon; |
| | | import com.doumee.dao.business.model.Orders; |
| | | import com.doumee.dao.business.model.ShopInfo; |
| | | import com.doumee.dao.business.model.MemberRevenue; |
| | | import com.doumee.dao.business.model.Smsrecord; |
| | | import com.doumee.dao.dto.MemberListQueryDTO; |
| | | import com.doumee.dao.dto.OperationConfigDTO; |
| | | import com.doumee.dao.dto.UpdMobileRequest; |
| | | import com.doumee.dao.dto.WxPhoneRequest; |
| | | import com.doumee.dao.vo.AccountResponse; |
| | | import com.doumee.dao.vo.MemberContactVO; |
| | | import com.doumee.dao.vo.MemberDetailVO; |
| | | import com.doumee.dao.vo.MemberListVO; |
| | | import com.doumee.dao.vo.PlatformAboutVO; |
| | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import me.chanjar.weixin.common.error.WxErrorException; |
| | | import nonapi.io.github.classgraph.json.Id; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Random; |
| | | import java.util.concurrent.TimeUnit; |
| | |
| | | * @author 江蹄蹄 |
| | | * @date 2025/07/09 12:00 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class MemberServiceImpl implements MemberService { |
| | | |
| | |
| | | |
| | | @Autowired |
| | | private OrdersMapper ordersMapper; |
| | | |
| | | @Autowired |
| | | private OperationConfigBiz operationConfigBiz; |
| | | |
| | | @Autowired |
| | | private CouponMapper couponMapper; |
| | | |
| | | @Autowired |
| | | private MemberCouponMapper memberCouponMapper; |
| | | |
| | | |
| | | @Override |
| | |
| | | member.setReceiveNum(Constants.ZERO.longValue()); |
| | | member.setPublishNum(Constants.ZERO.longValue()); |
| | | member.setAutoReceiveStatus(Constants.ONE); |
| | | member.setUseIdentity(Constants.ZERO); |
| | | member.setUserType(Constants.ZERO); |
| | | memberMapper.insert(member); |
| | | } |
| | | String token = JwtTokenUtil.generateTokenForRedis(member.getId(), Constants.ZERO, JSONObject.toJSONString(member), redisTemplate); |
| | |
| | | * 门店用户身份时,填充门店审核状态 |
| | | */ |
| | | private void fillShopInfo(UserCenterVO userCenterVO, Member member) { |
| | | ShopInfo shopInfo = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda() |
| | | // 查询正式版本门店 |
| | | ShopInfo official = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda() |
| | | .eq(ShopInfo::getRegionMemberId, member.getId()) |
| | | .eq(ShopInfo::getVersionType, Constants.ZERO) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .last("limit 1")); |
| | | if (shopInfo != null) { |
| | | userCenterVO.setShopId(shopInfo.getId()); |
| | | userCenterVO.setShopAuditStatus(shopInfo.getAuditStatus()); |
| | | if (official != null) { |
| | | userCenterVO.setShopId(official.getId()); |
| | | if (Constants.equalsInteger(official.getAuditStatus(), Constants.THREE)) { |
| | | // 正式版本已支付押金,查询最新变更版本状态 |
| | | ShopInfo changeVersion = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda() |
| | | .eq(ShopInfo::getRelationShopId, official.getId()) |
| | | .eq(ShopInfo::getVersionType, Constants.ONE) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .orderByDesc(ShopInfo::getCreateTime) |
| | | .last("limit 1")); |
| | | if (changeVersion != null) { |
| | | if (Constants.equalsInteger(changeVersion.getAuditStatus(), Constants.THREE)) { |
| | | userCenterVO.setShopAuditStatus(Constants.THREE); |
| | | } else if (Constants.equalsInteger(changeVersion.getAuditStatus(), Constants.ZERO)) { |
| | | userCenterVO.setShopAuditStatus(4); // 变更中 |
| | | } else if (Constants.equalsInteger(changeVersion.getAuditStatus(), Constants.TWO)) { |
| | | userCenterVO.setShopAuditStatus(5); // 变更未通过 |
| | | } else { |
| | | userCenterVO.setShopAuditStatus(Constants.THREE); |
| | | } |
| | | } else { |
| | | // 无变更版本,保持正式版本状态 |
| | | userCenterVO.setShopAuditStatus(Constants.THREE); |
| | | } |
| | | } else { |
| | | // 正式版本未支付押金,直接返回当前状态 |
| | | userCenterVO.setShopAuditStatus(official.getAuditStatus()); |
| | | } |
| | | } |
| | | // 根据openid查询当前绑定的门店 |
| | | if (StringUtils.isNotBlank(member.getOpenid())) { |
| | |
| | | public PlatformAboutVO getPlatformAboutUs(){ |
| | | PlatformAboutVO vo = new PlatformAboutVO(); |
| | | vo.setAboutUs(StringUtils.trimToNull(systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.ABOUT_US).getCode())); |
| | | vo.setUserAgreement(StringUtils.trimToNull(systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.USER_AGREEMENT).getCode())); |
| | | vo.setPrivacyAgreement(StringUtils.trimToNull(systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.PRIVACY_AGREEMENT).getCode())); |
| | | vo.setServerIntroduce(StringUtils.trimToNull(systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.SERVER_INTRODUCE).getCode())); |
| | | vo.setStoreRiskCommitment(getDictValue(Constants.STORE_RISK_COMMITMENT)); |
| | | vo.setStoreCooperationAgreement(getDictValue(Constants.STORE_COOPERATION_AGREEMENT)); |
| | | vo.setStoreLuggageStorageNotice(getDictValue(Constants.STORE_LUGGAGE_STORAGE_NOTICE)); |
| | | vo.setStorePrivacyPolicy(getDictValue(Constants.STORE_PRIVACY_POLICY)); |
| | | vo.setOwnerLuggageStorageNotice(getDictValue(Constants.OWNER_LUGGAGE_STORAGE_NOTICE)); |
| | | vo.setOwnerServiceAgreement(getDictValue(Constants.OWNER_SERVICE_AGREEMENT)); |
| | | vo.setOwnerRiskCommitment(getDictValue(Constants.OWNER_RISK_COMMITMENT)); |
| | | vo.setErrandRiskCommitment(getDictValue(Constants.ERRAND_RISK_COMMITMENT)); |
| | | vo.setErrandServiceAgreement(getDictValue(Constants.ERRAND_SERVICE_AGREEMENT)); |
| | | vo.setErrandLuggageStorageNotice(getDictValue(Constants.ERRAND_LUGGAGE_STORAGE_NOTICE)); |
| | | vo.setUserServiceAgreement(getDictValue(Constants.USER_SERVICE_AGREEMENT)); |
| | | vo.setUserPrivacyPolicy(getDictValue(Constants.USER_PRIVACY_POLICY)); |
| | | vo.setDriverPrivacyPolicy(getDictValue(Constants.DRIVER_PRIVACY_POLICY)); |
| | | vo.setPriceDescription(getDictValue(Constants.PRICE_DESCRIPTION)); |
| | | vo.setProhibitedItems(getDictValue(Constants.PROHIBITED_ITEMS)); |
| | | vo.setServerPhone(StringUtils.trimToNull(systemDictDataBiz.queryByCode(Constants.SYSTEM, Constants.SERVER_PHONE).getCode())); |
| | | return vo; |
| | | } |
| | | |
| | | private String getDictValue(String key) { |
| | | try { |
| | | return StringUtils.trimToNull(systemDictDataBiz.queryByCode(Constants.SYSTEM, key).getCode()); |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void logOut(String token,Integer memberId){ |
| | | memberMapper.update(new UpdateWrapper<Member>().lambda().setSql(" openid = null ").eq(Member::getId,memberId)); |
| | | jwtTokenUtil.logoutForH5(token); |
| | | public void logOut(String token,Integer userId,Integer userType){ |
| | | if(Constants.equalsInteger(userType,Constants.ZERO)){ |
| | | memberMapper.update(new UpdateWrapper<Member>().lambda().setSql(" openid = null ").eq(Member::getId,userId)); |
| | | }else if (Constants.equalsInteger(userType,Constants.TWO)){ |
| | | try { |
| | | Integer lastIndex = token.lastIndexOf("_")+1; |
| | | Integer tokenId = Integer.valueOf(token.substring(lastIndex)); |
| | | memberMapper.update(new UpdateWrapper<Member>().lambda().setSql(" LOGIN_SHOP_ID = null ").eq(Member::getId,tokenId)); |
| | | }catch (Exception e){ |
| | | |
| | | } |
| | | } |
| | | jwtTokenUtil.logout(token); |
| | | } |
| | | |
| | | |
| | |
| | | ); |
| | | } |
| | | redisTemplate.delete(token); |
| | | } |
| | | |
| | | @Override |
| | | public MemberContactVO getContactInfo(Integer memberId) { |
| | | MemberContactVO vo = new MemberContactVO(); |
| | | // 优先从历史订单取收件人信息 |
| | | Orders lastOrder = ordersMapper.selectOne(new QueryWrapper<Orders>().lambda() |
| | | .eq(Orders::getMemberId, memberId) |
| | | .eq(Orders::getDeleted, Constants.ZERO) |
| | | .isNotNull(Orders::getTakeUser) |
| | | .ne(Orders::getTakeUser, "") |
| | | .orderByDesc(Orders::getId) |
| | | .last("limit 1")); |
| | | if (lastOrder != null && StringUtils.isNotBlank(lastOrder.getTakeUser())) { |
| | | vo.setName(lastOrder.getTakeUser()); |
| | | vo.setPhone(lastOrder.getTakePhone()); |
| | | return vo; |
| | | } |
| | | // 取用户信息 |
| | | Member member = memberMapper.selectById(memberId); |
| | | if (member != null) { |
| | | vo.setName(member.getName() != null ? member.getName() : ""); |
| | | vo.setPhone(member.getTelephone() != null ? member.getTelephone() : ""); |
| | | } |
| | | return vo; |
| | | } |
| | | |
| | | |
| | |
| | | queryWrapper.lambda().le(Member::getCreateTime, Utils.Date.getEnd(query.getEndTime())); |
| | | } |
| | | } |
| | | for (PageWrap.SortData sortData : pageWrap.getSorts()) { |
| | | if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) { |
| | | queryWrapper.orderByDesc(sortData.getProperty()); |
| | | } else { |
| | | queryWrapper.orderByAsc(sortData.getProperty()); |
| | | } |
| | | } |
| | | queryWrapper.lambda().orderByDesc(Member::getId); |
| | | IPage<Member> memberPage = memberMapper.selectPage(page, queryWrapper); |
| | | IPage<MemberListVO> voPage = memberPage.convert(this::toListVO); |
| | | return PageData.from(voPage); |
| | |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST); |
| | | } |
| | | //判断新手机号是否已被使用 |
| | | if(memberMapper.selectCount(new QueryWrapper<Member>().lambda().eq(Member::getTelephone,request.getPhone()))>Constants.ZERO){ |
| | | if(memberMapper.selectCount(new QueryWrapper<Member>().lambda() |
| | | .eq(Member::getDeleted,Constants.ZERO) |
| | | .eq(Member::getUserType,Constants.ZERO) |
| | | .eq(Member::getTelephone,request.getPhone()))>Constants.ZERO){ |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,新手机号已被绑定,无法进行换绑!"); |
| | | } |
| | | Member member = memberMapper.selectById(request.getMemberId()); |
| | |
| | | ); |
| | | } |
| | | |
| | | @Override |
| | | public void giftRegisterCoupon() { |
| | | // 1. 读取配置 |
| | | OperationConfigDTO config = operationConfigBiz.getConfig(); |
| | | String yearsStr = config.getRegisterCouponYears(); |
| | | String maxGiftStr = config.getRegisterCouponGiftCount(); |
| | | String couponIdStr = config.getRegisterCouponId(); |
| | | if (StringUtils.isBlank(yearsStr) || StringUtils.isBlank(maxGiftStr) || StringUtils.isBlank(couponIdStr)) { |
| | | return; |
| | | } |
| | | int configYears = Integer.parseInt(yearsStr); |
| | | int maxGiftCount = Integer.parseInt(maxGiftStr); |
| | | int couponId = Integer.parseInt(couponIdStr); |
| | | if (configYears <= 0 || maxGiftCount <= 0) { |
| | | return; |
| | | } |
| | | |
| | | // 2. 校验优惠券存在且启用 |
| | | Coupon coupon = couponMapper.selectById(couponId); |
| | | if (coupon == null || !Constants.equalsInteger(coupon.getIsdeleted(), Constants.ZERO) |
| | | || !Constants.equalsInteger(coupon.getStatus(), Constants.ZERO)) { |
| | | return; |
| | | } |
| | | |
| | | // 3. 查询所有普通会员 |
| | | List<Member> members = memberMapper.selectList(new QueryWrapper<Member>().lambda() |
| | | .eq(Member::getDeleted, Constants.ZERO) |
| | | .eq(Member::getStatus, Constants.ZERO) |
| | | .eq(Member::getUserType, Constants.ZERO) |
| | | .isNotNull(Member::getCreateTime)); |
| | | |
| | | Date now = new Date(); |
| | | long msPerYear = 365L * 24 * 60 * 60 * 1000; |
| | | int giftedMemberCount = 0; |
| | | |
| | | for (Member member : members) { |
| | | int alreadyGifted = member.getRegisterCouponGiftCount() != null ? member.getRegisterCouponGiftCount() : 0; |
| | | // 已注册年数(取整) |
| | | int registeredYears = (int) ((now.getTime() - member.getCreateTime().getTime()) / msPerYear); |
| | | // 应赠送总次数 |
| | | int shouldGiftTotal = registeredYears / configYears; |
| | | // 实际还需赠送次数 |
| | | int remainGift = Math.min(shouldGiftTotal, maxGiftCount) - alreadyGifted; |
| | | if (remainGift <= 0) { |
| | | continue; |
| | | } |
| | | |
| | | // 4. 赠送优惠券 |
| | | for (int i = 0; i < remainGift; i++) { |
| | | MemberCoupon mc = new MemberCoupon(); |
| | | mc.setCouponId(couponId); |
| | | mc.setMemberId(member.getId()); |
| | | mc.setStatus(Constants.CouponStatus.waitClaim.getKey()); |
| | | // 推送后领取有效期 |
| | | Calendar validCal = Calendar.getInstance(); |
| | | validCal.add(Calendar.DAY_OF_MONTH, coupon.getPushDays() != null ? coupon.getPushDays() : 7); |
| | | mc.setValidDate(validCal.getTime()); |
| | | // 拷贝优惠券信息 |
| | | mc.setName(coupon.getName()); |
| | | mc.setInfo(coupon.getInfo()); |
| | | mc.setType(coupon.getType()); |
| | | mc.setLimitPrice(coupon.getLimitPrice()); |
| | | mc.setPrice(coupon.getPrice()); |
| | | mc.setGetMethod(coupon.getGetMethod()); |
| | | mc.setCouponType(coupon.getCouponType()); |
| | | mc.setPushDays(coupon.getPushDays()); |
| | | mc.setValidDays(coupon.getValidDays()); |
| | | mc.setIsdeleted(Constants.ZERO); |
| | | mc.setCreateDate(now); |
| | | mc.setEditDate(now); |
| | | memberCouponMapper.insert(mc); |
| | | } |
| | | |
| | | // 5. 更新会员已赠送次数 |
| | | memberMapper.update(new UpdateWrapper<Member>().lambda() |
| | | .set(Member::getRegisterCouponGiftCount, alreadyGifted + remainGift) |
| | | .eq(Member::getId, member.getId())); |
| | | giftedMemberCount++; |
| | | } |
| | | log.info("注册满年赠送优惠券完成,共处理{}名会员", giftedMemberCount); |
| | | } |
| | | |
| | | } |