diff --git a/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountBaseUserLevelController.java b/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountBaseUserLevelController.java index bae3ff66..61d10fb0 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountBaseUserLevelController.java +++ b/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountBaseUserLevelController.java @@ -11,6 +11,7 @@ import com.suisung.mall.common.utils.I18nUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -32,6 +33,7 @@ public class AccountBaseUserLevelController { @Autowired private AccountBaseUserLevelService accountBaseUserLevelService; + @Lazy @Autowired private AccountService accountService; diff --git a/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountUserBaseController.java b/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountUserBaseController.java index 39838857..d4d63932 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountUserBaseController.java +++ b/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountUserBaseController.java @@ -31,6 +31,7 @@ import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.util.Pair; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -231,5 +232,17 @@ public class AccountUserBaseController extends BaseControllerImpl { return CommonResult.success(accountUserBaseService.logout()); } + @ApiOperation("注册商家账号,项目之间远程调用") + @RequestMapping(value = "/merchant/inner-register", method = RequestMethod.POST) + public Pair merchantInnerRegister(@RequestParam("mobile") String mobile, @RequestParam("regPwd") String regPwd) { + return accountUserBaseService.merchantInnerRegister(mobile, regPwd); + } + + @ApiOperation("更改分店商家的手机号(仅限于分店,尽量不要更高总店的手机号),项目之间远程调用") + @RequestMapping(value = "/change/merchant/login-mobile", method = RequestMethod.POST) + public Pair changeMerchantLoginMobile(@RequestParam("oldMobile") String oldMobile, @RequestParam("newMobile") String newMobile, @RequestParam("password") String password) { + return accountUserBaseService.changeMerchantLoginMobile(oldMobile, newMobile, password); + } + } diff --git a/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountUserBindConnectController.java b/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountUserBindConnectController.java index 99c100c4..9d3ca063 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountUserBindConnectController.java +++ b/mall-account/src/main/java/com/suisung/mall/account/controller/admin/AccountUserBindConnectController.java @@ -85,5 +85,17 @@ public class AccountUserBindConnectController { return accountUserBindConnectService.getUserBindConnectUserIdByCondition(bind_id, bind_type, user_type); } + /** + * 检查手机注册的商家是否存在(仅供内部调用) + * + * @param mobile + * @return + */ + @ApiOperation(value = "检查手机注册的商家是否存在(仅供内部调用)", notes = "检查手机注册的商家是否存在(仅供内部调用)") + @RequestMapping(value = "/is-merchant-exists", method = RequestMethod.POST) + public Integer isMerchantExists(@RequestParam(name = "mobile") String mobile) { + return accountUserBindConnectService.isMerchantExists(mobile); + } + } diff --git a/mall-account/src/main/java/com/suisung/mall/account/service/AccountUserBaseService.java b/mall-account/src/main/java/com/suisung/mall/account/service/AccountUserBaseService.java index c11c71aa..d45acea5 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/service/AccountUserBaseService.java +++ b/mall-account/src/main/java/com/suisung/mall/account/service/AccountUserBaseService.java @@ -298,6 +298,25 @@ public interface AccountUserBaseService extends IBaseService { */ ThirdApiRes saveBatchAccountInfo(List accountUserInfoList); + /** + * 商家内部注册(服务之间调用) + * + * @param mobile 商家手机号 + * @param regPwd 注册密码 + * @return Pair 第一个元素表示是否成功,第二个元素表示提示信息 + */ + Pair merchantInnerRegister(String mobile, String regPwd); + + /** + * 更改分店商家的手机号(仅限于分店,尽量不要更改总店的手机号),项目之间远程调用 + * + * @param oldMobile 老的手机号 + * @param newMobile 新的手机号 + * @param password 新的登录密码(可选) + * @return Pair 操作结果和提示信息,true表示成功,false表示失败 + */ + Pair changeMerchantLoginMobile(String oldMobile, String newMobile, String password); + /** * 批量保存accountInfo * diff --git a/mall-account/src/main/java/com/suisung/mall/account/service/AccountUserBindConnectService.java b/mall-account/src/main/java/com/suisung/mall/account/service/AccountUserBindConnectService.java index ebc26691..5bca855c 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/service/AccountUserBindConnectService.java +++ b/mall-account/src/main/java/com/suisung/mall/account/service/AccountUserBindConnectService.java @@ -4,6 +4,7 @@ import cn.hutool.json.JSONObject; import com.suisung.mall.common.modules.account.AccountUserBindConnect; import com.suisung.mall.common.pojo.req.WxUserInfoReq; import com.suisung.mall.core.web.service.IBaseService; + import java.util.List; import java.util.Map; @@ -89,9 +90,17 @@ public interface AccountUserBindConnectService extends IBaseService getAllBindPage(String bindTmpl,Integer pageNum, Integer pageSize); + List getAllBindPage(String bindTmpl, Integer pageNum, Integer pageSize); long getAllBindCount(String bindTmpl); void bindTmplId(JSONObject jsonObject); + + /** + * 检查手机注册的商家是否存在 + * + * @param mobile + * @return 1-存在;2-不存在;3-参数有误 + */ + Integer isMerchantExists(String mobile); } diff --git a/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBaseServiceImpl.java b/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBaseServiceImpl.java index e4567a8f..f3b21bee 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBaseServiceImpl.java +++ b/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBaseServiceImpl.java @@ -97,7 +97,7 @@ import static com.suisung.mall.common.utils.I18nUtil._; @Service public class AccountUserBaseServiceImpl extends BaseServiceImpl implements AccountUserBaseService { - private final String VERIFY_CODE_KEY = "register:verifyCode:"; + private final String VERIFY_CODE_KEY = RedisConstant.VERIFY_CODE_KEY; //"register:verifyCode:"; private final Logger logger = LoggerFactory.getLogger(AccountUserBaseServiceImpl.class); @Autowired private AuthService authService; @@ -1715,8 +1715,6 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl smsArgs = new HashMap<>(); smsArgs.put("password", user_password_src); - sendSmsMessage(PhoneNumberUtils.cleanPhoneNumber(user_mobile), "SMS_496910525", smsArgs); // SMS_496910525 + sendSmsMessage(PhoneNumberUtils.cleanPhoneNumber(user_mobile), "SMS_496910525", smsArgs); } //初次注册发送消息 @@ -3221,6 +3218,20 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl 第一个元素表示是否成功,第二个元素表示提示信息 + */ + @Override + public Pair merchantInnerRegister(String mobile, String regPwd) { + log.info("商家内部注册开始,手机号: {}", mobile); + + // 1. 参数校验 + if (StrUtil.isBlank(mobile)) { + log.warn("商家内部注册失败:手机号为空"); + return Pair.of(false, "手机号不能为空"); + } + + try { + // 2. 转换手机号格式(添加国家区号) + String convertedMobile = PhoneNumberUtils.convZhPhoneNumber(mobile); + + // 3. 检查手机号是否已注册为商家 + Integer isExists = accountUserBindConnectService.isMerchantExists(convertedMobile); + if (CommonConstant.Enable.equals(isExists)) { + log.warn("商家内部注册失败:手机号已注册,手机号: {}", convertedMobile); + return Pair.of(false, "该手机号已注册!"); + } + + // 4. 执行手机号绑定登录(注册商家账号) + CommonResult result = doMobileBindLogin(convertedMobile, regPwd, CommonConstant.USER_TYPE_MCH, null, null); + + // 5. 检查注册结果 + if (result == null || result.getCode() != ResultCode.SUCCESS.getCode()) { + String errorMsg = result != null ? result.getMsg() : "注册结果为空"; + log.error("商家账号注册失败:{},手机号: {}", errorMsg, convertedMobile); + return Pair.of(false, "商家账号注册失败:" + errorMsg); + } + + log.info("商家内部注册成功,手机号: {}", convertedMobile); + return Pair.of(true, "商家注册成功"); + + } catch (Exception e) { + log.error("商家内部注册异常,手机号: {}", mobile, e); + return Pair.of(false, "商家注册失败:" + e.getMessage()); + } + } + + /** + * 更改分店商家的手机号(仅限于分店,尽量不要更改总店的手机号),项目之间远程调用 + * + * @param oldMobile 老的手机号 + * @param newMobile 新的手机号 + * @param password 新的登录密码(可选) + * @return Pair 操作结果和提示信息,true表示成功,false表示失败 + */ + @Override + public Pair changeMerchantLoginMobile(String oldMobile, String newMobile, String password) { + log.debug("开始更改商家登录手机号,老手机号:{},新手机号:{},是否需要设置密码:{}", oldMobile, newMobile, StrUtil.isNotBlank(password)); + + try { + // 验证输入参数 + if (StrUtil.isBlank(oldMobile) || StrUtil.isBlank(newMobile)) { + log.warn("手机号参数为空,老手机号:{},新手机号:{}", oldMobile, newMobile); + return Pair.of(false, "手机号不能为空"); + } + + // 格式化手机号,添加国际区号 + String formattedOldMobile = PhoneNumberUtils.convZhPhoneNumber(oldMobile); + String formattedNewMobile = PhoneNumberUtils.convZhPhoneNumber(newMobile); + log.debug("格式化后的手机号:老:{} 新:{}", formattedOldMobile, formattedNewMobile); + + // 查询老手机号是否绑定商家账号 + AccountUserBindConnect bindConnect = bindConnectService.getBindByBindId(formattedOldMobile, BindCode.MOBILE, CommonConstant.USER_TYPE_MCH); + if (bindConnect == null) { + log.warn("该老手机号未绑定商家账号,手机号:{}", formattedOldMobile); + return Pair.of(false, "该老手机号未绑定商家账号,无法进行更换"); + } + + // 获取用户信息 + Integer userId = bindConnect.getUser_id(); + log.debug("绑定记录中的用户ID:{}", userId); + + AccountUserBase userBase = get(userId); + if (userBase == null) { + log.warn("用户信息不存在,用户ID:{}", userId); + return Pair.of(false, "用户信息不存在,无法进行更换"); + } + + // 验证用户确实是商家类型 + if (!userBase.getUser_is_admin().equals(CommonConstant.USER_TYPE_MCH)) { + log.warn("该账号不是商家账号,用户ID:{},用户类型:{}", userId, userBase.getUser_is_admin()); + return Pair.of(false, "该账号不是商家账号,无法进行更换"); + } + + // 检查目标手机号是否已被其他商家账号使用 + AccountUserBase existingNewUser = getByAccountAndType(formattedNewMobile, CommonConstant.USER_TYPE_MCH); + if (existingNewUser != null && !existingNewUser.getUser_id().equals(userId)) { + log.warn("目标手机号已被其他商家账号使用,手机号:{},用户ID:{}", formattedNewMobile, existingNewUser.getUser_id()); + return Pair.of(false, "该手机号已被其他商家账号使用"); + } + + // 检查新手机号是否已被其他商家绑定 + AccountUserBindConnect newBindConnect = bindConnectService.getBindByBindId(formattedNewMobile, BindCode.MOBILE, CommonConstant.USER_TYPE_MCH); + if (newBindConnect != null && !newBindConnect.getUser_id().equals(userId)) { + log.warn("该新手机号已被其他商家账号绑定,手机号:{},用户ID:{}", formattedNewMobile, newBindConnect.getUser_id()); + return Pair.of(false, "该手机号已被其他商家账号绑定"); + } + + // 更新用户账号为新手机号 + log.debug("开始更新用户账号信息,用户ID:{},新手机号:{}", userId, formattedNewMobile); + userBase.setUser_account(formattedNewMobile); + + // 如果提供了密码,则更新密码 + if (StrUtil.isNotBlank(password)) { + log.debug("需要更新用户密码"); + String user_salt = IdUtil.simpleUUID(); + String encryptedPassword = SecureUtil.md5(user_salt + SecureUtil.md5(password)); + userBase.setUser_password(encryptedPassword); + userBase.setUser_salt(user_salt); + } + + // 更新用户基础信息 + boolean updateUserResult = saveOrUpdate(userBase); + if (!updateUserResult) { + log.error("更新用户账号信息失败,用户ID:{}", userId); + return Pair.of(false, "更新用户账号信息失败"); + } + + // 更新绑定表中的bind_id为新手机号 + log.debug("开始更新绑定信息,原绑定ID:{},新绑定ID:{}", bindConnect.getBind_id(), formattedNewMobile); + bindConnect.setBind_id(formattedNewMobile); + boolean updateBindResult = accountUserBindConnectService.saveOrUpdate(bindConnect); + if (!updateBindResult) { + log.error("更新绑定信息失败,绑定ID:{}", formattedNewMobile); + return Pair.of(false, "更新绑定信息失败"); + } + + log.info("更换商家登录手机号成功,用户ID:{},新手机号:{}", userId, formattedNewMobile); + return Pair.of(true, "更换商家登录手机号成功"); + } catch (Exception e) { + log.error("更改商家登录手机号过程中发生异常,老手机号:{},新手机号:{}", oldMobile, newMobile, e); + return Pair.of(false, "系统异常:" + e.getMessage()); + } + } + + @Override public Map doAppConnectLogin(String bind_name, String code) { String id_prefix = ""; diff --git a/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBindConnectServiceImpl.java b/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBindConnectServiceImpl.java index 30234da5..8c7a8db8 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBindConnectServiceImpl.java +++ b/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBindConnectServiceImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.suisung.mall.account.mapper.AccountUserBindConnectMapper; @@ -19,6 +20,7 @@ import com.suisung.mall.common.modules.account.AccountUserBase; import com.suisung.mall.common.modules.account.AccountUserBindConnect; import com.suisung.mall.common.modules.account.AccountUserInfo; import com.suisung.mall.common.pojo.req.WxUserInfoReq; +import com.suisung.mall.common.utils.CheckUtil; import com.suisung.mall.common.utils.I18nUtil; import com.suisung.mall.common.utils.StringUtils; import com.suisung.mall.common.utils.phone.PhoneNumberUtils; @@ -367,6 +369,65 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(AccountUserBindConnect::getBind_id, convertedMobile) + .eq(AccountUserBindConnect::getBind_type, BindCode.MOBILE) // 1-手机号 + .eq(AccountUserBindConnect::getUser_type, CommonConstant.USER_TYPE_MCH) // 2-入驻商家 + .eq(AccountUserBindConnect::getBind_active, CommonConstant.Enable) + .orderByAsc(AccountUserBindConnect::getBind_time) + .select(AccountUserBindConnect::getUser_id); + + log.debug("执行查询,转换后的手机号: {}, 查询条件: {}", convertedMobile, queryWrapper.getSqlSegment()); + + AccountUserBindConnect accountUserBindConnect = getOne(queryWrapper); + if (accountUserBindConnect == null || CheckUtil.isEmpty(accountUserBindConnect.getUser_id())) { + log.info("未找到手机号绑定的商家记录,手机号: {}", convertedMobile); + return 2; + } + + Integer userId = accountUserBindConnect.getUser_id(); + log.debug("找到用户ID: {}", userId); + + AccountUserBase accountUserBase = accountUserBaseService.get(userId); + if (accountUserBase == null) { + log.warn("用户基础信息不存在,用户ID: {}", userId); + return 2; + } + + log.info("商家存在,用户ID: {}", userId); + return 1; + + } catch (Exception e) { + log.error("查询商家绑定信息时发生异常,手机号: {}", mobile, e); + return null; + } + } + + /** * 用户绑定手机号和openid * @@ -505,24 +566,24 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl getAllBindPage(String bindTmpl,Integer pageNum, Integer pageSize) { + public List getAllBindPage(String bindTmpl, Integer pageNum, Integer pageSize) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.select("bind_id,bind_type,user_id,user_type"); - queryWrapper.in("bind_type", Arrays.asList(BindCode.MOBILE,BindCode.WEIXIN_XCX)) + queryWrapper.in("bind_type", Arrays.asList(BindCode.MOBILE, BindCode.WEIXIN_XCX)) .eq("user_type", CommonConstant.USER_TYPE_NORMAL) .eq("bind_active", CommonConstant.Enable) - .eq("bind_tmpl",bindTmpl) + .eq("bind_tmpl", bindTmpl) .orderByAsc("bind_time"); - return this.lists(queryWrapper,pageNum,pageSize).getRecords(); + return this.lists(queryWrapper, pageNum, pageSize).getRecords(); } @Override public long getAllBindCount(String bindTmpl) { QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.in("bind_type", Arrays.asList(BindCode.MOBILE,BindCode.WEIXIN_XCX)) + queryWrapper.in("bind_type", Arrays.asList(BindCode.MOBILE, BindCode.WEIXIN_XCX)) .eq("user_type", CommonConstant.USER_TYPE_NORMAL) .eq("bind_active", CommonConstant.Enable) - .eq("bind_tmpl",bindTmpl) + .eq("bind_tmpl", bindTmpl) .orderByAsc("bind_time"); return this.count(queryWrapper); } @@ -537,42 +598,42 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("bind_openid",openId) + queryWrapper.eq("bind_openid", openId) .eq("user_type", CommonConstant.USER_TYPE_NORMAL) - .in("bind_type",Arrays.asList(1,15)) + .in("bind_type", Arrays.asList(1, 15)) .eq("bind_active", CommonConstant.Enable); - List accountUserBindConnectList= list(queryWrapper); + List accountUserBindConnectList = list(queryWrapper); if (!accountUserBindConnectList.isEmpty()) { - AccountUserBindConnect accountUserBindConnect=accountUserBindConnectList.get(0); - JSONArray jsonArray=null; - JSONObject object= null; + AccountUserBindConnect accountUserBindConnect = accountUserBindConnectList.get(0); + JSONArray jsonArray = null; + JSONObject object = null; try { - jsonArray= jsonObject.getJSONArray("List"); - }catch (RuntimeException runtimeException){ + jsonArray = jsonObject.getJSONArray("List"); + } catch (RuntimeException runtimeException) { log.info("单个模板"); - object=jsonObject.getJSONObject("List"); + object = jsonObject.getJSONObject("List"); } UpdateWrapper updateWrapper = new UpdateWrapper<>(); if (jsonArray != null) { - object= (JSONObject) jsonArray.get(0); - String templateId= object.getStr("TemplateId");//模板id - String SubscribeStatusString= object.getStr("SubscribeStatusString");//订阅结果(accept接收;reject拒收)参考地址https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html#%E8%AE%A2%E9%98%85%E6%B6%88%E6%81%AF%E8%AF%AD%E9%9F%B3%E6%8F%90%E9%86%92 - if(SubscribeStatusString.equals("accept")){ + object = (JSONObject) jsonArray.get(0); + String templateId = object.getStr("TemplateId");//模板id + String SubscribeStatusString = object.getStr("SubscribeStatusString");//订阅结果(accept接收;reject拒收)参考地址https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html#%E8%AE%A2%E9%98%85%E6%B6%88%E6%81%AF%E8%AF%AD%E9%9F%B3%E6%8F%90%E9%86%92 + if (SubscribeStatusString.equals("accept")) { accountUserBindConnect.setBind_tmpl(templateId); getUpdateWrapper(updateWrapper, accountUserBindConnect); } - }else { + } else { assert object != null; - String templateId= object.getStr("TemplateId");//模板id - String SubscribeStatusString= object.getStr("SubscribeStatusString"); - if(StringUtils.isNotEmpty(SubscribeStatusString)&&SubscribeStatusString.equals("accept")){ + String templateId = object.getStr("TemplateId");//模板id + String SubscribeStatusString = object.getStr("SubscribeStatusString"); + if (StringUtils.isNotEmpty(SubscribeStatusString) && SubscribeStatusString.equals("accept")) { accountUserBindConnect.setBind_tmpl(templateId); getUpdateWrapper(updateWrapper, accountUserBindConnect); - }else { - String ErrorStatus=object.getStr("ErrorStatus"); - if(ErrorStatus.equals("success")){ + } else { + String ErrorStatus = object.getStr("ErrorStatus"); + if (ErrorStatus.equals("success")) { log.info("消息推送成功给用户,不需要操作"); return; } @@ -584,16 +645,17 @@ public class AccountUserBindConnectServiceImpl extends BaseServiceImpl updateWrapper, AccountUserBindConnect accountUserBindConnect) { - updateWrapper.set("bind_tmpl",accountUserBindConnect.getBind_tmpl()); - updateWrapper.eq("bind_id",accountUserBindConnect.getBind_id()); - updateWrapper.eq("bind_type",accountUserBindConnect.getBind_type()); - updateWrapper.eq("user_id",accountUserBindConnect.getUser_id()); - updateWrapper.eq("user_type",accountUserBindConnect.getUser_type()); + updateWrapper.set("bind_tmpl", accountUserBindConnect.getBind_tmpl()); + updateWrapper.eq("bind_id", accountUserBindConnect.getBind_id()); + updateWrapper.eq("bind_type", accountUserBindConnect.getBind_type()); + updateWrapper.eq("user_id", accountUserBindConnect.getUser_id()); + updateWrapper.eq("user_type", accountUserBindConnect.getUser_type()); } } diff --git a/mall-common/src/main/java/com/suisung/mall/common/constant/RedisConstant.java b/mall-common/src/main/java/com/suisung/mall/common/constant/RedisConstant.java index 37d51763..fab18fd7 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/constant/RedisConstant.java +++ b/mall-common/src/main/java/com/suisung/mall/common/constant/RedisConstant.java @@ -44,4 +44,9 @@ public class RedisConstant { // 预约订单任务新增键 public static final String Order_Booking_Task_Key = ConstantRedis.Cache_NameSpace + "new:order:booking:task:"; + public static final String VERIFY_CODE_KEY = "register:verifyCode:"; + + // 拉卡拉合同是否强制签署 + public static final String LKL_EC_REPEAT_SIGN = "lkl:ec:repeat:sign:"; + } diff --git a/mall-common/src/main/java/com/suisung/mall/common/feignService/AccountService.java b/mall-common/src/main/java/com/suisung/mall/common/feignService/AccountService.java index 9301e019..9887821f 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/feignService/AccountService.java +++ b/mall-common/src/main/java/com/suisung/mall/common/feignService/AccountService.java @@ -7,6 +7,7 @@ import com.suisung.mall.common.pojo.output.TimelineOutput; import com.suisung.mall.common.pojo.res.ThirdApiRes; import io.swagger.annotations.ApiOperation; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.data.util.Pair; import org.springframework.web.bind.annotation.*; import java.math.BigDecimal; @@ -312,4 +313,28 @@ public interface AccountService { @GetMapping(value = "/admin/account/accountController/getAllBindCount") long getAllBindCount(@RequestParam(name = "bindTmpl") String bindTmpl); + + + /** + * 检查手机注册的商家是否存在(仅供内部调用) + * + * @param mobile + * @return + */ + @RequestMapping(value = "/admin/account/account-user-bind-connect/is-merchant-exists", method = RequestMethod.POST) + Integer isMerchantExists(@RequestParam(name = "mobile") String mobile); + + /** + * 服务间注册商家账号,项目之间远程调用 + */ + @RequestMapping(value = "/admin/account/account-user-base/merchant/inner-register", method = RequestMethod.POST) + Pair merchantInnerRegister(@RequestParam("mobile") String mobile, @RequestParam("regPwd") String regPwd); + + /** + * 服务间注册商家账号,项目之间远程调用 + */ + @RequestMapping(value = "/admin/account/account-user-base/merchant/inner-register", method = RequestMethod.POST) + Pair changeMerchantLoginMobile(@RequestParam("oldMobile") String oldMobile, @RequestParam("newMobile") String newMobile, @RequestParam("password") String password); + + } diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopMchEntry.java b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopMchEntry.java index bc774c98..30a8edd3 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopMchEntry.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopMchEntry.java @@ -96,6 +96,9 @@ public class ShopMchEntry implements Serializable { @ApiModelProperty(value = "入驻商家店铺门面环境图片的存储路径", required = true) private String environment_image; + @ApiModelProperty(value = "收银台照片", required = true) + private String checkstand_image; + @ApiModelProperty(value = "入驻主体类型,企业或个人:1-企业;2-个人;", required = true) private Integer entity_type; @@ -183,6 +186,9 @@ public class ShopMchEntry implements Serializable { @ApiModelProperty(value = "结算账户⾏号", required = true) private String openning_bank_code; + @ApiModelProperty(value = "开户许可证(银行对公开户证明)") + private String opening_permit_image; + @ApiModelProperty(value = "结算账户清算⾏号") private String clearing_bank_code; @@ -258,6 +264,9 @@ public class ShopMchEntry implements Serializable { @ApiModelProperty(value = "是否绑定分账接收方:1-是;2-否;") private Integer has_bind_receiver; + @ApiModelProperty(value = "父入驻id(总店入驻id)") + private Long parent_id; + @ApiModelProperty(value = "该商家入驻记录是否有效,0:无效,1:有效") private Integer status; diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopMchEntryBranch.java b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopMchEntryBranch.java new file mode 100644 index 00000000..eedb62a8 --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopMchEntryBranch.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.common.modules.store; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("shop_mch_entry_branch") +@ApiModel(value = "shop_mch_entry_branch 实体", description = "商家分店拉卡拉商户申请数据") +public class ShopMchEntryBranch implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "自增ID") + @TableId(value = "id", type = IdType.INPUT) + private Long id; + + @ApiModelProperty(value = "拉卡拉外部(银联)商户号", required = true) + private String lkl_mer_cup_no; + + @ApiModelProperty(value = "拉卡拉终端号") + private String lkl_term_no; + + @ApiModelProperty(value = "审核关联号", required = true) + private String review_related_id; + + @ApiModelProperty(value = "请求拉卡拉参数") + private String lkl_req; + + @ApiModelProperty(value = "拉卡拉响应数据") + private String lkl_reps; + + @ApiModelProperty(value = "拉卡拉通知响应数据") + private String lkl_notify_reps; + + @ApiModelProperty(value = "该商家入驻记录是否有效,0:无效,1:有效") + private Integer status; + + @ApiModelProperty(value = "商家入驻记录的创建时间") + private Date created_at; + + @ApiModelProperty(value = "商家入驻记录的更新时间") + private Date updated_at; +} diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreBase.java b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreBase.java index b6b4d9ba..c0b38f3d 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreBase.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreBase.java @@ -141,6 +141,9 @@ public class ShopStoreBase implements Serializable { @ApiModelProperty(value = "店铺统一的打包费, 0-10元范围") private BigDecimal packing_fee; + @ApiModelProperty(value = "分店所属总店 Id,一般分店有值,总店为0") + private Integer parent_id; + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @ApiModelProperty(value = "新增时间") diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreInfo.java b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreInfo.java index 4d9136e1..fafa733b 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreInfo.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreInfo.java @@ -126,6 +126,9 @@ public class ShopStoreInfo implements Serializable { @ApiModelProperty(value = "店铺内部运费,单位(分)0-使用平台的内部运费;>0 使用店铺的内部运费") private Integer shopping_fee_inner; + @ApiModelProperty(value = "是否自配送:1-是;2-否;") + private Integer is_delivery_self; + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @ApiModelProperty(value = "新增时间") diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreSameCityTransportBase.java b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreSameCityTransportBase.java index 8204ee6e..6df4c0ac 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreSameCityTransportBase.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/store/ShopStoreSameCityTransportBase.java @@ -52,6 +52,9 @@ public class ShopStoreSameCityTransportBase implements Serializable { @ApiModelProperty(value = "顺丰同城(第三方)店铺ID") private String shop_id; + @ApiModelProperty(value = "顺丰平台商家Id (用于县级代理商创建店铺的)") + private String supplier_id; + @ApiModelProperty(value = "店铺主营商品分类ID") private Integer business_type; diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/MainStoreBranchReqDTO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/MainStoreBranchReqDTO.java new file mode 100644 index 00000000..61e890a2 --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/MainStoreBranchReqDTO.java @@ -0,0 +1,72 @@ +package com.suisung.mall.common.pojo.dto; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 新增主店的分店的请求DTO实体类 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "新增主店的分店的请求DTO实体类", description = "新增主店的分店的请求DTO实体类") +public class MainStoreBranchReqDTO implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + /** + * 主店店铺 ID + */ + private Integer parent_store_id; + + /** + * 登录手机号 + */ + private String login_mobile; + + /** + * 登录密码 + */ + private String password; + + /** + * 分店名称 + */ + private String store_name; + + /** + * 分店联系人 + */ + private String contact_name; + + /** + * 分店联系人手机号 + */ + private String email; + + /** + * 门头图片 + */ + private String front_facade_image; + + /** + * 环境图片 + */ + private String environment_image; + + /** + * 分店地址 + */ + private String store_address; + + /** + * 分店经度 + */ + private String store_longitude; + + /** + * 分店纬度 + */ + private String store_latitude; + + +} diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/RestTemplateHttpUtil.java b/mall-common/src/main/java/com/suisung/mall/common/utils/RestTemplateHttpUtil.java index de99feb6..e3539972 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/RestTemplateHttpUtil.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/RestTemplateHttpUtil.java @@ -11,6 +11,7 @@ package com.suisung.mall.common.utils; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; +import com.suisung.mall.common.exception.ApiException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.*; @@ -250,6 +251,44 @@ public class RestTemplateHttpUtil { } } + /** + * 发送拉卡拉的POST请求并处理异常,原样返回 + * + * @param url 请求URL + * @param headers 请求头 + * @param requestBody 请求体 + * @param responseType 响应类型 + * @param 泛型类型 + * @return ResponseEntity + */ + public static JSONObject sendLklPostSrc(String url, JSONObject headers, JSONObject requestBody, Class responseType) { + // 使用 APPLICATION_JSON 作为默认 content-type + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + + // 安全添加 headers + if (headers != null) { + headers.forEach((key, value) -> { + if (value != null) { + httpHeaders.add(key, value.toString()); + } + }); + } + + HttpEntity entity = new HttpEntity<>(requestBody, httpHeaders); + + try { + ResponseEntity response = restTemplate.postForEntity(url, entity, responseType); + Object body = response.getBody(); + return (body instanceof JSONObject) ? (JSONObject) body : JSONUtil.parseObj(body); + } catch (Exception e) { + log.error("Unexpected error occurred while calling LKL API: {}", e.getMessage(), e); + new ApiException("Unexpected error occurred while calling LKL API"); + } + return null; + } + + /** * 在JSONObject中查找第一个非空值 * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityGroupbookingServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityGroupbookingServiceImpl.java index e910890b..c9fc354e 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityGroupbookingServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/activity/service/impl/ShopActivityGroupbookingServiceImpl.java @@ -57,9 +57,11 @@ import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser; @Service public class ShopActivityGroupbookingServiceImpl extends BaseServiceImpl implements ShopActivityGroupbookingService { + @Lazy @Autowired private ShopActivityGroupbookingHistoryService shopActivityGroupbookingHistoryService; + @Lazy @Autowired private ShopActivityGroupbookingService shopActivityGroupbookingService; @@ -67,9 +69,11 @@ public class ShopActivityGroupbookingServiceImpl extends BaseServiceImpl configMap; public static Long version = 0L; + + @Lazy @Autowired private AccountService accountService; diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java index 984bf952..39ddd481 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java @@ -14,6 +14,7 @@ import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.service.impl.BaseControllerImpl; import com.suisung.mall.shop.lakala.service.LakalaApiService; import com.suisung.mall.shop.lakala.service.LklLedgerEcService; +import com.suisung.mall.shop.lakala.service.impl.LklTkServiceImpl; import com.suisung.mall.shop.library.service.LibraryProductService; import com.suisung.mall.shop.message.service.MqMessageService; import com.suisung.mall.shop.message.service.PushMessageService; @@ -80,9 +81,13 @@ public class LakalaController extends BaseControllerImpl { @Resource private ShopStorePrinterService shopStorePrinterService; + @Lazy @Resource private LklLedgerEcService lklLedgerEcService; + @Resource + private LklTkServiceImpl lklTkService; + @ApiOperation(value = "测试案例", notes = "测试案例") @RequestMapping(value = "/testcase", method = RequestMethod.POST) @@ -94,7 +99,8 @@ public class LakalaController extends BaseControllerImpl { // return lakalaApiService.tradeQuery(paramsJSON.getInt("storeId"), paramsJSON.getStr("orderId")); - return shopStorePrinterService.printShopStoreReturnOrder(paramsJSON.getStr("returnId")); + return lklTkService.openMerchantAddTerm("8226330541100J8"); + } @ApiOperation(value = "批量发送推送消息 - 测试案例", notes = "批量发送推送消息 - 测试案例") diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LklTkController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LklTkController.java index dd4f758e..5741f833 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LklTkController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LklTkController.java @@ -100,7 +100,7 @@ public class LklTkController extends BaseControllerImpl { return CommonResult.failed(resp.getSecond()); } - // https://mall.gpxscs.cn/api/mobile/shop/lakala/ledger/applyLedgerMerReceiverBindNotify + // https://mall.gpxscs.cn/api/mobile/shop/lakala/tk/registrationMerchantNotify @ApiOperation(value = "拉卡拉进件申请异步回调通知", notes = "拉卡拉进件申请异步回调通知") @RequestMapping(value = "/registrationMerchantNotify", method = {RequestMethod.POST}) public ResponseEntity registrationMerchantNotify(HttpServletRequest request) { @@ -112,6 +112,18 @@ public class LklTkController extends BaseControllerImpl { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp); } + // https://mall.gpxscs.cn/api/mobile/shop/lakala/tk/updateMerchantNotify + @ApiOperation(value = "商户改件异步回调通知", notes = "商户改件异步回调通知") + @RequestMapping(value = "/updateMerchantNotify", method = {RequestMethod.POST}) + public ResponseEntity updateMerchantNotify(HttpServletRequest request) { + JSONObject resp = lklTkService.updateMerchantNotify(request); + if (resp != null && resp.get("code").equals("200")) { + return ResponseEntity.ok(resp); + } + + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp); + } + @ApiOperation(value = "上传文件", notes = "上传文件") @RequestMapping(value = "/uploadOcrImg", method = RequestMethod.POST) public CommonResult uploadOcrImg(@RequestParam(name = "upfile") MultipartFile file, diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerEcService.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerEcService.java index b6b3954c..03452138 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerEcService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerEcService.java @@ -9,6 +9,7 @@ package com.suisung.mall.shop.lakala.service; import com.suisung.mall.common.modules.lakala.LklLedgerEc; +import com.suisung.mall.common.modules.store.ShopMchEntry; import com.suisung.mall.core.web.service.IBaseService; public interface LklLedgerEcService extends IBaseService { @@ -58,4 +59,13 @@ public interface LklLedgerEcService extends IBaseService { */ String getLklEcResultUrl(Long mchId); + /** + * 是否已签署拉卡拉商户合同 + * + * @param lklLedgerEc + * @param shopMchEntry + * @return + */ + Boolean isSignedLklEc(LklLedgerEc lklLedgerEc, ShopMchEntry shopMchEntry); + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java index bafd6aef..a2088b47 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java @@ -25,7 +25,9 @@ import com.lkl.laop.sdk.request.model.V3LabsTradeLocationInfo; import com.lkl.laop.sdk.request.model.V3SacsSeparateRecvDatas; import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.constant.CommonConstant; +import com.suisung.mall.common.constant.RedisConstant; import com.suisung.mall.common.exception.ApiException; +import com.suisung.mall.common.feignService.AccountService; import com.suisung.mall.common.feignService.ShopService; import com.suisung.mall.common.modules.esign.EsignPlatformInfo; import com.suisung.mall.common.modules.lakala.*; @@ -36,6 +38,7 @@ import com.suisung.mall.common.pojo.dto.LklSeparateWithTotalAmountDTO; import com.suisung.mall.common.service.impl.CommonService; import com.suisung.mall.common.utils.*; import com.suisung.mall.core.web.service.RedisService; +import com.suisung.mall.shop.base.service.impl.AccountBaseConfigServiceImpl; import com.suisung.mall.shop.esign.service.EsignPlatformInfoService; import com.suisung.mall.shop.lakala.service.*; import com.suisung.mall.shop.lakala.utils.LakalaUtil; @@ -48,6 +51,7 @@ import com.suisung.mall.shop.store.service.ShopMchEntryService; import com.suisung.mall.shop.store.service.ShopStoreBaseService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.time.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.data.util.Pair; @@ -175,6 +179,10 @@ public class LakalaApiServiceImpl implements LakalaApiService { @Lazy @Resource private OssService ossService; + @Autowired + private AccountService accountService; + @Autowired + private AccountBaseConfigServiceImpl accountBaseConfigService; /** @@ -419,14 +427,35 @@ public class LakalaApiServiceImpl implements LakalaApiService { return Pair.of(false, "缺少商家相关入驻信息!"); } + // 3. 检查是否已存在已完成的电子合同 + LklLedgerEc lklLedgerEc = lklLedgerEcService.getByMchId(mchId, "", CommonConstant.Enable); + + // 如果配置不允许重复签署拉卡拉电子合同,则检查是否已签署拉卡拉电子合同,已签署直接跳过签署合同 + if (ObjectUtil.notEqual("1", accountBaseConfigService.getConfig(RedisConstant.LKL_EC_REPEAT_SIGN))) { + if (lklLedgerEcService.isSignedLklEc(lklLedgerEc, shopMchEntry)) { + log.info("商户:{} 已签署拉卡拉电子合同,直接进行进件处理!", mchId); + + // 13. 触发拉卡拉商家进件流程 + log.info("开始触发拉卡拉商家进件流程,mchId: {}", mchId); + Pair resultPair = lklTkService.registrationMerchant(mchId); + if (!resultPair.getFirst()) { + String errMsg = resultPair.getSecond(); + log.error("拉卡拉商家进件失败: {},mchId: {}", errMsg, mchId); + shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg); + throw new ApiException(errMsg); + } + + return Pair.of(true, "已签署合同,等待进件中!"); + } + } + + String contractMobile = shopMchEntry.getLegal_person_mobile(); if (StrUtil.isBlank(contractMobile)) { log.warn("商家申请入网电子合同失败:联系人手机号为空,入驻编号: {}", mchId); return Pair.of(false, "联系人手机号不能为空!"); } - // 3. 检查是否已存在已完成的电子合同 - LklLedgerEc lklLedgerEc = lklLedgerEcService.getByMchId(shopMchEntry.getId(), "", CommonConstant.Enable); if (lklLedgerEc != null && "COMPLETED".equals(lklLedgerEc.getEc_status())) { log.info("商户:{} 电子合同已签署过,重新提交将被覆盖!", mchId); } @@ -1061,6 +1090,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { updRecord.setEc_file(ecCosFileUrl); // 合同本地文件COS URL链接 updRecord.setLkl_file_path(eclklFilePath); updRecord.setEc_status(paramsJSON.getStr("ecStatus")); + updRecord.setResp_notify_body(paramsJSON.toString()); Boolean success = lklLedgerEcService.updateByApplyId(updRecord); if (!success) { diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerEcServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerEcServiceImpl.java index 8c251d88..d71080ec 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerEcServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerEcServiceImpl.java @@ -13,6 +13,7 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.suisung.mall.common.constant.CommonConstant; import com.suisung.mall.common.modules.lakala.LklLedgerEc; +import com.suisung.mall.common.modules.store.ShopMchEntry; import com.suisung.mall.common.utils.CheckUtil; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.lakala.mapper.LklLedgerEcMapper; @@ -150,4 +151,31 @@ public class LklLedgerEcServiceImpl extends BaseServiceImpl areaCode = getAreaCode(shopMchEntry.getStore_area(), false); if (ObjectUtil.isNotEmpty(areaCode)) { - reqJsonBody.put("provinceCode", areaCode.get("provinceCode")); - reqJsonBody.put("cityCode", areaCode.get("cityCode")); - reqJsonBody.put("countyCode", areaCode.get("countyCode")); + reqJsonBody.set("provinceCode", areaCode.get("provinceCode")); + reqJsonBody.set("cityCode", areaCode.get("cityCode")); + reqJsonBody.set("countyCode", areaCode.get("countyCode")); } //银行结算信息省市信息 @@ -503,54 +515,55 @@ public class LklTkServiceImpl { String[] bankAreaCodes = shopMchEntry.getBank_district().split("/"); String[] bankAreaNames = shopMchEntry.getBank_area().split("/"); if (bankAreaCodes.length >= 2 && bankAreaNames.length >= 2) { - reqJsonBody.put("settleProvinceCode", bankAreaCodes[0]); - reqJsonBody.put("settleProvinceName", bankAreaCodes[1]); - reqJsonBody.put("settleCityCode", bankAreaNames[0]); - reqJsonBody.put("settleCityName", bankAreaNames[1]); + reqJsonBody.set("settleProvinceCode", bankAreaCodes[0]); + reqJsonBody.set("settleProvinceName", bankAreaCodes[1]); + reqJsonBody.set("settleCityCode", bankAreaNames[0]); + reqJsonBody.set("settleCityName", bankAreaNames[1]); } } else { Map bankAreaCode = getAreaCode(shopMchEntry.getBank_area(), true); if (ObjectUtil.isNotEmpty(bankAreaCode)) { - reqJsonBody.put("settleProvinceCode", bankAreaCode.get("provinceCode")); - reqJsonBody.put("settleCityCode", bankAreaCode.get("cityCode")); + reqJsonBody.set("settleProvinceCode", bankAreaCode.get("provinceCode")); + reqJsonBody.set("settleCityCode", bankAreaCode.get("cityCode")); String[] bankAreaName = shopMchEntry.getBank_area().split("/"); if (bankAreaName.length >= 2) { - reqJsonBody.put("settleProvinceName", bankAreaName[0]); - reqJsonBody.put("settleCityName", bankAreaName[1]); + reqJsonBody.set("settleProvinceName", bankAreaName[0]); + reqJsonBody.set("settleCityName", bankAreaName[1]); } } } // 费率和设备、活动 JSONObject bizContent = new JSONObject(); - bizContent.put("activityId", activityId); - bizContent.put("termNum", "1"); - bizContent.put("mcc", "12015"); // 超市的 MCC code - bizContent.put("fees", new JSONArray() {{ + bizContent.set("activityId", activityId); + bizContent.set("termNum", "1"); + bizContent.set("mcc", "12015"); // 超市的 MCC code + bizContent.set("fees", new JSONArray() {{ put(new JSONObject() { { - put("feeCode", "WECHAT"); - put("feeValue", wxFee); + set("feeCode", "WECHAT"); + set("feeValue", wxFee); } }); }}); - reqJsonBody.put("bizContent", bizContent); + reqJsonBody.set("bizContent", bizContent); // 附件文件相关开始 logger.debug("开始处理商户附件文件,商户ID: {}", mchId); JSONArray attachments = new JSONArray(); if (Boolean.TRUE.equals(isQy)) { - JSONObject SETTLE_ID_CARD_FRONT = updatePhoto(shopMchEntry.getLegal_person_id_images(), "FR_ID_CARD_FRONT", false); + // 企业 + JSONObject SETTLE_ID_CARD_FRONT = updatePhoto(shopMchEntry.getLegal_person_id_images(), "ID_CARD_FRONT", false); if (SETTLE_ID_CARD_FRONT != null) { - attachments.put(SETTLE_ID_CARD_FRONT); // 法人身份证正面 + attachments.set(SETTLE_ID_CARD_FRONT); // 法人身份证正面 logger.debug("成功添加法人身份证正面图片"); } else { logger.warn("法人身份证正面图片添加失败"); } - JSONObject SETTLE_ID_CARD_BEHIND = updatePhoto(shopMchEntry.getLegal_person_id_images2(), "FR_ID_CARD_BEHIND", false); + JSONObject SETTLE_ID_CARD_BEHIND = updatePhoto(shopMchEntry.getLegal_person_id_images2(), "ID_CARD_BEHIND", false); if (SETTLE_ID_CARD_BEHIND != null) { - attachments.put(SETTLE_ID_CARD_BEHIND); // 法人身份证国徽面 + attachments.set(SETTLE_ID_CARD_BEHIND); // 法人身份证国徽面 logger.debug("成功添加法人身份证国徽面图片"); } else { logger.warn("法人身份证国徽面图片添加失败"); @@ -558,16 +571,26 @@ public class LklTkServiceImpl { JSONObject BUSINESS_LICENCE = updatePhoto(shopMchEntry.getBiz_license_image(), "BUSINESS_LICENCE", false); if (BUSINESS_LICENCE != null) { - attachments.put(BUSINESS_LICENCE); // 营业执照 + attachments.set(BUSINESS_LICENCE); // 营业执照 logger.debug("成功添加营业执照图片"); } else { logger.warn("营业执照图片添加失败"); } + // 银行对公开户正面 + JSONObject OPENING_PERMIT = updatePhoto(shopMchEntry.getOpening_permit_image(), "OPENING_PERMIT", false); + if (OPENING_PERMIT != null) { + attachments.set(OPENING_PERMIT); // 营业执照 + logger.debug("成功添加开户许可证证明图片"); + } else { + logger.warn("成功添加开户许可证证明图片添加失败"); + } + } else { + // 小微个人 JSONObject ID_CARD_FRONT = updatePhoto(shopMchEntry.getIndividual_id_images(), "ID_CARD_FRONT", false); if (ID_CARD_FRONT != null) { - attachments.put(ID_CARD_FRONT); // 身份证正面 + attachments.set(ID_CARD_FRONT); // 身份证正面 logger.debug("成功添加身份证正面图片"); } else { logger.warn("身份证正面图片添加失败"); @@ -575,16 +598,25 @@ public class LklTkServiceImpl { JSONObject ID_CARD_BEHIND = updatePhoto(shopMchEntry.getIndividual_id_images2(), "ID_CARD_BEHIND", false); if (ID_CARD_BEHIND != null) { - attachments.put(ID_CARD_BEHIND); // 身份证国徽面 + attachments.set(ID_CARD_BEHIND); // 身份证国徽面 logger.debug("成功添加身份证国徽面图片"); } else { logger.warn("身份证国徽面图片添加失败"); } + + // 对私必传银行卡 + JSONObject BANK_CARD = updatePhoto(shopMchEntry.getBank_image(), "BANK_CARD", false); + if (BANK_CARD != null) { + attachments.set(BANK_CARD); // 银行卡图片 + logger.debug("成功添加银行卡图片"); + } else { + logger.warn("银行卡图片添加失败"); + } } JSONObject SHOP_OUTSIDE_IMG = updatePhoto(shopMchEntry.getFront_facade_image(), "SHOP_OUTSIDE_IMG", false); if (SHOP_OUTSIDE_IMG != null) { - attachments.put(SHOP_OUTSIDE_IMG); // 门店门面图片 + attachments.set(SHOP_OUTSIDE_IMG); // 门店门面图片 logger.debug("成功添加门店门面图片"); } else { logger.warn("门店门面图片添加失败"); @@ -592,20 +624,22 @@ public class LklTkServiceImpl { JSONObject SHOP_INSIDE_IMG = updatePhoto(shopMchEntry.getEnvironment_image(), "SHOP_INSIDE_IMG", false); if (SHOP_INSIDE_IMG != null) { - attachments.put(SHOP_INSIDE_IMG); // 门店内部图片 + attachments.set(SHOP_INSIDE_IMG); // 门店内部图片 logger.debug("成功添加门店内部图片"); } else { logger.warn("门店内部图片添加失败"); } - JSONObject BANK_CARD = updatePhoto(shopMchEntry.getBank_image(), "BANK_CARD", false); - if (BANK_CARD != null) { - attachments.put(BANK_CARD); // 银行卡图片 - logger.debug("成功添加银行卡图片"); + // 收银台图片 + JSONObject CHECKSTAND_IMG = updatePhoto(shopMchEntry.getCheckstand_image(), "CHECKSTAND_IMG", false); + if (CHECKSTAND_IMG != null) { + attachments.set(CHECKSTAND_IMG); // 收银台图片 + logger.debug("成功添加收银台图片"); } else { - logger.warn("银行卡图片添加失败"); + logger.warn("收银台图片添加失败"); } - reqJsonBody.put("attchments", attachments); + + reqJsonBody.set("attchments", attachments); logger.debug("商户附件文件处理完成,共添加 {} 个附件", attachments.size()); // 附件文件相关结束 @@ -726,7 +760,7 @@ public class LklTkServiceImpl { ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerInnerNo(merInnerNo); if (shopMchEntry == null) { logger.error("拉卡拉进件异步通知:{}内部商户号入驻信息不存在!", merInnerNo); - return new JSONObject().put("code", "500").put("message", merInnerNo + "内部商户号入驻信息不存在"); + return new JSONObject().set("code", "500").set("message", merInnerNo + "内部商户号入驻信息不存在"); } Long mchId = shopMchEntry.getId(); @@ -774,6 +808,310 @@ public class LklTkServiceImpl { } } + /** + * 商户改件异步回调通知 + * + * @param request + * @return + */ + public JSONObject updateMerchantNotify(HttpServletRequest request) { + try { + // 解密请求参数 + String requestBody = LakalaUtil.getBody(request); + logger.info("拉卡拉商户增终异步通知 - 接收原始数据: {}", requestBody); + + if (StrUtil.isBlank(requestBody)) { + logger.warn("拉卡拉商户增终异步通知 - 请求参数为空"); + return new JSONObject().set("code", "400").set("message", "返回参数为空"); + } + + JSONObject reqBodyJSON = JSONUtil.parseObj(requestBody); + if (reqBodyJSON.isEmpty() || reqBodyJSON.get("data") == null) { + logger.warn("拉卡拉商户增终异步通知 - 参数格式有误,无法解析: {}", requestBody); + return new JSONObject().set("code", "400").set("message", "参数格式有误,无法解析"); + } + + String srcData = reqBodyJSON.getStr("data"); + if (StrUtil.isBlank(srcData)) { + logger.warn("拉卡拉商户增终异步通知 - 关键参数为空值"); + return new JSONObject().set("code", "400").set("message", "关键参数为空值"); + } + + // 公钥解密出来的数据 + String notifyPubKey = LakalaUtil.getResourceFile(notifyPubKeyPath, false, false); + String lklNotifyResp = LakalaUtil.decryptNotifyData(notifyPubKey, srcData); + if (StrUtil.isBlank(lklNotifyResp)) { + logger.error("拉卡拉商户增终异步通知 - 数据解密失败,加密数据: {}", srcData); + return new JSONObject().set("code", "400").set("message", "数据解密出错!"); + } + logger.info("拉卡拉商户增终异步通知 - 解密后数据: {}", lklNotifyResp); + + // 逻辑处理 + JSONObject dataJSON = JSONUtil.parseObj(lklNotifyResp); + String reviewPass = dataJSON.getStr("reviewPass"); + String merCupNo = dataJSON.getStr("externalCustomerNo"); //拉卡拉外部商户号 + String termNo = dataJSON.getStr("termNo"); //拉卡拉分配的业务终端号 + String reviewRelatedId = dataJSON.getStr("reviewRelatedId"); //拉卡拉分配的业务终端号 + + logger.info("拉卡拉商户增终异步通知 - 解析数据完成 - 审核状态: {}, 外部商户号: {}, 终端号: {}, 审核关联ID: {}", + reviewPass, merCupNo, termNo, reviewRelatedId); + + // 合并参数校验 + if (dataJSON.isEmpty() || + StrUtil.isBlank(reviewPass) || + StrUtil.isBlank(reviewRelatedId) || + StrUtil.isBlank(termNo)) { + logger.warn("拉卡拉商户增终异步通知 - 参数解析出错,解密数据: {}", lklNotifyResp); + return new JSONObject().set("code", "500").set("message", "返回参数缺少关键数据"); + } + + // 更新商户分店入驻表 + // status 状态:1-已成功;2-审核未通过;3-未处理;4-待审核; + Integer status = "PASS".equals(reviewPass) ? CommonConstant.Enable : + "UNPASS".equals(reviewPass) ? CommonConstant.Disable2 : + "PASSING".equals(reviewPass) ? 3 : 4; + logger.info("拉卡拉商户增终异步通知 - 更新分店入驻表,审核关联ID: {}, 状态: {}, 通知响应: {}", reviewRelatedId, status, lklNotifyResp); + shopMchEntryBranchService.updateByReviewRelatedId(reviewRelatedId, status, lklNotifyResp); + + // 给商家总店入驻表增加拉卡拉的商户号和拉卡拉返回的数据 + ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(merCupNo, 0L); + if (shopMchEntry == null) { + logger.error("拉卡拉商户增终异步通知 - 商户号入驻信息不存在: {}", merCupNo); + return new JSONObject().set("code", "500").set("message", merCupNo + "商户号入驻信息不存在"); + } + + // 校验审核状态: PREPARE:待提交; PASS:通过; UNPASS:未通过; PASSING:审核中; + if (!"PASS".equals(reviewPass)) { + logger.info("拉卡拉商户增终异步通知 - 审核未通过,状态: {}, 结果: {}", reviewPass, dataJSON.getStr("reviewResult")); + return new JSONObject().set("code", "500").set("message", "忽略处理,因审核未通过:" + dataJSON.getStr("reviewResult")); + } + + logger.info("拉卡拉商户增终异步通知 - 审核通过,开始创建分店入驻记录,审核关联ID: {}, 终端号: {}", reviewRelatedId, termNo); + // RMK 拉卡拉增终成功, 创建分店入驻记录,创建商家账号、创建店铺和周边信息 + shopMchEntryBranchService.createMchEntryBranchStore(reviewRelatedId, termNo, lklNotifyResp); + + logger.info("拉卡拉商户增终异步通知 - 处理完成,审核关联ID: {}", reviewRelatedId); + return new JSONObject().set("code", "200").set("message", "处理成功"); + + } catch (Exception e) { + logger.error("处理拉卡拉增终异步通知异常", e); + return new JSONObject().set("code", "500").set("message", "处理异常:" + e.getMessage()); + } + } + + + /** + * 向拉卡拉申请增加终端 + * + * @param externalCustomerNo 拉卡拉外部商户号 + * @return 拉卡拉响应数据 + */ + public JSONObject openMerchantAddTerm(String externalCustomerNo) { + logger.debug("开始向拉卡拉申请增加终端,externalCustomerNo={}", externalCustomerNo); + + try { + // 参数校验 + if (StrUtil.isBlank(externalCustomerNo)) { + logger.warn("拉卡拉外部商户号不能为空"); + return null; + } + + // 构造请求参数并加密 + JSONObject requestParams = new JSONObject(); + requestParams.set("externalCustomerNo", externalCustomerNo); + requestParams.set("bzPos", "WECHAT_PAY"); + requestParams.set("termNum", 1); + + Long shopId = getLklShopId(externalCustomerNo, null); + if (shopId == null) { + logger.error("拉卡拉商户ID不存在,externalCustomerNo={}", externalCustomerNo); + return null; + } + + requestParams.set("shopId", shopId); + + JSONObject feeInfoDto = new JSONObject(); + feeInfoDto.set("topFee", Convert.toDouble(wxFee)); + feeInfoDto.set("fee", Convert.toDouble(wxFee)); + feeInfoDto.set("feeType", "WECHAT"); + requestParams.set("fees", feeInfoDto); + + String privateKey = LakalaUtil.getResourceFile(apiPriKeyPath, false, false); + if (StrUtil.isBlank(privateKey)) { + logger.error("获取拉卡拉私钥失败,apiPriKeyPath={}", apiPriKeyPath); + return null; + } + + String encryptedParams = LakalaUtil.encryptByPrivateKey(requestParams.toString(), privateKey); + logger.debug("请求参数加密完成"); + + // 获取认证信息 + String authorization = getLklTkAuthorization(); + if (StrUtil.isBlank(authorization)) { + logger.error("获取拉卡拉token失败"); + return null; + } + + // 构造请求头和请求体 + JSONObject header = new JSONObject().set("Authorization", authorization); + JSONObject requestBody = new JSONObject().set("data", encryptedParams); + + // 发送请求 + String urlPath = "/htkmerchants/open/merchant/addTerm"; + JSONObject response = RestTemplateHttpUtil.sendLklPostSrc( + buildLklTkUrl(urlPath), header, requestBody, JSONObject.class); + + // 检查响应结果 + if (response == null || !"000000".equals(response.getStr("code")) || response.get("data") == null) { + logger.error("向拉卡拉申请增加终端失败,response={}", response); + return null; + } + + // 解密响应数据 + String publicKey = LakalaUtil.getResourceFile(apiPubKeyPath, false, false); + if (StrUtil.isBlank(publicKey)) { + logger.error("向拉卡拉申请增加终端获取公钥失败,apiPubKeyPath={}", apiPubKeyPath); + return null; + } + + String responseData = LakalaUtil.decryptByPublicKey(response.getStr("data"), publicKey); + logger.debug("响应数据解密完成"); + + return JSONUtil.parseObj(responseData); + + } catch (Exception e) { + logger.error("向拉卡拉申请增加终端异常,externalCustomerNo={}", externalCustomerNo, e); + return null; + } + } + + + /** + * 商家进件成功,拉卡拉商户号获取商户信息(需加密) + * + * @param externalCustomerNo 外部商户号(优先使用) + * @param customerNo 内部商户号(备选) + * @return 商户信息JSONObject,获取失败返回null + */ + public JSONObject openMerchantInfo(String externalCustomerNo, String customerNo) { + try { + // 构造请求参数并加密(至少需要一个参数) + JSONObject requestParams = new JSONObject(); + if (StrUtil.isNotBlank(externalCustomerNo)) { + requestParams.set("externalCustomerNo", externalCustomerNo); + } + if (StrUtil.isNotBlank(customerNo)) { + requestParams.set("customerNo", customerNo); + } + + // 检查参数是否有效 + if (requestParams.isEmpty()) { + logger.warn("拉卡拉商户信息查询参数为空"); + return null; + } + + String privateKey = LakalaUtil.getResourceFile(apiPriKeyPath, false, false); + if (StrUtil.isBlank(privateKey)) { + logger.error("获取拉卡拉私钥失败,apiPriKeyPath={}", apiPriKeyPath); + return null; + } + + String encryptedParams = LakalaUtil.encryptByPrivateKey(requestParams.toString(), privateKey); + + // 获取认证信息 + String authorization = getLklTkAuthorization(); + if (StrUtil.isBlank(authorization)) { + logger.error("获取拉卡拉token失败"); + return null; + } + + // 构造请求头和请求体 + String urlPath = buildLklTkUrl("/htkmerchants/open/merchant/info"); + JSONObject header = new JSONObject().set("Authorization", authorization); + JSONObject requestBody = new JSONObject().set("data", encryptedParams); + + // 发送请求 + JSONObject response = RestTemplateHttpUtil.sendLklPostSrc(urlPath, header, requestBody, JSONObject.class); + + // 检查响应结果 + if (response == null || !"000000".equals(response.getStr("code")) || response.get("data") == null) { + logger.warn("拉卡拉商户信息获取失败,response={}", response); + return null; + } + + // 解密响应数据 + String publicKey = LakalaUtil.getResourceFile(apiPubKeyPath, false, false); + if (StrUtil.isBlank(publicKey)) { + logger.error("获取拉卡拉公钥失败,apiPubKeyPath={}", apiPubKeyPath); + return null; + } + + String responseData = LakalaUtil.decryptByPublicKey(response.getStr("data"), publicKey); + + return JSONUtil.parseObj(responseData); + + } catch (Exception e) { + logger.error("获取拉卡拉商户信息异常,externalCustomerNo={}, customerNo={}", externalCustomerNo, customerNo, e); + return null; + } + } + + + /** + * 获取拉卡拉商户的 shopId + * + * @param externalCustomerNo 外部商户号(优先使用) + * @param customerNo 内部商户号(备选) + * @return 拉卡拉商户的shopId,获取失败返回null + */ + public Long getLklShopId(String externalCustomerNo, String customerNo) { + logger.debug("开始获取拉卡拉商户shopId,externalCustomerNo={}, customerNo={}", externalCustomerNo, customerNo); + + try { + JSONObject response = openMerchantInfo(externalCustomerNo, customerNo); + if (response == null) { + logger.warn("获取拉卡拉商户信息失败,externalCustomerNo={}, customerNo={}", externalCustomerNo, customerNo); + return null; + } + + // 检查响应中的code字段是否表示成功 +// if (!"000000".equals(response.getStr("code"))) { +// logger.warn("拉卡拉商户信息获取失败,code={},response={}", response.getStr("code"), response); +// return null; +// } + + logger.info("拉卡拉商户信息:{}", response); + + // 检查shopInfoList是否存在且不为空 + JSONArray shopInfoList = response.getJSONArray("shopInfoList"); + if (CollUtil.isEmpty(shopInfoList)) { + logger.warn("拉卡拉商户信息中shopInfoList为空或不存在,response={}", response); + return null; + } + + // 获取第一个shopInfo中的shopId + JSONObject firstShopInfo = shopInfoList.getJSONObject(0); + if (firstShopInfo == null) { + logger.warn("拉卡拉商户信息中第一个shopInfo为空,shopInfoList={}", shopInfoList); + return null; + } + + Long shopId = firstShopInfo.getLong("shopId"); + if (shopId == null) { + logger.warn("拉卡拉商户信息中shopId为空,firstShopInfo={}", firstShopInfo); + return null; + } + + logger.debug("成功获取拉卡拉商户shopId: {}", shopId); + return shopId; + + } catch (Exception e) { + logger.error("获取拉卡拉商户shopId异常,externalCustomerNo={}, customerNo={}", externalCustomerNo, customerNo, e); + return null; + } + } + + /** * 进件审核通过之后,要下一步流程操作:申请分账业务、创建分账接收方 * @@ -842,7 +1180,7 @@ public class LklTkServiceImpl { } JSONObject header = new JSONObject(); - header.put("Authorization", getLklTkAuthorization()); + header.set("Authorization", getLklTkAuthorization()); String urlPath = "/sit/htkregistration/organization"; if (isLklProd) { @@ -946,10 +1284,10 @@ public class LklTkServiceImpl { // Base64Utils.encodeToString(file.getBytes()); JSONObject requestBody = new JSONObject(); - requestBody.put("fileBase64", fileBase64); - requestBody.put("imgType", imgType); - requestBody.put("sourcechnl", "0"); // 来源: 0:PC,1:安卓,2:IOS - requestBody.put("isOcr", "true"); + requestBody.set("fileBase64", fileBase64); + requestBody.set("imgType", imgType); + requestBody.set("sourcechnl", "0"); // 来源: 0:PC,1:安卓,2:IOS + requestBody.set("isOcr", "true"); String urlPath = "/sit/htkregistration/file/base/upload"; if (isLklProd) { @@ -970,7 +1308,7 @@ public class LklTkServiceImpl { return null; } - return new JSONObject().put("id", result.get("url")).put("type", imgType); + return new JSONObject().set("id", result.get("url")).set("type", imgType); } catch (Exception e) { logger.error("上传文件异常:{}", e.getMessage()); return null; @@ -982,13 +1320,13 @@ public class LklTkServiceImpl { } JSONObject header = new JSONObject(); - header.put("Authorization", getLklTkAuthorization()); + header.set("Authorization", getLklTkAuthorization()); // Base64Utils.encodeToString(file.getBytes()); JSONObject requestBody = new JSONObject(); - requestBody.put("areaCode", areaCode); - requestBody.put("bankName", bankName); + requestBody.set("areaCode", areaCode); + requestBody.set("bankName", bankName); String urlPath = "/sit/registration/bank"; if (isLklProd) { @@ -1009,7 +1347,7 @@ public class LklTkServiceImpl { return null; } - return new JSONObject().put("id", result.get("url")).put("type", ""); + return new JSONObject().set("id", result.get("url")).set("type", ""); } catch (Exception e) { logger.error("上传文件异常:{}", e.getMessage()); return null; diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/utils/LakalaUtil.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/utils/LakalaUtil.java index 26c5c03b..1cd26af0 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/utils/LakalaUtil.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/utils/LakalaUtil.java @@ -44,6 +44,38 @@ import java.util.regex.Pattern; @Slf4j public class LakalaUtil { + public static final String KEY_ALGORITHM = "RSA"; + /** + * RSA最大加密密文大小 + */ + private static final int MAX_ENCRYPT_BLOCK = 117; + + /** + * RSA最大解密密文大小 + */ + private static final int MAX_DECRYPT_BLOCK = 128; + + + public static void main(String[] args) { + try { + String publicK = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp5aV3ZiXG2R8Yd8Nxocv+cF7VAUHBc0TF4MNne7mI8wM2yEP2QgI+rK1qDf6G7ZFPhutpIHKQchpolbSuC0vgaHpSjO9OUs1fpnK/JjZq9o8DatUsA0n4Fccec9NBbV5dy5yrwro7xmDpsevp1/IeiIssi1+iD+nBWqqVFx7GVQIDAQAB"; + String privateK = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKnlpXdmJcbZHxh3w3Ghy/5wXtUBQcFzRMXgw2d7uYjzAzbIQ/ZCAj6srWoN/obtkU+G62kgcpByGmiVtK4LS+BoelKM705SzV+mcr8mNmr2jwNq1SwDSfgVxx5z00FtXl3LnKvCujvGYOmx6+nX8h6IiyyLX6IP6cFaqpUXHsZVAgMBAAECgYA4NpeM7etJ48T6H4Y3LsWEJkH6UDQlgbIblsaQkstMmLtTgOebrzN28UNfd8njcu9FVOrHGclOKbK7L+1cOLiduWsZKc/c/gAy9wAR4EhoLvlerH9EEPiPWFxdEDbMxPqlkpqLOo+PxHrhTn4vU4CaPdJtL2ujKn7nmsUdUDWo8QJBANS1TlM6nhPt2XlzN5kGfsJ4kBYNjuLXNA2YdNuC2ttYvEXHJ9T70FN/GnRBBIZu47uHH3Ie5nfep+qMk6a8RP8CQQDMecIyI0z1kVt+tOfWKw2ZFLsi74708qTaeR4W1ABtkngj1+bxoWWXr3KqhjqJkWxnhioSfXqu7CScNzjdM1CrAkAQd+ESjI1EmbumrYb2cAxMXi05p98SLPs4uj8B58WuCda5yEuLL9vXOxX/PjFtfxRepn2GxmGtki2J+UxNMnJdAkAFoORjlO0tZU7rcfdfwdeh+xwbnhSFUZiQGv1lC3jnizybX/oPdK3jOwUhBIjf+IzPXLYTxDh4UC/BzRNXo235AkEAhgYBk6H7RU2iIuvwz1c6CtE1gJ8DvEp1F0KOMWMFB0KCpDXUToix0dlMz962FozYENi4X4zYQo6nFwlXeS3Pfw=="; + byte[] privateKey = Base64.decodeBase64(privateK); + byte[] publicKey = Base64.decodeBase64(publicK); + + + String aaa = "中文怎么样"; + String bytes = encryptByPrivateKey(aaa, privateK); + + System.out.println(bytes); + String bytes1 = decryptByPublicKey(bytes, publicK); + System.out.println("result:" + bytes1); + + } catch (Exception e) { + e.printStackTrace(); + } + } + /** * 初始化 拉卡拉 SDK(全局只需设置一次) * @@ -496,6 +528,109 @@ public class LakalaUtil { return Pair.of(true, requestBody); } + /** + * 拉卡拉拓客 第三方接口 加密 + * + * @param data 待加密的数据(明文字符串) + * @param priKey Base64编码的私钥字符串 + * @return Base64编码的加密数据 + */ + public static String encryptByPrivateKey(String data, String priKey) { + log.debug("开始使用私钥进行数据加密,数据长度: {}", data.length()); + + try { + // 将Base64编码的私钥转换为字节数组 + byte[] keyBytes = Base64.decodeBase64(priKey); + // 将明文数据转换为字节数组 + byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8); + + PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + + int inputLen = dataBytes.length; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + int offSet = 0; + byte[] cache; + int i = 0; + + // 对数据分段加密 + while (inputLen - offSet > 0) { + if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { + cache = cipher.doFinal(dataBytes, offSet, MAX_ENCRYPT_BLOCK); + } else { + cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet); + } + out.write(cache, 0, cache.length); + i++; + offSet = i * MAX_ENCRYPT_BLOCK; + } + + byte[] encryptedData = out.toByteArray(); + // 将加密后的字节数组转换为Base64编码字符串 + String result = Base64.encodeBase64String(encryptedData); + log.debug("数据加密完成,加密后数据长度: {}", result.length()); + return result; + } catch (Exception e) { + log.error("使用私钥加密数据时发生异常", e); + throw new RuntimeException("私钥加密失败", e); + } + } + + /** + * 拉卡拉拓客 第三方接口 解密 + * + * @param data 待解密的数据(Base64编码的加密字符串) + * @param pubKey Base64编码的公钥字符串 + * @return 解密后的明文数据 + */ + public static String decryptByPublicKey(String data, String pubKey) { + log.debug("开始使用公钥进行数据解密,数据长度: {}", data.length()); + + try { + // 将Base64编码的公钥和数据转换为字节数组 + byte[] keyBytes = Base64.decodeBase64(pubKey); + byte[] dataBytes = Base64.decodeBase64(data); + + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); + + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + + int inputLen = dataBytes.length; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + int offSet = 0; + byte[] cache; + int i = 0; + + // 对数据分段解密 + while (inputLen - offSet > 0) { + if (inputLen - offSet > MAX_DECRYPT_BLOCK) { + cache = cipher.doFinal(dataBytes, offSet, MAX_DECRYPT_BLOCK); + } else { + cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet); + } + out.write(cache, 0, cache.length); + i++; + offSet = i * MAX_DECRYPT_BLOCK; + } + + byte[] decryptedData = out.toByteArray(); + // 将解密后的字节数组转换为明文字符串 + String result = new String(decryptedData, StandardCharsets.UTF_8); + log.debug("数据解密完成,解密后数据长度: {}", result.length()); + return result; + } catch (Exception e) { + log.error("使用公钥解密数据时发生异常", e); + throw new RuntimeException("公钥解密失败", e); + } + } + + /** * 构建拉卡拉接口公共参数 *

diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java index 3f181357..aac722ee 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/listener/OrderPayedListener.java @@ -69,7 +69,7 @@ public class OrderPayedListener { String dataStr = new String(data, StandardCharsets.UTF_8); listener(dataStr, channel, message); } - + public void listener(String data, Channel channel, Message message) throws IOException, InterruptedException { // String messageId = message.getMessageProperties().getMessageId(); if (StrUtil.isBlank(data)) { @@ -154,7 +154,7 @@ public class OrderPayedListener { && !isBookingOrder) { // 如果是立即下单,将触发顺丰同城下单,否则(预约下单) redis+cron 定时触发顺丰同城下单 - Pair pairCreateSfOrder = sfExpressApiService.innerCreateSfExpressOrder(orderId, orderPickupNum); + Pair pairCreateSfOrder = sfExpressApiService.innerCreateSfExpressOrder(orderId, orderPickupNum, false); if (pairCreateSfOrder == null) { logger.error("[订单支付监听] 顺丰同城下单失败,无返回值 订单ID: {}", orderId); continue; diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index c773836e..562a9a26 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -781,7 +781,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl order_ids = Convert.toList(String.class, order_id); @@ -801,10 +800,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl addressQueryWrapper = new QueryWrapper<>(); - addressQueryWrapper.eq("ud_is_default", 1).eq("user_id", buyer_user_id); + addressQueryWrapper.eq("ud_is_default", CommonConstant.Enable).eq("user_id", buyer_user_id); ShopUserDeliveryAddress deliveryAddress = userDeliveryAddressService.findOne(addressQueryWrapper); cart_data.put("address_row", Convert.toMap(String.class, Object.class, deliveryAddress)); } @@ -6594,11 +6599,16 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl sfResult = sfExpressApiService.innerCreateSfExpressOrder(orderId, 0L); + Pair sfResult = sfExpressApiService.innerCreateSfExpressOrder(orderId, 0L, false); if (sfResult == null) { logger.error("[预约订单顺丰下单] 调用顺丰接口无返回值, orderId={}", orderId); throw new RuntimeException("预约订单顺丰下单失败,接口无响应"); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/controller/admin/SFExpressAdminController.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/controller/admin/SFExpressAdminController.java index 1113041e..9c99e91e 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/controller/admin/SFExpressAdminController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/controller/admin/SFExpressAdminController.java @@ -44,7 +44,7 @@ public class SFExpressAdminController { } - @ApiOperation(value = "创建顺丰同城店铺", notes = "创建顺丰同城店铺") + @ApiOperation(value = "【测试补偿】创建顺丰同城店铺", notes = "创建顺丰同城店铺") @RequestMapping(value = "/create-shop-inner", method = RequestMethod.POST) public CommonResult createSfExpressShopNotify(@RequestBody JSONObject requestBody) { Pair result = sfExpressApiService.createSfExpressShopInner( @@ -64,4 +64,12 @@ public class SFExpressAdminController { } return CommonResult.failed(result.getSecond()); } + + @ApiOperation(value = "重新创建顺丰订单(重新派发)", notes = "重新创建顺丰订单(重新派发)") + @RequestMapping(value = "/recreate-order", method = RequestMethod.POST) + public CommonResult recreateOrder(@RequestBody JSONObject requestBody) { + return sfExpressApiService.recreateOrder( + requestBody.getStr("order_id") + ); + } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java index 73f6e8d2..ec0068d6 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java @@ -70,8 +70,23 @@ public interface SFExpressApiService { ThirdApiRes createSfExpressShopNotify(String jsonData, String sign); + /** + * 创建顺丰同城订单 + * + * @param shopOrderId + * @return + */ ThirdApiRes createOrder(String shopOrderId); + + /** + * 重新创建顺丰同城订单 + * + * @param shopOrderId + * @return + */ + CommonResult recreateOrder(String shopOrderId); + /** * 获取顺丰同城店铺信息 * @@ -85,9 +100,10 @@ public interface SFExpressApiService { * * @param orderId * @param orderPickupNum + * @param ignoreExists 是否忽略已存在本地订单 * @return */ - Pair innerCreateSfExpressOrder(String orderId, Long orderPickupNum); + Pair innerCreateSfExpressOrder(String orderId, Long orderPickupNum, Boolean ignoreExists); /** * 取消订单,当商家处发生异常需要取消配送时,可调用此接口对订单进行取消操作,同步返回结果。 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java index ac0eaf46..111c21c7 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java @@ -105,7 +105,6 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { @Autowired private ShopMchEntryService shopMchEntryService; - @Lazy @Autowired private PushMessageService pushMessageService; @@ -354,6 +353,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { return Pair.of(false, "创建顺丰店铺失败,返回的店铺ID为空"); } + transportBase.setSupplier_id(sfSupplierId); transportBase.setShop_id(sfShopId); transportBase.setShop_state(CommonConstant.Enable); // 顺丰同城快递商品特惠 transportBase.setDelivery_brand(CommonConstant.DELIVERY_BRAND_SF); @@ -553,6 +553,60 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { return JsonUtil.json2object(retRespStr, ThirdApiRes.class); } + /** + * 重新创建顺丰同城订单 + * 1、先获取顺丰同城订单的当前状态,如果没有取消的订单,则取消该订单 + * 2、取消成功,则重新创建顺丰同城订单,取消失败,则返回错误信息 + * 3、重新创建订单成功,更新订单轨迹 + * + * @param shopOrderId 商城订单ID + * @return CommonResult 操作结果 + */ + @Override + public CommonResult recreateOrder(String shopOrderId) { + logger.info("[顺丰] 开始重新创建订单: shopOrderId={}", shopOrderId); + + // 参数校验 + if (StrUtil.isBlank(shopOrderId)) { + logger.warn("[顺丰] 重新创建订单失败: 订单ID为空"); + return CommonResult.failed("订单ID不能为空"); + } + + // 获取顺丰订单ID + String sfOrderId = shopStoreSfOrderService.getSfOrderIdByShopOrderId(shopOrderId); + if (StrUtil.isBlank(sfOrderId)) { + logger.warn("[顺丰] 重新创建订单失败: 未找到对应的顺丰订单, shopOrderId={}", shopOrderId); + return CommonResult.failed("未找到对应的顺丰订单"); + } + + try { + // 取消原订单 + Map params = new HashMap<>(); + params.put("order_id", sfOrderId); + ThirdApiRes cancelOrderRes = cancelOrder(params); + if (cancelOrderRes != null && !ObjectUtil.equal(cancelOrderRes.getError_code(), 0)) { + logger.error("[顺丰] 取消原订单失败: errorCode={}, errorMsg={}", + cancelOrderRes.getError_code(), cancelOrderRes.getError_msg()); + return CommonResult.failed(cancelOrderRes.getError_msg()); + } + + // 重新创建订单,传递默认取货号1 + Pair createOrderRes = innerCreateSfExpressOrder(shopOrderId, 0L, true); + if (createOrderRes.getFirst()) { + logger.info("[顺丰] 重新创建订单成功: shopOrderId={}", shopOrderId); + return CommonResult.success(); + } + + logger.error("[顺丰] 重新创建订单失败: {}", createOrderRes.getSecond()); + return CommonResult.failed(createOrderRes.getSecond()); + + } catch (Exception e) { + logger.error("[顺丰] 重新创建订单过程中发生异常: shopOrderId={}", shopOrderId, e); + return CommonResult.failed("系统异常: " + e.getMessage()); + } + } + + /** * 获取顺丰同城店铺信息 * @@ -592,18 +646,19 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { * * @param shopOrderId * @param orderPickupNum + * @param ignoreExists * @return */ @Transactional @Override - public Pair innerCreateSfExpressOrder(String shopOrderId, Long orderPickupNum) { + public Pair innerCreateSfExpressOrder(String shopOrderId, Long orderPickupNum, Boolean ignoreExists) { logger.info("开始顺丰同城下单"); - if (StrUtil.isBlank(shopOrderId) || orderPickupNum == null) { + if (StrUtil.isBlank(shopOrderId) || CheckUtil.isEmpty(orderPickupNum)) { return Pair.of(false, "顺丰同城下单时,缺少必要参数!"); } // 检查 shop_store_sf_order 订单是否已存在? - if (shopStoreSfOrderService.exists(devId, shopOrderId)) { + if (!ignoreExists && shopStoreSfOrderService.exists(devId, shopOrderId)) { return Pair.of(true, "顺丰同城已下单过!"); } @@ -645,7 +700,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { shopStoreSfOrder.setStatus_desc("已创建顺丰同城订单"); // 下单成功,保存顺丰同城订单记录到 shop_store_sf_order 表里 - Boolean success = shopStoreSfOrderService.insertShopStoreSfOrder(shopStoreSfOrder); + Boolean success = shopStoreSfOrderService.saveShopStoreSfOrder(shopStoreSfOrder); if (!success) { logger.error("顺丰下单返回的结果:{}", sfExpressApiRes.get("result").toString()); return Pair.of(false, "保存顺丰同城下单失败!"); @@ -1367,14 +1422,17 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { if (!shopOrderBase.getOperate_flag().equals("0")) { return CommonResult.failed("该状态不允许发货操作"); } + Pair pair = wxOrderShippingService.uploadShippingInfoToWx(2, shopOrderBase.getOrder_id()); if (pair.getFirst()) { Integer orderStatus = StateCode.ORDER_STATE_SHIPPED;//已发货 Integer orderIsOutStatus = StateCode.ORDER_PICKING_STATE_YES; // 已出库 shopOrderInfoService.changeOrderStatus(orderId, orderStatus, orderIsOutStatus, 0); + //完成订单后修改订单异常操作流程进入完成订单环节 shopOrderBase.setOperate_flag("1"); shopOrderBaseService.updateById(shopOrderBase); + //出库扣减思迅库存star // RMK 第三方数据同步相关:redis 给这个商品减去对应的库存 QueryWrapper itemQueryWrapper = new QueryWrapper<>(); @@ -1383,6 +1441,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { if (picking(order_item_rows)) { logger.info("自行发货商品扣减库存成功"); } + if (!order_item_rows.isEmpty()) { for (ShopOrderItem shopOrderItem : order_item_rows) { Map stockDeltaMap = new HashMap<>(); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopMchEntryBranchAdminController.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopMchEntryBranchAdminController.java new file mode 100644 index 00000000..66886174 --- /dev/null +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopMchEntryBranchAdminController.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.shop.store.controller.admin; + +import cn.hutool.json.JSONObject; +import com.suisung.mall.common.api.CommonResult; +import com.suisung.mall.common.pojo.dto.MainStoreBranchReqDTO; +import com.suisung.mall.common.service.impl.BaseControllerImpl; +import com.suisung.mall.shop.store.service.ShopMchEntryBranchService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.util.Pair; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +@Slf4j +@Api(tags = "商家入驻业务控制器") +@RestController +@RequestMapping("/admin/shop/merch/branch") +public class ShopMchEntryBranchAdminController extends BaseControllerImpl { + + + @Resource + private ShopMchEntryBranchService shopMchEntryBranchService; + + /** + * 申请总店的分店 + * + * @param mainStoreBranchReqJSON + * @return + */ + @ApiOperation(value = "后台-申请总店的分店", notes = "向拉卡拉申请总店的分店") + @RequestMapping(value = "/apply/store", method = RequestMethod.POST) + public CommonResult shopMerchEntryList(@RequestBody JSONObject mainStoreBranchReqJSON) { + try { + // 参数校验 + if (mainStoreBranchReqJSON == null) { + return CommonResult.failed("请求参数不能为空"); + } + + MainStoreBranchReqDTO mainStoreBranchReq = mainStoreBranchReqJSON.toBean(MainStoreBranchReqDTO.class); + Pair result = shopMchEntryBranchService.applyMchEntryBranchStore(mainStoreBranchReq); + + if (result.getFirst()) { + return CommonResult.success(); + } + + return CommonResult.failed(result.getSecond()); + } catch (Exception e) { + log.error("申请总店分店异常", e); + return CommonResult.failed("系统异常,请稍后重试"); + } + } + + +} diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStoreBaseController.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStoreBaseController.java index 33b083b0..97d75e97 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStoreBaseController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStoreBaseController.java @@ -93,6 +93,7 @@ public class ShopStoreBaseController extends BaseControllerImpl { if (StrUtil.isNotBlank(store_area)) { queryWrapper.like("store_area", store_area); } + Integer user_id = shopStoreBase.getUser_id(); if (ObjectUtil.isNotNull(user_id)) { queryWrapper.eq("user_id", user_id); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStorePrinterController.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStorePrinterController.java index ec799cf9..595529f9 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStorePrinterController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStorePrinterController.java @@ -34,7 +34,7 @@ public class ShopStorePrinterController { @ApiOperation(value = "内部测试案例", notes = "内部测试案例") @RequestMapping(value = "/testcase", method = {RequestMethod.GET}) public CommonResult TestCase() { - Object data = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(3L, "110.078141", "23.375037", 100, BigDecimal.valueOf(19), BigDecimal.valueOf(5.5), BigDecimal.valueOf(5.5), true); + Object data = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(3L, "110.078141", "23.375037", 100, BigDecimal.valueOf(19), BigDecimal.valueOf(5.5), BigDecimal.valueOf(5.5), false, true); // Double distanceD = PositionUtil.getDistance4(110.084376,23.394216,110.11752034714767,23.31704849881646); // BigDecimal s = new BigDecimal(2.50).setScale(2, RoundingMode.HALF_UP); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/mobile/ShopMchEntryController.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/mobile/ShopMchEntryController.java index 6ffbd5cb..47203d1a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/mobile/ShopMchEntryController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/mobile/ShopMchEntryController.java @@ -62,7 +62,7 @@ public class ShopMchEntryController extends BaseControllerImpl { @ApiOperation(value = "获取商家入驻资料详情", notes = "获取商家入驻资料详情") @RequestMapping(value = "/detail", method = RequestMethod.POST) public CommonResult shopMerchEntryDetail(@RequestBody JSONObject jsonParam) { - return shopMchEntryService.shopMerchEntryDetail(null, jsonParam.getStr("mobile"), null); + return shopMchEntryService.shopMerchEntryDetail(jsonParam.getLong("mch_id"), jsonParam.getStr("mobile"), null); } @ApiOperation(value = "通过手机号mobile获取商家入驻审核状态", notes = "通过手机号获取商家入驻审核状态,远程调用用途") diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/mapper/ShopMchEntryBranchMapper.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/mapper/ShopMchEntryBranchMapper.java new file mode 100644 index 00000000..0c9d0026 --- /dev/null +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/mapper/ShopMchEntryBranchMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.shop.store.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.suisung.mall.common.modules.store.ShopMchEntryBranch; +import org.springframework.stereotype.Component; + +@Component +public interface ShopMchEntryBranchMapper extends BaseMapper { +} diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryBranchService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryBranchService.java new file mode 100644 index 00000000..85de8680 --- /dev/null +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryBranchService.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.shop.store.service; + +import com.suisung.mall.common.modules.store.ShopMchEntryBranch; +import com.suisung.mall.common.pojo.dto.MainStoreBranchReqDTO; +import org.springframework.data.util.Pair; + +public interface ShopMchEntryBranchService { + + /** + * 保存或更新商户终端入驻申请信息 + * + * @param shopMchEntryBranch 商户入驻申请信息 + * @return 保存结果 + */ + Boolean saveShopMchEntryBranch(ShopMchEntryBranch shopMchEntryBranch); + + + /** + * 更新商户终端入驻申请信息 + * + * @param reviewRelatedId 商户终端入驻申请ID + * @param status 商户终端入驻申请状态 + * @param notifyResp 商户终端入驻申请通知响应数据 + * @return 更新结果 + */ + Boolean updateByReviewRelatedId(String reviewRelatedId, Integer status, String notifyResp); + + /** + * 根据商户终端入驻申请ID查询商户终端入驻申请信息 + * + * @param reviewRelatedId 商户终端入驻申请ID + * @return 商户入驻申请信息 + */ + ShopMchEntryBranch getByReviewRelatedId(String reviewRelatedId); + + + /** + * (重要)创建主店铺的分店账号、店铺信息、店铺员工信息、店铺权限信息、入驻信息 + * + * @param mainStoreBranchReq 商户终端入驻申请门店信息 + * @return 创建结果 + */ + Pair applyMchEntryBranchStore(MainStoreBranchReqDTO mainStoreBranchReq); + + /** + * (重要)创建商户终端入驻申请门店信息、创建商户终端入驻申请门店员工信息、创建商户终端入驻申请门店权限信息、创建商户终端入驻申请门店入驻信息 + * + * @param reviewRelatedId 商户终端入驻申请ID + * @param termNo 终端号 + * @param lklNotifyResp 拉卡拉通知响应数据 + * @return 创建结果 + */ + Pair createMchEntryBranchStore(String reviewRelatedId, String termNo, String lklNotifyResp); +} diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java index 40ce92cc..02f3c29b 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java @@ -9,6 +9,7 @@ package com.suisung.mall.shop.store.service; import cn.hutool.json.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.modules.store.ShopMchEntry; import org.springframework.data.util.Pair; @@ -18,6 +19,14 @@ import java.util.List; public interface ShopMchEntryService { + /** + * 新增或修改商家入驻申请信息 + * + * @param shopMchEntry + * @return + */ + Boolean saveOrUpdateShopMchEntry(ShopMchEntry shopMchEntry); + /** * 获取店铺的经营类目列表 * @@ -129,6 +138,15 @@ public interface ShopMchEntryService { ShopMchEntry getShopMerchEntryByCondition(String loginMobile, String bizLicenseNumber, Integer... approvalStatusList); + /** + * 根据拉卡拉商户号获取有效的商家入驻申请记录 + * + * @param merCupNo + * @param parentId + * @return + */ + ShopMchEntry getShopMerchEntryByMerCupNo(String merCupNo, Long parentId); + /** * 根据拉卡拉外部商户号获取有效的商家入驻申请记录 * @@ -375,4 +393,14 @@ public interface ShopMchEntryService { * @return */ ShopMchEntry getLklContractStatusUrl(Integer storeId); + + ShopMchEntry findOneByLambdaQueryWrapper(LambdaQueryWrapper query); + + /** + * 根据商户入驻Id删除商户入驻记录 + * + * @param mchId 商户入驻Id + * @return 删除结果,true为成功,false为失败 + */ + Boolean removeByMchId(Long mchId); } \ No newline at end of file diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java index a24f75e2..191714b8 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java @@ -166,6 +166,17 @@ public interface ShopStoreBaseService extends IBaseService { */ Pair covMerchEntryInfo2StoreInfo(Long mchId, Boolean allowThrown); + /** + * (重要)入驻审批通过并且合同盖章完结之后,把商家入驻信息转换成店铺信息,正式生成店铺所需的数据 + * + * @param mchId 入驻编号 + * @param parentStoreId 总店店铺Id + * @param allowThrown 是否允许抛出异常? + * @return + */ + Pair covMerchEntryInfo2StoreInfo(Long mchId, Integer parentStoreId, Boolean allowThrown); + + /** * 根据店铺名称判断店铺是否存在 * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreInfoService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreInfoService.java index c821e3fa..d7a303ac 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreInfoService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreInfoService.java @@ -47,4 +47,12 @@ public interface ShopStoreInfoService extends IBaseService { * @return */ Integer getStoreShippingFeeInner(Integer storeId); + + /** + * 获取店铺的配送方式是否 自配送 + * + * @param storeId + * @return + */ + Boolean isDeliverySelf(Integer storeId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSameCityTransportBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSameCityTransportBaseService.java index 1ceef44b..927bf4b1 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSameCityTransportBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSameCityTransportBaseService.java @@ -94,10 +94,11 @@ public interface ShopStoreSameCityTransportBaseService { * @param orderProductAmount 订单商品原价金额 * @param orderDiscountAmount 订单商品折扣金额(订单原价减去每个商品折扣费) * @param orderPayAmount 订单实际支付金额(折扣金额-优惠券-积分扣-人工干预扣费),不包含运费 + * @param isPlatform 是否平台: 1-是;2-否 * @param canThrow 能否抛出异常? * @return */ - SameCityDeliveryFeeRespDTO computeSameCityTransportFee(Long storeId, String orderLongitude, String orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount, Boolean canThrow); + SameCityDeliveryFeeRespDTO computeSameCityTransportFee(Long storeId, String orderLongitude, String orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount, Boolean isPlatform, Boolean canThrow); /** * 平台计算同城订单的内部配送费(仅仅作用于平台内部配送费计算,商家配送费忽略此方法,只对下单成功的订单起效果) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSfOrderService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSfOrderService.java index 892e1841..f5f65fe1 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSfOrderService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSfOrderService.java @@ -31,12 +31,12 @@ public interface ShopStoreSfOrderService extends IBaseService String getSfOrderIdByShopOrderId(String shopOrderId); /** - * 新增一个顺丰同城订单记录 + * 保存(新增或更新)一个顺丰同城订单记录 * * @param record * @return */ - Boolean insertShopStoreSfOrder(ShopStoreSfOrder record); + Boolean saveShopStoreSfOrder(ShopStoreSfOrder record); /** diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryBranchServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryBranchServiceImpl.java new file mode 100644 index 00000000..2de5d095 --- /dev/null +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryBranchServiceImpl.java @@ -0,0 +1,482 @@ +package com.suisung.mall.shop.store.service.impl; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.suisung.mall.common.constant.CommonConstant; +import com.suisung.mall.common.exception.ApiException; +import com.suisung.mall.common.feignService.AccountService; +import com.suisung.mall.common.modules.store.ShopMchEntry; +import com.suisung.mall.common.modules.store.ShopMchEntryBranch; +import com.suisung.mall.common.modules.store.ShopStoreBase; +import com.suisung.mall.common.pojo.dto.MainStoreBranchReqDTO; +import com.suisung.mall.common.utils.CheckUtil; +import com.suisung.mall.core.web.service.impl.BaseServiceImpl; +import com.suisung.mall.shop.lakala.service.impl.LklTkServiceImpl; +import com.suisung.mall.shop.store.mapper.ShopMchEntryBranchMapper; +import com.suisung.mall.shop.store.mapper.ShopMchEntryMapper; +import com.suisung.mall.shop.store.service.ShopMchEntryBranchService; +import com.suisung.mall.shop.store.service.ShopMchEntryService; +import com.suisung.mall.shop.store.service.ShopStoreBaseService; +import io.seata.spring.annotation.GlobalTransactional; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.util.Pair; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.Date; +import java.util.Objects; + +@Slf4j +@Service +public class ShopMchEntryBranchServiceImpl extends BaseServiceImpl implements ShopMchEntryBranchService { + @Lazy + @Autowired + private ShopStoreBaseService shopStoreBaseService; + + @Lazy + @Autowired + private ShopMchEntryService shopMchEntryService; + + @Lazy + @Autowired + private AccountService accountService; + + @Lazy + @Autowired + private ShopMchEntryMapper shopMchEntryMapper; + + @Lazy + @Autowired + private LklTkServiceImpl lklTkService; + + + /** + * 保存或更新商户终端入驻申请信息 + *

+ * 根据 reviewRelatedId 确定新增或更改记录 + * + * @param shopMchEntryBranch 商户入驻申请信息 + * @return 保存结果 + */ + @Override + public Boolean saveShopMchEntryBranch(ShopMchEntryBranch shopMchEntryBranch) { + try { + if (shopMchEntryBranch == null) { + log.error("商户终端入驻申请信息不能为空"); + return false; + } + + // 验证必要字段 + if (StrUtil.isBlank(shopMchEntryBranch.getReview_related_id())) { + log.error("审核关联号不能为空"); + return false; + } + + String reviewRelatedId = shopMchEntryBranch.getReview_related_id(); + + // 查询是否已存在记录 + ShopMchEntryBranch existingRecord = getByReviewRelatedId(reviewRelatedId); + + boolean result; + if (existingRecord != null) { + // 更新现有记录 + shopMchEntryBranch.setId(existingRecord.getId()); + result = updateById(shopMchEntryBranch); + log.info("更新商户终端入驻申请信息成功,审核关联号: {}", reviewRelatedId); + } else { + // 新增记录 + result = save(shopMchEntryBranch); + log.info("新增商户终端入驻申请信息成功,审核关联号: {}", reviewRelatedId); + } + + return result; + } catch (Exception e) { + log.error("保存或更新商户终端入驻申请信息失败,审核关联号: {}", + shopMchEntryBranch != null ? shopMchEntryBranch.getReview_related_id() : "null", e); + return false; + } + } + + @Override + public Boolean updateByReviewRelatedId(String reviewRelatedId, Integer status, String notifyResp) { + if (StrUtil.isBlank(reviewRelatedId)) { + log.warn("审核关联号不能为空,无法执行更新操作"); + return false; + } + + try { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(ShopMchEntryBranch::getReview_related_id, reviewRelatedId) + .set(ShopMchEntryBranch::getUpdated_at, new Date()); + + // 更新状态字段 + if (CheckUtil.isNotEmpty(status)) { + updateWrapper.set(ShopMchEntryBranch::getStatus, status); + log.debug("更新状态字段为: {}", status); + } + + // 更新通知响应内容和终端号 + if (StrUtil.isNotBlank(notifyResp)) { + updateWrapper.set(ShopMchEntryBranch::getLkl_notify_reps, notifyResp); +// +// JSONObject notifyRespJson = JSONUtil.parseObj(notifyResp); +// String termNo = notifyRespJson.getStr("termNo", ""); +// if (StrUtil.isNotBlank(termNo)) { +// updateWrapper.set(ShopMchEntryBranch::getLkl_term_no, termNo); +// log.debug("更新商户终端编号字段为: {}", termNo); +// } + + } + + boolean result = update(updateWrapper); + log.info("{}更新分店入驻申请记录,审核关联号: {}", result ? "成功" : "失败", reviewRelatedId); + + return result; + } catch (Exception e) { + log.warn("解析通知响应数据失败,无法提取终端号: {}", e.getMessage()); + return false; + } + } + + + /** + * 根据商户终端入驻申请ID查询商户终端入驻申请信息 + * + * @param reviewRelatedId 商户终端入驻申请ID + * @return 商户入驻申请信息 + */ + @Override + public ShopMchEntryBranch getByReviewRelatedId(String reviewRelatedId) { + try { + if (StrUtil.isBlank(reviewRelatedId)) { + log.warn("审核关联号为空,无法查询商户终端入驻申请信息"); + return null; + } + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ShopMchEntryBranch::getReview_related_id, reviewRelatedId); + + ShopMchEntryBranch result = findOne(queryWrapper); + + if (result != null) { + log.debug("查询商户终端入驻申请信息成功,审核关联号: {}", reviewRelatedId); + } else { + log.info("未找到对应的商户终端入驻申请信息,审核关联号: {}", reviewRelatedId); + } + + return result; + } catch (Exception e) { + log.error("查询商户终端入驻申请信息失败,审核关联号: {}", reviewRelatedId, e); + return null; + } + } + + /** + * 检测分店信息,并向拉卡拉申请创建分店商户入驻申请 + * + * @param mainStoreBranchReq 分店入驻请求DTO + * @return Pair - 执行结果和提示信息 + */ + @Override + public Pair applyMchEntryBranchStore(MainStoreBranchReqDTO mainStoreBranchReq) { + log.info("开始创建分店商户入驻申请,请求参数: {}", JSONUtil.toJsonStr(mainStoreBranchReq)); + + try { + // 1. 参数校验 + if (mainStoreBranchReq == null) { + log.warn("分店入驻信息不能为空"); + return Pair.of(false, "分店入驻信息不能为空"); + } + + // 必填参数校验 + if (mainStoreBranchReq.getParent_store_id() == null) { + return Pair.of(false, "主店ID不能为空"); + } + if (StrUtil.isBlank(mainStoreBranchReq.getLogin_mobile())) { + return Pair.of(false, "登录手机号不能为空"); + } + if (StrUtil.isBlank(mainStoreBranchReq.getStore_name())) { + return Pair.of(false, "分店名称不能为空"); + } + if (StrUtil.isBlank(mainStoreBranchReq.getStore_address())) { + return Pair.of(false, "分店地址不能为空"); + } + if (StrUtil.isBlank(mainStoreBranchReq.getStore_longitude())) { + return Pair.of(false, "分店经度不能为空"); + } + if (StrUtil.isBlank(mainStoreBranchReq.getStore_latitude())) { + return Pair.of(false, "分店纬度不能为空"); + } + + // 2. 检查主店信息是否存在及入驻状态 + LambdaQueryWrapper entryQueryWrapper = new LambdaQueryWrapper<>(); + entryQueryWrapper.eq(ShopMchEntry::getStore_id, mainStoreBranchReq.getParent_store_id()) + .eq(ShopMchEntry::getApproval_status, CommonConstant.MCH_APPR_STA_PASS) + .eq(ShopMchEntry::getParent_id, 0L); // 总店记录 + ShopMchEntry mchEntry = shopMchEntryService.findOneByLambdaQueryWrapper(entryQueryWrapper); + + if (mchEntry == null) { + return Pair.of(false, "主店商户入驻信息不存在"); + } + + if (!Objects.equals(mchEntry.getLkl_tk_audit_status(), CommonConstant.Enable)) { + return Pair.of(false, "主店入驻状态未完成,无法创建分店"); + } + + // 3. 检查店铺名称是否已经存在 + LambdaQueryWrapper nameQueryWrapper = new LambdaQueryWrapper<>(); + nameQueryWrapper.eq(ShopStoreBase::getStore_name, mainStoreBranchReq.getStore_name()); + if (shopStoreBaseService.getOne(nameQueryWrapper) != null) { + return Pair.of(false, "店铺名称已存在"); + } + + // 4. 检查分店登录手机号是否已经注册过商户 + Integer status = accountService.isMerchantExists(mainStoreBranchReq.getLogin_mobile()); + if (CheckUtil.isEmpty(status)) { + return Pair.of(false, "检查商户信息失败!"); + } + + if (CommonConstant.Enable.equals(status)) { + return Pair.of(false, "手机已注册过商家账号,请换另一个手机号"); + } + + // 5. 检查分店终端号是否已经申请或申请中 + LambdaQueryWrapper branchQueryWrapper = new LambdaQueryWrapper<>(); + branchQueryWrapper.eq(ShopMchEntryBranch::getLkl_mer_cup_no, mchEntry.getLkl_mer_inner_no()) + .in(ShopMchEntryBranch::getStatus, Arrays.asList(1, 3)); // 1-申请中,3-可能的其他状态 + if (count(branchQueryWrapper) > 0) { + return Pair.of(false, "分店终端号已申请或申请中,请等待审核"); + } + + // 6. 调用拉卡拉接口创建商户终端 + JSONObject lklResp = lklTkService.openMerchantAddTerm(mchEntry.getLkl_mer_cup_no()); + if (lklResp == null || StrUtil.isBlank(lklResp.getStr("reviewRelatedId"))) { + log.error("调用拉卡拉接口创建商户终端失败,主店拉卡拉商户号: {}", mchEntry.getLkl_mer_cup_no()); + return Pair.of(false, "分店提交申请失败"); + } + + // 7. 保存商户入驻申请信息 + ShopMchEntryBranch shopMchEntryBranch = new ShopMchEntryBranch(); + shopMchEntryBranch.setLkl_mer_cup_no(mchEntry.getLkl_mer_cup_no()); + shopMchEntryBranch.setReview_related_id(lklResp.getStr("reviewRelatedId")); + shopMchEntryBranch.setLkl_req(JSONUtil.toJsonStr(mainStoreBranchReq)); + shopMchEntryBranch.setLkl_reps(JSONUtil.toJsonStr(lklResp)); + + if (!saveShopMchEntryBranch(shopMchEntryBranch)) { + return Pair.of(false, "分店提交申请失败"); + } + + log.info("分店商户入驻申请创建成功,审核关联号: {}", lklResp.getStr("reviewRelatedId")); + return Pair.of(true, "分店提交申请成功"); + + } catch (Exception e) { + log.error("创建分店商户入驻申请时发生异常,请求参数: {}", JSONUtil.toJsonStr(mainStoreBranchReq), e); + return Pair.of(false, "分店提交申请失败:" + e.getMessage()); + } + } + + /** + * (重要)创建商户终端入驻申请门店信息、创建商户终端入驻申请门店员工信息、创建商户终端入驻申请门店权限信息、创建商户终端入驻申请门店入驻信息 + * + * @param reviewRelatedId 商户终端入驻申请ID + * @param termNo 商户终端编号 + * @param lklNotifyResp 拉卡拉通知响应数据 + * @return 创建结果 + */ + @GlobalTransactional + @Override + public Pair createMchEntryBranchStore(String reviewRelatedId, String termNo, String lklNotifyResp) { + log.info("开始处理分店商户入驻,审核关联号: {}, 终端号: {}", reviewRelatedId, termNo); + + // 1. 参数校验 + if (StrUtil.isBlank(reviewRelatedId) || StrUtil.isBlank(termNo)) { + return Pair.of(false, "参数不能为空"); + } + + try { + // 2. 查询分店入驻申请记录 + ShopMchEntryBranch shopMchEntryBranch = getByReviewRelatedId(reviewRelatedId); + if (shopMchEntryBranch == null) { + return Pair.of(false, "分店商户入驻申请不存在"); + } + + // 3. 更新分店入驻申请记录 + shopMchEntryBranch.setLkl_term_no(termNo); + shopMchEntryBranch.setStatus(CommonConstant.Enable); + shopMchEntryBranch.setLkl_notify_reps(lklNotifyResp); + + // 使用 LambdaUpdateWrapper 确保只更新指定字段 + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(ShopMchEntryBranch::getReview_related_id, reviewRelatedId) + .set(ShopMchEntryBranch::getLkl_term_no, termNo) + .set(ShopMchEntryBranch::getStatus, CommonConstant.Enable) + .set(ShopMchEntryBranch::getLkl_notify_reps, lklNotifyResp) + .set(ShopMchEntryBranch::getUpdated_at, new Date()); + + if (!update(updateWrapper)) { + throw new ApiException("更新分店入驻申请记录失败"); + } + + // 4. 解析分店入驻请求数据 + MainStoreBranchReqDTO mainStoreBranchReq = JSONUtil.toBean(shopMchEntryBranch.getLkl_req(), MainStoreBranchReqDTO.class); + if (mainStoreBranchReq == null) { + throw new ApiException("解析分店入驻请求数据失败"); + } + + // 5. 获取总店入驻信息 + ShopMchEntry parentShopMchEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(shopMchEntryBranch.getLkl_mer_cup_no(), 0L); + if (parentShopMchEntry == null) { + throw new ApiException("主店入驻信息不存在"); + } + + // 6. 构建分店入驻信息 + ShopMchEntry shopMchEntry = new ShopMchEntry(); + cn.hutool.core.bean.BeanUtil.copyProperties(parentShopMchEntry, shopMchEntry, "id"); + shopMchEntry.setId(null); // ID设置为null,以便插入新记录 + shopMchEntry.setLkl_term_no(termNo); + shopMchEntry.setLogin_mobile(mainStoreBranchReq.getLogin_mobile()); + shopMchEntry.setParent_id(parentShopMchEntry.getId()); // 设置主店入驻ID为父ID + shopMchEntry.setStore_name(mainStoreBranchReq.getStore_name()); + shopMchEntry.setStore_address(mainStoreBranchReq.getStore_address()); + shopMchEntry.setStore_longitude(mainStoreBranchReq.getStore_longitude()); + shopMchEntry.setStore_latitude(mainStoreBranchReq.getStore_latitude()); + shopMchEntry.setStatus(CommonConstant.Enable); + + if (StrUtil.isNotBlank(mainStoreBranchReq.getContact_name())) { + shopMchEntry.setContact_name(mainStoreBranchReq.getContact_name()); + } + if (StrUtil.isNotBlank(mainStoreBranchReq.getFront_facade_image())) { + shopMchEntry.setFront_facade_image(mainStoreBranchReq.getFront_facade_image()); + } + if (StrUtil.isNotBlank(mainStoreBranchReq.getEnvironment_image())) { + shopMchEntry.setEnvironment_image(mainStoreBranchReq.getEnvironment_image()); + } + shopMchEntry.setEmail(StrUtil.isBlank(mainStoreBranchReq.getEmail()) ? parentShopMchEntry.getLogin_mobile() + "@qq.com" : mainStoreBranchReq.getEmail()); + + // 7. 保存分店入驻记录 + if (!shopMchEntryService.saveOrUpdateShopMchEntry(shopMchEntry)) { + throw new ApiException("保存分店入驻记录失败:" + shopMchEntry.getStore_name()); + } + + // 8. 创建分店店铺商家登录账号 + Pair registerResult = accountService.merchantInnerRegister(mainStoreBranchReq.getLogin_mobile(), mainStoreBranchReq.getPassword()); + if (!registerResult.getFirst()) { + throw new ApiException("分店商户注册账号失败:" + registerResult.getSecond()); + } + + // 9. 创建分店店铺信息 + Pair storeResult = shopStoreBaseService.covMerchEntryInfo2StoreInfo(shopMchEntry.getId(), Convert.toInt(parentShopMchEntry.getStore_id(), 0), true); + if (storeResult == null || storeResult.getFirst() <= 0) { + throw new ApiException("创建分店店铺信息失败: " + (storeResult != null ? storeResult.getSecond() : "未知错误")); + } + + log.info("分店商户入驻处理成功,分店入驻ID: {}, 店铺ID: {}", shopMchEntry.getId(), storeResult.getFirst()); + return Pair.of(true, "分店商户入驻处理成功"); + + } catch (Exception e) { + log.error("处理分店商户入驻时发生异常,审核关联号: {}, 终端号: {}", reviewRelatedId, termNo, e); + throw new ApiException("处理分店商户入驻时发生异常,审核关联号: " + reviewRelatedId + ", 终端号: " + termNo); + } + } + + + /** + * 清理分店商户入驻信息 + * + * @param lklMerCupNo 拉卡拉商户号 + * @param lklTermNo 拉卡拉终端号 + * @return 清理结果 + */ + @GlobalTransactional + public Pair cleanMchEntryBranchStore(String lklMerCupNo, String lklTermNo) { + log.info("开始清理分店商户入驻信息,拉卡拉商户号: {}, 终端号: {}", lklMerCupNo, lklTermNo); + + // 1. 参数校验 + if (StrUtil.isBlank(lklMerCupNo) || StrUtil.isBlank(lklTermNo)) { + log.warn("清理分店商户入驻参数校验失败,lklMerCupNo: {}, lklTermNo: {}", lklMerCupNo, lklTermNo); + return Pair.of(false, "参数不能为空"); + } + + try { + log.debug("步骤1 - 查询分店入驻记录,拉卡拉商户号: {}, 终端号: {}", lklMerCupNo, lklTermNo); + // 2. 查询分店入驻记录 + LambdaQueryWrapper entryQueryWrapper = new LambdaQueryWrapper<>(); + entryQueryWrapper.eq(ShopMchEntry::getLkl_mer_cup_no, lklMerCupNo) + .eq(ShopMchEntry::getLkl_term_no, lklTermNo); + ShopMchEntry shopMchEntry = shopMchEntryService.findOneByLambdaQueryWrapper(entryQueryWrapper); + + if (shopMchEntry == null) { + log.warn("未找到对应的分店入驻记录,拉卡拉商户号: {}, 终端号: {}", lklMerCupNo, lklTermNo); + return Pair.of(false, "未找到对应的分店入驻记录"); + } + log.debug("步骤1 - 找到分店入驻记录,分店ID: {}, 店铺名称: {}", shopMchEntry.getId(), shopMchEntry.getStore_name()); + + log.debug("步骤2 - 查询分店店铺信息,分店入驻ID: {}", shopMchEntry.getId()); + // 3. 查询分店店铺信息 + LambdaQueryWrapper storeQueryWrapper = new LambdaQueryWrapper<>(); + storeQueryWrapper.eq(ShopStoreBase::getStore_id, shopMchEntry.getStore_id()); + ShopStoreBase shopStore = shopStoreBaseService.getOne(storeQueryWrapper); + + if (shopStore == null) { + log.warn("未找到对应的分店店铺信息,分店入驻ID: {}", shopMchEntry.getId()); + } else { + log.debug("步骤2 - 找到分店店铺信息,店铺ID: {}, 店铺名称: {}", shopStore.getStore_id(), shopStore.getStore_name()); + } + + log.debug("步骤3 - 删除分店店铺信息,店铺ID: {}", shopStore != null ? shopStore.getStore_id() : "null"); + // 4. 删除分店店铺信息 + if (shopStore != null) { + boolean deleteStoreResult = shopStoreBaseService.removeById(shopStore.getStore_id()); + if (!deleteStoreResult) { + log.error("删除分店店铺信息失败,店铺ID: {}", shopStore.getStore_id()); + throw new ApiException("删除分店店铺信息失败"); + } + log.debug("步骤3 - 删除分店店铺信息成功,店铺ID: {}", shopStore.getStore_id()); + } + + log.debug("步骤4 - 删除分店入驻记录,分店ID: {}", shopMchEntry.getId()); + // 5. 删除分店入驻记录 + boolean deleteEntryResult = shopMchEntryService.removeByMchId(shopMchEntry.getId()); + if (!deleteEntryResult) { + log.error("删除分店入驻记录失败,分店ID: {}", shopMchEntry.getId()); + throw new ApiException("删除分店入驻记录失败"); + } + log.debug("步骤4 - 删除分店入驻记录成功,分店ID: {}", shopMchEntry.getId()); + + log.debug("步骤5 - 查询分店入驻申请记录,拉卡拉商户号: {}, 终端号: {}", lklMerCupNo, lklTermNo); + // 6. 查询分店入驻申请记录 + LambdaQueryWrapper branchQueryWrapper = new LambdaQueryWrapper<>(); + branchQueryWrapper.eq(ShopMchEntryBranch::getLkl_mer_cup_no, lklMerCupNo) + .eq(ShopMchEntryBranch::getLkl_term_no, lklTermNo); + ShopMchEntryBranch shopMchEntryBranch = getOne(branchQueryWrapper); + + if (shopMchEntryBranch != null) { + log.debug("步骤5 - 找到分店入驻申请记录,审核关联ID: {}", shopMchEntryBranch.getReview_related_id()); + + log.debug("步骤6 - 删除分店入驻申请记录,审核关联ID: {}", shopMchEntryBranch.getReview_related_id()); + // 7. 删除分店入驻申请记录 + boolean deleteBranchResult = removeById(shopMchEntryBranch.getId()); + if (!deleteBranchResult) { + log.error("删除分店入驻申请记录失败,审核关联ID: {}", shopMchEntryBranch.getReview_related_id()); + throw new ApiException("删除分店入驻申请记录失败"); + } + log.debug("步骤6 - 删除分店入驻申请记录成功,审核关联ID: {}", shopMchEntryBranch.getReview_related_id()); + } + + log.info("分店商户入驻信息清理完成,拉卡拉商户号: {}, 终端号: {}", lklMerCupNo, lklTermNo); + return Pair.of(true, "分店商户入驻信息清理成功"); + + } catch (Exception e) { + log.error("清理分店商户入驻信息时发生异常,拉卡拉商户号: {}, 终端号: {}", lklMerCupNo, lklTermNo, e); + throw new ApiException("清理分店商户入驻信息时发生异常,拉卡拉商户号: " + lklMerCupNo + ", 终端号: " + lklTermNo); + } + } + + +} diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java index 498727e8..95c707b7 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java @@ -30,6 +30,7 @@ import com.suisung.mall.common.modules.account.AccountUserBase; import com.suisung.mall.common.modules.lakala.LklLedgerEc; import com.suisung.mall.common.modules.store.ShopMchEntry; import com.suisung.mall.common.modules.store.ShopStoreEmployee; +import com.suisung.mall.common.modules.store.ShopStoreInfo; import com.suisung.mall.common.pojo.to.AddressParseResultTO; import com.suisung.mall.common.utils.*; import com.suisung.mall.common.utils.phone.PhoneNumberUtils; @@ -45,6 +46,7 @@ import com.suisung.mall.shop.store.mapper.ShopMchEntryMapper; import com.suisung.mall.shop.store.service.ShopMchEntryService; import com.suisung.mall.shop.store.service.ShopStoreBaseService; import com.suisung.mall.shop.store.service.ShopStoreEmployeeService; +import com.suisung.mall.shop.store.service.ShopStoreInfoService; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.data.util.Pair; @@ -97,6 +99,61 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl 0) { + log.info("开始更新商家入驻申请信息,ID: {}, 店铺名称: {}, 手机号: {}", mchId, storeName, loginMobile); + } else { + log.info("开始新增商家入驻申请信息,店铺名称: {}, 手机号: {}", storeName, loginMobile); + } + + // 3. 执行保存或更新操作 + boolean result = saveOrUpdate(shopMchEntry); + + // 4. 记录操作结果 + if (result) { + if (mchId != null && mchId > 0) { + log.info("商家入驻申请信息更新成功,ID: {}", mchId); + } else { + log.info("商家入驻申请信息新增成功,新ID: {}", shopMchEntry.getId()); + } + } else { + log.error("商家入驻申请信息保存或更新失败,ID: {}, 店铺名称: {}, 手机号: {}", + mchId, storeName, loginMobile); + } + + return result; + + } catch (Exception e) { + log.error("商家入驻申请信息保存或更新异常,店铺名称: {}, 手机号: {}", + shopMchEntry.getStore_name(), shopMchEntry.getLogin_mobile(), e); + return false; + } + } + + /** * 获取店铺的经营类目列表 * @@ -189,6 +246,11 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl approvalStatusList) { - // 检查登录用户是否有管理权限或者是用户自己 + public CommonResult shopMerchEntryDetail(Long mchId, String mobile, List approvalStatusList) { + log.debug("获取商家入驻申请详情开始: recordId={}, mobile={}", mchId, mobile); - // approvalStatus 入驻商家的审批状态:1-已通过;2-未通过;3-待审核; - if (ObjectUtil.isEmpty(recordId) && StrUtil.isBlank(mobile)) { + // 参数校验:recordId 和 mobile 至少提供一个 + if (ObjectUtil.isEmpty(mchId) && StrUtil.isBlank(mobile)) { + log.warn("获取商家入驻详情失败:缺少必要参数 recordId 或 mobile"); return CommonResult.failed("缺少必要参数!"); } - QueryWrapper queryWrapper = new QueryWrapper<>(); - if (ObjectUtil.isNotEmpty(recordId)) { - queryWrapper.eq("id", recordId); - } + try { + // 构建查询条件 + QueryWrapper queryWrapper = new QueryWrapper<>(); - if (StrUtil.isNotBlank(mobile)) { - queryWrapper.eq("login_mobile", mobile); - } + // 根据ID查询 + if (ObjectUtil.isNotEmpty(mchId)) { + queryWrapper.eq("id", mchId); + } - if (CollectionUtil.isNotEmpty(approvalStatusList)) { - queryWrapper.in("approval_status", approvalStatusList); - } - queryWrapper.orderByDesc("id"); - List recordList = list(queryWrapper); - if (CollectionUtil.isEmpty(recordList)) { - return CommonResult.success(new JSONObject().set("approval_status", CommonConstant.MCH_APPR_STA_NONE), "请求成功!"); - } + // 根据手机号查询 + if (StrUtil.isNotBlank(mobile)) { + queryWrapper.eq("login_mobile", mobile); + } - ShopMchEntry record = recordList.get(0); - // 审核意见空值,返回"[]" - if (StrUtil.isBlank(record.getApproval_invalid_col())) { - record.setApproval_invalid_col("[]"); + // 状态过滤条件 + if (CollectionUtil.isNotEmpty(approvalStatusList)) { + queryWrapper.in("approval_status", approvalStatusList); + } + + // 按ID倒序排列,获取最新一条记录 + queryWrapper.orderByDesc("id"); + ShopMchEntry record = getOne(queryWrapper); + + // 如果没有找到记录,返回默认的成功结果 + if (ObjectUtil.isEmpty(record)) { + log.debug("未找到商家入驻记录: recordId={}, mobile={}", mchId, mobile); + return CommonResult.success( + new JSONObject().set("approval_status", CommonConstant.MCH_APPR_STA_NONE), + "请求成功!" + ); + } + + + // 处理审核意见空值情况 + if (StrUtil.isBlank(record.getApproval_invalid_col())) { + record.setApproval_invalid_col("[]"); + } + + // 尝试更新入驻表的合同下载地址和合同签署状态 + updateMerchEntrySignedStatusAndContractDownloadUrl(record); + if (StrUtil.isNotBlank(record.getStore_id())) { + // 转换为JSONObject并添加额外属性 + JSONObject retObj = JSONUtil.parseObj(record); + // 获取店铺信息 + ShopStoreInfo storeInfo = shopStoreInfoService.getById(record.getStore_id()); + if (storeInfo != null && retObj != null) { + retObj.set("is_delivery_self", storeInfo.getIs_delivery_self()); + return CommonResult.success(record); + } + } + + return CommonResult.success(record); + + } catch (Exception e) { + log.error("获取商家入驻申请详情异常: recordId={}, mobile={}", mchId, mobile, e); + return CommonResult.failed("系统异常,请稍后重试"); } - - // 试试更新入驻表的合同下载地址和合同签署状态 - updateMerchEntrySignedStatusAndContractDownloadUrl(record); - - return CommonResult.success(record); } @@ -825,7 +923,6 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("lkl_mer_cup_no", merCupNo).eq("status", CommonConstant.Enable).orderByAsc("id"); - List recordList = list(queryWrapper); - if (CollectionUtil.isEmpty(recordList)) { + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ShopMchEntry::getLkl_mer_cup_no, merCupNo) + .eq(ShopMchEntry::getStatus, CommonConstant.Enable) + .orderByAsc(ShopMchEntry::getId); + + if (parentId != null && parentId >= 0) { + queryWrapper.eq(ShopMchEntry::getParent_id, parentId); + } + + ShopMchEntry record = findOne(queryWrapper); + if (ObjectUtil.isEmpty(record)) { return null; } - return recordList.get(0); + return record; + } + + @Override + public ShopMchEntry getShopMerchEntryByMerCupNo(String merCupNo) { + return getShopMerchEntryByMerCupNo(merCupNo, null); } @Override @@ -1252,14 +1362,14 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("lkl_mer_inner_no", merInnerNo).eq("status", CommonConstant.Enable).orderByAsc("id"); - List recordList = list(queryWrapper); - if (CollectionUtil.isEmpty(recordList)) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ShopMchEntry::getLkl_mer_inner_no, merInnerNo).eq(ShopMchEntry::getStatus, CommonConstant.Enable).orderByAsc(ShopMchEntry::getId); + ShopMchEntry record = findOne(queryWrapper); + if (ObjectUtil.isEmpty(record)) { return null; } - return recordList.get(0); + return record; } /** @@ -2542,6 +2652,40 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl query) { + // 参数校验 + if (query == null) { + log.warn("查询条件为空,无法执行查询"); + return null; + } + + try { + // 执行查询 + return findOne(query); + } catch (Exception e) { + log.error("执行商户入驻查询时发生异常", e); + return null; + } + } + + /** + * 根据商户入驻Id删除商户入驻记录 + * + * @param mchId 商户入驻Id + * @return 删除结果,true为成功,false为失败 + */ + @Override + public Boolean removeByMchId(Long mchId) { + return remove(mchId); + } + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java index 14fb2e54..b0f5795f 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java @@ -12,6 +12,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -74,6 +75,7 @@ import com.suisung.mall.shop.wechat.service.WxQrCodeService; import io.seata.spring.annotation.GlobalTransactional; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -270,8 +272,8 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl shopStoreInfos = store_info_rows.stream().filter(r -> r.equals(ObjectUtil.equal(r.getStore_id(), store_id))).findFirst(); - if (shopStoreInfos.isPresent()) { + Optional shopStoreInfos = store_info_rows.stream().filter(r -> ObjectUtil.equal(r.getStore_id(), store_id)).findFirst(); + if (shopStoreInfos.isPresent()) { // 匹配到店铺信息 ShopStoreInfo shopStoreInfo = shopStoreInfos.orElseGet(ShopStoreInfo::new); Map map = Convert.toMap(Object.class, Object.class, shopStoreInfo); s.putAll(map); @@ -2473,12 +2475,8 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl 0) { + BigDecimal packingFee = Convert.toBigDecimal(getParameter("packing_fee"), BigDecimal.ZERO); + if (packingFee.compareTo(new BigDecimal("10")) >= 0) { logger.warn("打包费超出范围: {}", packingFee); return CommonResult.failed("打包费请控制在0到10元范围"); } @@ -2503,6 +2501,11 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl 0) { + BigDecimal packingFee = Convert.toBigDecimal(getParameter("packing_fee"), BigDecimal.ZERO); + if (packingFee.compareTo(new BigDecimal("10")) >= 0) { logger.warn("打包费超出范围: {}", packingFee); return CommonResult.failed("打包费请控制在0到10元范围"); } @@ -3254,6 +3253,11 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl covMerchEntryInfo2StoreInfo(Long mchId, Boolean allowThrown) { + return covMerchEntryInfo2StoreInfo(mchId, 0, allowThrown); + } + + @Override + public Pair covMerchEntryInfo2StoreInfo(Long mchId, Integer parentStoreId, Boolean allowThrown) { // 参数校验 if (ObjectUtil.isEmpty(mchId)) { logger.error("生成店铺:入驻商家自增Id不能为空"); @@ -3285,9 +3289,10 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl 0 ? areaNames[areaNames.length - 1] : storeArea.replace("/", ""); - sfExpressApiService.createSfExpressShop(mchId, storeId, shopMchEntry.getContact_name(), contact_mobile, shopMchEntry.getStore_longitude(), shopMchEntry.getStore_latitude()); -// } return Pair.of(storeId, "新增成功"); } catch (Exception e) { @@ -4287,15 +4294,12 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("store_id", storeId).select("packing_fee"); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.select(ShopStoreBase::getPacking_fee) + .eq(ShopStoreBase::getStore_id, storeId); ShopStoreBase shopStoreBase = shopStoreBaseService.findOne(queryWrapper); - if (shopStoreBase != null) { - return shopStoreBase.getPacking_fee(); - } - - return BigDecimal.ZERO; + return ObjectUtil.isEmpty(shopStoreBase) ? BigDecimal.ZERO : shopStoreBase.getPacking_fee(); } /** diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreEmployeeServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreEmployeeServiceImpl.java index 60d1696d..384b6b6c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreEmployeeServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreEmployeeServiceImpl.java @@ -50,6 +50,7 @@ import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser; @Service public class ShopStoreEmployeeServiceImpl extends BaseServiceImpl implements ShopStoreEmployeeService { + @Lazy @Autowired private AccountService accountService; diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreInfoServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreInfoServiceImpl.java index a804394b..af5bfbdd 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreInfoServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreInfoServiceImpl.java @@ -2,8 +2,10 @@ package com.suisung.mall.shop.store.service.impl; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.suisung.mall.common.constant.CommonConstant; import com.suisung.mall.common.feignService.AccountService; import com.suisung.mall.common.modules.account.AccountUserBase; import com.suisung.mall.common.modules.store.ShopStoreAnalytics; @@ -160,4 +162,38 @@ public class ShopStoreInfoServiceImpl extends BaseServiceImpl queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ShopStoreInfo::getStore_id, storeId) + .select(ShopStoreInfo::getIs_delivery_self); + ShopStoreInfo shopStoreInfo = findOne(queryWrapper); + + // 店铺不存在或配送方式字段为空时返回false + if (shopStoreInfo == null || shopStoreInfo.getIs_delivery_self() == null) { + log.debug("店铺信息不存在或配送方式未设置,storeId: {}", storeId); + return false; + } + + return CommonConstant.Enable.equals(shopStoreInfo.getIs_delivery_self()); + } catch (Exception e) { + log.error("查询店铺配送方式异常,storeId: {}", storeId, e); + return false; + } + } + + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportBaseServiceImpl.java index 9d2ab37e..7c1c348c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportBaseServiceImpl.java @@ -43,6 +43,7 @@ import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.data.util.Pair; import org.springframework.stereotype.Service; @@ -62,6 +63,10 @@ import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser; public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl implements ShopStoreSameCityTransportBaseService { private static final Logger logger = LoggerFactory.getLogger(ShopStoreSameCityTransportBaseServiceImpl.class); + + @Value("${sf-express.supplier_id}") + private String supplierId; + @Autowired private ShopStoreSameCityTransportService shopStoreSameCityTransportService; @Autowired @@ -71,7 +76,6 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); queryWrapper.eq("store_id", transportBase.getStore_id()); @@ -455,7 +469,6 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl 0) { // 没有一个满足起送距离和起送金额的规则订单 @@ -877,162 +889,171 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl transportList = shopStoreSameCityTransportService.selectShopStoreSameCityTransportList(Convert.toLong(storeId)); - - if (CollUtil.isEmpty(transportList)) { - // 没有配送范围规则的时候,直接以基础配送费来配送 - return deliveryBaseFee.multiply(BigDecimal.valueOf(100)).intValue(); - } - - // 判断配送范围和起送金额条件 - String canNotDeliveryReason = ""; - boolean canDelivery = false; - - // 优先处理距离和金额都满足的规则 - for (ShopStoreSameCityTransport transport : transportList) { - // 判断订单距离是否在配送范围内 - if (transport.getMax_delivery_radius() >= distance) { - // 距离在配送范围内,判断金额是否符合起配金额额度 - boolean moneyPassed = false; - if (CommonConstant.Delivery_Amount_Comput_Type_Original.equals(transport.getMin_delivery_amount_type())) { - moneyPassed = orderProductAmount != null && transport.getMin_delivery_amount().compareTo(orderProductAmount) <= 0; - } else if (CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getMin_delivery_amount_type())) { - moneyPassed = orderDiscountAmount != null && transport.getMin_delivery_amount().compareTo(orderDiscountAmount) <= 0; - } else if (CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getMin_delivery_amount_type())) { - moneyPassed = orderPayAmount != null && transport.getMin_delivery_amount().compareTo(orderPayAmount) <= 0; - } - - // 距离和金额都满足条件 - if (moneyPassed) { - canDelivery = true; - break; - } - } - } - - // 如果没有找到完全满足条件的规则,再详细检查找出失败原因 - if (!canDelivery) { - for (ShopStoreSameCityTransport transport : transportList) { - // 判断订单距离是否在配送范围内 - if (transport.getMax_delivery_radius() < distance) { - // 记录距离不满足的原因 - canNotDeliveryReason = storeName + "的订单不在配送范围内,订单无法配送。"; - } else { - // 距离在配送范围内,判断金额是否符合起配金额额度 - if (CommonConstant.Delivery_Amount_Comput_Type_Original.equals(transport.getMin_delivery_amount_type())) { - if (orderProductAmount != null && transport.getMin_delivery_amount().compareTo(orderProductAmount) > 0) { - BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderProductAmount); - canNotDeliveryReason = String.format("%s商品原价金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney); - } else { - canDelivery = true; - break; - } - } else if (CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getMin_delivery_amount_type())) { - if (orderDiscountAmount != null && transport.getMin_delivery_amount().compareTo(orderDiscountAmount) > 0) { - BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderDiscountAmount); - canNotDeliveryReason = String.format("%s订单折后金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney); - } else { - canDelivery = true; - break; - } - } else if (CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getMin_delivery_amount_type())) { - if (orderPayAmount != null && transport.getMin_delivery_amount().compareTo(orderPayAmount) > 0) { - BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderPayAmount); - canNotDeliveryReason = String.format("%s订单应支付金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney); - } else { - canDelivery = true; - break; - } - } - } - } - } - - // 如果仍然不能配送,记录日志并返回0 - if (!canDelivery) { - logger.warn(canNotDeliveryReason.isEmpty() ? (storeName + "订单不在配送范围内或未达起送金额,请检查!") : canNotDeliveryReason); - return 0; - } - - // 额外配送费计算 - // 每增加一个距离累加运费 - if (transportBase.getDistance_increase_km() != null && transportBase.getDistance_increase_fee() != null && distance > transportBase.getDistance_base() * 1000) { - // 实际配送距离超出基础距离,单位km - BigDecimal diffDistanceM = CommonUtil.DecimalRoundHalfUp(BigDecimal.valueOf(distance - transportBase.getDistance_base() * 1000).divide(BigDecimal.valueOf(1000))); - // 倍数 - BigDecimal times = BigDecimal.ZERO; - if (transportBase.getDistance_increase_km() > 0 && diffDistanceM.intValue() > transportBase.getDistance_increase_km()) { - // 末尾非零进位,比如:2.1将是3, 2.0将是2,2.001将是3 - times = NumberUtil.div(diffDistanceM, transportBase.getDistance_increase_km()).setScale(0, RoundingMode.UP); - } - - // 超过基础运费距离后,累加上运费 - deliveryBaseFee = deliveryBaseFee.add(transportBase.getDistance_increase_fee().multiply(times)); - } - - // 每增加一个重量累加运费(重量暂时忽略,配置的时候设置0) - if (transportBase.getWeight_increase_kg() != null && transportBase.getWeight_increase_fee() != null && orderWeightGram != null && orderWeightGram > transportBase.getWeight_base() * 1000) { - // 实际配送重量超出基础重量,单位kg - BigDecimal diffWeightKg = CommonUtil.DecimalRoundHalfUp(BigDecimal.valueOf(orderWeightGram - transportBase.getWeight_base() * 1000).divide(BigDecimal.valueOf(1000))); - // 倍数 - BigDecimal times = BigDecimal.ZERO; - if (transportBase.getWeight_increase_kg() > 0 && diffWeightKg.intValue() > transportBase.getWeight_increase_kg()) { - // 末尾非零进位,比如:2.1将是3, 2.0将是2,2.001将是3 - times = NumberUtil.div(diffWeightKg, transportBase.getWeight_increase_kg()).setScale(0, RoundingMode.UP); // 修正:应该除以weight_increase_kg而不是distance_increase_km - } - - deliveryBaseFee = deliveryBaseFee.add(transportBase.getWeight_increase_fee().multiply(times)); - } - - // 返回单位为分的配送费 - return deliveryBaseFee.multiply(BigDecimal.valueOf(100)).intValue(); +// 参数校验 +// if (storeId == null || orderLongitude == null || orderLatitude == null || storeId <= 0) { +// logger.warn("同城配送缺少必要参数,无法计算配送费。"); +// return 0; +// } +// +// // 获取店铺基本信息 +// ShopStoreBase storeBase = shopStoreBaseService.get(storeId); +// if (storeBase == null) { +// logger.warn("同城配送缺少店铺基本信息,无法计算配送费。"); +// return 0; +// } +// +// String storeName = storeBase.getStore_name(); +// String storeLng = storeBase.getStore_longitude(); +// String storeLat = storeBase.getStore_latitude(); +// if (StrUtil.isBlank(storeLng) || StrUtil.isBlank(storeLat)) { +// logger.warn("无法获取{}的具体位置,请联系商家。", storeName); +// return 0; +// } +// +// // 获取平台的基础运费设置记录 +// ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(Convert.toLong(storeId), CommonConstant.Enable); +// if (transportBase == null) { +// logger.warn("商家{}尚未完成同城配送设置,无法计算配送费。", storeName); +// return 0; +// } +// +// // 设置默认值 +// if (transportBase.getDistance_base() == null) { +// transportBase.setDistance_base(0); +// } +// if (transportBase.getWeight_base() == null) { +// transportBase.setWeight_base(0); +// } +// if (transportBase.getDelivery_base_fee() == null) { +// transportBase.setDelivery_base_fee(BigDecimal.ZERO); +// } +// +// // 计算两点的距离(单位米) +// Double distanceD = PositionUtil.getDistance1(Convert.toDouble(storeLng), Convert.toDouble(storeLat), Convert.toDouble(orderLongitude), Convert.toDouble(orderLatitude)); +// Integer distance = (distanceD != null) ? distanceD.intValue() : 0; +// +// // 基础配送费计算 +// BigDecimal deliveryBaseFee = Convert.toBigDecimal(transportBase.getDelivery_base_fee(), BigDecimal.ZERO); +// +// // 获取运费配送范围信息 +// List transportList = shopStoreSameCityTransportService.selectShopStoreSameCityTransportList(Convert.toLong(storeId)); +// +// if (CollUtil.isEmpty(transportList)) { +// // 没有配送范围规则的时候,直接以基础配送费来配送 +// return deliveryBaseFee.multiply(BigDecimal.valueOf(100)).intValue(); +// } +// +// // 判断配送范围和起送金额条件 +// String canNotDeliveryReason = ""; +// boolean canDelivery = false; +// +// // 优先处理距离和金额都满足的规则 +// for (ShopStoreSameCityTransport transport : transportList) { +// // 判断订单距离是否在配送范围内 +// if (transport.getMax_delivery_radius() >= distance) { +// // 距离在配送范围内,判断金额是否符合起配金额额度 +// boolean moneyPassed = false; +// if (CommonConstant.Delivery_Amount_Comput_Type_Original.equals(transport.getMin_delivery_amount_type())) { +// moneyPassed = orderProductAmount != null && transport.getMin_delivery_amount().compareTo(orderProductAmount) <= 0; +// } else if (CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getMin_delivery_amount_type())) { +// moneyPassed = orderDiscountAmount != null && transport.getMin_delivery_amount().compareTo(orderDiscountAmount) <= 0; +// } else if (CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getMin_delivery_amount_type())) { +// moneyPassed = orderPayAmount != null && transport.getMin_delivery_amount().compareTo(orderPayAmount) <= 0; +// } +// +// // 距离和金额都满足条件 +// if (moneyPassed) { +// canDelivery = true; +// break; +// } +// } +// } +// +// // 如果没有找到完全满足条件的规则,再详细检查找出失败原因 +// if (!canDelivery) { +// for (ShopStoreSameCityTransport transport : transportList) { +// // 判断订单距离是否在配送范围内 +// if (transport.getMax_delivery_radius() < distance) { +// // 记录距离不满足的原因 +// canNotDeliveryReason = storeName + "的订单不在配送范围内,订单无法配送。"; +// } else { +// // 距离在配送范围内,判断金额是否符合起配金额额度 +// if (CommonConstant.Delivery_Amount_Comput_Type_Original.equals(transport.getMin_delivery_amount_type())) { +// if (orderProductAmount != null && transport.getMin_delivery_amount().compareTo(orderProductAmount) > 0) { +// BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderProductAmount); +// canNotDeliveryReason = String.format("%s商品原价金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney); +// } else { +// canDelivery = true; +// break; +// } +// } else if (CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getMin_delivery_amount_type())) { +// if (orderDiscountAmount != null && transport.getMin_delivery_amount().compareTo(orderDiscountAmount) > 0) { +// BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderDiscountAmount); +// canNotDeliveryReason = String.format("%s订单折后金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney); +// } else { +// canDelivery = true; +// break; +// } +// } else if (CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getMin_delivery_amount_type())) { +// if (orderPayAmount != null && transport.getMin_delivery_amount().compareTo(orderPayAmount) > 0) { +// BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderPayAmount); +// canNotDeliveryReason = String.format("%s订单应支付金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney); +// } else { +// canDelivery = true; +// break; +// } +// } +// } +// } +// } +// +// // 如果仍然不能配送,记录日志并返回0 +// if (!canDelivery) { +// logger.warn(canNotDeliveryReason.isEmpty() ? (storeName + "订单不在配送范围内或未达起送金额,请检查!") : canNotDeliveryReason); +// return 0; +// } +// +// // 额外配送费计算 +// // 每增加一个距离累加运费 +// if (transportBase.getDistance_increase_km() != null && transportBase.getDistance_increase_fee() != null && distance > transportBase.getDistance_base() * 1000) { +// // 实际配送距离超出基础距离,单位km +// BigDecimal diffDistanceM = CommonUtil.DecimalRoundHalfUp(BigDecimal.valueOf(distance - transportBase.getDistance_base() * 1000).divide(BigDecimal.valueOf(1000))); +// // 倍数 +// BigDecimal times = BigDecimal.ZERO; +// if (transportBase.getDistance_increase_km() > 0 && diffDistanceM.intValue() > transportBase.getDistance_increase_km()) { +// // 末尾非零进位,比如:2.1将是3, 2.0将是2,2.001将是3 +// times = NumberUtil.div(diffDistanceM, transportBase.getDistance_increase_km()).setScale(0, RoundingMode.UP); +// } +// +// // 超过基础运费距离后,累加上运费 +// deliveryBaseFee = deliveryBaseFee.add(transportBase.getDistance_increase_fee().multiply(times)); +// } +// +// // 每增加一个重量累加运费(重量暂时忽略,配置的时候设置0) +// if (transportBase.getWeight_increase_kg() != null && transportBase.getWeight_increase_fee() != null && orderWeightGram != null && orderWeightGram > transportBase.getWeight_base() * 1000) { +// // 实际配送重量超出基础重量,单位kg +// BigDecimal diffWeightKg = CommonUtil.DecimalRoundHalfUp(BigDecimal.valueOf(orderWeightGram - transportBase.getWeight_base() * 1000).divide(BigDecimal.valueOf(1000))); +// // 倍数 +// BigDecimal times = BigDecimal.ZERO; +// if (transportBase.getWeight_increase_kg() > 0 && diffWeightKg.intValue() > transportBase.getWeight_increase_kg()) { +// // 末尾非零进位,比如:2.1将是3, 2.0将是2,2.001将是3 +// times = NumberUtil.div(diffWeightKg, transportBase.getWeight_increase_kg()).setScale(0, RoundingMode.UP); +// } +// +// deliveryBaseFee = deliveryBaseFee.add(transportBase.getWeight_increase_fee().multiply(times)); +// } +// +// // 返回单位为分的配送费 +// return deliveryBaseFee.multiply(BigDecimal.valueOf(100)).intValue(); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportServiceImpl.java index fc431599..a46c4082 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportServiceImpl.java @@ -10,6 +10,7 @@ package com.suisung.mall.shop.store.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.suisung.mall.common.api.CommonResult; @@ -45,13 +46,16 @@ public class ShopStoreSameCityTransportServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("transport_id", transportId); - queryWrapper.eq("store_id", storeId); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ShopStoreSameCityTransport::getTransport_id, transportId); + if (storeId != null && storeId > 0) { + queryWrapper.eq(ShopStoreSameCityTransport::getStore_id, storeId); + } ShopStoreSameCityTransport record = getOne(queryWrapper); if (record == null) { diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSfOrderServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSfOrderServiceImpl.java index f40f1e8a..8929021d 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSfOrderServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSfOrderServiceImpl.java @@ -92,7 +92,7 @@ public class ShopStoreSfOrderServiceImpl extends BaseServiceImpl (od.order_discount_amount + od.voucher_price + od.order_points_fee + od.order_adjust_fee) as total_discount_amount, - - (od.order_item_amount-od.order_discount_amount-od.voucher_price-od.order_points_fee-od.order_adjust_fee-od.platform_fee-order_shipping_fee_inner-lkl_fee+od.packing_fee) - as order_income_amount, + + + GREATEST(0, od.trade_payment_money-od.platform_fee-od.lkl_fee) as order_income_amount, od.platform_fee, od.packing_fee, od.order_message, diff --git a/mall-shop/src/main/resources/mapper/store/ShopStoreBaseMapper.xml b/mall-shop/src/main/resources/mapper/store/ShopStoreBaseMapper.xml index e0bbc023..99f6b240 100644 --- a/mall-shop/src/main/resources/mapper/store/ShopStoreBaseMapper.xml +++ b/mall-shop/src/main/resources/mapper/store/ShopStoreBaseMapper.xml @@ -9,7 +9,7 @@ store_biz_state, store_biz_opening_date, ringtone_is_enable, shop_parent_id, store_2nd_category_id, store_category_id, store_state_id, store_time, store_end_time, product_category_ids, store_o2o_tags, store_o2o_flag, store_o2o_merchant_id, store_circle, subsite_id, lkl_merchant_no, lkl_term_no, wx_qrcode, - split_ratio, packing_fee, created_at, updated_at + split_ratio, packing_fee,parent_id,created_at, updated_at + SELECT + + FROM + shop_store_info + WHERE + store_id = #{store_id} + + diff --git a/mall-shop/src/main/resources/payKey/lakala/prod/tk_api_private_key.txt b/mall-shop/src/main/resources/payKey/lakala/prod/tk_api_private_key.txt index a17740cc..02e68fcb 100644 --- a/mall-shop/src/main/resources/payKey/lakala/prod/tk_api_private_key.txt +++ b/mall-shop/src/main/resources/payKey/lakala/prod/tk_api_private_key.txt @@ -1 +1 @@ -MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKnlpXdmJcbZHxh3w3Ghy/5wXtUBQcFzRMXgw2d7uYjzAzbIQ/ZCAj6srWoN/obtkU+G62kgcpByGmiVtK4LS+BoelKM705SzV+mcr8mNmr2jwNq1SwDSfgVxx5z00FtXl3LnKvCujvGYOmx6+nX8h6IiyyLX6IP6cFaqpUXHsZVAgMBAAECgYA4NpeM7etJ48T6H4Y3LsWEJkH6UDQlgbIblsaQkstMmLtTgOebrzN28UNfd8njcu9FVOrHGclOKbK7L+1cOLiduWsZKc/c/gAy9wAR4EhoLvlerH9EEPiPWFxdEDbMxPqlkpqLOo+PxHrhTn4vU4CaPdJtL2ujKn7nmsUdUDWo8QJBANS1TlM6nhPt2XlzN5kGfsJ4kBYNjuLXNA2YdNuC2ttYvEXHJ9T70FN/GnRBBIZu47uHH3Ie5nfep+qMk6a8RP8CQQDMecIyI0z1kVt+tOfWKw2ZFLsi74708qTaeR4W1ABtkngj1+bxoWWXr3KqhjqJkWxnhioSfXqu7CScNzjdM1CrAkAQd+ESjI1EmbumrYb2cAxMXi05p98SLPs4uj8B58WuCda5yEuLL9vXOxX/PjFtfxRepn2GxmGtki2J+UxNMnJdAkAFoORjlO0tZU7rcfdfwdeh+xwbnhSFUZiQGv1lC3jnizybX/oPdK3jOwUhBIjf+IzPXLYTxDh4UC/BzRNXo235AkEAhgYBk6H7RU2iIuvwz1c6CtE1gJ8DvEp1F0KOMWMFB0KCpDXUToix0dlMz962FozYENi4X4zYQo6nFwlXeS3Pfw== \ No newline at end of file +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAI4dPEw5wEGxH9aN+5WwFazEDvhomT/FWX0yHQRMdL0CTi8dy0hIN1sdNEbBmcOKc6dw2XHQCVQS3hfFFvpmnUqLJi32RbMhzxYz8Li9zN45eNKhiUfm/LupucHeTm3axGfOT3dfi0uhgq9LHk7ku12Pe+JIYdDu8RMCNeLJ7/AJAgMBAAECgYBAJSgLS+HghN9XC50sMl+GLLSJIUVSyHQdE1qPjyb+DSVXFP6lcJsz0BnBei86WKrdQA2V1o3vWdjPJ9G4UkraJ3hz2elzEeYok+MpLiPRicUd9RNHTVp9YqTzFyAsuranMxwt07tQaZBGc0T6hiGEsSHShwA+FfLGmz0TacR7hQJBAMOjlnP6zEzjUiW0BoZDnLHR6B5EpVVwhN7gS1B0HZtkGOjuoMz8z/GBbKLniGUtoRTDqFE4MJe7iA7237DZvscCQQC59gcIU4ezoonbDvMPbr4GMCgjP2eVrXUD02qGLJlQ45Wla6FpFZvQH5Wno5qRjdU9+Kjwms4lTTLVPHHfh0qvAkEAj2O9CDCPwOLz+JJkHdA8btBskpK5o0+e80Ptr4ALmzLYVxFfZh79wgKcPyH4BEBXScLGARFv/CYE6QLknNhbTQJAZ+F5+DrBOaX4oHhvaxWP7WEFavtGYCSvk12MyjsrwjYAKJJBbrR1gAPE1Arek6TJlH7N0OqJcej4FopXimjHXQJBAIS5nqeJPd3J7ath+uge+itkQUJnrTDHe4Feinmenuh6YLcwVJwuGqtUqxUUW/6TCrxdlMdiFmBjBjr7lkhlnuc= \ No newline at end of file diff --git a/mall-shop/src/main/resources/payKey/lakala/prod/tk_api_public_key.txt b/mall-shop/src/main/resources/payKey/lakala/prod/tk_api_public_key.txt index 7f699e3a..d8f2bef4 100644 --- a/mall-shop/src/main/resources/payKey/lakala/prod/tk_api_public_key.txt +++ b/mall-shop/src/main/resources/payKey/lakala/prod/tk_api_public_key.txt @@ -1 +1 @@ -MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp5aV3ZiXG2R8Yd8Nxocv+cF7VAUHBc0TF4MNne7mI8wM2yEP2QgI+rK1qDf6G7ZFPhutpIHKQchpolbSuC0vgaHpSjO9OUs1fpnK/JjZq9o8DatUsA0n4Fccec9NBbV5dy5yrwro7xmDpsevp1/IeiIssi1+iD+nBWqqVFx7GVQIDAQAB \ No newline at end of file +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCOHTxMOcBBsR/WjfuVsBWsxA74aJk/xVl9Mh0ETHS9Ak4vHctISDdbHTRGwZnDinOncNlx0AlUEt4XxRb6Zp1KiyYt9kWzIc8WM/C4vczeOXjSoYlH5vy7qbnB3k5t2sRnzk93X4tLoYKvSx5O5Ltdj3viSGHQ7vETAjXiye/wCQIDAQAB \ No newline at end of file diff --git a/pom.xml b/pom.xml index 47bd110b..4b182fb6 100644 --- a/pom.xml +++ b/pom.xml @@ -324,10 +324,10 @@ 114.132.210.208:8718 114.132.210.208 - 3306 + 13307 mall_dev web_dev - Abc654321$^ + bbWHo1th]g25 com.mysql.cj.jdbc.Driver @@ -383,10 +383,10 @@ 114.132.210.208:8718 114.132.210.208 - 3306 + 13307 mall_dev web_dev - Abc654321$^ + bbWHo1th]g25 com.mysql.cj.jdbc.Driver 114.132.210.208 @@ -436,10 +436,10 @@ 10.1.8.3:8718 114.132.210.208 - 3306 + 13307 mall_dev web_dev - Abc654321$^ + bbWHo1th]g25 com.mysql.cj.jdbc.Driver 10.1.8.3