入驻修复

This commit is contained in:
Jack 2025-09-23 21:24:59 +08:00
parent f6460ab75c
commit 1d3fa6ebad
19 changed files with 46414 additions and 19165 deletions

View File

@ -11,7 +11,7 @@ import org.springframework.stereotype.Component;
@ToString
public class ConfigConstant {
public static final String VERSION = "1.0.1"; //网站版本
public static final String VERSION = "1.0.2"; //网站版本
public static final Integer MAX_LIST_NUM = -1; //最大页码

View File

@ -87,7 +87,10 @@ public class ShopStoreBase implements Serializable {
@ApiModelProperty(value = "上级店铺编号:创建店铺决定,所属分销商-不可更改! 佣金公平性考虑")
private Integer shop_parent_id;
@ApiModelProperty(value = "店铺分类编号")
@ApiModelProperty(value = "店铺二级分类编号")
private Integer store_2nd_category_id;
@ApiModelProperty(value = "店铺一级分类编号")
private Integer store_category_id;
@ApiModelProperty(value = "店铺资料信息状态(ENUM):3210-待完善资料; 3220-等待审核; 3230-资料审核没有通过; 3240-资料审核通过,待付款")

View File

@ -5,6 +5,7 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.suisung.mall.common.modules.base.ShopBaseStoreCategory;
import com.suisung.mall.common.utils.CheckUtil;
import com.suisung.mall.common.utils.CommonUtil;
import com.suisung.mall.core.web.service.RedisService;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
@ -167,17 +168,17 @@ public class ShopBaseStoreCategoryServiceImpl extends BaseServiceImpl<ShopBaseSt
@Override
public BigDecimal getStoreCategoryRatio(Integer storeCategoryId) {
// 默认分账比例为100%
BigDecimal defaultRatio = new BigDecimal(100);
BigDecimal defaultRatio = new BigDecimal(94);
try {
// 检查参数是否为空
if (ObjectUtil.isEmpty(storeCategoryId)) {
if (CheckUtil.isEmpty(storeCategoryId)) {
return defaultRatio;
}
// 根据ID获取店铺分类信息
ShopBaseStoreCategory shopBaseStoreCategory = get(storeCategoryId);
if (ObjectUtil.isEmpty(shopBaseStoreCategory)) {
if (shopBaseStoreCategory == null) {
return defaultRatio;
}

View File

@ -8,15 +8,19 @@
package com.suisung.mall.shop.lakala.controller.mobile;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.LklBanksService;
import com.suisung.mall.shop.lakala.service.impl.LklTkServiceImpl;
import com.suisung.mall.shop.lakala.utils.LakalaUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.util.Pair;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@ -27,6 +31,7 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Slf4j
@Api(tags = "拉卡拉商户进件控制器")
@RestController
@RequestMapping("/mobile/shop/lakala/tk")
@ -38,6 +43,10 @@ public class LklTkController extends BaseControllerImpl {
@Resource
private LklBanksService lklBanksService;
@Lazy
@Resource
private LakalaApiService lakalaPayService;
@ApiOperation(value = "解密拉卡拉进件返回的异步通知", notes = "解密拉卡拉进件返回的异步通知")
@RequestMapping(value = "/decode", method = RequestMethod.POST)
public String decryptLklTkData(@RequestParam(name = "data") String data,
@ -50,8 +59,33 @@ public class LklTkController extends BaseControllerImpl {
@ApiOperation(value = "搜索国内银行(支行)分页列表", notes = "搜索国内银行(支行)分页列表,数据包含有效的收款结清行号")
@RequestMapping(value = "/bank/search", method = RequestMethod.POST)
public CommonResult searchLklBanksPageList(@RequestBody JSONObject paramsJSON) {
// Page<LklBanks> list = lklBanksService.searchBranchBanksPageList(paramsJSON.getStr("keyword"), paramsJSON.getInt("pageNum"), paramsJSON.getInt("pageSize"));
IPage<Map> list = lklBanksService.pageBranchBanksList("", "", 2, paramsJSON.getStr("keyword"), paramsJSON.getInt("pageNum"), paramsJSON.getInt("pageSize"));
log.debug("开始搜索国内银行(支行)分页列表,参数: {}", paramsJSON);
String clearNo = "";
String bankCardNo = paramsJSON.getStr("bankCardNo");
String keyword = paramsJSON.getStr("keyword");
Integer pageNum = paramsJSON.getInt("pageNum");
Integer pageSize = paramsJSON.getInt("pageSize");
log.debug("搜索参数: bankCardNo={}, keyword={}, pageNum={}, pageSize={}", bankCardNo, keyword, pageNum, pageSize);
// 参数校验
if (StrUtil.isBlank(bankCardNo)) {
log.warn("银行卡号为空,无法获取银行信息");
} else {
// 通过卡号获取银行信息
CommonResult result = lakalaPayService.getBankCardBin(bankCardNo);
if (result != null && result.getStatus() == 200L && result.getData() != null) {
JSONObject bankInfo = (JSONObject) result.getData();
clearNo = bankInfo.getStr("clearingBankCode", bankInfo.getStr("bankCode"));
log.debug("获取到银行清算行号: {}", clearNo);
} else {
log.warn("获取银行卡BIN信息失败result={}", result);
}
}
IPage<Map> list = lklBanksService.pageBranchBanksList("", "", clearNo, 2, keyword, pageNum, pageSize);
log.info("搜索国内银行(支行)分页列表完成,结果数量: {}", list != null ? list.getTotal() : 0);
return CommonResult.success(list);
}

View File

@ -22,5 +22,5 @@ import java.util.Map;
@Repository
public interface LklBanksMapper extends BaseMapper<LklBanks> {
IPage<Map> pageBranchBanksList(Page<Map> page, @Param("bankNo") String bankNo, @Param("branchBankNo") String branchBankNo, @Param("type") Integer type, @Param("keywords") List<String> keywords);
IPage<Map> pageBranchBanksList(Page<Map> page, @Param("bankNo") String bankNo, @Param("branchBankNo") String branchBankNo, @Param("clearNo") String clearNo, @Param("type") Integer type, @Param("keywords") List<String> keywords);
}

View File

@ -32,13 +32,14 @@ public interface LklBanksService {
*
* @param bankNo 总行号
* @param branchBankNo 支行号
* @param clearNo 清算行号
* @param type 1-店铺地区2-银行地区
* @param keyword 查询关键字,做分词
* @param pageNum
* @param pageSize
* @return
*/
IPage<Map> pageBranchBanksList(String bankNo, String branchBankNo, Integer type, String keyword, Integer pageNum, Integer pageSize);
IPage<Map> pageBranchBanksList(String bankNo, String branchBankNo, String clearNo, Integer type, String keyword, Integer pageNum, Integer pageSize);
/**
* 根据支行号查询支行信息带省市地区

View File

@ -644,28 +644,30 @@ public class LakalaApiServiceImpl implements LakalaApiService {
String contactMobile = shopMchEntry.getLogin_mobile(); // 商户入驻注册的手机号
String fileName = "商家分账授权委托书.pdf";
JSONObject paramsJSON = new JSONObject();
paramsJSON.put("version", "2.0");
paramsJSON.put("orderNo", orderNo);
paramsJSON.put("orgCode", orgCode);
paramsJSON.put("merInnerNo", merCupNoValue);
paramsJSON.put("merCupNo", merCupNoValue);
paramsJSON.put("contactMobile", contactMobile);
JSONObject reqData = new JSONObject();
reqData.put("version", "1.0");
reqData.put("orderNo", orderNo);
reqData.put("orgCode", orgCode);
// reqData.put("merInnerNo", merCupNoValue);
reqData.put("merCupNo", merCupNoValue);
reqData.put("contactMobile", contactMobile);
// 电子合同号可能为空需要检查
String eleContractNo = shopMchEntry.getLkl_ec_no();
if (StringUtils.isNotBlank(eleContractNo)) {
paramsJSON.put("eleContractNo", eleContractNo);
reqData.put("eleContractNo", eleContractNo);
}
paramsJSON.put("splitEntrustFileName", fileName);
paramsJSON.put("splitEntrustFilePath", splitEntrustFilePath);
paramsJSON.put("retUrl", notifyUrl);
reqData.put("splitEntrustFileName", fileName);
reqData.put("splitEntrustFilePath", splitEntrustFilePath);
reqData.put("retUrl", notifyUrl);
paramsJSON.put("splitLowestRatio", splitLowestRatio); // 商家最低分账比例不低于 20%
paramsJSON.put("splitRange", "ALL");
paramsJSON.put("settleType", "01"); //01主动提款 03交易自动结算 不填默认01
reqData.put("splitLowestRatio", splitLowestRatio); // 商家最低分账比例不低于 20%
reqData.put("splitRange", "ALL");
reqData.put("settleType", "01"); //01主动提款 03交易自动结算 不填默认01
// paramsJSON.put("splitLaunchMode", "MANUAL");
// paramsJSON.put("splitRuleSource", "MER");
// paramsJSON.put("sepFundSource", "TR");
@ -689,10 +691,13 @@ public class LakalaApiServiceImpl implements LakalaApiService {
operationType = "开通";
}
JSONObject paramsJSON = LakalaUtil.buildParams();
paramsJSON.set("reqData", reqData);
//3. 发送请求
log.info("开始向拉卡拉提交分账业务{}申请,商户号: {}", operationType, merCupNo);
String responseStr = LKLSDK.httpPost(postUrl, paramsJSON.toString());
log.debug("商户分账业务{}申请请求参数: 请求地址:{}\n {}\n 响应数据:{}", operationType, postUrl, paramsJSON, responseStr);
log.debug("商户分账业务{}申请请求参数: 请求地址:{}\n {}\n 响应数据:{}", operationType, postUrl, reqData, responseStr);
if (StrUtil.isBlank(responseStr)) {
log.error("申请拉卡拉分账业务{}无返回值,商户号: {}", operationType, merCupNo);
return Pair.of(false, I18nUtil._("申请拉卡拉分账业务无返回值!"));
@ -716,16 +721,16 @@ public class LakalaApiServiceImpl implements LakalaApiService {
return Pair.of(false, errorMsg);
}
paramsJSON.set("applyId", applyId);
reqData.set("applyId", applyId);
String retMsg = lakalaRespJSON.getStr("retMsg");
paramsJSON.set("remark", retMsg);
paramsJSON.set("auditStatusText", retMsg); // 直接使用retMsg避免null值
paramsJSON.set("mchId", shopMchEntry.getId());
reqData.set("remark", retMsg);
reqData.set("auditStatusText", retMsg); // 直接使用retMsg避免null值
reqData.set("mchId", shopMchEntry.getId());
// 新增数据
log.debug("准备保存分账业务申请记录");
// JSON 对象的键名转换为下划线命名
String snakeCaseJson = StringUtils.convertCamelToSnake(paramsJSON.toString());
String snakeCaseJson = StringUtils.convertCamelToSnake(reqData.toString());
if (StringUtils.isBlank(snakeCaseJson)) {
log.error("JSON转换为下划线命名格式失败商户号: {}", merCupNo);
return Pair.of(false, I18nUtil._("数据格式转换失败!"));
@ -1170,6 +1175,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
String auditStatus = paramsJSON.getStr("auditStatus");
String merCupNo = paramsJSON.getStr("merCupNo");
String auditStatusText = paramsJSON.getStr("auditStatusText");
String remark = paramsJSON.getStr("remark");
if (StrUtil.isBlank(applyId) || StrUtil.isBlank(auditStatus) || StrUtil.isBlank(merCupNo)) {
String errMsg = "商户分账业务申请异步回调缺少必要参数applyId/auditStatus/merCupNo";
@ -1181,10 +1187,10 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 1:通过2拒绝
if (!auditStatus.equals("1")) {
log.warn("商户分账业务申请异步回调:审核未通过,状态={}", auditStatus);
log.warn("商户分账业务申请异步回调:审核未通过,状态={} {}", auditStatusText, auditStatus);
if (lklLedgerMember != null) {
shopMchEntryService.updateMerchEntryApprovalByMchId(
lklLedgerMember.getMch_id(), CommonConstant.MCH_APPR_STA_NOPASS, "拉卡拉分账业务审核未通过:" + auditStatusText
lklLedgerMember.getMch_id(), CommonConstant.MCH_APPR_STA_NOPASS, auditStatusText + remark
);
}
return JSONUtil.createObj().put("code", "FAIL").put("message", "分账业务审核未通过,不处理业务!");
@ -1202,7 +1208,6 @@ public class LakalaApiServiceImpl implements LakalaApiService {
String merInnerNo = paramsJSON.getStr("merInnerNo");
String entrustFileName = paramsJSON.getStr("entrustFileName");
String entrustFilePath = paramsJSON.getStr("entrustFilePath");
String remark = paramsJSON.getStr("remark");
try {
Boolean updateSuccess = lklLedgerMemberService.updateAuditResult(
@ -1283,7 +1288,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 基础参数设置
req.setOrderNo(orderNo);
req.setOrgCode(orgCode);
req.setVersion("2.0");
req.setVersion("1.0");
req.setReceiverName(paramsJSON.getStr("receiverName"));
req.setContactMobile(mchMobile);
req.setLicenseNo(paramsJSON.getStr("licenseNo"));
@ -1521,7 +1526,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
V2MmsOpenApiLedgerApplyBindRequest request = new V2MmsOpenApiLedgerApplyBindRequest();
request.setOrderNo(orderNo);
request.setOrgCode(orgCode);
request.setVersion("2.0");
request.setVersion("1.0");
request.setMerInnerNo(lklLedgerMember.getMer_inner_no());
request.setMerCupNo(merCupNo);
request.setReceiverNo(receiverNo);

View File

@ -83,6 +83,7 @@ public class LklBanksServiceImpl extends BaseServiceImpl<LklBanksMapper, LklBank
/**
* @param bankNo
* @param branchBankNo
* @param clearNo
* @param type
* @param keyword
* @param pageNum
@ -90,9 +91,9 @@ public class LklBanksServiceImpl extends BaseServiceImpl<LklBanksMapper, LklBank
* @return
*/
@Override
public IPage<Map> pageBranchBanksList(String bankNo, String branchBankNo, Integer type, String keyword, Integer pageNum, Integer pageSize) {
public IPage<Map> pageBranchBanksList(String bankNo, String branchBankNo, String clearNo, Integer type, String keyword, Integer pageNum, Integer pageSize) {
Page<Map> page = new Page<>(pageNum, pageSize);
return lklBanksMapper.pageBranchBanksList(page, bankNo, branchBankNo, type, jiebaUtils.segmentForSearch(keyword));
return lklBanksMapper.pageBranchBanksList(page, bankNo, branchBankNo, clearNo, type, jiebaUtils.segmentForSearch(keyword));
}
/**
@ -107,7 +108,7 @@ public class LklBanksServiceImpl extends BaseServiceImpl<LklBanksMapper, LklBank
return null;
}
IPage<Map> list = lklBanksMapper.pageBranchBanksList(new Page<>(1, 1), null, branchBankNo, 2, null);
IPage<Map> list = lklBanksMapper.pageBranchBanksList(new Page<>(1, 1), null, branchBankNo, "", 2, null);
if (list == null || CollectionUtil.isEmpty(list.getRecords())) {
return null;
}

View File

@ -924,5 +924,44 @@ public class LklTkServiceImpl {
}
}
public JSONObject bankList(String areaCode, String bankName) {
if (StrUtil.isBlank(areaCode)) {
}
JSONObject header = new JSONObject();
header.put("Authorization", getLklTkAuthorization());
// Base64Utils.encodeToString(file.getBytes());
JSONObject requestBody = new JSONObject();
requestBody.put("areaCode", areaCode);
requestBody.put("bankName", bankName);
String urlPath = "/sit/registration/bank";
if (isLklProd) {
// 生产环境启用
urlPath = "/registration/bank";
}
try {
ResponseEntity<JSONObject> updResponse = RestTemplateHttpUtil.sendPostBodyBackEntity(buildLklTkUrl(urlPath), header, requestBody, JSONObject.class);
if (ObjectUtil.isEmpty(updResponse)
|| updResponse.getStatusCode() != HttpStatus.OK) {
logger.error("上传文件返回值有误");
return null;
}
JSONObject result = updResponse.getBody();
if (ObjectUtil.isEmpty(result)) {
return null;
}
return new JSONObject().put("id", result.get("url")).put("type", "");
} catch (Exception e) {
logger.error("上传文件异常:{}", e.getMessage());
return null;
}
}
}

View File

@ -8,7 +8,10 @@
package com.suisung.mall.shop.lakala.utils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.lkl.laop.sdk.Config2;
import com.lkl.laop.sdk.LKLSDK;
import com.suisung.mall.common.exception.ApiException;
@ -32,6 +35,7 @@ import java.security.cert.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
@ -491,4 +495,31 @@ public class LakalaUtil {
return Pair.of(true, requestBody);
}
/**
* 构建拉卡拉接口公共参数
* <p>
* 公共参数包括:
* - reqTime: 时间戳格式为yyyyMMddHHmmss
* - version: 版本号固定为1.0.0
* - reqId: 请求序列号使用UUID生成唯一标识
*
* @return 包含公共参数的JSONObject
*/
public static JSONObject buildParams() {
JSONObject params = new JSONObject();
// 时间戳格式为yyyyMMddHHmmss
String reqTime = DateUtil.format(new Date(), "yyyyMMddHHmmss");
params.set("reqTime", reqTime);
// 版本号固定为1.0.0
params.set("version", "1.0.0");
// 请求序列号使用UUID生成唯一标识并去除横线
String reqId = IdUtil.simpleUUID();
params.set("reqId", reqId);
return params;
}
}

View File

@ -3268,7 +3268,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
// RMK 第三方数据同步相关redis 给这个商品减去对应的库存
Map<String, Integer> stockDeltaMap = new HashMap<>();
stockDeltaMap.put(Convert.toStr(item_src_id), -order_item_quantity);
stockDeltaMap.put(item_src_id, -order_item_quantity);
syncThirdDataService.incrProductStockToRedis(stockDeltaMap);
}
}

View File

@ -13,6 +13,7 @@ import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import org.springframework.data.util.Pair;
import java.math.BigDecimal;
import java.util.List;
public interface ShopMchEntryService {
@ -334,4 +335,17 @@ public interface ShopMchEntryService {
* @return boolean 是否成功修复至少一个商户信息
*/
Boolean checkAndFixMchStoreInfo(String loginMobile);
/**
* 获取商户入驻分账比例
* <p>
* 该分账比例是实际的分账百分比最终提交给拉卡拉的合同的分账比例是 20%
*
* @param mch1stBizCategory 商户一级业务分类
* @param mch2ndBizCategory 商户二级业务分类
* @param srcRatio 源比例
* @param defaultRatio 无值的时候默认比例
* @return 分账比例
*/
BigDecimal getMchEntryRatioOrDefault(Integer mch1stBizCategory, Integer mch2ndBizCategory, BigDecimal srcRatio, BigDecimal defaultRatio);
}

View File

@ -29,10 +29,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.utils.BankUtil;
import com.suisung.mall.common.utils.CheckUtil;
import com.suisung.mall.common.utils.DateTimeUtils;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.common.utils.*;
import com.suisung.mall.common.utils.phone.PhoneNumberUtils;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.base.service.AccountBaseConfigService;
@ -337,8 +334,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
if (mobileAndLicenseNumber != null) {
Map<String, Object> tmplArgs = new HashMap<>(1);
tmplArgs.put("name", record.getBiz_license_company()); // 商家公司名称
// 所有店铺管理员的发送邮件 提醒商家您有一笔新的订单 ${order_id}请及时处理
shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_486545331", tmplArgs);//SMS_479760276
shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_486545331", tmplArgs);
}
log.info("商家入驻申请提交成功recordId: {},手机号: {}", record.getId(), loginMobile);
@ -369,15 +365,15 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
return CommonResult.failed("缺少必要参数!");
}
// 验证合同签署状态如果已经签署不能再次申请
ShopMchEntry oldRecord = shopMerchEntryById(shopMerchEntryJSON.getLong("id"));
if (oldRecord == null) {
return CommonResult.failed("未找到入驻记录!");
}
if (oldRecord.getSigned_status() > 0) {
return CommonResult.failed("合同签署进行中(或已签署),不能再次申请!");
}
// // 验证合同签署状态如果已经签署不能再次申请
// if (oldRecord.getSigned_status() > 0) {
// return CommonResult.failed("合同签署进行中(或已签署),不能再次申请!");
// }
ShopMchEntry record = JSONUtil.toBean(shopMerchEntryJSON, ShopMchEntry.class);
if (record == null) {
@ -466,7 +462,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
Map<String, Object> tmplArgs = new HashMap<>(1);
tmplArgs.put("name", mchName); // 商家公司名称
// 尊敬的管理员商家 ${name}提交了入驻我们平台的申请请及时对相关资质材料予以审核以便推进后续流程
shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_479760276", tmplArgs);
shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_486545331", tmplArgs);
}
return CommonResult.success();
@ -906,29 +902,19 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
}
// 查询入驻记录
ShopMchEntry record = get(mchId);
if (record == null) {
ShopMchEntry shopMchEntry = get(mchId);
if (shopMchEntry == null) {
log.warn("商家入驻记录不存在mchId={}", mchId);
return CommonResult.failed("商家入驻记录不存在!");
}
// 分账比例
BigDecimal splitRatio = record.getSplit_ratio();
if (splitRatio == null || BigDecimal.ZERO.compareTo(splitRatio) >= 0
|| record.getSplit_ratio().compareTo(new BigDecimal(100)) >= 0) {
// 自动计算商家分成比例
splitRatio = shopBaseStoreCategoryService.getStoreCategoryRatio(record.getBiz_category());
if (splitRatio == null
|| splitRatio.compareTo(BigDecimal.ZERO) <= 0
|| splitRatio.compareTo(new BigDecimal(100)) >= 0) {
splitRatio = new BigDecimal(94);
}
}
// 分账比例最终提交给拉卡拉的分账比例是 20%
BigDecimal splitRatio = getMchEntryRatioOrDefault(shopMchEntry.getBiz_category(), shopMchEntry.getBiz_second_category(), shopMchEntry.getSplit_ratio(), new BigDecimal(94));
// 如果是驳回状态直接返回成功消息
if (approvalStatus.equals(CommonConstant.MCH_APPR_STA_NOPASS)) {
// 2-未通过驳回或重新申请入驻时重置入驻申请的合同信息
record = resetAuditColumns(record);
shopMchEntry = resetAuditColumns(shopMchEntry);
// 设置默认审批备注
if (StrUtil.isBlank(approvalRemark)) {
approvalRemark = "审核未通过,请继续完善入驻资料信息。";
@ -944,18 +930,18 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
approvalInvalidCol = "[]";
}
record.setApproval_status(approvalStatus);
record.setApproval_remark(approvalRemark);
record.setApproval_invalid_col(approvalInvalidCol);
record.setUpdated_by(userId);
record.setSettlement_method(1); // 结算类型0-秒到不分账1-次日结算需要分账
record.setSplit_ratio(splitRatio);
shopMchEntry.setApproval_status(approvalStatus);
shopMchEntry.setApproval_remark(approvalRemark);
shopMchEntry.setApproval_invalid_col(approvalInvalidCol);
shopMchEntry.setUpdated_by(userId);
shopMchEntry.setSettlement_method(1); // 结算类型0-秒到不分账1-次日结算需要分账
shopMchEntry.setSplit_ratio(splitRatio);
// 转换拉卡拉的日期格式 yyyy-MM-dd
record = convLklDateFormat(record);
shopMchEntry = convLklDateFormat(shopMchEntry);
// 执行更新操作
if (!updateById(record)) {
if (!updateById(shopMchEntry)) {
log.error("系统处理审批出错请联系管理员当前记录ID: {}", mchId);
return CommonResult.failed("系统处理审批出错,请联系管理员!");
}
@ -979,7 +965,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
}
// 执行更新操作
if (!updateMerchEntryApprovalByMchId(record.getId(), null, "入网申请已提交!")) {
if (!updateMerchEntryApprovalByMchId(shopMchEntry.getId(), null, "入网申请已提交!")) {
log.error("系统处理审批出错请联系管理员当前记录ID: {}", mchId);
return CommonResult.failed("系统处理审批出错,请联系管理员!");
}
@ -2335,4 +2321,68 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
return Pair.of(true, "");
}
}
/**
* 获取商户入驻分账比例
* <p>
* 该分账比例是实际的分账百分比最终提交给拉卡拉的合同的分账比例是 20%
*
* @param mch1stBizCategory 商户一级业务分类
* @param mch2ndBizCategory 商户二级业务分类
* @param srcRatio 源比例
* @param defaultRatio 无值的时候默认比例
* @return 分账比例
*/
@Override
public BigDecimal getMchEntryRatioOrDefault(Integer mch1stBizCategory, Integer mch2ndBizCategory, BigDecimal srcRatio, BigDecimal defaultRatio) {
log.debug("开始计算商户入驻分账比例mch1stBizCategory={}, mch2ndBizCategory={}, srcRatio={}, defaultRatio={}",
mch1stBizCategory, mch2ndBizCategory, srcRatio, defaultRatio);
// 如果源比例为空则需要重新计算
if (srcRatio == null) {
log.debug("源比例无效,尝试从商户业务分类获取比例");
// 确保默认比例有效
BigDecimal effectiveDefaultRatio = defaultRatio;
if (CheckUtil.isEmpty(effectiveDefaultRatio)) {
effectiveDefaultRatio = BigDecimal.valueOf(94);
log.debug("使用系统默认比例: {}", effectiveDefaultRatio);
}
// 确定分类ID优先级二级分类 > 一级分类
Integer categoryID = mch2ndBizCategory;
if (CheckUtil.isEmpty(categoryID)) {
categoryID = mch1stBizCategory;
log.debug("二级分类为空,使用一级分类: {}", categoryID);
}
// 如果分类ID也为空则直接使用默认比例
if (CheckUtil.isEmpty(categoryID)) {
log.warn("商户分类ID为空使用默认比例: {}", effectiveDefaultRatio);
srcRatio = effectiveDefaultRatio;
} else {
// 通过分类ID获取分账比例
srcRatio = shopBaseStoreCategoryService.getStoreCategoryRatio(categoryID);
log.debug("从分类获取分账比例: {}", srcRatio);
// 如果获取的比例无效或为默认值94则使用默认比例
if (srcRatio == null || srcRatio.compareTo(BigDecimal.valueOf(94)) == 0) {
log.debug("商户业务分类比例无效或为默认值,使用默认比例: {}", effectiveDefaultRatio);
srcRatio = effectiveDefaultRatio;
}
}
}
// 验证最终分账比例的有效性
if (!CommonUtil.checkSplitRatio(srcRatio)) {
log.warn("分账比例校验失败,使用默认比例: {}, 原始比例: {}", defaultRatio, srcRatio);
srcRatio = defaultRatio;
}
log.info("商户入驻分账比例计算完成,最终比例={}", srcRatio);
return srcRatio;
}
}

View File

@ -3187,7 +3187,12 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
shopStoreBase.setUser_id(userId); // 店铺管理员用户Id
shopStoreBase.setStore_name(shopMchEntry.getStore_name());
shopStoreBase.setStore_category_id(shopMchEntry.getBiz_category()); // 重要店铺分类id对应 shop_base_store_category 表的分类
shopStoreBase.setSplit_ratio(shopMchEntry.getSplit_ratio()); // 分账比例
shopStoreBase.setStore_2nd_category_id(shopMchEntry.getBiz_second_category());
// 分账比例最终提交给拉卡拉的分账比例是 20%
BigDecimal splitRatio = shopMchEntryService.getMchEntryRatioOrDefault(shopMchEntry.getBiz_category(), shopMchEntry.getBiz_second_category(), shopMchEntry.getSplit_ratio(), new BigDecimal(94));
shopStoreBase.setSplit_ratio(splitRatio); // 分账比例
shopStoreBase.setPacking_fee(BigDecimal.ZERO);// 默认0元打包费
String storeFacadeImage = shopMchEntry.getFront_facade_image();
String storeLogoImage = shopMchEntry.getStore_logo();
@ -3708,7 +3713,8 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
public BigDecimal getStoreSplitRatio(Integer storeId, boolean reCalculate) {
log.debug("开始获取店铺分账比例storeId={}, reCalculate={}", storeId, reCalculate);
BigDecimal defaultSplitRatio = new BigDecimal(94);
// 定义默认分账比例
final BigDecimal defaultSplitRatio = BigDecimal.valueOf(94);
if (storeId == null || storeId <= 0) {
log.warn("店铺ID无效使用默认分账比例: {}", defaultSplitRatio);
return defaultSplitRatio;
@ -3716,63 +3722,24 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
BigDecimal splitRatio = null;
// 获取店铺基础信息
ShopStoreBase shopStoreBase = get(storeId);
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByStoreId(storeId);
log.debug("获取店铺和商户入驻信息完成shopStoreBase={}, shopMchEntry={}",
shopStoreBase != null ? shopStoreBase.getStore_id() : null,
shopMchEntry != null ? shopMchEntry.getId() : null);
if (shopStoreBase != null && CheckUtil.isNotEmpty(shopStoreBase.getSplit_ratio())
&& shopMchEntry != null && CheckUtil.isNotEmpty(shopMchEntry.getSplit_ratio()) &&
shopMchEntry.getSplit_ratio().compareTo(shopStoreBase.getSplit_ratio()) != 0) {
// 如果入驻申请的分账比例和店铺的分账比例不一致则使用入驻申请比例并同步给店铺记录
splitRatio = shopMchEntry.getSplit_ratio();
log.debug("入驻申请分账比例与店铺分账比例不一致,使用入驻申请比例: {}", splitRatio);
// RMK 同步给店铺记录
updateStoreBaseSplitRatio(storeId, splitRatio);
} else if (shopMchEntry != null) {
// 优先获取商家入驻申请已配置的分账比例
splitRatio = CheckUtil.isEmpty(shopMchEntry.getSplit_ratio()) ? null : shopMchEntry.getSplit_ratio();
log.debug("从商户入驻信息获取分账比例: {}", splitRatio);
} else {
// 获取店铺基础信息
if (shopStoreBase == null) {
log.warn("店铺基础信息不存在,使用默认分账比例: {}", defaultSplitRatio);
return defaultSplitRatio;
}
log.debug("获取店铺基础信息完成shopStoreBase={}",
shopStoreBase != null ? shopStoreBase.getStore_id() : null);
if (shopStoreBase != null) {
// 获取店铺已配置的分账比例
splitRatio = CheckUtil.isEmpty(shopStoreBase.getSplit_ratio()) ? null : shopStoreBase.getSplit_ratio();
log.debug("从店铺基础信息获取分账比例: {}", splitRatio);
}
// 如果没有配置或需要重新计算则基于店铺分类获取比例
if (reCalculate || splitRatio == null) {
log.debug("需要重新计算分账比例或当前比例为空,基于店铺分类计算");
if (shopStoreBase == null) {
shopStoreBase = get(storeId);
}
Integer storeCategoryId = shopStoreBase != null ? shopStoreBase.getStore_category_id() : null;
if (storeCategoryId == null) {
log.warn("店铺分类ID为空使用默认分账比例: {}", defaultSplitRatio);
return defaultSplitRatio; // 默认 94%
}
// 获取店铺分类信息
ShopBaseStoreCategory category = shopBaseStoreCategoryService.get(storeCategoryId);
if (category != null && category.getSplit_ratio() != null) {
splitRatio = category.getSplit_ratio();
log.debug("从店铺分类获取分账比例: {}", splitRatio);
} else {
log.warn("店铺分类分账比例为空,使用默认分账比例: {}", defaultSplitRatio);
splitRatio = defaultSplitRatio; // 默认 94%
}
// 通过商户入驻服务计算分账比例传入null作为一级分类店铺分类ID作为二级分类
splitRatio = shopMchEntryService.getMchEntryRatioOrDefault(shopStoreBase.getStore_category_id(), shopStoreBase.getStore_2nd_category_id(), splitRatio, defaultSplitRatio);
log.debug("通过商户入驻服务计算分账比例: {}", splitRatio);
}
// 确保比例在有效范围内 (0%, 100%)

View File

@ -17,15 +17,15 @@
JOIN lkl_area c on c.area_code=b.parent_code and c.type=b.type
<where>
<if test="bankNo!=null and bankNo!=''">
and bank_no = #{bankNo}
and a.bank_no = #{bankNo}
</if>
<if test="branchBankNo!=null and branchBankNo!=''">
and branch_bank_no = #{branchBankNo}
and a.branch_bank_no = #{branchBankNo}
</if>
<if test="branchBankNo!=null and branchBankNo!=''">
and branch_bank_no = #{branchBankNo}
<if test="clearNo!=null and clearNo!=''">
and a.clear_no = #{clearNo}
</if>
<choose>
@ -40,7 +40,7 @@
<if test="keywords!=null and keywords.size>0">
AND (
<foreach collection="keywords" item="keyword" separator="AND">
branch_bank_name LIKE CONCAT('%', #{keyword}, '%')
a.branch_bank_name LIKE CONCAT('%', #{keyword}, '%')
</foreach>
)
</if>

View File

@ -6,7 +6,7 @@
store_id
, user_id, store_name, store_grade_id, store_logo, store_slogan, store_domain, store_area, store_district_id,
store_address, store_latitude, store_longitude, store_is_selfsupport, store_type, store_is_open, store_biz_state,
ringtone_is_enable, shop_parent_id,
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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff