| | |
| | | import com.doumee.dao.business.model.Orders; |
| | | import com.doumee.dao.business.model.PricingRule; |
| | | import com.doumee.dao.business.model.ShopInfo; |
| | | import com.doumee.config.xyy.XyyConfig; |
| | | import com.doumee.config.xyy.dto.AddPrinterRequest; |
| | | import com.doumee.config.xyy.dto.AddPrinterRequestItem; |
| | | import com.doumee.config.xyy.dto.DelPrinterRequest; |
| | | import com.doumee.config.xyy.vo.ObjectRestResponse; |
| | | import com.doumee.config.xyy.vo.PrinterResult; |
| | | import com.doumee.dao.dto.*; |
| | | import com.doumee.dao.system.model.SystemDictData; |
| | | import com.doumee.dao.system.SystemUserMapper; |
| | | import com.doumee.dao.system.model.SystemUser; |
| | | import com.doumee.dao.vo.ShopDetailVO; |
| | |
| | | |
| | | @Autowired |
| | | private SmsrecordMapper smsrecordMapper; |
| | | |
| | | @Autowired |
| | | private PrintService printService; |
| | | |
| | | @Autowired |
| | | private XyyConfig xyyConfig; |
| | | @Override |
| | | public Integer create(ShopInfo shopInfo) { |
| | | shopInfoMapper.insert(shopInfo); |
| | |
| | | if (pageWrap.getModel().getOpenid() != null) { |
| | | queryWrapper.lambda().like(ShopInfo::getOpenid, pageWrap.getModel().getOpenid()); |
| | | } |
| | | for (PageWrap.SortData sortData : pageWrap.getSorts()) { |
| | | if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) { |
| | | queryWrapper.orderByDesc(sortData.getProperty()); |
| | | } else { |
| | | queryWrapper.orderByAsc(sortData.getProperty()); |
| | | } |
| | | } |
| | | queryWrapper.lambda().orderByDesc(ShopInfo::getId); |
| | | return PageData.from(shopInfoMapper.selectPage(page, queryWrapper)); |
| | | } |
| | | |
| | |
| | | public void applyShop(ShopApplyDTO request) { |
| | | Member member = memberMapper.selectById(request.getMemberId()); |
| | | |
| | | // 根据类型校验附件 |
| | | validateCompanyTypeFields(request); |
| | | |
| | | // 2. 根据类型校验附件 |
| | | Date now = new Date(); |
| | | |
| | | // 查询该会员最新的变更版本记录 |
| | | QueryWrapper<ShopInfo> changeQw = new QueryWrapper<>(); |
| | | changeQw.lambda() |
| | | .eq(ShopInfo::getRegionMemberId, member.getId()) |
| | | .eq(ShopInfo::getVersionType, Constants.ONE) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .orderByDesc(ShopInfo::getCreateTime) |
| | | .last("limit 1"); |
| | | ShopInfo changeVersion = shopInfoMapper.selectOne(changeQw); |
| | | |
| | | if (changeVersion == null) { |
| | | // 首次申请:创建正式版本 + 变更版本 |
| | | checkTelephoneUnique(request.getTelephone(), null); |
| | | |
| | | String rawPassword = generateDefaultPassword(request.getTelephone()); |
| | | String salt = RandomStringUtils.randomAlphabetic(6); |
| | | String encryptedPassword = Utils.Secure.encryptPassword(rawPassword, salt); |
| | | |
| | | // 正式版本 |
| | | ShopInfo official = new ShopInfo(); |
| | | applyFieldsFromRequest(official, request, member, encryptedPassword, salt, now); |
| | | official.setVersionType(Constants.ZERO); |
| | | official.setAuditStatus(Constants.ZERO); |
| | | official.setStatus(Constants.ZERO); |
| | | official.setDeleted(Constants.ZERO); |
| | | official.setCreateTime(now); |
| | | official.setUpdateTime(now); |
| | | official.setRegionMemberId(member.getId()); |
| | | setDepositAmountFromPricingRule(official); |
| | | setDefaultDeliveryRange(official); |
| | | shopInfoMapper.insert(official); |
| | | |
| | | // 保存正式版本附件 |
| | | saveShopAttachments(official.getId(), request, now); |
| | | |
| | | // 创建变更版本(拷贝正式版本数据) |
| | | createChangeVersion(official, official.getId(), now); |
| | | } else if (Constants.equalsInteger(changeVersion.getAuditStatus(), Constants.ONE)) { |
| | | // 审批通过待支付押金 |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "门店已审批通过,请完成押金支付"); |
| | | } else if (Constants.equalsInteger(changeVersion.getAuditStatus(), Constants.THREE)) { |
| | | // 最新变更版本已支付押金(status=3):生成新的变更版本 |
| | | Integer relationShopId = changeVersion.getRelationShopId(); |
| | | |
| | | // 校验手机号唯一性(排除正式版本和变更版本) |
| | | checkTelephoneUnique(request.getTelephone(), relationShopId); |
| | | |
| | | String rawPassword = generateDefaultPassword(request.getTelephone()); |
| | | String salt = RandomStringUtils.randomAlphabetic(6); |
| | | String encryptedPassword = Utils.Secure.encryptPassword(rawPassword, salt); |
| | | |
| | | ShopInfo newChange = new ShopInfo(); |
| | | applyFieldsFromRequest(newChange, request, member, encryptedPassword, salt, now); |
| | | newChange.setVersionType(Constants.ONE); |
| | | newChange.setRelationShopId(relationShopId); |
| | | newChange.setAuditStatus(Constants.ZERO); |
| | | newChange.setStatus(Constants.ZERO); |
| | | newChange.setDeleted(Constants.ZERO); |
| | | newChange.setCreateTime(now); |
| | | newChange.setUpdateTime(now); |
| | | newChange.setRegionMemberId(member.getId()); |
| | | setDepositAmountFromPricingRule(newChange); |
| | | shopInfoMapper.insert(newChange); |
| | | |
| | | // 保存新变更版本附件 |
| | | saveShopAttachments(newChange.getId(), request, now); |
| | | } else { |
| | | // 最新变更版本 status=0(待审批) 或 2(被驳回):直接更新 |
| | | Integer relationShopId = changeVersion.getRelationShopId(); |
| | | |
| | | // 校验手机号唯一性 |
| | | checkTelephoneUnique(request.getTelephone(), relationShopId); |
| | | |
| | | String rawPassword = generateDefaultPassword(request.getTelephone()); |
| | | String salt = RandomStringUtils.randomAlphabetic(6); |
| | | String encryptedPassword = Utils.Secure.encryptPassword(rawPassword, salt); |
| | | |
| | | applyFieldsFromRequest(changeVersion, request, member, encryptedPassword, salt, now); |
| | | changeVersion.setAuditStatus(Constants.ZERO); |
| | | changeVersion.setAuditRemark(null); |
| | | changeVersion.setAuditTime(null); |
| | | changeVersion.setAuditUserId(null); |
| | | changeVersion.setUpdateTime(now); |
| | | setDepositAmountFromPricingRule(changeVersion); |
| | | shopInfoMapper.updateById(changeVersion); |
| | | |
| | | // 删除旧附件 + 保存新附件 |
| | | deleteShopAttachments(changeVersion.getId()); |
| | | saveShopAttachments(changeVersion.getId(), request, now); |
| | | } |
| | | } |
| | | |
| | | private void validateCompanyTypeFields(ShopApplyDTO request) { |
| | | if (Constants.equalsInteger(request.getCompanyType(), Constants.ZERO)) { |
| | | // 个人类型:必须上传劳动合同和社保证明 |
| | | if (CollectionUtils.isEmpty(request.getLaborContractImgs())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "个人类型必须上传有效劳动合同"); |
| | | } |
| | |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "个人类型必须上传社保缴纳证明"); |
| | | } |
| | | } else if (Constants.equalsInteger(request.getCompanyType(), Constants.ONE)) { |
| | | // 企业类型:必须填写法人信息和营业执照 |
| | | if (StringUtils.isBlank(request.getBusinessImg())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "企业类型必须上传营业执照"); |
| | | } |
| | |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "企业类型必须填写法人身份证号码"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | Date now = new Date(); |
| | | String rawPassword = generateDefaultPassword(request.getTelephone()); |
| | | String salt = RandomStringUtils.randomAlphabetic(6); |
| | | String encryptedPassword = Utils.Secure.encryptPassword(rawPassword, salt); |
| | | private void applyFieldsFromRequest(ShopInfo shop, ShopApplyDTO request, Member member, |
| | | String password, String salt, Date now) { |
| | | shop.setCompanyType(request.getCompanyType()); |
| | | shop.setName(request.getName()); |
| | | shop.setTelephone(request.getTelephone()); |
| | | shop.setLinkName(request.getLinkName()); |
| | | shop.setLinkPhone(request.getLinkPhone()); |
| | | shop.setIdcard(request.getIdcard()); |
| | | shop.setAreaId(request.getAreaId()); |
| | | shop.setLongitude(request.getLongitude()); |
| | | shop.setLatitude(request.getLatitude()); |
| | | shop.setAddress(request.getAddress()); |
| | | shop.setIdcardImg(request.getIdcardImg()); |
| | | shop.setIdcardImgBack(request.getIdcardImgBack()); |
| | | shop.setBusinessImg(request.getBusinessImg()); |
| | | shop.setLegalPersonName(request.getLegalPersonName()); |
| | | shop.setLegalPersonPhone(request.getLegalPersonPhone()); |
| | | shop.setLegalPersonCard(request.getLegalPersonCard()); |
| | | shop.setPassword(password); |
| | | shop.setSalt(salt); |
| | | shop.setAliAccount(request.getAliAccount()); |
| | | shop.setAliName(request.getAliName()); |
| | | shop.setRevenueShareConfig(buildRevenueShareConfig(request.getLocalDeposit(), request.getRemoteDeposit(), request.getRemoteTake())); |
| | | shop.setOpenid(member.getOpenid()); |
| | | } |
| | | |
| | | // 3. 查询该会员是否已有门店记录 |
| | | QueryWrapper<ShopInfo> existQw = new QueryWrapper<>(); |
| | | existQw.lambda() |
| | | .eq(ShopInfo::getRegionMemberId, member.getId()) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .last("limit 1"); |
| | | ShopInfo existing = shopInfoMapper.selectOne(existQw); |
| | | private void saveShopAttachments(Integer shopId, ShopApplyDTO request, Date now) { |
| | | saveMultifileList(shopId, Constants.FileType.STORE_FRONT.getKey(), request.getStoreFrontImgs(), now); |
| | | saveMultifileList(shopId, Constants.FileType.STORE_INTERIOR.getKey(), request.getStoreInteriorImgs(), now); |
| | | saveMultifileList(shopId, Constants.FileType.OTHER_MATERIAL.getKey(), request.getOtherMaterialImgs(), now); |
| | | saveMultifileList(shopId, Constants.FileType.LABOR_CONTRACT.getKey(), request.getLaborContractImgs(), now); |
| | | saveMultifileList(shopId, Constants.FileType.SOCIAL_SECURITY.getKey(), request.getSocialSecurityImgs(), now); |
| | | } |
| | | |
| | | Integer shopId; |
| | | if (existing != null) { |
| | | // 校验状态:只有待审批(0)和被驳回(2)可修改 |
| | | if (!Constants.equalsInteger(existing.getAuditStatus(), Constants.ZERO) |
| | | && !Constants.equalsInteger(existing.getAuditStatus(), Constants.TWO)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "当前门店状态不允许修改"); |
| | | } |
| | | // 校验openid匹配:当前登录会员的openid必须与门店的openid一致 |
| | | if (existing.getOpenid() != null && !existing.getOpenid().equals(member.getOpenid())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "无权限操作当前门店信息"); |
| | | } |
| | | // 校验手机号唯一性(排除自身) |
| | | if (!request.getTelephone().equals(existing.getTelephone())) { |
| | | checkTelephoneUnique(request.getTelephone(), existing.getId()); |
| | | } |
| | | // 更新 |
| | | existing.setCompanyType(request.getCompanyType()); |
| | | existing.setName(request.getName()); |
| | | existing.setTelephone(request.getTelephone()); |
| | | existing.setLinkName(request.getLinkName()); |
| | | existing.setLinkPhone(request.getLinkPhone()); |
| | | existing.setIdcard(request.getIdcard()); |
| | | existing.setAreaId(request.getAreaId()); |
| | | existing.setLongitude(request.getLongitude()); |
| | | existing.setLatitude(request.getLatitude()); |
| | | existing.setAddress(request.getAddress()); |
| | | existing.setIdcardImg(request.getIdcardImg()); |
| | | existing.setIdcardImgBack(request.getIdcardImgBack()); |
| | | existing.setBusinessImg(request.getBusinessImg()); |
| | | existing.setLegalPersonName(request.getLegalPersonName()); |
| | | existing.setLegalPersonPhone(request.getLegalPersonPhone()); |
| | | existing.setLegalPersonCard(request.getLegalPersonCard()); |
| | | existing.setPassword(encryptedPassword); |
| | | existing.setSalt(salt); |
| | | existing.setAliAccount(request.getAliAccount()); |
| | | existing.setAliName(request.getAliName()); |
| | | existing.setUpdateTime(now); |
| | | existing.setAuditRemark(null); |
| | | existing.setAuditTime(null); |
| | | existing.setAuditUserId(null); |
| | | existing.setAuditStatus(Constants.ZERO); |
| | | // 读取押金金额 |
| | | setDepositAmountFromPricingRule(existing); |
| | | shopInfoMapper.updateById(existing); |
| | | shopId = existing.getId(); |
| | | } else { |
| | | // 1. 校验门店手机号唯一性(shop_info.telephone) |
| | | checkTelephoneUnique(request.getTelephone(), null); |
| | | // 新建 |
| | | ShopInfo shopInfo = new ShopInfo(); |
| | | shopInfo.setCompanyType(request.getCompanyType()); |
| | | shopInfo.setName(request.getName()); |
| | | shopInfo.setTelephone(request.getTelephone()); |
| | | shopInfo.setLinkName(request.getLinkName()); |
| | | shopInfo.setLinkPhone(request.getLinkPhone()); |
| | | shopInfo.setIdcard(request.getIdcard()); |
| | | shopInfo.setAreaId(request.getAreaId()); |
| | | shopInfo.setLongitude(request.getLongitude()); |
| | | shopInfo.setLatitude(request.getLatitude()); |
| | | shopInfo.setAddress(request.getAddress()); |
| | | shopInfo.setIdcardImg(request.getIdcardImg()); |
| | | shopInfo.setIdcardImgBack(request.getIdcardImgBack()); |
| | | shopInfo.setBusinessImg(request.getBusinessImg()); |
| | | shopInfo.setLegalPersonName(request.getLegalPersonName()); |
| | | shopInfo.setLegalPersonPhone(request.getLegalPersonPhone()); |
| | | shopInfo.setLegalPersonCard(request.getLegalPersonCard()); |
| | | shopInfo.setPassword(encryptedPassword); |
| | | shopInfo.setSalt(salt); |
| | | shopInfo.setAliAccount(request.getAliAccount()); |
| | | shopInfo.setAliName(request.getAliName()); |
| | | shopInfo.setStatus(Constants.ZERO); |
| | | shopInfo.setDeleted(Constants.ZERO); |
| | | shopInfo.setCreateTime(now); |
| | | shopInfo.setUpdateTime(now); |
| | | shopInfo.setRegionMemberId(member.getId()); |
| | | // 读取押金金额 |
| | | setDepositAmountFromPricingRule(shopInfo); |
| | | shopInfoMapper.insert(shopInfo); |
| | | shopId = shopInfo.getId(); |
| | | } |
| | | |
| | | // 4. 删除旧附件记录 |
| | | private void deleteShopAttachments(Integer shopId) { |
| | | multifileMapper.delete(new QueryWrapper<Multifile>().lambda() |
| | | .eq(Multifile::getObjId, shopId) |
| | | .in(Multifile::getObjType, |
| | |
| | | Constants.FileType.OTHER_MATERIAL.getKey(), |
| | | Constants.FileType.LABOR_CONTRACT.getKey(), |
| | | Constants.FileType.SOCIAL_SECURITY.getKey())); |
| | | |
| | | // 5. 保存新附件记录 |
| | | saveMultifileList(shopId, Constants.FileType.STORE_FRONT.getKey(), request.getStoreFrontImgs(), now); |
| | | saveMultifileList(shopId, Constants.FileType.STORE_INTERIOR.getKey(), request.getStoreInteriorImgs(), now); |
| | | saveMultifileList(shopId, Constants.FileType.OTHER_MATERIAL.getKey(), request.getOtherMaterialImgs(), now); |
| | | saveMultifileList(shopId, Constants.FileType.LABOR_CONTRACT.getKey(), request.getLaborContractImgs(), now); |
| | | saveMultifileList(shopId, Constants.FileType.SOCIAL_SECURITY.getKey(), request.getSocialSecurityImgs(), now); |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | public ShopDetailVO getMyShop(Integer memberId) { |
| | | // 查询最新的变更版本 |
| | | QueryWrapper<ShopInfo> qw = new QueryWrapper<>(); |
| | | qw.lambda() |
| | | .eq(ShopInfo::getRegionMemberId, memberId) |
| | | .eq(ShopInfo::getVersionType, Constants.ONE) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .orderByDesc(ShopInfo::getCreateTime) |
| | | .last("limit 1"); |
| | | ShopInfo shopInfo = shopInfoMapper.selectOne(qw); |
| | | if (shopInfo == null) { |
| | | // 无变更版本则查正式版本 |
| | | QueryWrapper<ShopInfo> officialQw = new QueryWrapper<>(); |
| | | officialQw.lambda() |
| | | .eq(ShopInfo::getRegionMemberId, memberId) |
| | | .eq(ShopInfo::getVersionType, Constants.ZERO) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .last("limit 1"); |
| | | shopInfo = shopInfoMapper.selectOne(officialQw); |
| | | } |
| | | if (shopInfo == null) { |
| | | return null; |
| | | } |
| | |
| | | || (auditDTO.getAuditStatus() != 0 && auditDTO.getAuditStatus() != 1)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "审批状态参数错误"); |
| | | } |
| | | ShopInfo shopInfo = shopInfoMapper.selectById(auditDTO.getId()); |
| | | if (shopInfo == null || Constants.equalsInteger(shopInfo.getDeleted(), Constants.ONE)) { |
| | | // 审批的是变更版本 |
| | | ShopInfo changeVersion = shopInfoMapper.selectById(auditDTO.getId()); |
| | | if (changeVersion == null || Constants.equalsInteger(changeVersion.getDeleted(), Constants.ONE)) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY); |
| | | } |
| | | if (!Constants.equalsInteger(shopInfo.getAuditStatus(), Constants.ZERO)) { |
| | | if (!Constants.equalsInteger(changeVersion.getAuditStatus(), Constants.ZERO)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "当前状态不允许审批"); |
| | | } |
| | | |
| | | Date now = new Date(); |
| | | // auditDTO.auditStatus: 0=通过 → auditStatus=1, 1=驳回 → auditStatus=2 |
| | | // auditDTO.auditStatus: 0=通过 → 1, 1=驳回 → 2 |
| | | Integer newAuditStatus = Constants.equalsInteger(auditDTO.getAuditStatus(), Constants.ZERO) ? Constants.ONE : Constants.TWO; |
| | | shopInfo.setAuditStatus(newAuditStatus); |
| | | shopInfo.setAuditTime(now); |
| | | shopInfo.setAuditRemark(auditDTO.getAuditRemark()); |
| | | shopInfo.setAuditUserId(auditDTO.getAuditUser()); |
| | | shopInfo.setUpdateTime(now); |
| | | // 审批通过时,校验城市pricing_rule配置,读取押金金额 |
| | | if (Constants.equalsInteger(newAuditStatus, Constants.ONE)) { |
| | | // 1. 解析门店所在城市 |
| | | Areas area = areasBiz.resolveArea(shopInfo.getAreaId()); |
| | | if (area == null || area.getParentId() == null) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "门店区划信息异常,无法确定所在城市"); |
| | | } |
| | | Integer cityId = area.getParentId(); |
| | | |
| | | // 2. 校验 pricing_rule 配置(城市开通在押金支付完成后处理) |
| | | Areas cityArea = areasService.findById(cityId, Constants.ONE); |
| | | if (cityArea == null) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "城市信息不存在"); |
| | | // 查找正式版本 |
| | | Integer officialId = changeVersion.getRelationShopId(); |
| | | ShopInfo official = officialId != null ? shopInfoMapper.selectById(officialId) : null; |
| | | boolean hasPaidOfficial = official != null |
| | | && Constants.equalsInteger(official.getAuditStatus(), Constants.THREE); |
| | | |
| | | if (!hasPaidOfficial) { |
| | | // 场景1:不存在auditStatus=3的正式版本(首次审批) |
| | | changeVersion.setAuditStatus(newAuditStatus); |
| | | changeVersion.setAuditTime(now); |
| | | changeVersion.setAuditRemark(auditDTO.getAuditRemark()); |
| | | changeVersion.setAuditUserId(auditDTO.getAuditUser()); |
| | | changeVersion.setUpdateTime(now); |
| | | |
| | | if (Constants.equalsInteger(newAuditStatus, Constants.ONE)) { |
| | | validateCityAndSetDeposit(changeVersion); |
| | | } |
| | | if (!Constants.equalsInteger(cityArea.getStatus(), Constants.ONE)) { |
| | | List<String> errors = validateCityPricingRules(cityId); |
| | | if (!errors.isEmpty()) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), |
| | | "城市[" + cityArea.getName() + "]尚未开通,定价规则未配置完整:" + String.join(";", errors)); |
| | | shopInfoMapper.updateById(changeVersion); |
| | | |
| | | // 同步更新正式版本审批状态 |
| | | if (official != null) { |
| | | official.setAuditStatus(newAuditStatus); |
| | | official.setAuditTime(now); |
| | | official.setAuditRemark(auditDTO.getAuditRemark()); |
| | | official.setAuditUserId(auditDTO.getAuditUser()); |
| | | official.setUpdateTime(now); |
| | | if (Constants.equalsInteger(newAuditStatus, Constants.ONE)) { |
| | | official.setDepositAmount(changeVersion.getDepositAmount()); |
| | | } |
| | | shopInfoMapper.updateById(official); |
| | | } |
| | | |
| | | // 3. 从PricingRule读取押金金额(审批时更新) |
| | | setDepositAmountFromPricingRule(shopInfo); |
| | | } |
| | | shopInfoMapper.updateById(shopInfo); |
| | | // 短信通知 |
| | | sendAuditSms(changeVersion, newAuditStatus, auditDTO.getAuditRemark()); |
| | | } else { |
| | | // 场景2:存在auditStatus=3的正式版本(变更审批) |
| | | if (Constants.equalsInteger(newAuditStatus, Constants.ONE)) { |
| | | // 审批通过:变更版本直接标记auditStatus=3,同步数据到正式版本 |
| | | changeVersion.setAuditStatus(Constants.THREE); |
| | | changeVersion.setAuditTime(now); |
| | | changeVersion.setAuditRemark(auditDTO.getAuditRemark()); |
| | | changeVersion.setAuditUserId(auditDTO.getAuditUser()); |
| | | changeVersion.setUpdateTime(now); |
| | | shopInfoMapper.updateById(changeVersion); |
| | | |
| | | // 短信通知 |
| | | // 同步变更版本数据到正式版本 |
| | | syncChangeToOfficial(changeVersion, official, now); |
| | | } else { |
| | | // 审批驳回:仅标记变更版本状态 |
| | | changeVersion.setAuditStatus(Constants.TWO); |
| | | changeVersion.setAuditTime(now); |
| | | changeVersion.setAuditRemark(auditDTO.getAuditRemark()); |
| | | changeVersion.setAuditUserId(auditDTO.getAuditUser()); |
| | | changeVersion.setUpdateTime(now); |
| | | shopInfoMapper.updateById(changeVersion); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void validateCityAndSetDeposit(ShopInfo shopInfo) { |
| | | Areas area = areasBiz.resolveArea(shopInfo.getAreaId()); |
| | | if (area == null || area.getParentId() == null) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "门店区划信息异常,无法确定所在城市"); |
| | | } |
| | | Integer cityId = area.getParentId(); |
| | | Areas cityArea = areasService.findById(cityId, Constants.ONE); |
| | | if (cityArea == null) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "城市信息不存在"); |
| | | } |
| | | if (!Constants.equalsInteger(cityArea.getStatus(), Constants.ONE)) { |
| | | List<String> errors = validateCityPricingRules(cityId); |
| | | if (!errors.isEmpty()) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), |
| | | "城市[" + cityArea.getName() + "]尚未开通,定价规则未配置完整:" + String.join(";", errors)); |
| | | } |
| | | } |
| | | setDepositAmountFromPricingRule(shopInfo); |
| | | } |
| | | |
| | | private void syncChangeToOfficial(ShopInfo changeVersion, ShopInfo official, Date now) { |
| | | official.setCompanyType(changeVersion.getCompanyType()); |
| | | official.setName(changeVersion.getName()); |
| | | official.setTelephone(changeVersion.getTelephone()); |
| | | official.setLinkName(changeVersion.getLinkName()); |
| | | official.setLinkPhone(changeVersion.getLinkPhone()); |
| | | official.setIdcard(changeVersion.getIdcard()); |
| | | official.setAreaId(changeVersion.getAreaId()); |
| | | official.setLongitude(changeVersion.getLongitude()); |
| | | official.setLatitude(changeVersion.getLatitude()); |
| | | official.setAddress(changeVersion.getAddress()); |
| | | official.setIdcardImg(changeVersion.getIdcardImg()); |
| | | official.setIdcardImgBack(changeVersion.getIdcardImgBack()); |
| | | official.setBusinessImg(changeVersion.getBusinessImg()); |
| | | official.setLegalPersonName(changeVersion.getLegalPersonName()); |
| | | official.setLegalPersonPhone(changeVersion.getLegalPersonPhone()); |
| | | official.setLegalPersonCard(changeVersion.getLegalPersonCard()); |
| | | official.setPassword(changeVersion.getPassword()); |
| | | official.setSalt(changeVersion.getSalt()); |
| | | official.setAliAccount(changeVersion.getAliAccount()); |
| | | official.setAliName(changeVersion.getAliName()); |
| | | official.setRevenueShareConfig(changeVersion.getRevenueShareConfig()); |
| | | official.setDepositAmount(changeVersion.getDepositAmount()); |
| | | official.setUpdateTime(now); |
| | | shopInfoMapper.updateById(official); |
| | | |
| | | // 同步附件:先删正式版本旧附件,再从变更版本拷贝 |
| | | deleteShopAttachments(official.getId()); |
| | | List<Multifile> changeFiles = multifileMapper.selectList(new QueryWrapper<Multifile>().lambda() |
| | | .eq(Multifile::getObjId, changeVersion.getId()) |
| | | .eq(Multifile::getIsdeleted, Constants.ZERO) |
| | | .in(Multifile::getObjType, |
| | | Constants.FileType.STORE_FRONT.getKey(), |
| | | Constants.FileType.STORE_INTERIOR.getKey(), |
| | | Constants.FileType.OTHER_MATERIAL.getKey(), |
| | | Constants.FileType.LABOR_CONTRACT.getKey(), |
| | | Constants.FileType.SOCIAL_SECURITY.getKey())); |
| | | for (Multifile f : changeFiles) { |
| | | Multifile copy = new Multifile(); |
| | | copy.setCreator(f.getCreator()); |
| | | copy.setCreateDate(now); |
| | | copy.setIsdeleted(Constants.ZERO); |
| | | copy.setName(f.getName()); |
| | | copy.setInfo(f.getInfo()); |
| | | copy.setObjId(official.getId()); |
| | | copy.setType(f.getType()); |
| | | copy.setObjType(f.getObjType()); |
| | | copy.setFileurl(f.getFileurl()); |
| | | copy.setSortnum(f.getSortnum()); |
| | | multifileMapper.insert(copy); |
| | | } |
| | | } |
| | | |
| | | private void sendAuditSms(ShopInfo shopInfo, Integer newAuditStatus, String auditRemark) { |
| | | if (Constants.equalsInteger(newAuditStatus, Constants.ONE)) { |
| | | // 审核通过 → 通知缴纳押金 |
| | | String depositMoney = shopInfo.getDepositAmount() != null |
| | | ? String.valueOf(shopInfo.getDepositAmount() / 100.0) : "0"; |
| | | ? new java.math.BigDecimal(shopInfo.getDepositAmount()) |
| | | .divide(new java.math.BigDecimal(100), 2, java.math.RoundingMode.HALF_UP).toPlainString() : "0"; |
| | | sendSmsNotify(shopInfo.getTelephone(), |
| | | Constants.SmsNotify.SHOP_AUTH_APPROVED_DEPOSIT, |
| | | "storeName", shopInfo.getName(), |
| | | "money", depositMoney); |
| | | } else if (Constants.equalsInteger(newAuditStatus, Constants.TWO)) { |
| | | // 审核驳回 |
| | | sendSmsNotify(shopInfo.getTelephone(), |
| | | Constants.SmsNotify.SHOP_AUTH_REJECTED, |
| | | "storeName", shopInfo.getName(), |
| | | "reason", auditDTO.getAuditRemark() != null ? auditDTO.getAuditRemark() : ""); |
| | | "reason", auditRemark != null ? auditRemark : ""); |
| | | } |
| | | } |
| | | |
| | |
| | | shopInfo.setLegalPersonCard(request.getLegalPersonCard()); |
| | | shopInfo.setAliAccount(request.getAliAccount()); |
| | | shopInfo.setAliName(request.getAliName()); |
| | | shopInfo.setRevenueShareConfig(buildRevenueShareConfig(request.getLocalDeposit(), request.getRemoteDeposit(), request.getRemoteTake())); |
| | | shopInfo.setUpdateTime(now); |
| | | shopInfoMapper.updateById(shopInfo); |
| | | |
| | |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "手机号格式异常,无法生成默认密码"); |
| | | } |
| | | return telephone.substring(telephone.length() - 6) + "@123456"; |
| | | } |
| | | |
| | | private String buildRevenueShareConfig(Double localDeposit, Double remoteDeposit, Double remoteTake) { |
| | | if (localDeposit == null && remoteDeposit == null && remoteTake == null) { |
| | | return null; |
| | | } |
| | | JSONObject config = new JSONObject(); |
| | | if (localDeposit != null) { |
| | | config.put("localDeposit", localDeposit); |
| | | } |
| | | if (remoteDeposit != null) { |
| | | config.put("remoteDeposit", remoteDeposit); |
| | | } |
| | | if (remoteTake != null) { |
| | | config.put("remoteTake", remoteTake); |
| | | } |
| | | return config.toJSONString(); |
| | | } |
| | | |
| | | private void createChangeVersion(ShopInfo origin, Integer originShopId, Date now) { |
| | | ShopInfo changeShop = new ShopInfo(); |
| | | changeShop.setCompanyType(origin.getCompanyType()); |
| | | changeShop.setName(origin.getName()); |
| | | changeShop.setTelephone(origin.getTelephone()); |
| | | changeShop.setLinkName(origin.getLinkName()); |
| | | changeShop.setLinkPhone(origin.getLinkPhone()); |
| | | changeShop.setIdcard(origin.getIdcard()); |
| | | changeShop.setAreaId(origin.getAreaId()); |
| | | changeShop.setLongitude(origin.getLongitude()); |
| | | changeShop.setLatitude(origin.getLatitude()); |
| | | changeShop.setAddress(origin.getAddress()); |
| | | changeShop.setIdcardImg(origin.getIdcardImg()); |
| | | changeShop.setIdcardImgBack(origin.getIdcardImgBack()); |
| | | changeShop.setBusinessImg(origin.getBusinessImg()); |
| | | changeShop.setLegalPersonName(origin.getLegalPersonName()); |
| | | changeShop.setLegalPersonPhone(origin.getLegalPersonPhone()); |
| | | changeShop.setLegalPersonCard(origin.getLegalPersonCard()); |
| | | changeShop.setAliAccount(origin.getAliAccount()); |
| | | changeShop.setAliName(origin.getAliName()); |
| | | changeShop.setDepositAmount(origin.getDepositAmount()); |
| | | changeShop.setRevenueShareConfig(origin.getRevenueShareConfig()); |
| | | changeShop.setVersionType(Constants.ONE); |
| | | changeShop.setRelationShopId(originShopId); |
| | | changeShop.setRegionMemberId(origin.getRegionMemberId()); |
| | | changeShop.setOpenid(origin.getOpenid()); |
| | | changeShop.setStatus(Constants.ZERO); |
| | | changeShop.setDeleted(Constants.ZERO); |
| | | changeShop.setCreateTime(now); |
| | | changeShop.setUpdateTime(now); |
| | | shopInfoMapper.insert(changeShop); |
| | | |
| | | // 拷贝附件到变更版本 |
| | | List<Multifile> originFiles = multifileMapper.selectList(new QueryWrapper<Multifile>().lambda() |
| | | .eq(Multifile::getObjId, originShopId) |
| | | .eq(Multifile::getIsdeleted, Constants.ZERO) |
| | | .in(Multifile::getObjType, |
| | | Constants.FileType.STORE_FRONT.getKey(), |
| | | Constants.FileType.STORE_INTERIOR.getKey(), |
| | | Constants.FileType.OTHER_MATERIAL.getKey(), |
| | | Constants.FileType.LABOR_CONTRACT.getKey(), |
| | | Constants.FileType.SOCIAL_SECURITY.getKey())); |
| | | for (Multifile f : originFiles) { |
| | | Multifile copy = new Multifile(); |
| | | copy.setCreator(f.getCreator()); |
| | | copy.setCreateDate(now); |
| | | copy.setIsdeleted(Constants.ZERO); |
| | | copy.setName(f.getName()); |
| | | copy.setInfo(f.getInfo()); |
| | | copy.setObjId(changeShop.getId()); |
| | | copy.setType(f.getType()); |
| | | copy.setObjType(f.getObjType()); |
| | | copy.setFileurl(f.getFileurl()); |
| | | copy.setSortnum(f.getSortnum()); |
| | | multifileMapper.insert(copy); |
| | | } |
| | | } |
| | | |
| | | private void checkTelephoneUnique(String telephone, Integer excludeId) { |
| | |
| | | vo.setAliAccount(shopInfo.getAliAccount()); |
| | | vo.setAliName(shopInfo.getAliName()); |
| | | vo.setDepositAmount(shopInfo.getDepositAmount()); |
| | | vo.setDeliveryRange(shopInfo.getDeliveryArea()); |
| | | vo.setVersionType(shopInfo.getVersionType()); |
| | | vo.setRelationShopId(shopInfo.getRelationShopId()); |
| | | // 解析收益比例配置 |
| | | if (StringUtils.isNotBlank(shopInfo.getRevenueShareConfig())) { |
| | | try { |
| | | JSONObject config = JSONObject.parseObject(shopInfo.getRevenueShareConfig()); |
| | | if (config != null) { |
| | | vo.setLocalDeposit(config.getDouble("localDeposit")); |
| | | vo.setRemoteDeposit(config.getDouble("remoteDeposit")); |
| | | vo.setRemoteTake(config.getDouble("remoteTake")); |
| | | } |
| | | } catch (Exception ignored) { |
| | | } |
| | | } |
| | | |
| | | // 拼接图片前缀 |
| | | String imgPrefix = ""; |
| | |
| | | } |
| | | } |
| | | |
| | | // 门店头像:优先使用 coverImg,为空则取门头照第一张 |
| | | if (StringUtils.isNotBlank(shopInfo.getCoverImg())) { |
| | | vo.setShopAvatar(imgPrefix + shopInfo.getCoverImg()); |
| | | } else if (!CollectionUtils.isEmpty(vo.getStoreFrontImgUrls())) { |
| | | vo.setShopAvatar(vo.getStoreFrontImgUrls().get(0)); |
| | | } |
| | | |
| | | return vo; |
| | | } |
| | | |
| | |
| | | qw.lambda() |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .eq(ShopInfo::getStatus, Constants.ZERO) |
| | | .eq(ShopInfo::getVersionType, Constants.ZERO) |
| | | .eq(ShopInfo::getAuditStatus, Constants.THREE); |
| | | |
| | | // 门店营业类型筛选 |
| | |
| | | |
| | | // 门店名称模糊查询 |
| | | if (StringUtils.isNotBlank(dto.getName())) { |
| | | qw.lambda().like(ShopInfo::getName, dto.getName()); |
| | | qw.lambda().and(q -> q.like(ShopInfo::getName, dto.getName()).or() |
| | | .like(ShopInfo::getAddress, dto.getName())); |
| | | } |
| | | |
| | | // 城市筛选(areaId是区县,需匹配其parentId等于城市ID) |
| | |
| | | @Override |
| | | public ShopWebDetailVO getShopWebDetail(ShopDetailQueryDTO dto) { |
| | | ShopInfo shop = shopInfoMapper.selectById(dto.getId()); |
| | | if (Objects.isNull(shop) || Constants.equalsInteger(shop.getDeleted(), Constants.ONE)) { |
| | | if (Objects.isNull(shop) || Constants.equalsInteger(shop.getDeleted(), Constants.ONE) || Constants.equalsInteger(shop.getVersionType(), Constants.ONE)) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY); |
| | | } |
| | | |
| | |
| | | vo.setFeeStandard(shop.getFeeStandard()); |
| | | vo.setLatitude(shop.getLatitude()); |
| | | vo.setLongitude(shop.getLongitude()); |
| | | vo.setLinkPhone(shop.getLinkPhone()); |
| | | |
| | | // 门头照 + 内部照 全路径集合 |
| | | String imgPrefix = getShopPrefix(); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public ShopInfoMaintainDTO getShopMaintainInfo(Integer memberId) { |
| | | ShopInfo shop = shopInfoMapper.selectById(memberId); |
| | | public ShopInfoMaintainDTO getShopMaintainInfo(Integer shopId) { |
| | | ShopInfo shop = shopInfoMapper.selectById(shopId); |
| | | if (Objects.isNull(shop) || Constants.equalsInteger(shop.getDeleted(), Constants.ONE)) { |
| | | return null; |
| | | } |
| | |
| | | dto.setDeliveryArea(shop.getDeliveryArea()); |
| | | dto.setShopHours(shop.getShopHours()); |
| | | dto.setBusinessType(shop.getBusinessType()); |
| | | // 头像全路径 |
| | | if (StringUtils.isNotBlank(shop.getCoverImg())) { |
| | | dto.setCoverImgUrl(getShopPrefix() + shop.getCoverImg()); |
| | | } |
| | | return dto; |
| | | } |
| | | |
| | |
| | | @Override |
| | | public ShopCenterVO getShopCenterInfo(Integer shopId) { |
| | | ShopInfo shop = shopInfoMapper.selectById(shopId); |
| | | if (shop == null || Constants.equalsInteger(shop.getDeleted(), Constants.ONE)) { |
| | | if (shop == null || Constants.equalsInteger(shop.getDeleted(), Constants.ONE) || Constants.equalsInteger(shop.getVersionType(), Constants.ONE)) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY); |
| | | } |
| | | ShopCenterVO vo = new ShopCenterVO(); |
| | |
| | | // 存件门店 |
| | | List<Orders> depositSalesOrders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda() |
| | | .eq(Orders::getDeleted, Constants.ZERO) |
| | | .notIn(Orders::getStatus,Constants.OrderStatus.cancelled.getStatus(),Constants.OrderStatus.waitPay.getStatus()) |
| | | .ge(Orders::getCreateTime, startTime) |
| | | .lt(Orders::getCreateTime, endTime) |
| | | .eq(Orders::getDepositShopId, shopId)); |
| | | // 取件门店 |
| | | List<Orders> takeSalesOrders = ordersMapper.selectList(new QueryWrapper<Orders>().lambda() |
| | | .eq(Orders::getDeleted, Constants.ZERO) |
| | | .eq(Orders::getType,Constants.ONE) |
| | | .notIn(Orders::getStatus,Constants.OrderStatus.cancelled.getStatus(),Constants.OrderStatus.waitPay.getStatus()) |
| | | .ge(Orders::getCreateTime, startTime) |
| | | .lt(Orders::getCreateTime, endTime) |
| | | .eq(Orders::getTakeShopId, shopId)); |
| | |
| | | vo.setSettlementProfit(depositFee + takeFee); |
| | | |
| | | // 3. 在库订单数 |
| | | // 3.1 存件门店=本门店,status in (2已寄存, 5待取件) |
| | | Long depositStorageCount = ordersMapper.selectCount(new QueryWrapper<Orders>().lambda() |
| | | // 3.1 就地订单:存件门店=本门店,type=0,status in (2已寄存, 5待取件) |
| | | Long localStorageCount = ordersMapper.selectCount(new QueryWrapper<Orders>().lambda() |
| | | .eq(Orders::getDeleted, Constants.ZERO) |
| | | .eq(Orders::getDepositShopId, shopId) |
| | | .eq(Orders::getType, Constants.ZERO) |
| | | .in(Orders::getStatus, |
| | | Constants.OrderStatus.deposited.getStatus(), |
| | | Constants.OrderStatus.arrived.getStatus())); |
| | | // 3.2 取件门店=本门店,status = 5待取件 |
| | | // 3.2 异地订单:存件门店=本门店,type=1,status=2已寄存 |
| | | Long remoteStorageCount = ordersMapper.selectCount(new QueryWrapper<Orders>().lambda() |
| | | .eq(Orders::getDeleted, Constants.ZERO) |
| | | .eq(Orders::getDepositShopId, shopId) |
| | | .eq(Orders::getType, Constants.ONE) |
| | | .eq(Orders::getStatus, Constants.OrderStatus.deposited.getStatus())); |
| | | // 3.3 取件门店=本门店,异地订单,status = 5待取件 |
| | | Long takeStorageCount = ordersMapper.selectCount(new QueryWrapper<Orders>().lambda() |
| | | .eq(Orders::getDeleted, Constants.ZERO) |
| | | .eq(Orders::getType,Constants.ONE) |
| | | .eq(Orders::getTakeShopId, shopId) |
| | | .eq(Orders::getStatus, Constants.OrderStatus.arrived.getStatus())); |
| | | vo.setStorageCount(depositStorageCount.intValue() + takeStorageCount.intValue()); |
| | | vo.setStorageCount(localStorageCount.intValue() + remoteStorageCount.intValue() + takeStorageCount.intValue()); |
| | | |
| | | return vo; |
| | | } |
| | |
| | | public ShopLoginVO shopPasswordLogin(ShopLoginDTO dto){ |
| | | if(StringUtils.isBlank(dto.getTelephone()) |
| | | || StringUtils.isBlank(dto.getPassword()) |
| | | || StringUtils.isBlank(dto.getOpenid()) |
| | | ){ |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"用户名或密码不能为空"); |
| | | } |
| | | ShopInfo shop = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda().eq(ShopInfo::getTelephone, dto.getTelephone()) |
| | | .eq(ShopInfo::getDeleted,Constants.ZERO) |
| | | .eq(ShopInfo::getVersionType,Constants.ZERO) |
| | | .last("limit 1") |
| | | ); |
| | | if(shop==null){ |
| | | throw new BusinessException(ResponseStatus.ACCOUNT_INCORRECT); |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"请核对登录手机号是否正确"); |
| | | } |
| | | if(Constants.equalsInteger(shop.getStatus(),Constants.ONE)){ |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"门店已禁用,请联系管理员"); |
| | | } |
| | | if(!Constants.equalsInteger(shop.getAuditStatus(),Constants.THREE)){ |
| | | if(Constants.equalsInteger(shop.getAuditStatus(),Constants.ONE)){ |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"请完成审批流程 - 支付押金"); |
| | | } |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"门店审批流程未完成,请完成审批流程"); |
| | | } |
| | | //加密密码 |
| | | String pwd = Utils.Secure.encryptPassword( dto.getPassword(), shop.getSalt()); |
| | | if(!pwd.equals(shop.getPassword())){ |
| | | throw new BusinessException(ResponseStatus.ACCOUNT_INCORRECT); |
| | | } |
| | | |
| | | // 更新当前登录会员的openid到门店 |
| | | if(StringUtils.isNotBlank(dto.getOpenid())){ |
| | | shopInfoMapper.update(null,new UpdateWrapper<ShopInfo>().lambda() |
| | | .set(ShopInfo::getOpenid,dto.getOpenid()) |
| | | .eq(ShopInfo::getId,shop.getId()) |
| | | ); |
| | | // 清空其他门店的同一openid,保证唯一 |
| | | shopInfoMapper.update(null,new UpdateWrapper<ShopInfo>().lambda() |
| | | .set(ShopInfo::getOpenid,null) |
| | | .eq(ShopInfo::getOpenid,dto.getOpenid()) |
| | | .ne(ShopInfo::getId,shop.getId()) |
| | | ); |
| | | shop.setOpenid(dto.getOpenid()); |
| | | if(Objects.nonNull(dto.getMemberId())){ |
| | | Member member = memberMapper.selectById(dto.getMemberId()); |
| | | if(Objects.nonNull(member)){ |
| | | memberMapper.update(new UpdateWrapper<Member>().lambda() |
| | | .set(Member::getLoginShopId,shop.getId()) |
| | | .eq(Member::getId,member.getId()) |
| | | ); |
| | | shop.setMemberId(member.getId()); |
| | | }else{ |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"会员信息异常,请联系管理员"); |
| | | } |
| | | } |
| | | |
| | | // 创建token(generateTokenForRedis 已自动清除该用户旧token,保证唯一有效) |
| | | String token = JwtTokenUtil.generateTokenForRedis(shop.getId(), Constants.TWO, JSONObject.toJSONString(shop), redisTemplate); |
| | | |
| | | String token = JwtTokenUtil.generateShopTokenForRedis(shop.getMemberId(), JSONObject.toJSONString(shop), redisTemplate); |
| | | // 构建响应 |
| | | ShopLoginVO vo = new ShopLoginVO(); |
| | | vo.setToken(token); |
| | | vo.setShopId(shop.getId()); |
| | | vo.setShopName(shop.getName()); |
| | | vo.setCompanyType(shop.getCompanyType()); |
| | | |
| | | // 所属城市名称 |
| | | Areas area = areasBiz.resolveArea(shop.getAreaId()); |
| | | if (area != null) { |
| | |
| | | @Override |
| | | public ShopLoginVO shopSilentLogin(Integer memberId) { |
| | | Member member = memberMapper.selectById(memberId); |
| | | if(Objects.isNull(member)||StringUtils.isBlank(member.getOpenid())){ |
| | | if(Objects.isNull(member)){ |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "当前登录会员身份异常,请联系管理员!"); |
| | | } |
| | | if (Objects.isNull(member.getLoginShopId())) { |
| | | return null; |
| | | } |
| | | ShopInfo shop = shopInfoMapper.selectOne(new QueryWrapper<ShopInfo>().lambda() |
| | | .eq(ShopInfo::getOpenid, member.getOpenid()) |
| | | .eq(ShopInfo::getId, member.getLoginShopId()) |
| | | .eq(ShopInfo::getVersionType,Constants.ZERO) |
| | | .eq(ShopInfo::getDeleted, Constants.ZERO) |
| | | .last("limit 1")); |
| | | if (shop == null) { |
| | | return null; |
| | | } |
| | | if(Constants.equalsInteger(shop.getStatus(),Constants.ONE)){ |
| | | throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"门店已禁用,请联系管理员"); |
| | | } |
| | | // 创建token(generateTokenForRedis 已自动清除该用户旧token,保证唯一有效) |
| | | String token = JwtTokenUtil.generateTokenForRedis(shop.getId(), Constants.TWO, JSONObject.toJSONString(shop), redisTemplate); |
| | | String token = JwtTokenUtil.generateShopTokenForRedis(member.getId(), JSONObject.toJSONString(shop), redisTemplate); |
| | | |
| | | ShopLoginVO vo = new ShopLoginVO(); |
| | | vo.setToken(token); |
| | |
| | | if (shopInfo.getCompanyType() == null) { |
| | | return; |
| | | } |
| | | Areas areas = areasService.findById(shopInfo.getAreaId()); |
| | | PricingRule pricingRule = pricingRuleMapper.selectOne(new QueryWrapper<PricingRule>().lambda() |
| | | .eq(PricingRule::getDeleted, Constants.ZERO) |
| | | .eq(PricingRule::getType, Constants.THREE) |
| | | .eq(PricingRule::getFieldA, String.valueOf(shopInfo.getCompanyType())) |
| | | .eq(PricingRule::getFieldA, String.valueOf(Constants.equalsInteger(shopInfo.getCompanyType(),Constants.ZERO)?Constants.ONE:Constants.ZERO)) |
| | | .eq(PricingRule::getCityId, areas.getParentId()) |
| | | .last("limit 1")); |
| | | if (pricingRule != null && StringUtils.isNotBlank(pricingRule.getFieldB())) { |
| | | shopInfo.setDepositAmount(Long.parseLong(pricingRule.getFieldB())); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 从运营配置读取默认配送范围并赋值到门店记录 |
| | | */ |
| | | private void setDefaultDeliveryRange(ShopInfo shopInfo) { |
| | | SystemDictData data = systemDictDataBiz.queryByCode(Constants.OPERATION_CONFIG, Constants.OP_DEFAULT_DELIVERY_RANGE); |
| | | if (data != null && StringUtils.isNotBlank(data.getCode())) { |
| | | shopInfo.setDeliveryArea(new java.math.BigDecimal(data.getCode())); |
| | | } |
| | | } |
| | | |
| | |
| | | if (StringUtils.isBlank(phone)) { |
| | | return; |
| | | } |
| | | if (!smsNotify.isEnabled()) { |
| | | return; |
| | | } |
| | | String content = smsNotify.format(paramPairs); |
| | | try { |
| | | JSONObject templateParam = new JSONObject(); |
| | | for (int i = 0; i < paramPairs.length - 1; i += 2) { |
| | | templateParam.put(paramPairs[i], paramPairs[i + 1]); |
| | | } |
| | | boolean result = AliSmsService.sendSms(phone, smsNotify.getTemplateCode(), |
| | | String error = AliSmsService.sendSms(phone, smsNotify.getTemplateCode(), |
| | | templateParam.toJSONString()); |
| | | if (result) { |
| | | log.info("短信发送成功: phone={}, template={}", phone, smsNotify.name()); |
| | | } else { |
| | | log.warn("短信发送失败: phone={}, template={}", phone, smsNotify.name()); |
| | | } |
| | | // 存储短信记录 |
| | | Smsrecord smsRecord = new Smsrecord(); |
| | | smsRecord.setPhone(phone); |
| | | smsRecord.setContent(content); |
| | | smsRecord.setType(Constants.ONE); |
| | | smsRecord.setStatus(result ? Constants.ONE : Constants.ZERO); |
| | | smsRecord.setStatus(error == null ? Constants.ONE : Constants.ZERO); |
| | | if (error != null) { |
| | | smsRecord.setRemark(error); |
| | | } |
| | | smsRecord.setCreateTime(new Date()); |
| | | smsRecord.setDeleted(Constants.ZERO); |
| | | smsrecordMapper.insert(smsRecord); |
| | |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void changePassword(Integer shopId, String oldPassword, String newPassword, String token) { |
| | | if (StringUtils.isBlank(oldPassword)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "旧密码不能为空"); |
| | | } |
| | | if (StringUtils.isBlank(newPassword)) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "新密码不能为空"); |
| | | } |
| | | // 校验新密码必须同时包含字母和数字 |
| | | boolean hasLetter = newPassword.chars().anyMatch(Character::isLetter); |
| | | boolean hasDigit = newPassword.chars().anyMatch(Character::isDigit); |
| | | if (!hasLetter || !hasDigit) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "密码必须同时包含字母和数字"); |
| | | } |
| | | // 查询门店 |
| | | ShopInfo shopInfo = shopInfoMapper.selectById(shopId); |
| | | if (shopInfo == null || Constants.equalsInteger(shopInfo.getDeleted(), Constants.ONE)) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY); |
| | | } |
| | | // 校验旧密码 |
| | | String oldEncryptPwd = Utils.Secure.encryptPassword(oldPassword, shopInfo.getSalt()); |
| | | if (!oldEncryptPwd.equals(shopInfo.getPassword())) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "旧密码错误"); |
| | | } |
| | | // 重新生成salt,加密新密码并更新 |
| | | String salt = RandomStringUtils.randomAlphabetic(6); |
| | | shopInfo.setPassword(Utils.Secure.encryptPassword(newPassword, salt)); |
| | | shopInfo.setSalt(salt); |
| | | shopInfoMapper.updateById(shopInfo); |
| | | // 清除token,强制重新登录 |
| | | if (StringUtils.isNotBlank(token)) { |
| | | redisTemplate.delete(token); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void maintainPrinterSn(ShopPrinterDTO dto) { |
| | | ShopInfo shop = shopInfoMapper.selectById(dto.getId()); |
| | | if (shop == null || Constants.equalsInteger(shop.getDeleted(), Constants.ONE)) { |
| | | throw new BusinessException(ResponseStatus.DATA_EMPTY); |
| | | } |
| | | String oldSn = shop.getPrinterSn(); |
| | | String newSn = dto.getPrinterSn(); |
| | | boolean hasNewSn = StringUtils.isNotBlank(newSn); |
| | | boolean hasOldSn = StringUtils.isNotBlank(oldSn); |
| | | |
| | | if (!hasNewSn) { |
| | | // 未传打印机SN → 删除逻辑 |
| | | if (hasOldSn) { |
| | | delPrinterFromXyy(oldSn); |
| | | shop.setPrinterSn(null); |
| | | shopInfoMapper.updateById(shop); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | // 传了打印机SN → 如果旧绑定存在,先删除 |
| | | if (hasOldSn) { |
| | | delPrinterFromXyy(oldSn); |
| | | } |
| | | |
| | | // 绑定新打印机 |
| | | AddPrinterRequest addReq = new AddPrinterRequest(); |
| | | xyyConfig.createRequestHeader(addReq); |
| | | addReq.setItems(new AddPrinterRequestItem[]{new AddPrinterRequestItem() {{ |
| | | setSn(newSn); |
| | | setName(shop.getName()); |
| | | }}}); |
| | | ObjectRestResponse<PrinterResult> addResp = printService.addPrinters(addReq); |
| | | if (addResp.getCode() != 0) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "绑定打印机失败:" + addResp.getMsg()); |
| | | } |
| | | log.info("绑定成功:{}", newSn); |
| | | shop.setPrinterSn(newSn); |
| | | shopInfoMapper.updateById(shop); |
| | | } |
| | | |
| | | private void delPrinterFromXyy(String sn) { |
| | | DelPrinterRequest delReq = new DelPrinterRequest(); |
| | | xyyConfig.createRequestHeader(delReq); |
| | | delReq.setSnlist(new String[]{sn}); |
| | | ObjectRestResponse<PrinterResult> delResp = printService.delPrinters(delReq); |
| | | if (delResp.getCode() != 0) { |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "解绑打印机失败:" + delResp.getMsg()); |
| | | } |
| | | log.info("解绑成功:{}", sn); |
| | | } |
| | | |
| | | } |