rk
昨天 996b2f16afaa271ce8aad6abf6858aa5db503eb3
server/services/src/main/java/com/doumee/service/business/impl/ShopInfoServiceImpl.java
@@ -14,6 +14,7 @@
import com.doumee.core.utils.Utils;
import com.doumee.biz.system.AreasBiz;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.core.utils.aliyun.AliSmsService;
import com.doumee.dao.business.MemberMapper;
import com.doumee.dao.business.MultifileMapper;
import com.doumee.dao.business.OrdersMapper;
@@ -36,6 +37,9 @@
import com.doumee.dao.vo.ShopWebDetailVO;
import com.doumee.service.business.AreasService;
import com.doumee.service.business.ShopInfoService;
import com.doumee.dao.business.SmsrecordMapper;
import com.doumee.dao.business.model.Smsrecord;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.RandomStringUtils;
@@ -52,6 +56,7 @@
 * @author rk
 * @date 2026/04/08
 */
@Slf4j
@Service
public class ShopInfoServiceImpl implements ShopInfoService {
@@ -84,6 +89,9 @@
    @Autowired
    private AreasService areasService;
    @Autowired
    private SmsrecordMapper smsrecordMapper;
    @Override
    public Integer create(ShopInfo shopInfo) {
        shopInfoMapper.insert(shopInfo);
@@ -197,6 +205,9 @@
        }
        if (pageWrap.getModel().getAreaId() != null) {
            queryWrapper.lambda().eq(ShopInfo::getAreaId, pageWrap.getModel().getAreaId());
        }
        if (pageWrap.getModel().getAddress() != null) {
            queryWrapper.lambda().like(ShopInfo::getAddress, pageWrap.getModel().getAddress());
        }
        if (pageWrap.getModel().getAuditStatus() != null) {
            queryWrapper.lambda().eq(ShopInfo::getAuditStatus, pageWrap.getModel().getAuditStatus());
@@ -320,6 +331,8 @@
            existing.setAuditTime(null);
            existing.setAuditUserId(null);
            existing.setAuditStatus(Constants.ZERO);
            // 读取押金金额
            setDepositAmountFromPricingRule(existing);
            shopInfoMapper.updateById(existing);
            shopId = existing.getId();
        } else {
@@ -352,6 +365,8 @@
            shopInfo.setCreateTime(now);
            shopInfo.setUpdateTime(now);
            shopInfo.setRegionMemberId(member.getId());
            // 读取押金金额
            setDepositAmountFromPricingRule(shopInfo);
            shopInfoMapper.insert(shopInfo);
            shopId = shopInfo.getId();
        }
@@ -445,17 +460,27 @@
                }
            }
            // 3. 从PricingRule读取押金金额
            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()))
                    .last("limit 1"));
            if (pricingRule != null && StringUtils.isNotBlank(pricingRule.getFieldB())) {
                shopInfo.setDepositAmount(Long.parseLong(pricingRule.getFieldB()));
            }
            // 3. 从PricingRule读取押金金额(审批时更新)
            setDepositAmountFromPricingRule(shopInfo);
        }
        shopInfoMapper.updateById(shopInfo);
        // 短信通知
        if (Constants.equalsInteger(newAuditStatus, Constants.ONE)) {
            // 审核通过 → 通知缴纳押金
            String depositMoney = shopInfo.getDepositAmount() != null
                    ? String.valueOf(shopInfo.getDepositAmount() / 100.0) : "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() : "");
        }
    }
    @Override
@@ -732,6 +757,13 @@
            }
        }
        // 门店头像:优先使用 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;
    }
@@ -881,8 +913,8 @@
    }
    @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;
        }
@@ -894,6 +926,10 @@
        dto.setDeliveryArea(shop.getDeliveryArea());
        dto.setShopHours(shop.getShopHours());
        dto.setBusinessType(shop.getBusinessType());
        // 头像全路径
        if (StringUtils.isNotBlank(shop.getCoverImg())) {
            dto.setCoverImgUrl(getShopPrefix() + shop.getCoverImg());
        }
        return dto;
    }
@@ -1275,4 +1311,82 @@
        return errors;
    }
    /**
     * 从PricingRule读取押金金额并赋值到门店记录
     */
    private void setDepositAmountFromPricingRule(ShopInfo shopInfo) {
        if (shopInfo.getCompanyType() == null) {
            return;
        }
        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()))
                .last("limit 1"));
        if (pricingRule != null && StringUtils.isNotBlank(pricingRule.getFieldB())) {
            shopInfo.setDepositAmount(Long.parseLong(pricingRule.getFieldB()));
        }
    }
    /**
     * 发送短信通知(失败不影响主业务)
     */
    private void sendSmsNotify(String phone, Constants.SmsNotify smsNotify, String... paramPairs) {
        if (StringUtils.isBlank(phone)) {
            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(),
                    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.setCreateTime(new Date());
            smsRecord.setDeleted(Constants.ZERO);
            smsrecordMapper.insert(smsRecord);
        } catch (Exception e) {
            log.error("短信发送异常: phone={}, template={}, error={}", phone, smsNotify.name(), e.getMessage());
        }
    }
    @Override
    public void changePassword(Integer shopId, String newPassword, String token) {
        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);
        }
        // 重新生成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);
        }
    }
}