Compare commits

...

41 Commits

Author SHA1 Message Date
3c680bdf13 Merge branch 'main' into dev 2025-05-21 09:11:49 +08:00
20726bf256 Merge remote-tracking branch 'origin/main' 2025-05-20 21:13:35 +08:00
ba284b945f 优化个别异步通知方法 2025-05-20 21:13:30 +08:00
7cdb9f88f2 同步目录添加 2025-05-20 19:02:28 +08:00
b063d41b4f 同步目录添加 2025-05-20 19:02:06 +08:00
46af45ebd9 还原多余代码 2025-05-20 18:59:29 +08:00
db25392dbb 商瑞9.7客户端代码提交 2025-05-20 18:59:11 +08:00
1459581e37 商瑞9.7同步数据服务端开发 2025-05-20 18:56:54 +08:00
bff10a587e im项目添加长度 2025-05-20 18:11:55 +08:00
9d287da156 分账业务申请和异步通知方法 修复 2025-05-20 17:04:47 +08:00
a01c9adb25 增加分账指令模块,和表结构 2025-05-18 23:49:10 +08:00
42dc03453d 回归测试,修复bug 2025-05-18 16:47:25 +08:00
9614312bcd 异步通知处理,加上事务处理。 2025-05-18 11:09:33 +08:00
b865aafadf 回归测试,bug修改 2025-05-18 03:51:21 +08:00
2feebfafd4 分账比例 默认配置化 2025-05-17 11:10:45 +08:00
3f35de9507 拉卡拉银行搜索,带出区域code 和 name 2025-05-16 10:24:12 +08:00
98275e1593 拉卡拉 入网电子合同申请 相关业务逻辑,修改加密方法 2025-05-16 07:04:34 +08:00
8eb9cf3ce6 拉卡拉 入网电子合同申请 相关业务逻辑,修改加密方法 2025-05-15 15:53:29 +08:00
40beddaaa5 拉卡拉 入网电子合同申请 相关业务逻辑 2025-05-14 23:49:03 +08:00
b377244cb4 拉卡拉联调 bug 修复 2025-05-14 16:13:54 +08:00
d1c6630ef5 修改拉卡拉的加密解密 2025-05-14 00:51:51 +08:00
fe3a25b352 银行搜索增加了分词功能 2025-05-12 23:29:16 +08:00
2d2b0364f0 入驻审核状态调整,bug 修复 2025-05-11 22:37:35 +08:00
764ebfbc48 更新商家分账的四个状态 2025-05-10 16:12:16 +08:00
1e5c8145c4 增加拉卡拉银行接口进去 2025-05-10 14:47:42 +08:00
59473c5dc7 修改配置文件,和 bug 修改 2025-05-09 12:05:37 +08:00
3974a08c85 ocr 调试,todo 2025-05-09 00:30:19 +08:00
2407520ca5 ocr 调试,todo 2025-05-08 11:50:39 +08:00
d46541b90a ocr 调试,todo 2025-05-08 00:35:12 +08:00
8873bff6e5 入驻连起来 2025-05-06 00:25:52 +08:00
2ed235f8fb 修改代理商表结构 2025-05-04 23:33:26 +08:00
0f563493ef 修改代理商表结构 2025-05-03 19:07:41 +08:00
17778c2e1c 修复 拉卡拉 分账接口bug, 商家订单列表 修复 2025-04-30 16:58:59 +08:00
f335937d3e 修复 拉卡拉 分账接口bug 2025-04-28 11:40:16 +08:00
ce558afe78 fix:文件上传后缀不支持大写问题修复 2025-04-28 11:25:12 +08:00
c34aa3365e 修复 拉卡拉 分账接口bug 2025-04-27 17:37:05 +08:00
5f796adc02 优化拉卡拉分账相关的方法 2025-04-27 10:23:22 +08:00
18da67511e shop 项目增加拉卡拉的业务逻辑 2025-04-25 00:19:48 +08:00
c1896f3c39 shop 项目增加拉卡拉的业务逻辑 2025-04-24 17:38:12 +08:00
39e52b54fd 热更新包维护接口 2025-04-23 22:43:34 +08:00
a4aa10f1bc 热更新包维护接口 2025-04-22 00:29:57 +08:00
99 changed files with 7169 additions and 795 deletions

View File

@ -84,8 +84,14 @@ public class WeiXinController extends BaseControllerImpl {
return CommonResult.success(weiXinService.jsCode2Session(code, encryptedData, iv, activity_id, user_info));
}
@ApiOperation(value = "获取微信的 OpenId")
@RequestMapping(value = "/getWxOpenId", method = {RequestMethod.GET, RequestMethod.POST})
public CommonResult jsCode2Session(@RequestParam(name = "code") String code) {
return CommonResult.success(weiXinService.getJsCode2Session(code));
}
@ApiOperation(value = "获取微信小程序用户授权手机号,并绑定登录用户")
@RequestMapping(value = "/getUserPhoneNumber", method = RequestMethod.GET)
@RequestMapping(value = "/getUserPhoneNumber", method = {RequestMethod.GET, RequestMethod.POST})
public CommonResult getUserPhoneNumber(@RequestParam(name = "code") String code) {
return CommonResult.success(weiXinService.getUserPhoneNumberAndBindUser(code, getCurrentUser()));
}

View File

@ -35,6 +35,14 @@ public interface WeiXinService {
Map<String, Object> checkAppLogin(String code);
/**
* 纯粹获取微信用户的 OpenId
*
* @param code
* @return
*/
Map<String, String> getJsCode2Session(String code);
Map jsCode2Session(String code, String encryptedData, String iv, String activity_id, String user_info);
/**

View File

@ -359,7 +359,14 @@ public class WeiXinServiceImpl implements WeiXinService {
return userInfo;
}
private Map<String, String> getJsCode2Session(String code) {
/**
* 纯粹获取微信用户的 OpenId
*
* @param code
* @return
*/
@Override
public Map<String, String> getJsCode2Session(String code) {
//从微信服务器获得session_key,openid,unionid
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";

View File

@ -0,0 +1,56 @@
/*
* 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.admin.controller.admin;
import cn.hutool.json.JSONObject;
import com.suisung.mall.admin.service.AdminAppMarketUpdateService;
import com.suisung.mall.common.api.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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;
@Api(tags = "安卓应用市场 APP 版本检查")
@RestController
@RequestMapping("/admin/admin/app-market-update")
public class AdminAppMarketUpdateController {
@Resource
private AdminAppMarketUpdateService adminAppMarketUpdateService;
@ApiOperation(value = "安卓市场热更新记录搜索列表", notes = "安卓市场热更新记录搜索列表")
@RequestMapping(value = "/search/list", method = RequestMethod.POST)
public CommonResult searchList(@RequestBody JSONObject paramsJSON) {
return adminAppMarketUpdateService.searchListInAdmin(paramsJSON.getInt("marketId"), paramsJSON.getStr("keyword"), paramsJSON.getInt("pageNum"), paramsJSON.getInt("pageSize"));
}
@ApiOperation(value = "新增安卓市场热更新记录", notes = "新增安卓市场热更新记录")
@RequestMapping(value = "/add/new", method = RequestMethod.POST)
public CommonResult addNew(@RequestBody JSONObject paramsJSON) {
return adminAppMarketUpdateService.addNewInAdmin(paramsJSON);
}
@ApiOperation(value = "修改安卓市场热更新记录", notes = "修改安卓市场热更新记录")
@RequestMapping(value = "/modify", method = RequestMethod.POST)
public CommonResult modify(@RequestBody JSONObject paramsJSON) {
return adminAppMarketUpdateService.modifyInAdmin(paramsJSON);
}
@ApiOperation(value = "关闭安卓市场热更新记录", notes = "关闭安卓市场热更新记录")
@RequestMapping(value = "/enable-or-disable", method = RequestMethod.POST)
public CommonResult enableOrDisable(@RequestBody JSONObject paramsJSON) {
return adminAppMarketUpdateService.enableOrDisableInAdmin(paramsJSON.getLong("id"), paramsJSON.getInt("status"));
}
}

View File

@ -9,6 +9,7 @@
package com.suisung.mall.admin.controller.mobile;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.suisung.mall.admin.service.AdminAppMarketUpdateService;
import com.suisung.mall.common.api.CommonResult;
@ -24,7 +25,7 @@ import javax.annotation.Resource;
@Api(tags = "安卓应用市场 APP 版本检查")
@RestController
@RequestMapping("/mobile/admin/app-market-update")
public class AdminAppMarketUpdateController {
public class AppMarketUpdateController {
@Resource
private AdminAppMarketUpdateService adminAppMarketUpdateService;
@ -35,4 +36,14 @@ public class AdminAppMarketUpdateController {
return adminAppMarketUpdateService.checkLatestVersion(paramsJSON.getInt("marketId"), paramsJSON.getStr("packageName"), paramsJSON.getInt("currVersionKey"));
}
@ApiOperation(value = "最新通用商家版App下载地址", notes = "最新通用商家版App下载地址")
@RequestMapping(value = "/last/apk", method = RequestMethod.POST)
public CommonResult lastCommonApp(@RequestBody(required = false) JSONObject paramsJSON) {
Integer marketId = 100;
if (paramsJSON != null && ObjectUtil.isNotEmpty(paramsJSON.getInt("marketId"))) {
marketId = paramsJSON.getInt("marketId");
}
return adminAppMarketUpdateService.lastAdminAppMarketUpdate(marketId);
}
}

View File

@ -41,6 +41,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
@ -92,6 +93,18 @@ public class OssServiceImpl implements OssService {
@Value("${upload.filepath}")
private String FILEPATH;
/**
* 判断路径是否存在不存在创建
*
* @param dirPath
*/
private static void isChartPathExist(String dirPath) {
File file = new File(dirPath);
if (!file.exists()) {
file.mkdirs();
}
}
/**
* 移动端上传文件
*
@ -163,7 +176,7 @@ public class OssServiceImpl implements OssService {
if (uploadType.equals(1)) {
url = ConfigConstant.URL_BASE + "/admin/oss/upload/" + dir + "/" + uploadName; // 文件本地路径
} else if (uploadType.equals(2)){
} else if (uploadType.equals(2)) {
// oss 服务
try {
url = uploadObject2OSS(new File(uploadPath), ALIYUN_OSS_DIR_PREFIX.concat("/").concat(dir).concat(uploadName));
@ -186,13 +199,11 @@ public class OssServiceImpl implements OssService {
//截图
//todo 放入upload中
String thumb_file_url = "";
if (VideoUtil.videoAllowFiles.contains(VideoUtil.getVideoFormat(uploadPath)))
{
if (VideoUtil.videoAllowFiles.contains(VideoUtil.getVideoFormat(uploadPath))) {
String cover_path = uploadPath.replace("." + VideoUtil.getVideoFormat(uploadPath), ".jpg");
String cover_upname = uploadName.replace("." + VideoUtil.getVideoFormat(uploadName), ".jpg");
if (VideoUtil.getVideoCover(uploadPath, cover_path, 1, "375*667"))
{
if (VideoUtil.getVideoCover(uploadPath, cover_path, 1, "375*667")) {
try {
thumb_file_url = uploadObject2OSS(new File(cover_path), ALIYUN_OSS_DIR_PREFIX.concat("/").concat(dir).concat("/").concat(cover_upname));
} catch (Exception e) {
@ -200,9 +211,7 @@ public class OssServiceImpl implements OssService {
thumb_file_url = "";
}
}
else
{
} else {
thumb_file_url = "";
}
}
@ -247,7 +256,7 @@ public class OssServiceImpl implements OssService {
// 创建唯一文件名称
String suffix = fileName.substring(fileName.lastIndexOf("."));
String uploadName = IdUtil.simpleUUID() + suffix;
String uploadPath = FILEPATH + "/" + dir + "/" + uploadName;
String uploadPath = FILEPATH + "/" + dir + "/" + uploadName;
String imageAllowExt = configService.getConfig("image_allow_ext", "");
String[] imageAllowExtList = imageAllowExt.split(",");
@ -297,9 +306,9 @@ public class OssServiceImpl implements OssService {
}
}
/**
* 腾讯云上传
*
* @param file
* @param concat
* @return
@ -378,10 +387,10 @@ public class OssServiceImpl implements OssService {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String dir = ALIYUN_OSS_DIR_PREFIX + sdf.format(new Date());
// 签名有效期
long expireEndTime = System.currentTimeMillis() + ALIYUN_OSS_EXPIRE * 1000;
long expireEndTime = System.currentTimeMillis() + ALIYUN_OSS_EXPIRE * 1000L;
Date expiration = new Date(expireEndTime);
// 文件大小
long maxSize = ALIYUN_OSS_MAX_SIZE * 1024 * 1024;
long maxSize = (long) ALIYUN_OSS_MAX_SIZE * 1024 * 1024;
// 回调
OssCallbackParamDTO callback = new OssCallbackParamDTO();
callback.setCallbackUrl(ALIYUN_OSS_CALLBACK);
@ -394,10 +403,10 @@ public class OssServiceImpl implements OssService {
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
String policy = BinaryUtil.toBase64String(binaryData);
String signature = ossClient.calculatePostSignature(postPolicy);
String callbackData = BinaryUtil.toBase64String(JSONUtil.parse(callback).toString().getBytes("utf-8"));
String callbackData = BinaryUtil.toBase64String(JSONUtil.parse(callback).toString().getBytes(StandardCharsets.UTF_8));
// 返回结果
result.setAccessKeyId(ossClient.getCredentialsProvider().getCredentials().getAccessKeyId());
result.setPolicy(policy);
@ -486,7 +495,7 @@ public class OssServiceImpl implements OssService {
* @return
*/
private String getUserDirName(UserDto user) {
if (user.getId() == null) {
if (user == null || user.getId() == null) {
throw new ApiException(I18nUtil._("获取用户信息失败!"));
}
if (user.isPlatform()) {
@ -499,16 +508,4 @@ public class OssServiceImpl implements OssService {
}
}
}
/**
* 判断路径是否存在不存在创建
*
* @param dirPath
*/
private static void isChartPathExist(String dirPath) {
File file = new File(dirPath);
if (!file.exists()) {
file.mkdirs();
}
}
}

View File

@ -8,7 +8,9 @@
package com.suisung.mall.admin.service;
import cn.hutool.json.JSONObject;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.modules.admin.AdminAppMarketUpdate;
public interface AdminAppMarketUpdateService {
@ -22,5 +24,57 @@ public interface AdminAppMarketUpdateService {
*/
CommonResult checkLatestVersion(Integer marketId, String packageName, Integer currVersionKey);
/**
* 获取最新的(默认通用)商家版 App 下载地址
*
* @param marketId
* @return
*/
CommonResult lastAdminAppMarketUpdate(Integer marketId);
/**
* 后台管理员搜索列表
*
* @param marketId
* @param keyword
* @param pageNum
* @param pageSize
* @return
*/
CommonResult searchListInAdmin(Integer marketId, String keyword, Integer pageNum, Integer pageSize);
/**
* 后台管理员新增
*
* @param paramsJSON
* @return
*/
CommonResult addNewInAdmin(JSONObject paramsJSON);
/**
* 后台管理员修改
*
* @param paramsJSON
* @return
*/
CommonResult modifyInAdmin(JSONObject paramsJSON);
/**
* 后台管理员禁用/启用
*
* @param id
* @param status
* @return
*/
CommonResult enableOrDisableInAdmin(Long id, Integer status);
/**
* 获取最后一条记录
*
* @param marketId
* @param packageName
* @return
*/
AdminAppMarketUpdate getLastAppMarketUpdate(Integer marketId, String packageName);
}

View File

@ -9,16 +9,30 @@
package com.suisung.mall.admin.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suisung.mall.admin.mapper.AdminAppMarketUpdateMapper;
import com.suisung.mall.admin.service.AdminAppMarketUpdateService;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.modules.admin.AdminAppMarketUpdate;
import com.suisung.mall.common.pojo.dto.FileInfoDTO;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
@Service
public class AdminAppMarketUpdateServiceImpl extends BaseServiceImpl<AdminAppMarketUpdateMapper, AdminAppMarketUpdate> implements AdminAppMarketUpdateService {
@Value("${spring.profiles.active}")
private String profile;
/**
* 获取某个市场的最新 APP 版本
*
@ -33,20 +47,244 @@ public class AdminAppMarketUpdateServiceImpl extends BaseServiceImpl<AdminAppMar
return CommonResult.failed("缺少必要参数");
}
QueryWrapper<AdminAppMarketUpdate> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("market_id", marketId).eq("package_name", packageName)
.orderByDesc("version_key").last("limit 1");
AdminAppMarketUpdate adminAppMarketUpdate = getOne(queryWrapper);
AdminAppMarketUpdate adminAppMarketUpdate = getLastAppMarketUpdate(marketId, packageName);
if (adminAppMarketUpdate == null) {
return CommonResult.failed("当前应用已是最新版本");
return CommonResult.success(null, "当前已是最新版本");
}
if (ObjectUtil.isNotEmpty(currVersionKey) && adminAppMarketUpdate.getVersion_key() <= currVersionKey) {
return CommonResult.success(null, "当前已是最新版本");
}
if (!ObjectUtil.isEmpty(currVersionKey) && adminAppMarketUpdate.getVersion_key() <= currVersionKey) {
return CommonResult.failed("当前应用已是最新版本");
// 更新包后缀处理
if (StrUtil.isNotBlank(adminAppMarketUpdate.getDownload_apk_url()) && StrUtil.isBlank(adminAppMarketUpdate.getFile_ext())) {
adminAppMarketUpdate.setFile_ext(StringUtils.getFileExt(adminAppMarketUpdate.getDownload_apk_url()));
}
// 解决跨域问题更换包的域名https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/ https://static.gpxscs.cn/
if ("prod".equals(profile) && StrUtil.isNotBlank(adminAppMarketUpdate.getDownload_apk_url())) {
String downloadUrl = adminAppMarketUpdate.getDownload_apk_url();
downloadUrl = downloadUrl.replace("https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/", "https://static.gpxscs.cn/");
adminAppMarketUpdate.setDownload_apk_url(downloadUrl);
}
// 解决跨域问题更换包的域名https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/ https://static.gpxscs.cn/
if ("prod".equals(profile) && StrUtil.isNotBlank(adminAppMarketUpdate.getDownload_wgt_url())) {
String downloadWgtUrl = adminAppMarketUpdate.getDownload_wgt_url();
downloadWgtUrl = downloadWgtUrl.replace("https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/", "https://static.gpxscs.cn/");
adminAppMarketUpdate.setDownload_wgt_url(downloadWgtUrl);
}
return CommonResult.success(adminAppMarketUpdate);
}
/**
* 获取最新的(默认通用)商家版 App 下载地址
*
* @param marketId
* @return
*/
@Override
public CommonResult lastAdminAppMarketUpdate(Integer marketId) {
Integer defMarketId = 100;
if (ObjectUtil.isEmpty(marketId)) {
marketId = defMarketId;
}
QueryWrapper<AdminAppMarketUpdate> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("market_id", marketId).eq("status", CommonConstant.Enable).orderByDesc("version_key");
AdminAppMarketUpdate adminAppMarketUpdate = findOne(queryWrapper);
if (adminAppMarketUpdate == null) {
return CommonResult.success(null, "没有找到最新版本");
}
return CommonResult.success(adminAppMarketUpdate);
}
/**
* 后台管理员搜索列表
*
* @param marketId
* @param keyword
* @return
*/
@Override
public CommonResult searchListInAdmin(Integer marketId, String keyword, Integer pageNum, Integer pageSize) {
QueryWrapper<AdminAppMarketUpdate> queryWrapper = new QueryWrapper<>();
if (ObjectUtil.isNotEmpty(marketId)) {
queryWrapper.eq("market_id", marketId);
}
if (StrUtil.isNotBlank(keyword)) {
queryWrapper.and(wrapper -> wrapper.like("package_name", keyword)
.or().like("version_name", keyword)
.or().like("description", keyword));
}
queryWrapper.orderByDesc("id");
Page<AdminAppMarketUpdate> list = lists(queryWrapper, pageNum, pageSize);
return CommonResult.success(list);
}
/**
* 后台管理员新增
*
* @param paramsJSON
* @return
*/
@Override
public CommonResult addNewInAdmin(JSONObject paramsJSON) {
String userId = "0";
UserDto user = getCurrentUser();
if (user != null) {
userId = String.valueOf(user.getId());
}
if (ObjectUtil.isEmpty(paramsJSON)) {
return CommonResult.failed("缺少必要参数");
}
AdminAppMarketUpdate adminAppMarketUpdate = JSONUtil.toBean(paramsJSON, AdminAppMarketUpdate.class);
if (ObjectUtil.isEmpty(adminAppMarketUpdate)) {
return CommonResult.failed("参数格式有误");
}
if (ObjectUtil.isEmpty(adminAppMarketUpdate.getMarket_id()) || ObjectUtil.isEmpty(adminAppMarketUpdate.getPackage_name())
|| ObjectUtil.isEmpty(adminAppMarketUpdate.getVersion_key()) || ObjectUtil.isEmpty(adminAppMarketUpdate.getVersion_name())
|| ObjectUtil.isEmpty(adminAppMarketUpdate.getDownload_apk_url())) {
return CommonResult.failed("缺少关键参数");
}
AdminAppMarketUpdate record = getLastAppMarketUpdate(adminAppMarketUpdate.getMarket_id(), adminAppMarketUpdate.getPackage_name());
if (record != null && ObjectUtil.isNotEmpty(adminAppMarketUpdate.getVersion_key()) && record.getVersion_key().equals(adminAppMarketUpdate.getVersion_key())) {
return CommonResult.failed("当前版本升级包已存在");
}
if ("prod".equals(profile) && StrUtil.isNotBlank(adminAppMarketUpdate.getDownload_apk_url())) {
String downloadUrl = adminAppMarketUpdate.getDownload_apk_url();
downloadUrl = downloadUrl.replace("https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/", "https://static.gpxscs.cn/");
adminAppMarketUpdate.setDownload_apk_url(downloadUrl);
}
// 解决跨域问题更换包的域名https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/ https://static.gpxscs.cn/
if ("prod".equals(profile) && StrUtil.isNotBlank(adminAppMarketUpdate.getDownload_wgt_url())) {
String downloadWgtUrl = adminAppMarketUpdate.getDownload_wgt_url();
downloadWgtUrl = downloadWgtUrl.replace("https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/", "https://static.gpxscs.cn/");
adminAppMarketUpdate.setDownload_wgt_url(downloadWgtUrl);
}
FileInfoDTO fileInfoDTO = StringUtils.getFileInfoFromUrl(adminAppMarketUpdate.getDownload_apk_url());
if (fileInfoDTO != null) {
adminAppMarketUpdate.setPackage_size(fileInfoDTO.getFileSize());
adminAppMarketUpdate.setFile_ext(fileInfoDTO.getFileExtension());
adminAppMarketUpdate.setMd5_checksum(fileInfoDTO.getMd5());
}
adminAppMarketUpdate.setCreated_by(userId);
adminAppMarketUpdate.setUpdated_by(userId);
return add(adminAppMarketUpdate) ? CommonResult.success() : CommonResult.failed("操作失败");
}
/**
* 后台管理员修改
*
* @param paramsJSON
* @return
*/
@Override
public CommonResult modifyInAdmin(JSONObject paramsJSON) {
String userId = "0";
UserDto user = getCurrentUser();
if (user != null) {
userId = String.valueOf(user.getId());
}
if (ObjectUtil.isEmpty(paramsJSON)) {
return CommonResult.failed("缺少必要参数");
}
if (ObjectUtil.isEmpty(paramsJSON.getLong("id"))) {
return CommonResult.failed("缺少id参数");
}
AdminAppMarketUpdate adminAppMarketUpdate = JSONUtil.toBean(paramsJSON, AdminAppMarketUpdate.class);
if (ObjectUtil.isEmpty(adminAppMarketUpdate)) {
return CommonResult.failed("参数格式有误");
}
if ("prod".equals(profile) && StrUtil.isNotBlank(adminAppMarketUpdate.getDownload_apk_url())) {
String downloadUrl = adminAppMarketUpdate.getDownload_apk_url();
downloadUrl = downloadUrl.replace("https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/", "https://static.gpxscs.cn/");
adminAppMarketUpdate.setDownload_apk_url(downloadUrl);
}
// 解决跨域问题更换包的域名https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/ https://static.gpxscs.cn/
if ("prod".equals(profile) && StrUtil.isNotBlank(adminAppMarketUpdate.getDownload_wgt_url())) {
String downloadWgtUrl = adminAppMarketUpdate.getDownload_wgt_url();
downloadWgtUrl = downloadWgtUrl.replace("https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/", "https://static.gpxscs.cn/");
adminAppMarketUpdate.setDownload_wgt_url(downloadWgtUrl);
}
FileInfoDTO fileInfoDTO = StringUtils.getFileInfoFromUrl(adminAppMarketUpdate.getDownload_apk_url());
if (fileInfoDTO != null) {
adminAppMarketUpdate.setPackage_size(fileInfoDTO.getFileSize());
adminAppMarketUpdate.setFile_ext(fileInfoDTO.getFileExtension());
adminAppMarketUpdate.setMd5_checksum(fileInfoDTO.getMd5());
}
adminAppMarketUpdate.setUpdated_by(userId);
return saveOrUpdate(adminAppMarketUpdate) ? CommonResult.success() : CommonResult.failed("操作失败");
}
/**
* 后台管理员禁用/启用
*
* @param id
* @param status
* @return
*/
@Override
public CommonResult enableOrDisableInAdmin(Long id, Integer status) {
Integer userId = 0;
UserDto user = getCurrentUser();
if (user != null) {
userId = user.getId();
}
if (ObjectUtil.isEmpty(id) || ObjectUtil.isEmpty(status)) {
return CommonResult.failed("缺少必要参数");
}
AdminAppMarketUpdate adminAppMarketUpdate = new AdminAppMarketUpdate();
adminAppMarketUpdate.setId(id);
adminAppMarketUpdate.setStatus(status);
adminAppMarketUpdate.setUpdated_by(String.valueOf(userId));
return saveOrUpdate(adminAppMarketUpdate) ? CommonResult.success() : CommonResult.failed("操作失败");
}
/**
* 获取一条记录
*
* @param marketId
* @param packageName
* @return
*/
@Override
public AdminAppMarketUpdate getLastAppMarketUpdate(Integer marketId, String packageName) {
if (ObjectUtil.isEmpty(marketId) || StrUtil.isBlank(packageName)) {
return null;
}
QueryWrapper<AdminAppMarketUpdate> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("market_id", marketId).eq("status", CommonConstant.Enable)
.eq("package_name", packageName).orderByDesc("version_key");
return findOne(queryWrapper);
}
}

View File

@ -102,19 +102,19 @@
</exclusions>
</dependency>
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>-->
<!-- <version>2.7.18</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>-->
<!-- <version>2.7.18</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.data</groupId>-->
<!-- <artifactId>spring-data-jpa</artifactId>-->
<!-- <version>2.7.18</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.data</groupId>-->
<!-- <artifactId>spring-data-jpa</artifactId>-->
<!-- <version>2.7.18</version>-->
<!-- </dependency>-->
<!--excel工具-->
<dependency>
@ -274,6 +274,11 @@
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>com.huaban</groupId>
<artifactId>jieba-analysis</artifactId>
<version>1.0.2</version>
</dependency>
</dependencies>
<!-- 指定仓库为阿里云与阿帕奇 -->

View File

@ -45,11 +45,13 @@ public class CommonConstant {
public static final Integer PRODUCT_DATA_SOURCE_USER = 1;
public static final Integer PRODUCT_DATA_SOURCE_SX = 2;
// 入驻商家的审批状态1-已通过2-未通过3-待审核4-未申请
// 入驻审批状态1-已通过2-未通过3-待审核4-未申请5-已提交拉卡拉审核21-拉卡拉审核未通过
public static final Integer MCH_APPR_STA_PASS = 1;
public static final Integer MCH_APPR_STA_NOPASS = 2;
public static final Integer MCH_APPR_STA_PADDING = 3;
public static final Integer MCH_APPR_STA_NONE = 4;
public static final Integer MCH_APPR_STA_LKL_PADDING = 5;
public static final Integer MCH_APPR_STA_LKL_NOPASS = 21;
// 入驻商家主体类型企业或个人1-企业2-个人
public static final Integer MCH_ENTITY_TYPE_QY = 1;

View File

@ -43,8 +43,14 @@ public class AdminAppMarketUpdate implements Serializable {
@ApiModelProperty(value = "热更新包显示的版本号,用于标识不同的热更新版本,遵循一定命名规则,如 1.23.21")
private String version_name;
@ApiModelProperty(value = "热更新包的下载链接,用户可通过此链接下载更新包完成应用更新")
private String download_url;
@ApiModelProperty(value = "apk包的下载链接用户可通过此链接下载更新包完成应用更新")
private String download_apk_url;
@ApiModelProperty(value = "增量包的下载链接,用户可通过此链接下载更新包完成应用更新")
private String download_wgt_url;
@ApiModelProperty(value = "更新包后缀apk wgt")
private String file_ext;
@ApiModelProperty(value = "热更新的发布时间,记录更新包正式发布的时刻")
private Date release_time;

View File

@ -47,6 +47,15 @@ public class EsignPlatformInfo implements Serializable {
@ApiModelProperty(value = "平台方营业执照公司名称")
private String license_company;
@ApiModelProperty(value = "平台方营业执照上的经营内容")
private String license_content;
@ApiModelProperty(value = "代理商的省/市/区,如:广东省/深圳市/福田区")
private String license_area;
@ApiModelProperty(value = "代理商的省id/市id/区id11000/11100/11101")
private String license_district_id;
@ApiModelProperty(value = "平台方营业执照公司详细地址")
private String license_address;
@ -74,7 +83,7 @@ public class EsignPlatformInfo implements Serializable {
@ApiModelProperty(value = "收款账户名称")
private String rec_acc_name;
@ApiModelProperty(value = "收款账户账户类型:1-个人2-企业;")
@ApiModelProperty(value = "收款账户账户类型:1-个人(对私)2-企业(对公)")
private Integer rec_acc_type;
@ApiModelProperty(value = "收款账户证件号")
@ -95,17 +104,11 @@ public class EsignPlatformInfo implements Serializable {
@ApiModelProperty(value = "平台方公司维度")
private String latitude;
@ApiModelProperty(value = "平台方公司店铺所在的省")
private String province_id;
@ApiModelProperty(value = "代理商等级:0-平台方(只能一条记录)1-一级代理2-二级代理3-三级代理4-四级代理;")
private Integer level;
@ApiModelProperty(value = "平台方公司所在的市")
private String city_id;
@ApiModelProperty(value = "平台方公司所在的县区")
private String county_id;
@ApiModelProperty(value = "类型:0-平台方(只能一条记录)1-一级代理2-二级代理3-三级代理4-四级代理;")
private Integer type;
@ApiModelProperty(value = "邀请码,后期跟收益有关")
private String invite_code;
@ApiModelProperty(value = "记录状态:1-有效2-无效;")
private Integer status;

View File

@ -0,0 +1,58 @@
/*
* 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.lakala;
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("lkl_banks")
@ApiModel(value = "拉卡拉银行信息(包含账户行号、结清行号)", description = "拉卡拉银行信息(包含账户行号、结清行号)")
public class LklBanks implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value = "自增ID")
private Long id;
@ApiModelProperty(value = "地区号")
private String area_code;
@ApiModelProperty(value = "总行号")
private String bank_no;
@ApiModelProperty(value = "银行名称")
private String branch_bank_name;
@ApiModelProperty(value = "支行行号")
private String branch_bank_no;
@ApiModelProperty(value = "结清行号")
private String clear_no;
@ApiModelProperty(value = "记录状态:1-有效2-无效;")
private Integer status;
@ApiModelProperty(value = "记录创建时间")
private Date created_at;
@ApiModelProperty(value = "记录更新时间")
private Date updated_at;
}

View File

@ -0,0 +1,50 @@
/*
* 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.lakala;
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("lkl_ledger_ec")
@ApiModel(value = "拉卡拉商家入网电子合同申请表", description = "拉卡拉商家入网电子合同申请表")
public class LklLedgerEc implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value = "自增ID")
private Long id;
private Long mch_id;
private String mch_mobile;
private String req_params;
private String resp_body;
private String resp_notify_body;
private String ec_no;
private String ec_name;
private String ec_file;
private String lkl_file_path;
private String ec_status;
private Long ec_apply_id;
private String result_url;
private String notify_url;
private Integer status;
private Date created_at;
private Date updated_at;
}

View File

@ -8,8 +8,11 @@
package com.suisung.mall.common.modules.lakala;
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;
@ -25,6 +28,8 @@ import java.util.Date;
public class LklLedgerMember implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value = "自增ID")
private Long id;
private String order_no;
private String org_code;
@ -42,8 +47,9 @@ public class LklLedgerMember implements Serializable {
private String split_rule_source;
private String ret_url;
private String apply_id;
private String audit_status;
private Integer audit_status;
private String audit_status_text;
private String audit_resp;
private String remark;
private Long mch_id;
private String version;

View File

@ -8,8 +8,11 @@
package com.suisung.mall.common.modules.lakala;
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;
@ -25,6 +28,8 @@ import java.util.Date;
public class LklLedgerMerReceiverBind implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value = "自增ID")
private Long id;
private String order_no;
private String org_code;

View File

@ -8,8 +8,11 @@
package com.suisung.mall.common.modules.lakala;
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;
@ -25,6 +28,8 @@ import java.util.Date;
public class LklLedgerReceiver implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value = "自增ID")
private Long id;
private String order_no;
private String org_id;

View File

@ -0,0 +1,90 @@
/*
* 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.lakala;
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.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("lkl_order_separate")
@ApiModel(value = "拉卡拉分账接收方", description = "拉卡拉分账接收方表")
public class LklOrderSeparate {
@TableId(value = "id", type = IdType.INPUT)
@ApiModelProperty(value = "自增Id", example = "1")
private Long id;
@ApiModelProperty(value = "拉卡拉外部商户号")
private String merchant_no;
@ApiModelProperty(value = "拉卡拉对账单流水号 posp流水号查清结算用")
private String log_no;
@ApiModelProperty(value = "交易日期yyyyMMdd查清结算用")
private String log_date;
@ApiModelProperty(value = "商户分账指令流水号,每个商户号下唯一,否则会校验失败")
private String out_separate_no;
@ApiModelProperty(value = "分账指令流水号,分账系统生成唯一流水")
private String separate_no;
@ApiModelProperty(value = "分账总金额,单位:分")
private String total_amt;
@ApiModelProperty(value = "分账计算类型0- 按照指定金额1- 按照指定比例。默认 0")
private String cal_type;
@ApiModelProperty(value = "指令类型 SEPARATE-分账, CANCEL-分账撤销FALLBACK-分账回退")
private String cmd_type;
@ApiModelProperty(value = "分账接收类型0-全部分账到商户本身。1-分账到多方,默认 1")
private String separate_type;
@ApiModelProperty(value = "分账日期 yyyyMMdd")
private String separate_date;
@ApiModelProperty(value = "完成日期 yyyyMMdd")
private String finish_date;
@ApiModelProperty(value = "拉卡拉异步通知回调地址")
private String notify_url;
@ApiModelProperty(value = "分账接收数据对象JSON 格式")
private String recv_datas;
@ApiModelProperty(value = "最终分账明细JSON 格式")
private String detail_datas;
@ApiModelProperty(value = "拉卡拉机构编号")
private String lkl_org_no;
@ApiModelProperty(value = "分账状态PROCESSING-处理中, ACCEPTED-已受理, SUCCESS-成功, FAIL-失败")
private String status;
@ApiModelProperty(value = "处理状态ACCEPTED-已受理, PROCESSING-处理中, FAIL-失败, SUCCESS-成功")
private String final_status;
@ApiModelProperty(value = "新建时间")
private Date created_at;
@ApiModelProperty(value = "更新时间")
private Date updated_at;
}

View File

@ -6,7 +6,7 @@
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.suisung.mall.common.modules.merch;
package com.suisung.mall.common.modules.store;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
@ -25,8 +25,8 @@ import java.util.Date;
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("shop_mch_entry")
@ApiModel(value = "ShopMerchEntry 实体", description = "商家入驻信息表")
public class ShopMerchEntry implements Serializable {
@ApiModel(value = "ShopMchEntry 实体", description = "商家入驻信息表")
public class ShopMchEntry implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "自增ID")
@ -81,16 +81,10 @@ public class ShopMerchEntry implements Serializable {
@ApiModelProperty(value = "邮箱")
private String email;
@ApiModelProperty(value = "入驻商家店铺所在的省")
private String province_id;
@ApiModelProperty(value = "店铺地区编号省份code/城市code/区code")
private String store_district;
@ApiModelProperty(value = "入驻商家店铺所在的市")
private String city_id;
@ApiModelProperty(value = "入驻商家店铺所在的县区")
private String county_id;
@ApiModelProperty(value = "店铺地区 省份/城市/乡县")
@ApiModelProperty(value = "店铺地区名称,省份/城市/区")
private String store_area;
@ApiModelProperty(value = "入驻商家店铺的详细地址")
@ -114,14 +108,11 @@ public class ShopMerchEntry implements Serializable {
@ApiModelProperty(value = "入驻商家营业执照图片的存储路径")
private String biz_license_image;
@ApiModelProperty(value = "入驻商家的许可证类型1-许可证2-特许证件3-其他证件")
private Integer license_type;
@ApiModelProperty(value = "入驻商家营业执照的经营范围")
private String biz_license_content;
@ApiModelProperty(value = "入驻商家的许可证编号")
private String license_number;
@ApiModelProperty(value = "入驻商家许可证图片的存储路径")
private String license_image;
@ApiModelProperty(value = "营业执照以外的许可证信息列表JSON格式 [{'type':1,'number':'91450881MA5P8MWX69','img':'https://media-mall-prod-1259811287.cos.ap-guangzhou.myqcloud.com/1.png'}]type:1-许可证2-特许证件3-其他证件")
private String other_license_list;
@ApiModelProperty(value = "商家营业执照有效开始时间")
private String biz_license_period_begin;
@ -174,31 +165,34 @@ public class ShopMerchEntry implements Serializable {
@ApiModelProperty(value = "个人身份证有效期结束时间")
private String individual_id_period_end;
@ApiModelProperty(value = "入驻商家的开户⾏号")
private String bank_code;
@ApiModelProperty(value = "入驻商家的开户银行")
@ApiModelProperty(value = "入驻商家的开户银行名称")
private String bank_name;
@ApiModelProperty(value = "入驻商家开户银行的支行名称")
private String bank_branch_name;
@ApiModelProperty(value = "结算账户清算⾏号")
private String clearing_bank_code;
@ApiModelProperty(value = "结算账户银行卡图片")
private String bank_image;
@ApiModelProperty(value = "结算银行地区,格式: 省份/城市/乡县")
@ApiModelProperty(value = "结算账号省市区编号 省code/市code/区code必填项")
private String bank_district;
@ApiModelProperty(value = "结算银行地区名称,格式: 省份/城市/区")
private String bank_area;
@ApiModelProperty(value = "结算账号类型57-对公 58-对私")
private String account_type;
@ApiModelProperty(value = "结算账户⾏号")
private String openning_bank_code;
@ApiModelProperty(value = "结算账户清算⾏号")
private String clearing_bank_code;
@ApiModelProperty(value = "入驻商家的收款账户号码")
private String account_number;
@ApiModelProperty(value = "入驻商家的收款账户姓名")
private String account_holder_name;
@ApiModelProperty(value = "入驻商家的审批状态1-已通过2-未通过3-待审核;")
@ApiModelProperty(value = "入驻商家的审批状态1-已通过2-未通过3-待审核;4-未申请过5-已提交审核;")
private Integer approval_status;
@ApiModelProperty(value = "入驻商家审批时的备注信息")
@ -210,12 +204,57 @@ public class ShopMerchEntry implements Serializable {
@ApiModelProperty(value = "商家的代理商ID")
private Long distributor_id;
@ApiModelProperty(value = "拉卡拉内部商户号")
private String lkl_mer_inner_no;
@ApiModelProperty(value = "拉卡拉银联商户号(唯一)")
private String lkl_mer_cup_no;
@ApiModelProperty(value = "拉卡拉分配的业务终端号")
private String lkl_term_no;
@ApiModelProperty(value = "拉卡拉审核状态1-已通过2-未通过")
private Integer lkl_tk_audit_status;
@ApiModelProperty(value = "拉卡拉进件请求参数")
private String lkl_tk_reg_params;
@ApiModelProperty(value = "异步通知的请求参数(加密过)")
private String lkl_tk_reg_notify_req;
@ApiModelProperty(value = "拉卡拉进件成功返回的JSON数据")
private String lkl_tk_reg_resp;
@ApiModelProperty(value = "拉卡拉入网电子合同编号(进件必须使用)")
private String lkl_ec_no;
@ApiModelProperty(value = "拉卡拉入网电子合同名称")
private String lkl_ec_name;
@ApiModelProperty(value = "入网电子合同拉卡拉相对路径")
private String lkl_ec_file_path;
@ApiModelProperty(value = "拉卡拉入网电子合同签署H5地址进件必须使用")
private String lkl_ec_result_url;
@ApiModelProperty(value = "合同签署状态0-无任何签署1-一方签署2-双方已签署;")
private Integer signed_status;
@ApiModelProperty(value = "店铺创建状态1-已启用入驻已审批合同已生成2-未启用")
private Integer store_status;
@ApiModelProperty(value = "是否签署电子合同1-是2-否;")
private Integer has_ec_signed;
@ApiModelProperty(value = "是否申请分账业务1-是2-否;")
private Integer has_apply_split;
@ApiModelProperty(value = "是否新增分账接收方1-是2-否;")
private Integer has_apply_receiver;
@ApiModelProperty(value = "是否绑定分账接收方1-是2-否;")
private Integer has_bind_receiver;
@ApiModelProperty(value = "该商家入驻记录是否有效0:无效1:有效")
private Integer status;

View File

@ -0,0 +1,35 @@
/*
* 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.pojo.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "文件信息", description = "文件信息")
public class FileInfoDTO {
String md5;
String fileExtension;
long fileSize;
public FileInfoDTO(String md5, String fileExtension, long fileSize) {
this.md5 = md5;
this.fileExtension = fileExtension;
this.fileSize = fileSize;
}
@Override
public String toString() {
return "MD5: " + md5 + ", 文件后缀: " + fileExtension + ", 文件大小: " + fileSize + " 字节";
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.utils;
import com.huaban.analysis.jieba.JiebaSegmenter;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 结巴分词工具类
*/
@Component
public class JiebaUtils {
private final JiebaSegmenter segmenter = new JiebaSegmenter();
public static void main(String[] args) {
JiebaUtils jiebaUtils = new JiebaUtils();
String text = "农行桂平";
List<String> words = jiebaUtils.segment(text);
System.out.println(words);
}
/**
* 精确模式分词
*/
public List<String> segment(String text) {
return segmenter.process(text, JiebaSegmenter.SegMode.INDEX)
.stream()
.map(token -> token.word)
.collect(Collectors.toList());
}
/**
* 搜索模式分词更细粒度
*/
public List<String> segmentForSearch(String text) {
return segmenter.process(text, JiebaSegmenter.SegMode.SEARCH)
.stream()
.map(token -> token.word)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,159 @@
/*
* 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.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RSAUtil {
private static final Logger logger = LoggerFactory.getLogger(RSAUtil.class);
/**
* 使用私钥对数据进行 SHA256withRSA 签名
*
* @param data 待签名的数据
* @param privateKey 私钥(Base64编码)
* @return 签名结果(Base64编码)
*/
public static String signSHA256withRSA(String data, String privateKey) {
try {
// 解码私钥 并去掉头尾的标识
byte[] keyBytes = Base64.getDecoder().decode(privateKey);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
// 生成私钥对象
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyFactory.generatePrivate(keySpec);
// 初始化签名
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(priKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
// 生成签名并编码为Base64
byte[] signBytes = signature.sign();
return Base64.getEncoder().encodeToString(signBytes);
} catch (NoSuchAlgorithmException e) {
logger.error("不支持的加密算法: {}", e.getMessage(), e);
} catch (InvalidKeySpecException e) {
logger.error("私钥格式错误: {}", e.getMessage(), e);
} catch (InvalidKeyException e) {
logger.error("无效的私钥: {}", e.getMessage(), e);
} catch (SignatureException e) {
logger.error("签名处理异常: {}", e.getMessage(), e);
} catch (Exception e) {
logger.error("签名过程发生未知异常: {}", e.getMessage(), e);
}
return null;
}
/**
* 使用公钥验证 SHA256withRSA 签名
*
* @param data 原始数据
* @param sign 签名结果(Base64编码)
* @param publicKey 公钥(Base64编码)
* @return 验证结果
*/
public static boolean verifySHA256withRSA(String data, String sign, String publicKey) {
try {
// 解码公钥
byte[] keyBytes = Base64.getDecoder().decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
// 生成公钥对象
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(keySpec);
// 初始化签名验证
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(pubKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
// 验证签名
byte[] signBytes = Base64.getDecoder().decode(sign);
return signature.verify(signBytes);
} catch (NoSuchAlgorithmException e) {
logger.error("不支持的加密算法: {}", e.getMessage(), e);
} catch (InvalidKeySpecException e) {
logger.error("公钥格式错误: {}", e.getMessage(), e);
} catch (InvalidKeyException e) {
logger.error("无效的公钥: {}", e.getMessage(), e);
} catch (SignatureException e) {
logger.error("签名验证异常: {}", e.getMessage(), e);
} catch (Exception e) {
logger.error("验证过程发生未知异常: {}", e.getMessage(), e);
}
return false;
}
/**
* 生成 RSA 密钥对
*
* @param keySize 密钥长度推荐 2048
* @return 密钥对
*/
public static KeyPair generateKeyPair(int keySize) {
KeyPairGenerator keyPairGen = null;
try {
keyPairGen = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
keyPairGen.initialize(keySize);
return keyPairGen.generateKeyPair();
}
/**
* 获取公钥的 Base64 编码字符串
*/
public static String getPublicKeyString(KeyPair keyPair) {
PublicKey publicKey = keyPair.getPublic();
return Base64.getEncoder().encodeToString(publicKey.getEncoded());
}
/**
* 获取私钥的 Base64 编码字符串
*/
public static String getPrivateKeyString(KeyPair keyPair) {
PrivateKey privateKey = keyPair.getPrivate();
return Base64.getEncoder().encodeToString(privateKey.getEncoded());
}
// 示例用法
public static void main(String[] args) {
try {
// 生成密钥对
KeyPair keyPair = generateKeyPair(2048);
String publicKey = getPublicKeyString(keyPair);
String privateKey = getPrivateKeyString(keyPair);
// 待签名数据
String data = "Hello, RSA Signature!";
// 签名
String signature = signSHA256withRSA(data, privateKey);
System.out.println("签名结果: " + signature);
// 验证
boolean isValid = verifySHA256withRSA(data, signature, publicKey);
System.out.println("验证结果: " + isValid);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -91,6 +91,22 @@ public class RestTemplateHttpUtil {
return response.getBody();
}
public static <T> ResponseEntity<T> sendPostBodyBackEntity(String url, JSONObject headers, JSONObject requestBody, Class<T> responseType) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
if (headers != null) {
for (Map.Entry<String, Object> entry : headers.entrySet()) {
httpHeaders.add(entry.getKey(), (String) entry.getValue());
}
}
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Object> entity = new HttpEntity<>(requestBody, httpHeaders);
ResponseEntity<T> response = restTemplate.postForEntity(url, entity, responseType);
return response;
}
/**
* 发送带 header POST form-data 请求
*

View File

@ -1,7 +1,9 @@
package com.suisung.mall.common.utils;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.*;
import com.suisung.mall.common.pojo.dto.FileInfoDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
@ -10,8 +12,12 @@ import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
@ -709,6 +715,64 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
return false;
}
/**
* 根据url文件生成文件MD5文摘签名
*
* @param fileUrl
* @return
*/
public static FileInfoDTO getFileInfoFromUrl(String fileUrl) {
if (StrUtil.isBlank(fileUrl)) {
return null;
}
try {
URL url = new URL(fileUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
// 获取文件大小
long fileSize = connection.getContentLengthLong();
// 获取文件后缀
String path = url.getPath();
String fileExtension = "";
int dotIndex = path.lastIndexOf('.');
if (dotIndex != -1) {
fileExtension = path.substring(dotIndex + 1);
}
try (InputStream inputStream = connection.getInputStream()) {
// 获取 MD5 消息摘要实例
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] buffer = new byte[8192];
int bytesRead;
// 从输入流读取数据并更新摘要
while ((bytesRead = inputStream.read(buffer)) != -1) {
digest.update(buffer, 0, bytesRead);
}
// 完成摘要计算
byte[] md5Bytes = digest.digest();
// 将字节数组转换为十六进制字符串
StringBuilder md5String = new StringBuilder();
for (byte b : md5Bytes) {
md5String.append(String.format("%02x", b));
}
String md5 = md5String.toString();
return new FileInfoDTO(StrUtil.isBlank(md5) ? "" : md5, fileExtension, fileSize);
} finally {
connection.disconnect();
}
} catch (MalformedURLException e) {
logger.error("错误:提供的 URL 格式不正确,请检查 URL 字符串", e);
} catch (NoSuchAlgorithmException e) {
logger.error("错误:系统不支持 MD5 算法,这可能是 Java 环境的问题", e);
} catch (IOException e) {
logger.error("错误:在连接 URL 或读取文件内容时发生 I/O 异常,可能是网络问题或文件不存在", e);
}
return null;
}
/**
* 生成的随机数类型

View File

@ -3,14 +3,13 @@ package com.suisung.mall.common.utils;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.tika.Tika;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
@ -25,14 +24,17 @@ public class UploadUtil {
* token通过header传递的名称
*/
public static final String TOKEN_HEADER_NAME = "Authorization";
// text/* 外也需要设置输出编码的 content-type
private final static List<String> SET_CHARSET_CONTENT_TYPES = Arrays.asList(
"application/json",
"application/javascript"
);
public static void main(String[] args) {
String base64 = fileUrlToBase64("http://gips3.baidu.com/it/u=1022347589,1106887837&fm=3028&app=3028&f=JPEG&fmt=auto?w=960&h=1280");
System.out.println(base64);
}
/**
* 查看文件, 支持断点续传
*
@ -269,11 +271,76 @@ public class UploadUtil {
// inputStream 用完之后记得关闭
return inputStream;
} catch (IOException e) {
e.printStackTrace();
log.error("发生 I/O 错误: ", e.getMessage());
return null;
}
}
/**
* 将URL地址转换为Base64字符串
*
* @param fileUrl
* @return
*/
public static String fileUrlToBase64(String fileUrl) {
try {
URL url = new URL(fileUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
byte[] imageBytes = outputStream.toByteArray();
inputStream.close();
outputStream.close();
return Base64Utils.encodeToString(imageBytes);
}
} catch (IOException e) {
// 可以在这里添加日志记录方便调试这里简单打印异常信息
log.error("处理图片 URL 时出现 IOException: ", e.getMessage());
}
return null;
}
public static String fileToBase64(File file) {
if (file == null) {
return null;
}
try {
byte[] bytes = Files.readAllBytes(file.toPath());
return Base64Utils.encodeToString(bytes);
} catch (IOException e) {
// 可以在这里添加日志记录方便调试这里简单打印异常信息
log.error("处理file时出现 IOException: ", e.getMessage());
}
return null;
}
/**
* 将MultipartFile 图片转换为Base64字符串
*
* @param multipartFile
* @return
*/
public static String multipartFileToBase64(MultipartFile multipartFile) {
try {
return Base64Utils.encodeToString(multipartFile.getBytes());
} catch (IOException e) {
// 可以在这里添加日志记录方便调试这里简单打印异常信息
log.error("处理图片 URL 时出现 IOException: ", e.getMessage());
}
return null;
}
/**
* 下载图片到本地
*
@ -317,5 +384,57 @@ public class UploadUtil {
return path.substring(lastIndex + 1);
}
/**
* base64UrlSafeString Base64字符串转换为文件
*
* @param base64UrlSafeString
* @return
*/
public static File convertBase64ToFile(String base64UrlSafeString) {
// 输入校验
if (base64UrlSafeString == null || base64UrlSafeString.isEmpty()) {
log.error("Base64字符串不能为空");
return null;
// throw new IllegalArgumentException("Base64字符串不能为空");
}
try {
// 1. 替换URL安全字符为标准Base64字符
String standardBase64 = base64UrlSafeString.replace('-', '+').replace('_', '/');
// 2. 补齐缺失的填充字符 '='
while (standardBase64.length() % 4 != 0) {
standardBase64 += '=';
}
// 3. 解码为字节数组
byte[] decodedBytes = Base64Utils.decodeFromString(standardBase64);
// 4. 创建临时文件自动生成唯一文件名
File tempFile = File.createTempFile("base64-", ".tmp");
// 5. 设置JVM退出时自动删除可选
tempFile.deleteOnExit();
// 6. 写入文件内容
try (FileOutputStream fos = new FileOutputStream(tempFile)) {
fos.write(decodedBytes);
}
return tempFile;
} catch (IllegalArgumentException e) {
// 处理Base64解码失败
// throw new IllegalArgumentException("无效的Base64字符串: " + e.getMessage(), e);
log.error("无效的Base64字符串: " + e.getMessage());
return null;
} catch (IOException e) {
// 处理文件操作异常
// throw new RuntimeException("临时文件创建失败: " + e.getMessage(), e);
log.error("临时文件创建失败: " + e.getMessage());
return null;
}
}
}

View File

@ -69,29 +69,29 @@ secure:
- "/admin/account/account-user-base/register"
- "/admin/account/account-user-base/login"
- "/static/image/**"
- "/mobile/pay/index/notify_url"
#- "/mobile/pay/index/lkl_wxPay_notify_url" #拉卡拉微信支付回调
- "/mobile/pay/index/return_url"
- "/shop/static/**"
- "/mobile/shop/qrcode/getQrcode"
- "/admin/shop/shop-base-config/image"
- "/admin/account/open/**"
- "/admin/account/account-user-base/doLogin"
#- "/mobile/pay/index/lkl_wxPay_notify_url" #拉卡拉微信支付回调
- "/mobile/pay/index/notify_url"
- "/mobile/pay/index/return_url"
- "/admin/pay/pay-user-resource/userInfoImport"
- "/admin/pay/pay-card-history/payCardHistoryImport"
- "/admin/pay/payController/wxRefundNotify"
- "/mobile/shop/qrcode/getQrcode"
- "/admin/shop/shop-purchase-invoice/impPurchaseInvoiceTemp"
- "/admin/shop/shop-product-base/impProductTemp"
- "/admin/pay/payController/wxRefundNotify"
- "/admin/shop/shop-base-config/image"
- "/mobile/shop/sf-express/order/status/listening/**"
- "/admin/shop/open/**"
- "/admin/shop/esign/async/notify" #E签宝电子签章异步回调
- "/shop/sf-express/cancel-order/notify"
- "/shop/sf-express/rider-order-status/notify"
- "/shop/sf-express/order-complete/notify"
- "/shop/sync/third/**"
- "/mobile/shop/sf-express/order/status/listening/**"
- "/admin/shop/open/**"
- "/admin/account/open/**"
- "/esProduct/**"
- "/admin/oss/upload/**"
- "/mobile/**/**/test/case"
- "/admin/shop/esign/async/notify" #E签宝电子签章异步回调
universal:
urls:
- "/admin/account/account-user-base/info"

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@ -161,6 +161,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 拉卡拉外部引用了jar 必须配置-->
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>

View File

@ -103,6 +103,10 @@ public class LakalaPayServiceImpl implements LakalaPayService {
return true;
}
protected boolean isProdProject() {
return "prod".equalsIgnoreCase(profile);
}
@Override
public cn.hutool.json.JSONObject transPreOrder(HttpServletRequest request, HttpServletResponse response, String orderId) {
// 1. 配置初始化
@ -419,19 +423,19 @@ public class LakalaPayServiceImpl implements LakalaPayService {
String fileName = paramsJSON.getStr("splitEntrustFileName");
req.setSplitEntrustFileName(fileName);
// 文件上传到拉卡拉服务器
// 分账结算委托书文件上传到拉卡拉服务器
JSONObject fileUploadResp = uploadFile(orderNo, "SPLIT_ENTRUST_FILE", StringUtils.getFileExt(fileName), paramsJSON.getStr("splitEntrustFile"));
if (fileUploadResp == null || StrUtil.isBlank(fileUploadResp.getStr("attFileId"))) {
throw new ApiException(I18nUtil._("分账结算委托书上传失败!"));
}
String splitEntrustFilePath = fileUploadResp.getStr("attFileId");
req.setSplitEntrustFilePath(splitEntrustFilePath);
// req.setSplitEntrustFilePath("G1/M00/06/64/CrFdEmBQc-aAGc_XAAAiIbS3WIE960.pdf");
req.setSplitEntrustFilePath(splitEntrustFilePath); //比如G1/M00/06/64/CrFdEmBQc-aAGc_XAAAiIbS3WIE960.pdf;
if (profile.equals("prod")) {
if (isProdProject()) {
projectDomain = projectDomain + "/api";
}
// 给拉卡拉通知的回调地址
String retUrl = projectDomain + "/mobile/pay/lakala/ledger/applyLedgerMerNotify";
req.setRetUrl(retUrl);
@ -445,11 +449,10 @@ public class LakalaPayServiceImpl implements LakalaPayService {
//3. 发送请求
String responseStr = LKLSDK.httpPost(req);
// {'retCode':'000000','retMsg':'申请已受理请等待审核结果','respData':{'version':'1.0','orderNo':'KFPT20230223181025407788734','orgCode':'1','applyId':681201215598657536}}
JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr);
if (lakalaRespJSON == null || !lakalaRespJSON.getStr("retCode").equals("000000")) {
throw new ApiException(I18nUtil._(lakalaRespJSON.getStr("retMsg")));
// responseStr="{'retCode':'000000','retMsg':'申请已受理,请等待审核结果','respData':{'version':'1.0','orderNo':'KFPT20230223181025407788734','orgCode':'1','applyId':681201215598657536}}";
// lakalaRespJSON = JSONUtil.parseObj(responseStr);
}
paramsJSON.set("apply_id", lakalaRespJSON.getByPath("respData.applyId"));
@ -464,7 +467,7 @@ public class LakalaPayServiceImpl implements LakalaPayService {
return CommonResult.success(null, "提交成功,待审核中!");
} catch (SDKException e) {
log.error("分账申请失败:", e);
throw new ApiException(I18nUtil._("申请失败!"), e);
throw new ApiException(I18nUtil._("分账申请失败!"), e);
}
}
@ -503,6 +506,7 @@ public class LakalaPayServiceImpl implements LakalaPayService {
reqData.getStr("auditStatus"),
reqData.getStr("auditStatusText"),
reqData.getStr("remark"));
if (success) {
respData.put("retCode", "000000");
respData.put("retMsg", "操作成功!");

View File

@ -11,7 +11,6 @@ package com.suisung.mall.pay.utils;
import cn.hutool.core.util.StrUtil;
import com.lkl.laop.sdk.Config2;
import com.lkl.laop.sdk.LKLSDK;
import com.lkl.laop.sdk.auth.PrivateKeySigner;
import com.suisung.mall.common.exception.ApiException;
import com.suisung.mall.common.utils.I18nUtil;
import lombok.extern.slf4j.Slf4j;
@ -76,6 +75,7 @@ public class LakalaUtil {
}
}
/**
* 获取 body 请求数据
*
@ -130,7 +130,6 @@ public class LakalaUtil {
}
}
/**
* 签名验证
*
@ -155,9 +154,9 @@ public class LakalaUtil {
}
}
/**
* 签名校验
*
* @param authorization
* @param reqBody
* @param lklNotifyCerPath
@ -176,11 +175,9 @@ public class LakalaUtil {
return false;
}
StringBuilder preSignData = new StringBuilder();
preSignData.append(timestamp).append("\n")
.append(nonceStr).append("\n")
.append(reqBody).append("\n");
String preSignDataStr = preSignData.toString();
String preSignDataStr = timestamp + "\n" +
nonceStr + "\n" +
reqBody + "\n";
log.debug("拉卡拉签名明文内容:{}", preSignDataStr);
if (verify(lklNotifyCer, preSignDataStr.getBytes(StandardCharsets.UTF_8), signature)) {
log.debug("验签成功");
@ -237,4 +234,5 @@ public class LakalaUtil {
return map;
}
}

View File

@ -115,7 +115,7 @@ project:
domain: @project.domain@
#拉卡拉支付和分账
lakala:
# 服务地址
#服务地址
server_url: https://s2.lakala.com
#应用Id
app_id: OP10000439
@ -127,7 +127,7 @@ lakala:
api_pri_key_path: payKey/lakala/prod/api_private_key.pem
#拉卡拉平台证书
lkl_platform_cer_path: payKey/lakala/prod/lkl_platform.cer
# 机构代码
#机构代码
org_code: 980688
#商户号
merchant_no: 8226330599900LN

View File

@ -278,12 +278,30 @@
<version>9.4.1.jre8</version> <!-- 或者使用合适的版本 -->
</dependency>
<!--拉卡拉支付与分账 开始-->
<dependency>
<groupId>com.lkl.laop.sdk</groupId>
<artifactId>lkl-laop-java-sdk</artifactId>
<version>1.0.7</version>
<systemPath>${project.basedir}/src/main/resources/lib/lkl-java-sdk-1.0.7.jar</systemPath>
<scope>system</scope>
</dependency>
<!--拉卡拉支付与分账 结束-->
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-Core</artifactId>
<version>2.8.0</version>
<scope>compile</scope>
</dependency>
<!--jdbc数据库-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.2.1.jre8</version>
</dependency>
</dependencies>
<profiles>
@ -345,6 +363,11 @@
<include>bootstrap.yml</include>
<include>bootstrap-${profiles.active}.yml</include>
<include>**/*.xml</include>
<include>**/*.crt</include>
<include>**/*.pem</include>
<include>**/*.p12</include>
<include>**/*.cer</include>
<include>**/*.txt</include>
</includes>
</resource>
</resources>
@ -353,6 +376,10 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 拉卡拉外部引用了jar 必须配置-->
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
@ -365,6 +392,11 @@
<nonFilteredFileExtensions>
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
<nonFilteredFileExtension>ttc</nonFilteredFileExtension>
<nonFilteredFileExtension>p12</nonFilteredFileExtension>
<nonFilteredFileExtension>cer</nonFilteredFileExtension>
<nonFilteredFileExtension>pem</nonFilteredFileExtension>
<nonFilteredFileExtension>pfx</nonFilteredFileExtension>
<nonFilteredFileExtension>txt</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>

View File

@ -29,11 +29,16 @@ public class IpUtil implements ApplicationRunner {
log.error("IP2RegionUtils 没有成功加载数据文件");
return null;
}
if (CheckUtil.isEmpty(ip)) {
return null;
}
try {
return searcher.search(ip);
} catch (Exception e) {
log.error("IP 格式错误:{}", e);
return null;
log.error("IP{} 格式错误:{}", ip, e.getMessage());
return ip;
}
}

View File

@ -13,6 +13,7 @@ import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.shop.esign.service.EsignContractFillingFileService;
import com.suisung.mall.shop.esign.service.EsignContractService;
import com.suisung.mall.shop.esign.service.EsignPlatformInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.ResponseEntity;
@ -36,11 +37,14 @@ public class EsignController extends BaseControllerImpl {
@Resource
private EsignContractService esignContractService;
@Resource
private EsignPlatformInfoService esignPlatformInfoService;
@ApiOperation(value = "测试填充模版控件", notes = "测试填充模版控件")
@RequestMapping(value = "/testcase", method = RequestMethod.POST)
public Object testCase() {
//return esignContractFillingFileService.fillDocTemplate("13128997057", "91450881MADEQ92533");
return esignContractService.getSignedContractFileUrl("27e8dad5491d4d9ab4bc6f8154ae8ff5");
return esignPlatformInfoService.getDistributorAndPlatformByIds(1L);
}
@ApiOperation(value = "管理员发起签署电子合同流程", notes = "基于文件发起签署电子合同")

View File

@ -26,6 +26,14 @@ public interface EsignContractService {
*/
CommonResult signFlowCreateByFile(String mchMobile);
/**
* 内部调用发起合同签署流程
*
* @param mchMobile
* @return
*/
Pair<Boolean, String> innerSignFlowCreateByFile(String mchMobile);
/**
* 签署流程结束异步通知由e签宝通知
*

View File

@ -11,6 +11,8 @@ package com.suisung.mall.shop.esign.service;
import com.suisung.mall.common.modules.esign.EsignPlatformInfo;
import org.springframework.data.util.Pair;
import java.util.List;
/**
* 平台方详细信息接口
*/
@ -24,14 +26,29 @@ public interface EsignPlatformInfoService {
*/
EsignPlatformInfo getDistributorInfoById(Long id);
/**
* 根据ID获取代理商信息
*
* @param ids
* @return
*/
List<EsignPlatformInfo> getDistributorAndPlatformByIds(Long... ids);
/**
* 根据分类和营业执照号获取平台方信息
*
* @param type 分类必选类型:0-平台方(只能一条记录)1-一级代理2-二级代理3-三级代理4-四级代理
* @param level 分类必选类型:0-平台方(只能一条记录)1-一级代理2-二级代理3-三级代理4-四级代理
* @param licenseNumber 营业执照号码可选
* @return
*/
EsignPlatformInfo getEsignPlatformInfo(Integer type, String licenseNumber);
EsignPlatformInfo getEsignPlatformInfo(Integer level, String licenseNumber);
/**
* 是否存在平台方的相关记录信息
*
* @return
*/
EsignPlatformInfo hasPlatformMch();
/**

View File

@ -20,7 +20,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.modules.esign.EsignContractFillingFile;
import com.suisung.mall.common.modules.esign.EsignPlatformInfo;
import com.suisung.mall.common.modules.merch.ShopMerchEntry;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.esign.mapper.EsignContractFillingFileMapper;
@ -32,7 +32,7 @@ import com.suisung.mall.shop.esign.utils.comm.EsignHttpResponse;
import com.suisung.mall.shop.esign.utils.enums.EsignRequestType;
import com.suisung.mall.shop.esign.utils.exception.EsignDemoException;
import com.suisung.mall.shop.page.service.OssService;
import com.suisung.mall.shop.store.service.ShopMerchEntryService;
import com.suisung.mall.shop.store.service.ShopMchEntryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
@ -70,7 +70,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
private EsignPlatformInfoService esignPlatformInfoService;
@Resource
private ShopMerchEntryService shopMerchEntryService;
private ShopMchEntryService shopMchEntryService;
@Resource
private EsignContractFillingFileService esignContractFillingFileService;
@ -107,14 +107,14 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
}
// 获取入驻商家(审批通过的)的信息
ShopMerchEntry shopMerchEntry = shopMerchEntryService.getShopMerchEntryByCondition(mchMobile, "", CommonConstant.MCH_APPR_STA_PASS);
if (shopMerchEntry == null) {
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByCondition(mchMobile, "", CommonConstant.MCH_APPR_STA_PASS);
if (shopMchEntry == null) {
log.error("缺少商家入驻信息");
return null;
}
// 代理商信息
EsignPlatformInfo distributor = esignPlatformInfoService.getDistributorInfoById(shopMerchEntry.getDistributor_id());
EsignPlatformInfo distributor = esignPlatformInfoService.getDistributorInfoById(shopMchEntry.getDistributor_id());
String apiaddr = "/v3/files/create-by-doc-template";
EsignRequestType requestType = EsignRequestType.POST;
@ -128,14 +128,14 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
String today = DateUtil.format(new Date(), "yyyy年MM月dd日");
// 甲方公司名称甲方是个人的时候没有公司名直接用店铺名个人实名
String mchCompany = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMerchEntry.getEntity_type()) ? shopMerchEntry.getBiz_license_company() : shopMerchEntry.getStore_name() + "" + shopMerchEntry.getContact_name() + ")";
String mchCompany = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? shopMchEntry.getBiz_license_company() : shopMchEntry.getStore_name() + "" + shopMchEntry.getContact_name() + ")";
String platCompany = esignPlatformInfo.getLicense_company();
// 甲方法人姓名甲方是个人的时候没有法人直接用个人实名
String legalPersonName = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMerchEntry.getEntity_type()) ? shopMerchEntry.getLegal_person_name() : shopMerchEntry.getContact_name();
String LegalPersonMobile = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMerchEntry.getEntity_type()) ? shopMerchEntry.getLegal_person_mobile() : shopMerchEntry.getLogin_mobile();
String legalPersonName = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? shopMchEntry.getLegal_person_name() : shopMchEntry.getContact_name();
String LegalPersonMobile = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? shopMchEntry.getLegal_person_mobile() : shopMchEntry.getLogin_mobile();
// 甲方法人身份证号甲方是个人的时候没有法人直接用个人身份证
String legalPersonIdNumber = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMerchEntry.getEntity_type()) ? shopMerchEntry.getLegal_person_id_number() : shopMerchEntry.getIndividual_id_number();
String legalPersonIdNumber = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? shopMchEntry.getLegal_person_id_number() : shopMchEntry.getIndividual_id_number();
String contractNumber = StringUtils.genLklOrderNo(4);
@ -180,7 +180,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
}});
}
if (CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMerchEntry.getEntity_type())) {
if (CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())) {
// 甲方公司名称甲方是个人的时候没有公司名直接用店铺名
for (int i = 1; i <= 17; i++) {
int finalI = i;
@ -200,10 +200,10 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
}
//特殊甲方收款账方企业是公司名个人是个人实名
if (!CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMerchEntry.getEntity_type())) {
if (!CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())) {
list.add(new HashMap<String, Object>() {{
put("componentKey", "mch_company17");
put("componentValue", shopMerchEntry.getContact_name());
put("componentValue", shopMchEntry.getContact_name());
}});
}
}
@ -234,7 +234,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
list.add(new HashMap<String, Object>() {{
put("componentKey", "mch_store_name1");
put("componentValue", shopMerchEntry.getStore_name());
put("componentValue", shopMchEntry.getStore_name());
}});
list.add(new HashMap<String, Object>() {{
@ -244,27 +244,27 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
list.add(new HashMap<String, Object>() {{
put("componentKey", "mch_ratio");
put("componentValue", shopMerchEntry.getSplit_ratio());
put("componentValue", shopMchEntry.getSplit_ratio());
}});
list.add(new HashMap<String, Object>() {{
put("componentKey", "settlement_method");
put("componentValue", shopMerchEntry.getSettlement_method());
put("componentValue", shopMchEntry.getSettlement_method());
}});
list.add(new HashMap<String, Object>() {{
put("componentKey", "mch_address1");
put("componentValue", shopMerchEntry.getStore_address());
put("componentValue", shopMchEntry.getStore_address());
}});
list.add(new HashMap<String, Object>() {{
put("componentKey", "mch_bank1");
put("componentValue", shopMerchEntry.getBank_name());
put("componentValue", shopMchEntry.getBank_name());
}});
list.add(new HashMap<String, Object>() {{
put("componentKey", "mch_account_number1");
put("componentValue", shopMerchEntry.getAccount_number());
put("componentValue", shopMchEntry.getAccount_number());
}});
// 乙方公司名称
@ -407,9 +407,9 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
String fileId = jsonObject.getStr("fileId");
// 把合同文件 url 上传到cos服务器
// String contractPath = StrUtil.isBlank(shopMerchEntry.getBiz_license_number()) ? mchMobile : shopMerchEntry.getBiz_license_number();
// String contractPath = StrUtil.isBlank(shopMchEntry.getBiz_license_number()) ? mchMobile : shopMchEntry.getBiz_license_number();
String cosFileName = TENGXUN_DEFAULT_DIR.concat("/").concat("contract")
.concat("/").concat(shopMerchEntry.getLogin_mobile()).concat("/")
.concat("/").concat(shopMchEntry.getLogin_mobile()).concat("/")
.concat(jsonObject.getStr("fileId")).concat(".pdf");
// 上传到cos服务器
String localFileUrl = ossService.uploadObject4OSS(esignContractFillingFile.getUnsigned_contract_url(), cosFileName);

View File

@ -21,7 +21,7 @@ import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.modules.esign.EsignContract;
import com.suisung.mall.common.modules.esign.EsignContractFillingFile;
import com.suisung.mall.common.modules.esign.EsignPlatformInfo;
import com.suisung.mall.common.modules.merch.ShopMerchEntry;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.components.TaskService;
import com.suisung.mall.shop.esign.mapper.EsignContractMapper;
@ -32,8 +32,10 @@ import com.suisung.mall.shop.esign.utils.comm.EsignHttpHelper;
import com.suisung.mall.shop.esign.utils.comm.EsignHttpResponse;
import com.suisung.mall.shop.esign.utils.enums.EsignRequestType;
import com.suisung.mall.shop.esign.utils.exception.EsignDemoException;
import com.suisung.mall.shop.lakala.service.LakalaApiService;
import com.suisung.mall.shop.lakala.service.LklLedgerMemberService;
import com.suisung.mall.shop.page.service.OssService;
import com.suisung.mall.shop.store.service.ShopMerchEntryService;
import com.suisung.mall.shop.store.service.ShopMchEntryService;
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -84,7 +86,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
private EsignContractFillingFileService esignContractFillingFileService;
@Resource
private ShopMerchEntryService shopMerchEntryService;
private ShopMchEntryService shopMchEntryService;
@Resource
private EsignPlatformInfoService esignPlatformInfoService;
@ -92,6 +94,15 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
@Resource
private ShopStoreBaseService shopStoreBaseService;
@Lazy
@Resource
private LakalaApiService lakalaApiService;
@Lazy
@Resource
private LklLedgerMemberService lklLedgerMemberService;
@Resource
private OssService ossService;
@ -159,31 +170,35 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
*/
@Override
public CommonResult signFlowCreateByFile(String mchMobile) {
String userId = "0";
Pair<Boolean, String> ret = innerSignFlowCreateByFile(mchMobile);
if (!ret.getFirst()) {
return CommonResult.failed(ret.getSecond());
}
// UserDto user = getCurrentUser();
// if (!user.isAdmin()) {
// return CommonResult.failed("权限不足!");
// }
// userId = user.getId().toString();
return CommonResult.success(null, ret.getSecond());
}
@Override
public Pair<Boolean, String> innerSignFlowCreateByFile(String mchMobile) {
//String userId = "0";
if (StrUtil.isBlank(mchMobile)) {
return CommonResult.failed("缺少必要参数!");
return Pair.of(false, "缺少必要参数!");
}
EsignContract esignContract = getEsignContractByMchMobile(mchMobile);
if (esignContract == null) {
return CommonResult.failed("未找到商家合同信息");
return Pair.of(false, "未找到商家合同信息");
}
// 检查商户入驻信息是否被审核通过
// 检查店铺是否已经申请过入驻
Integer apprStatus = shopMerchEntryService.getApprovalStatus(mchMobile);
Integer apprStatus = shopMchEntryService.getApprovalStatus(mchMobile);
if (!CommonConstant.MCH_APPR_STA_PASS.equals(apprStatus)) {
return CommonResult.failed("请先审核商家入驻信息");
return Pair.of(false, "请先审核商家入驻信息");
}
//"{\"docs\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"fileName\":\"平台商户入驻合同协议.pdf\"}],\"signFlowConfig\":{\"signFlowTitle\":\"平台商户入驻合同协议\",\"signFlowExpireTime\":1746844718000,\"autoFinish\":true,\"notifyUrl\":\"https://mall.gpxscs.cn/asyn/notify\",\"redirectConfig\":{\"redirectUrl\":\"https://mall.gpxscs.cn/\"}},\"signers\":[{\"signConfig\":{\"signOrder\":1},\"noticeConfig\":{\"noticeTypes\":\"1\"},\"signerType\":0,\"psnSignerInfo\":{\"psnAccount\":\"13128997057\",\"psnInfo\":{\"psnName\":\"潘军杰\"}},\"signFields\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":40,\"positionX\":472.3607,\"positionY\":277.19104}}},{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":5,\"positionX\":470.58798,\"positionY\":589.14496}}}]},{\"signConfig\":{\"signOrder\":2},\"noticeConfig\":{\"noticeTypes\":\"1\"},\"signerType\":1,\"orgSignerInfo\":{\"orgName\":\"桂平发发网络有限公司\",\"orgInfo\":{\"orgIDCardNum\":\"91450881MADEQ92533\",\"orgIDCardType\":\"CRED_ORG_USCC\"},\"transactorInfo\":{\"psnAccount\":\"17777525395\",\"psnInfo\":{\"psnName\":\"谢能坤\"}}},\"signFields\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":2,\"positionX\":479.04996,\"positionY\":357.2327}}},{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":5,\"positionX\":255.96832,\"positionY\":588.4553}}}]}]}";
//"{\"docs\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"fileName\":\"小发同城平台商户合作协议.pdf\"}],\"signFlowConfig\":{\"signFlowTitle\":\"小发同城平台商户合作协议\",\"signFlowExpireTime\":1746844718000,\"autoFinish\":true,\"notifyUrl\":\"https://mall.gpxscs.cn/asyn/notify\",\"redirectConfig\":{\"redirectUrl\":\"https://mall.gpxscs.cn/\"}},\"signers\":[{\"signConfig\":{\"signOrder\":1},\"noticeConfig\":{\"noticeTypes\":\"1\"},\"signerType\":0,\"psnSignerInfo\":{\"psnAccount\":\"13128997057\",\"psnInfo\":{\"psnName\":\"潘军杰\"}},\"signFields\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":40,\"positionX\":472.3607,\"positionY\":277.19104}}},{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":5,\"positionX\":470.58798,\"positionY\":589.14496}}}]},{\"signConfig\":{\"signOrder\":2},\"noticeConfig\":{\"noticeTypes\":\"1\"},\"signerType\":1,\"orgSignerInfo\":{\"orgName\":\"桂平发发网络有限公司\",\"orgInfo\":{\"orgIDCardNum\":\"91450881MADEQ92533\",\"orgIDCardType\":\"CRED_ORG_USCC\"},\"transactorInfo\":{\"psnAccount\":\"17777525395\",\"psnInfo\":{\"psnName\":\"谢能坤\"}}},\"signFields\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":2,\"positionX\":479.04996,\"positionY\":357.2327}}},{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":5,\"positionX\":255.96832,\"positionY\":588.4553}}}]}]}";
// esignContractService.
String jsonParams = esignContract.getReq_params();
@ -196,30 +211,36 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
//发起接口请求
EsignHttpResponse createByDocTemplate = EsignHttpHelper.doCommHttp(serverUrl, apiAddr, requestType, jsonParams, header, debug);
if (createByDocTemplate.getStatus() != 200 || createByDocTemplate.getBody() == null) {
log.error("e签宝请求失败返回状态码{}", createByDocTemplate.getStatus());
return CommonResult.failed("签署失败,状态码:" + createByDocTemplate.getStatus());
log.debug("发起合同签署流程返回消息:{},{}", createByDocTemplate.getStatus(), createByDocTemplate.getBody());
if (createByDocTemplate.getStatus() != 200) {
if (createByDocTemplate.getBody() != null) {
JSONObject resBody = JSONUtil.parseObj(createByDocTemplate.getBody());
log.error("e签宝请求失败返回状态码{}, {}", createByDocTemplate.getStatus(), resBody.getStr("message"));
return Pair.of(false, "e签宝请求失败{}" + resBody.getStr("message"));
}
return Pair.of(false, "e签宝请求失败!");
}
JSONObject jsonObject = JSONUtil.parseObj(createByDocTemplate.getBody());
Integer code = jsonObject.getInt("code");
String signFlowId = (String) jsonObject.getByPath("data.signFlowId");
if (code == null || code != 0 || StrUtil.isBlank(signFlowId)) {
log.error("e签宝请求失败返回状态码:{}", createByDocTemplate.getStatus());
return CommonResult.failed("签署失败,状态码:" + createByDocTemplate.getStatus());
log.error("e签宝请求失败返回status码{}", code);
return Pair.of(false, "e签宝请求失败!");
}
//合同签署状态-1预备数据阶段0-等待签署1-已部分签署2-已完成所有签署方完成签署3-已撤销发起方撤销签署任务5-已过期签署截止日到期后触发7-已拒签签署方拒绝签署
Boolean success = updateContractFlowIdAndFileUrl(esignContract.getId(), signFlowId, CommonConstant.CONTRACT_SIGN_STA_ING, null);
if (!success) {
log.error("更新合同流程状态失败");
return CommonResult.failed("更新合同流程状态失败");
return Pair.of(false, "更新合同流程状态失败");
}
return CommonResult.success("合同流程创建成功合同流程ID" + signFlowId);
return Pair.of(true, "合同流程创建成功合同流程ID" + signFlowId);
} catch (EsignDemoException e) {
throw new RuntimeException(e);
log.error("发起签署电子合同请求失败:", e);
return Pair.of(false, "发起签署电子合同请求失败!");
}
}
@ -288,20 +309,14 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
boolean success = updateContractFlowStatusAndFileUrlBySignFlowId(signFlowId, CommonConstant.CONTRACT_SIGN_STA_FINISH, downloadUrl);
if (success && StrUtil.isNotBlank(downloadUrl)) {
// 新建一个正式的已审核通过的店铺
taskService.executeTask(() -> {
// 1电子合同给商家申请分账功能使用务必检查是否申请过申请过忽略
Pair<Boolean, String> retPair = lakalaApiService.innerApplyLedgerMer(esignContract.getMch_mobile());
if (!retPair.getFirst()) {
log.error("商家申请分账功能失败:{}", retPair.getSecond());
}
Pair<Integer, String> retPair = shopStoreBaseService.merchEntryInfo2StoreInfo(esignContract.getMch_mobile());
if (retPair.getFirst() > 0) {
// 更改合同记录表的店铺id
updateContractStoreId(esignContract.getMch_mobile(), retPair.getFirst());
// 填充合同模版表的店铺Id
esignContractFillingFileService.updateContractFillingStoreId(esignContract.getMch_mobile(), retPair.getFirst());
// 店铺创建状态已完成
shopMerchEntryService.updateMerchEntryStoreStatus(esignContract.getMch_mobile(), CommonConstant.Enable);
}
});
// 更新商家的hasEsigned状态=1
shopMchEntryService.updateMulStatus(esignContract.getMch_mobile(), "", 1, 0, 0, 0);
return new ResponseEntity<>(new JSONObject().put("code", 200).put("msg", "success").toString(), HttpStatus.OK);
}
@ -499,7 +514,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
taskService.executeTask(() -> {
log.debug("###更改同步合同审核状态和下载地址###");
// 更改同步合同审核状态和下载地址
if (!shopMerchEntryService.updateMerchEntrySignedStatusAndContractDownloadUrl(esignContract.getMch_mobile(), signFlowStatus, localFileUrl)) {
if (!shopMchEntryService.updateMerchEntrySignedStatusAndContractDownloadUrl(esignContract.getMch_mobile(), signFlowStatus, localFileUrl)) {
log.error("###更改同步合同审核状态和下载地址失败###");
}
});
@ -527,8 +542,8 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
}
// 获取商家审核通过的入驻信息
ShopMerchEntry shopMerchEntry = shopMerchEntryService.getShopMerchEntryByCondition(esignContractFillingFile.getMobile(), "", CommonConstant.MCH_APPR_STA_PASS);
if (shopMerchEntry == null) {
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByCondition(esignContractFillingFile.getMobile(), "", CommonConstant.MCH_APPR_STA_PASS);
if (shopMchEntry == null) {
return false;
}
@ -539,13 +554,13 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
}
// 获取代理商信息
EsignPlatformInfo distributor = esignPlatformInfoService.getDistributorInfoById(shopMerchEntry.getDistributor_id());
EsignPlatformInfo distributor = esignPlatformInfoService.getDistributorInfoById(shopMchEntry.getDistributor_id());
// 未签合同文件ID
String fileId = esignContractFillingFile.getFile_id();
// (重要)组织生成签署合同的请求参数
String reqParams = buildSignReqParams(shopMerchEntry, esignPlatformInfo, distributor, esignContractFillingFile);
String reqParams = buildSignReqParams(shopMchEntry, esignPlatformInfo, distributor, esignContractFillingFile);
// 保存签署合同记录
EsignContract esignContract = new EsignContract();
@ -554,12 +569,12 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
esignContract.setContract_name(esignContractFillingFile.getContract_name());
esignContract.setContract_file_id(fileId);
esignContract.setMch_mobile(esignContractFillingFile.getMobile());
esignContract.setMch_company(shopMerchEntry.getBiz_license_company());
esignContract.setMch_biz_license(shopMerchEntry.getBiz_license_number());
esignContract.setMch_company(shopMchEntry.getBiz_license_company());
esignContract.setMch_biz_license(shopMchEntry.getBiz_license_number());
esignContract.setReq_params(reqParams);
esignContract.setUnsigned_contract_url(esignContractFillingFile.getUnsigned_contract_local_url());
esignContract.setStore_id(esignContractFillingFile.getStore_id());
esignContract.setDistributor_id(shopMerchEntry.getDistributor_id()); // 代理商ID(esign_platform_info表id)0-表示只有平台方没有代理商
esignContract.setDistributor_id(shopMchEntry.getDistributor_id()); // 代理商ID(esign_platform_info表id)0-表示只有平台方没有代理商
esignContract.setSign_flow_status(-1);//合作方签署状态-1:预备数据阶段1-等待签署2 - 已完成所有签署方完成签署3 - 已撤销发起方撤销签署任务5 - 已过期签署截止日到期后触发7 - 已拒签签署方拒绝签署
return saveOrUpdateByMchMobile(esignContract);
@ -729,13 +744,13 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
/**
* 重要组织生成签署合同的所有请求参数
*
* @param shopMerchEntry
* @param shopMchEntry
* @param esignPlatformInfo
* @param esignContractFillingFile
* @return
*/
protected String buildSignReqParams(ShopMerchEntry shopMerchEntry, EsignPlatformInfo esignPlatformInfo, EsignPlatformInfo distributor, EsignContractFillingFile esignContractFillingFile) {
if (shopMerchEntry == null || esignPlatformInfo == null || esignContractFillingFile == null) {
protected String buildSignReqParams(ShopMchEntry shopMchEntry, EsignPlatformInfo esignPlatformInfo, EsignPlatformInfo distributor, EsignContractFillingFile esignContractFillingFile) {
if (shopMchEntry == null || esignPlatformInfo == null || esignContractFillingFile == null) {
return "";
}
@ -765,19 +780,19 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
mchSigner.putByPath("signConfig.signOrder", 1);
mchSigner.putByPath("noticeConfig.noticeTypes", "1");// 短信
mchSigner.putByPath("signFields", JSONUtil.parseArray(esignContractFillingFile.getMch_sign_position()));
if (shopMerchEntry.getEntity_type().equals(CommonConstant.MCH_ENTITY_TYPE_QY)) {
if (shopMchEntry.getEntity_type().equals(CommonConstant.MCH_ENTITY_TYPE_QY)) {
// 企业
mchSigner.put("signerType", 1);
mchSigner.putByPath("orgSignerInfo.orgName", shopMerchEntry.getBiz_license_company());
mchSigner.putByPath("orgSignerInfo.orgInfo.orgIDCardNum", shopMerchEntry.getBiz_license_number());
mchSigner.putByPath("orgSignerInfo.orgName", shopMchEntry.getBiz_license_company());
mchSigner.putByPath("orgSignerInfo.orgInfo.orgIDCardNum", shopMchEntry.getBiz_license_number());
mchSigner.putByPath("orgSignerInfo.orgInfo.orgIDCardType", "CRED_ORG_USCC");
mchSigner.putByPath("orgSignerInfo.transactorInfo.psnAccount", shopMerchEntry.getLogin_mobile());
mchSigner.putByPath("orgSignerInfo.transactorInfo.psnInfo.psnName", shopMerchEntry.getLegal_person_name());
mchSigner.putByPath("orgSignerInfo.transactorInfo.psnAccount", shopMchEntry.getLogin_mobile());
mchSigner.putByPath("orgSignerInfo.transactorInfo.psnInfo.psnName", shopMchEntry.getLegal_person_name());
} else {
// 个人
mchSigner.put("signerType", 0);
mchSigner.putByPath("psnSignerInfo.psnAccount", shopMerchEntry.getLogin_mobile());
mchSigner.putByPath("psnSignerInfo.psnInfo.psnName", shopMerchEntry.getContact_name());
mchSigner.putByPath("psnSignerInfo.psnAccount", shopMchEntry.getLogin_mobile());
mchSigner.putByPath("psnSignerInfo.psnInfo.psnName", shopMchEntry.getContact_name());
}
// 加入甲方信息
signers.add(mchSigner);
@ -787,7 +802,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
platSigner.putByPath("signConfig.signOrder", 2);
platSigner.putByPath("noticeConfig.noticeTypes", "1,2"); // 短信和邮件
platSigner.putByPath("signFields", JSONUtil.parseArray(esignContractFillingFile.getPlat_sign_position()));
//if (shopMerchEntry.getEntity_type().equals(CommonConstant.MCH_ENTITY_TYPE_QY)) {
//if (shopMchEntry.getEntity_type().equals(CommonConstant.MCH_ENTITY_TYPE_QY)) {
// 企业平台方只能企业
platSigner.put("signerType", 1);
platSigner.putByPath("orgSignerInfo.orgName", esignPlatformInfo.getLicense_company());
@ -810,7 +825,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
distrSigner.putByPath("signConfig.signOrder", 3);
distrSigner.putByPath("noticeConfig.noticeTypes", "1"); // 短信和邮件
distrSigner.putByPath("signFields", JSONUtil.parseArray(esignContractFillingFile.getDistri_sign_position()));
//if (shopMerchEntry.getEntity_type().equals(CommonConstant.MCH_ENTITY_TYPE_QY)) {
//if (shopMchEntry.getEntity_type().equals(CommonConstant.MCH_ENTITY_TYPE_QY)) {
// 企业代理商只能企业
distrSigner.put("signerType", 1);
distrSigner.putByPath("orgSignerInfo.orgName", distributor.getLicense_company());

View File

@ -33,12 +33,15 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformI
*/
@Override
public EsignPlatformInfo getDistributorInfoById(Long id) {
if (ObjectUtils.isEmpty(id)) {
if (id == null || id <= 0) {
return null;
}
QueryWrapper<EsignPlatformInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id", id).gt("type", 0).eq("status", CommonConstant.Enable);
queryWrapper.eq("id", id)
.gt("level", 0)
.eq("status", CommonConstant.Enable).orderByAsc("level");
List<EsignPlatformInfo> esignPlatformInfos = list(queryWrapper);
if (CollectionUtil.isEmpty(esignPlatformInfos)) {
return null;
@ -47,21 +50,50 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformI
return esignPlatformInfos.get(0);
}
/**
* 根据一个或多个代理商自增ID获取代理商和平台记录无论怎么都要获取一条平台方的记录
*
* @param ids
* @return
*/
@Override
public List<EsignPlatformInfo> getDistributorAndPlatformByIds(Long... ids) {
QueryWrapper<EsignPlatformInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("status", CommonConstant.Enable).orderByAsc("level");
if (ids != null && ids.length > 0) {
queryWrapper.and(wrapper -> {
wrapper.in("id", ids).gt("level", 0);
wrapper.or(wrapperOr -> {
wrapperOr.eq("level", 0);
});
});
} else {
queryWrapper.eq("level", 0);
}
List<EsignPlatformInfo> esignPlatformInfos = list(queryWrapper);
if (CollectionUtil.isEmpty(esignPlatformInfos)) {
return null;
}
return esignPlatformInfos;
}
/**
* 根据分类和营业执照号获取平台方信息
*
* @param type 分类可选类型:0-平台方(只能一条记录)1-一级代理2-二级代理3-三级代理4-四级代理
* @param level 分类可选类型:0-平台方(只能一条记录)1-一级代理2-二级代理3-三级代理4-四级代理
* @param licenseNumber 营业执照号码可选
* @return
*/
@Override
public EsignPlatformInfo getEsignPlatformInfo(Integer type, String licenseNumber) {
public EsignPlatformInfo getEsignPlatformInfo(Integer level, String licenseNumber) {
QueryWrapper<EsignPlatformInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("status", CommonConstant.Enable);
if (!ObjectUtils.isEmpty(type)) {
queryWrapper.eq("type", type);
if (!ObjectUtils.isEmpty(level)) {
queryWrapper.eq("level", level);
} else {
queryWrapper.eq("type", 0);
queryWrapper.eq("level", 0);
}
if (StrUtil.isNotBlank(licenseNumber)) {
@ -76,6 +108,24 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformI
return esignPlatformInfos.get(0);
}
/**
* 是否存在平台方的相关记录信息
*
* @return
*/
@Override
public EsignPlatformInfo hasPlatformMch() {
QueryWrapper<EsignPlatformInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("level", 0).eq("status", CommonConstant.Enable);
EsignPlatformInfo esignPlatformInfo = getOne(queryWrapper);
if (ObjectUtils.isEmpty(esignPlatformInfo)) {
return null;
}
return esignPlatformInfo;
}
/**
* 获取平台方手机号和营业执照号
*
@ -84,7 +134,7 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformI
@Override
public Pair<String, String> getEsignPlatformMobileAndLicenseNumber() {
QueryWrapper<EsignPlatformInfo> queryWrapper = new QueryWrapper();
queryWrapper.eq("type", 0).select("telephone", "license_number", "legal_person_mobile");
queryWrapper.eq("level", 0).select("telephone", "license_number", "legal_person_mobile");
List<EsignPlatformInfo> esignPlatformInfos = list(queryWrapper);
if (CollectionUtil.isEmpty(esignPlatformInfos)) {
return null;

View File

@ -6,10 +6,10 @@
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.suisung.mall.shop.lakala.controller;
package com.suisung.mall.shop.lakala.controller.admin;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.shop.lakala.service.impl.CommonService;
import com.suisung.mall.shop.lakala.service.impl.LklTkServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestMapping;
@ -21,21 +21,21 @@ import javax.annotation.Resource;
@Api(tags = "拉卡拉商户进件控制器")
@RestController
@RequestMapping("/admin/shop/lakala/tk")
public class LklTkController extends BaseControllerImpl {
public class LklTkAdminController extends BaseControllerImpl {
@Resource
private CommonService commonService;
private LklTkServiceImpl lklTkService;
@ApiOperation(value = "请求获取token商户进件", notes = "请求获取token商户进件")
@RequestMapping(value = "/token", method = RequestMethod.POST)
public String getLklTkAuthorization() {
return commonService.getLklTkAuthorization();
return lklTkService.getLklTkAuthorization();
}
@ApiOperation(value = "请求获取token商户进件", notes = "请求获取token商户进件")
@RequestMapping(value = "/token1", method = RequestMethod.POST)
public String getLklTkAuthorization1() {
return commonService.getLklTkAuthorization();
return lklTkService.getLklTkAuthorization();
}

View File

@ -0,0 +1,106 @@
/*
* 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.lakala.controller.mobile;
import cn.hutool.json.JSONObject;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.shop.lakala.service.LakalaApiService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@Api(tags = "拉卡拉相关接口 - 前端控制器")
@RestController
@RequestMapping("/mobile/shop/lakala")
public class LakalaController extends BaseControllerImpl {
@Resource
private LakalaApiService lakalaPayService;
@ApiOperation(value = "测试案例", notes = "测试案例")
@RequestMapping(value = "/testcase", method = RequestMethod.POST)
public Object testcase(@RequestBody JSONObject paramsJSON) {
return lakalaPayService.applyLedgerMerEc(paramsJSON.getStr("mchMobile"));
// return lakalaPayService.LedgerMerEcDownload(975790666910121984L);
}
@ApiOperation(value = "本地文件转base64", notes = "本地文件转base64")
@RequestMapping(value = "/file2base64", method = RequestMethod.POST)
public String file2Base64(@RequestParam("file") MultipartFile file) throws IOException {
String str = Base64Utils.encodeToString(file.getBytes());
return str;
}
@ApiOperation(value = "获取银行卡的 BIN 信息", notes = "获取银行卡的 BIN 信息")
@RequestMapping(value = "/bankCardBin", method = RequestMethod.POST)
public JSONObject bankCardBin(@RequestBody JSONObject paramsJSON) {
return lakalaPayService.getBankCardBin(paramsJSON.getStr("bankCardNo"));
}
@ApiOperation(value = "商户入网电子合同申请回调通知", notes = "商户入网电子合同申请回调通知")
@RequestMapping(value = "/ec/applyNotify", method = RequestMethod.POST)
public ResponseEntity<JSONObject> ecApplyNotify(HttpServletRequest request) {
JSONObject resp = lakalaPayService.applyLedgerMerEcNotify(request);
if (resp != null && "SUCCESS".equals(resp.get("code"))) {
return new ResponseEntity<>(resp, HttpStatus.OK);
}
return new ResponseEntity<>(resp, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ApiOperation(value = "商户分账业务开通申请", notes = "商户分账业务开通申请")
@RequestMapping(value = "/ledger/applyLedgerMer", method = RequestMethod.POST)
public CommonResult ledgerApplyLedgerMer(@RequestBody JSONObject paramsJSON) {
return lakalaPayService.applyLedgerMer(paramsJSON);
}
@ApiOperation(value = "商户分账业务开通申请异步回调通知", notes = "商户分账业务开通申请异步回调通知")
@RequestMapping(value = "/ledger/applyLedgerMerNotify", method = RequestMethod.POST)
public ResponseEntity<JSONObject> ledgerApplyLedgerMerNotify(HttpServletRequest request) {
JSONObject resp = lakalaPayService.applyLedgerMerNotify(request);
if (resp != null && "SUCCESS".equals(resp.get("code"))) {
return new ResponseEntity<>(resp, HttpStatus.OK);
}
return new ResponseEntity<>(resp, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ApiOperation(value = "分账接收方创建申请", notes = "分账接收方创建申请")
@RequestMapping(value = "/ledger/applyLedgerReceiver", method = RequestMethod.POST)
public CommonResult applyLedgerReceiver(@RequestBody JSONObject paramsJSON) {
return lakalaPayService.applyLedgerReceiver(paramsJSON);
}
@ApiOperation(value = "分账关系绑定申请", notes = "分账关系绑定申请")
@RequestMapping(value = "/ledger/applyBind", method = RequestMethod.POST)
public CommonResult applyBind(@RequestBody JSONObject paramsJSON) {
return lakalaPayService.applyLedgerMerReceiverBind(paramsJSON);
}
// https://mall.gpxscs.cn/api/mobile/shop/lakala/ledger/applyLedgerMerReceiverBindNotify
@ApiOperation(value = "分账关系绑定申请异步回调通知", notes = "分账关系绑定申请异步回调通知")
@RequestMapping(value = "/ledger/applyLedgerMerReceiverBindNotify", method = RequestMethod.POST)
public ResponseEntity<JSONObject> applyBindNotify(HttpServletRequest request) {
JSONObject resp = lakalaPayService.applyLedgerMerReceiverBindNotify(request);
if (resp != null && "SUCCESS".equals(resp.get("code"))) {
return new ResponseEntity<>(resp, HttpStatus.OK);
}
return new ResponseEntity<>(resp, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

View File

@ -0,0 +1,97 @@
/*
* 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.lakala.controller.mobile;
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.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 org.springframework.data.util.Pair;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Api(tags = "拉卡拉商户进件控制器")
@RestController
@RequestMapping("/mobile/shop/lakala/tk")
public class LklTkController extends BaseControllerImpl {
@Resource
private LklTkServiceImpl lklTkService;
@Resource
private LklBanksService lklBanksService;
@ApiOperation(value = "解密拉卡拉进件返回的异步通知", notes = "解密拉卡拉进件返回的异步通知")
@RequestMapping(value = "/decode", method = RequestMethod.POST)
public String decryptLklTkData(@RequestParam(name = "data") String data,
@RequestParam(name = "key") String key) {
return LakalaUtil.decryptNotifyData(key, data);
}
@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"));
return CommonResult.success(list);
}
@ApiOperation(value = "拉卡拉进件申请", notes = "拉卡拉进件申请")
@RequestMapping(value = "/registrationMerchant", method = {RequestMethod.POST, RequestMethod.GET})
public CommonResult registrationMerchant(@RequestBody JSONObject paramsJSON) {
Pair<Boolean, String> resp = lklTkService.registrationMerchant(paramsJSON.getStr("mchMobile"), paramsJSON.getStr("bizLicenseNumber"));
if (resp.getFirst()) {
return CommonResult.success(null, resp.getSecond());
}
return CommonResult.failed(resp.getSecond());
}
// https://mall.gpxscs.cn/api/mobile/shop/lakala/ledger/applyLedgerMerReceiverBindNotify
@ApiOperation(value = "拉卡拉进件申请异步回调通知", notes = "拉卡拉进件申请异步回调通知")
@RequestMapping(value = "/registrationMerchantNotify", method = {RequestMethod.POST})
public ResponseEntity<JSONObject> registrationMerchantNotify(HttpServletRequest request) {
JSONObject resp = lklTkService.registrationMerchantNotify(request);
if (resp != null && resp.get("code").equals("200")) {
return new ResponseEntity<>(resp, HttpStatus.OK);
}
return new ResponseEntity<>(resp, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ApiOperation(value = "上传文件", notes = "上传文件")
@RequestMapping(value = "/uploadOcrImg", method = RequestMethod.POST)
public CommonResult uploadOcrImg(@RequestParam(name = "upfile") MultipartFile file,
@RequestParam(name = "imgType") String imgType) {
return lklTkService.uploadOcrImg(file, imgType);
}
@ApiOperation(value = "获取(身份证、营业执照、身份证)图片的信息", notes = "获取(身份证、营业执照、身份证)图片的信息")
@RequestMapping(value = "/imgOcrResult", method = RequestMethod.POST)
public CommonResult imgOcrResult(@RequestParam(name = "batchNo") String batchNo,
@RequestParam(name = "imgType") String imgType) {
return lklTkService.imgOcrResult(batchNo, imgType);
}
}

View File

@ -0,0 +1,26 @@
/*
* 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.lakala.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suisung.mall.common.modules.lakala.LklBanks;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
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);
}

View File

@ -0,0 +1,18 @@
/*
* 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.lakala.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.lakala.LklLedgerEc;
import org.springframework.stereotype.Repository;
@Repository
public interface LklLedgerEcMapper extends BaseMapper<LklLedgerEc> {
}

View File

@ -0,0 +1,18 @@
/*
* 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.lakala.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.lakala.LklLedgerMember;
import org.springframework.stereotype.Repository;
@Repository
public interface LklLedgerMemberMapper extends BaseMapper<LklLedgerMember> {
}

View File

@ -0,0 +1,18 @@
/*
* 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.lakala.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.lakala.LklLedgerMerReceiverBind;
import org.springframework.stereotype.Repository;
@Repository
public interface LklLedgerMerReceiverBindMapper extends BaseMapper<LklLedgerMerReceiverBind> {
}

View File

@ -0,0 +1,18 @@
/*
* 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.lakala.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.lakala.LklLedgerReceiver;
import org.springframework.stereotype.Repository;
@Repository
public interface LklLedgerReceiverMapper extends BaseMapper<LklLedgerReceiver> {
}

View File

@ -0,0 +1,19 @@
/*
* 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.lakala.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.lakala.LklOrderSeparate;
import org.springframework.stereotype.Repository;
@Repository
public interface LklOrderSeparateMapper extends BaseMapper<LklOrderSeparate> {
}

View File

@ -0,0 +1,212 @@
/*
* 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.lakala.service;
import cn.hutool.json.JSONObject;
import com.lkl.laop.sdk.request.V3SacsSeparateRequest;
import com.suisung.mall.common.api.CommonResult;
import org.springframework.data.util.Pair;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 拉卡拉业务接口
*/
public interface LakalaApiService {
Boolean initLKLSDK();
JSONObject transPreOrder(HttpServletRequest request, HttpServletResponse response, String orderId);
/**
* 拉卡拉预下单
* 参考https://o.lakala.com/#/home/document/detail?id=110
*
* @param merchantNo 商户号
* @param termNo 终端号
* @param xcxAppId 小程序appid
* @param openId openid
* @param orderId 订单号
* @param subject 订单标题
* @param totalAmount 订单金额
* @param notifyURL 回调地址
* @param requestIP 请求ip
* @param remark 备注
* @return
*/
JSONObject transPreOrder(String merchantNo, String termNo, String xcxAppId, String openId, String orderId, String subject, String totalAmount, String notifyURL, String requestIP, String remark);
/**
* 聚合扫码-交易查询
*
* @param storeId
* @param orderId
* @return
*/
JSONObject tradeQuery(Integer storeId, String orderId);
/**
* 聚合扫码-退款交易
* 主被扫交易发生后因商家或消费者原因需要退款时商家调用此接口退还消费者支付款项
* 注意 1调用退款接口时请保证商户/账户余额大于等于本次退款金额
*
* @param storeId
* @param out_trade_no
* @param origin_trade_no // 原拉卡拉交易流水号
* @param refund_amount 单位分整数数字型字符
* @param refund_reason
* @param requestIP
* @return
*/
JSONObject refund(Integer storeId, String out_trade_no, String origin_trade_no, String refund_amount, String refund_reason, String requestIP);
/**
* 账户余额查询
* 参考https://o.lakala.com/#/home/document/detail?id=364
*
* @param orgNo bmcp机构号
* @param merchantNo 商户号 receiveNo 商户用户编号
* @param payNo 账号若该参数上送则payType将无效
* @param payType 账号类型01收款账户02付款账户03分账商户账户04分账接收方账户05充值代付账户06结算代付账户- 未上送则默认为01
* @return
*/
JSONObject ewalletBalanceQuery(String orgNo, String merchantNo, String payNo, String payType);
/**
* 文件上传
* 参考https://o.lakala.com/#/home/document/detail?id=90
*
* @param orderNo
* @param attType
* @param attExtName
* @param attContext
* @return
*/
JSONObject uploadFile(String orderNo, String attType, String attExtName, String attContext);
/**
* 商家申请入网电子合同
*
* @param mchMobile
* @return
*/
Pair<Boolean, String> applyLedgerMerEc(String mchMobile);
/**
* 商户分账业务开通申请
* 参考https://o.lakala.com/#/home/document/detail?id=379
*
* @param paramsJSON
* @return
*/
CommonResult applyLedgerMer(JSONObject paramsJSON);
/**
* 内部调用商户分账业务开通申请
*
* @param merCupNo
* @return
*/
Pair<Boolean, String> innerApplyLedgerMer(String merCupNo);
/**
* 商户入网电子合同申请回调通知
* 参考https://o.lakala.com/#/home/document/detail?id=289
*
* @param request
* @return
*/
JSONObject applyLedgerMerEcNotify(HttpServletRequest request);
/**
* 商户入网电子合同下载
* 参考https://o.lakala.com/#/home/document/detail?id=294
*
* @param ecApplyId
* @return
*/
Pair<String, String> ledgerMerEcDownload(Long ecApplyId);
/**
* 商户分账业务开通申请回调
* 参考https://o.lakala.com/#/home/document/detail?id=379
*
* @param request
* @return
*/
JSONObject applyLedgerMerNotify(HttpServletRequest request);
/**
* 分账接收方创建申请
* 参考https://o.lakala.com/#/home/document/detail?id=380
*
* @param paramsJSON
* @return
*/
CommonResult applyLedgerReceiver(JSONObject paramsJSON);
/**
* 分账关系绑定申请
* 参考https://o.lakala.com/#/home/document/detail?id=386
*
* @param paramsJSON
* @return
*/
CommonResult applyLedgerMerReceiverBind(JSONObject paramsJSON);
/**
* 分账关系绑定申请回调
* 参考https://o.lakala.com/#/home/document/detail?id=379
*
* @param request
* @return
*/
JSONObject applyLedgerMerReceiverBindNotify(HttpServletRequest request);
/**
* 获取银行卡信息
* 参考https://o.lakala.com/#/home/document/detail?id=387
*
* @param bankCardNo
* @return
*/
JSONObject getBankCardBin(String bankCardNo);
/**
* 查询拉卡拉商户可分账的金额
* 参考https://o.lakala.com/#/home/document/detail?id=394
*
* @param merchantNo 拉卡拉外部商户号
* @param logNo 拉卡拉对账单流水号
* @param logDate 拉卡拉对账单交易日期 yyyyMMdd
* @return 响应结果 {
* "merchant_no": "82229005943096D",
* "total_separate_amt": "9900",
* "can_separate_amt": "0",
* "log_date": "20221220",
* "log_no": "66210306990190"
* }
*/
JSONObject queryMchCanSplitAmt(String merchantNo, String logNo, String logDate);
/**
* 拉卡拉订单分账用户下单成功之后进行分账
* 说明分账指令是异步处理模式响应报文成功时指令状态是status: PROCESSING需要等待分账结果通知或者主动发起查询建议主动发起查询与分账指令动作之间间隔15秒以上
* 参考https://o.lakala.com/#/home/document/detail?id=389
*
* @param v3SacsSeparateRequest
* @return
*/
Pair<Boolean, String> innerDoOrderSeparate(V3SacsSeparateRequest v3SacsSeparateRequest);
}

View File

@ -0,0 +1,50 @@
/*
* 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.lakala.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suisung.mall.common.modules.lakala.LklBanks;
import java.util.Map;
public interface LklBanksService {
/**
* 根据关键字查询有效记录分页列表不带地区
*
* @param keyword
* @param pageNum
* @param pageSize
* @return
*/
Page<LklBanks> searchBranchBanksPageList(String keyword, Integer pageNum, Integer pageSize);
/**
* 根据关键字分词进行分页查询支行列表带省市地区
*
* @param bankNo 总行号
* @param branchBankNo 支行号
* @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);
/**
* 根据支行号查询支行信息带省市地区
*
* @param branchBankNo 支行号
* @return
*/
Map<String, Object> GetLklBankByBranchBankNo(String branchBankNo);
}

View File

@ -0,0 +1,53 @@
/*
* 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.lakala.service;
import com.suisung.mall.common.modules.lakala.LklLedgerEc;
import com.suisung.mall.core.web.service.IBaseService;
public interface LklLedgerEcService extends IBaseService<LklLedgerEc> {
/**
* 根据商家Id新增或更新记录
*
* @param record
* @return
*/
Boolean saveOrUpdateByMchId(LklLedgerEc record);
/**
* 根据applyId更新记录
*
* @param record
* @return
*/
Boolean updateByApplyId(LklLedgerEc record);
/**
* 根据接applyId查询记录
*
* @param applyId
* @param ecStatus
* @param status
* @return
*/
LklLedgerEc getByApplyId(Long applyId, String ecStatus, Integer status);
/**
* 根据商户手机号查询记录
*
* @param mchMobile
* @param ecStatus
* @param status
* @return
*/
LklLedgerEc getByMchMobile(String mchMobile, String ecStatus, Integer status);
}

View File

@ -0,0 +1,57 @@
/*
* 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.lakala.service;
import com.suisung.mall.common.modules.lakala.LklLedgerMember;
import com.suisung.mall.core.web.service.IBaseService;
public interface LklLedgerMemberService extends IBaseService<LklLedgerMember> {
/**
* 根据银联商户号查询记录
*
* @param merCupNo
* @return
*/
LklLedgerMember getByMerCupNo(String merCupNo);
/**
* 根据申请单号和审核状态查询记录
*
* @param applyId
* @param auditStatus
* @return
*/
LklLedgerMember getByApplyId(String applyId, Integer auditStatus);
/**
* 根据银联商户号新增或修改记录
*
* @param record
* @return
*/
Boolean saveOrUpdateByMerCupNo(LklLedgerMember record);
/**
* 更新审核结果
*
* @param applyId
* @param merInnerNo
* @param merCupNo
* @param entrustFileName
* @param entrustFilePath
* @param auditStatus
* @param auditStatusText
* @param remark
* @return
*/
Boolean updateAuditResult(String applyId, String merInnerNo, String merCupNo, String entrustFileName, String entrustFilePath, String auditStatus, String auditStatusText, String remark);
}

View File

@ -0,0 +1,48 @@
/*
* 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.lakala.service;
import com.suisung.mall.common.modules.lakala.LklLedgerMerReceiverBind;
import com.suisung.mall.core.web.service.IBaseService;
public interface LklLedgerMerReceiverBindService extends IBaseService<LklLedgerMerReceiverBind> {
/**
* 根据接收方编号新增或更新记录
*
* @param record
* @return
*/
Boolean saveOrUpdateByMerCupNoReceiverNo(LklLedgerMerReceiverBind record);
/**
* 根据接收方编号查询记录
*
* @param merCupNo
* @param receiverNo
* @return
*/
LklLedgerMerReceiverBind getByCondition(String merCupNo, String receiverNo);
/**
* 更新审核结果
*
* @param applyId
* @param merInnerNo
* @param merCupNo
* @param receiverNo
* @param entrustFileName
* @param entrustFilePath
* @param auditStatus
* @param auditStatusText
* @param remark
* @return
*/
Boolean updateAuditResult(String applyId, String merInnerNo, String merCupNo, String receiverNo, String entrustFileName, String entrustFilePath, String auditStatus, String auditStatusText, String remark);
}

View File

@ -0,0 +1,85 @@
/*
* 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.lakala.service;
import cn.hutool.json.JSONArray;
import com.suisung.mall.common.modules.lakala.LklLedgerReceiver;
import com.suisung.mall.core.web.service.IBaseService;
import java.util.List;
public interface LklLedgerReceiverService extends IBaseService<LklLedgerReceiver> {
/**
* 根据接收方编号新增或更新记录
*
* @param record
* @return
*/
Boolean saveOrUpdateByReceiverNo(LklLedgerReceiver record);
/**
* 根据接收方编号查询记录
*
* @param receiverNo
* @return
*/
LklLedgerReceiver getByReceiverNo(String receiverNo);
/**
* 通过平台方代理商 ID 查询记录
*
* @param platformId
* @return
*/
LklLedgerReceiver getByPlatformId(Long platformId);
/**
* 通过平台方代理商记录信息构建申请分账接收方的请求参数
*
* @param platformId
* @return
*/
JSONArray buildApplyLedgerReceiverReqParams(Long platformId);
/**
* 内部调用申请分账接收方
*
* @param merCupNo
* @param platformId
* @return
*/
Boolean innerApplyLedgerReceiver(String merCupNo, Long platformId);
/**
* 是否存在平台方的相关记录信息
*
* @return
*/
LklLedgerReceiver hasPlatformMch();
/**
* 根据条件查询记录
*
* @param LicenseNo
* @param ContactMobile
* @param platformId
* @return
*/
LklLedgerReceiver getByCondition(String LicenseNo, String ContactMobile, Long platformId);
/**
* 根据条件查询记录
*
* @param LicenseNo
* @param ContactMobile
* @return
*/
List<LklLedgerReceiver> getByCondition(String LicenseNo, String ContactMobile);
}

View File

@ -1,409 +0,0 @@
/*
* 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.lakala.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.modules.merch.ShopMerchEntry;
import com.suisung.mall.common.utils.RestTemplateHttpUtil;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.common.utils.UploadUtil;
import com.suisung.mall.core.web.service.RedisService;
import com.suisung.mall.shop.store.service.ShopMerchEntryService;
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.data.util.Pair;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
@Service
public class CommonService {
private static final Logger log = LoggerFactory.getLogger(CommonService.class);
@Value("${lakala.tk.server_url}")
private String serverUrl;
@Value("${lakala.tk.client_id}")
private String clientId;
@Value("${lakala.tk.client_secret}")
private String clientSecret;
@Value("${spring.profiles.active}")
private String profile;
@Resource
private ShopMerchEntryService shopMerchEntryService;
@Autowired
private RedisService redisService;
protected String buildLklTkUrl(String urlPath) {
return serverUrl + urlPath;
}
protected boolean isProd() {
return "prod".equalsIgnoreCase(profile);
}
/**
* 请求获取token商户进件
*
* @return AuthorizationKey
*/
public String getLklTkAuthorization() {
String authorizationKey = "lkl_tk_authorization";
Object lklTkToken = redisService.get(authorizationKey);
if (ObjectUtil.isNotEmpty(lklTkToken)) {
return lklTkToken.toString();
}
Map<String, String> formData = new HashMap<>();
formData.put("grant_type", "client_credentials");
formData.put("client_id", clientId);
formData.put("client_secret", clientSecret);
String response = RestTemplateHttpUtil.sendPostFormData(buildLklTkUrl("/oauth/token"), null, formData, String.class);
if (ObjectUtil.isEmpty(response)) {
return "";
}
JSONObject jsonObj = JSONUtil.parseObj(response);
if (jsonObj == null || StrUtil.isBlank(jsonObj.getStr("access_token"))) {
return "";
}
String token = jsonObj.getStr("token_type") + " " + jsonObj.getStr("access_token");
redisService.set(authorizationKey, token, jsonObj.getLong("expires_in"));
return token;
}
/**
* (重要) 请求拉卡拉进件
*
* @param mchMobile 商家手机号
* @return
*/
public Pair<Boolean, String> registrationMerchant(String mchMobile) {
String authorization = getLklTkAuthorization();
if (StrUtil.isBlank(authorization)) {
return Pair.of(false, "获取拉卡拉token失败");
}
JSONObject header = new JSONObject();
header.put("Authorization", getLklTkAuthorization());
// 获取商家入驻信息组成请求参数
ShopMerchEntry shopMerchEntry = shopMerchEntryService.getShopMerchEntryByCondition(mchMobile, null, CommonConstant.MCH_APPR_STA_PASS);
if (ObjectUtil.isEmpty(shopMerchEntry)) {
return Pair.of(false, "商家入驻信息不存在");
}
JSONObject formData = new JSONObject();
formData.put("userNo", "29153396");
formData.put("email", mchMobile + "@163.com");
formData.put("busiCode", "B2B_SYT");
formData.put("merRegName", shopMerchEntry.getStore_name());
Boolean isQy = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMerchEntry.getEntity_type());
String merType = isQy ? "TP_MERCHANT" : "TP_PERSONAL";
formData.put("merType", merType);
formData.put("merName", shopMerchEntry.getStore_name());
formData.put("merAddr", StringUtils.removeProvinceCityDistrict(shopMerchEntry.getStore_address()));
Map<String, String> areaCode = getAreaCode(shopMerchEntry.getStore_area(), false);
if (ObjectUtil.isNotEmpty(areaCode)) {
formData.put("provinceCode", areaCode.get("provinceCode"));
formData.put("cityCode", areaCode.get("cityCode"));
formData.put("countyCode", areaCode.get("countyCode"));
}
formData.put("longtude", shopMerchEntry.getStore_longitude()); //longitude 经度
formData.put("latitude", shopMerchEntry.getStore_latitude());
formData.put("source", "H5");
formData.put("larIdType", "01");
String larName = isQy ? shopMerchEntry.getLegal_person_name() : shopMerchEntry.getContact_name();
String larIdCard = isQy ? shopMerchEntry.getLegal_person_id_number() : shopMerchEntry.getIndividual_id_number();
String larIdCardStart = isQy ? shopMerchEntry.getLegal_person_id_period_begin() : shopMerchEntry.getIndividual_id_period_begin();
String larIdCardEnd = isQy ? shopMerchEntry.getLegal_person_id_period_end() : shopMerchEntry.getIndividual_id_period_end();
formData.put("larName", larName);
formData.put("larIdCard", larIdCard);
formData.put("larIdCardStart", larIdCardStart); // 身份证有效期开始时间
formData.put("larIdCardEnd", larIdCardEnd); // 身份证有效期结束时间
formData.put("businessContent", shopMerchEntry.getSales_info());
// 营业执照信息
if (isQy) {
formData.put("licenseName", shopMerchEntry.getBiz_license_company());
formData.put("licenseNo", shopMerchEntry.getBiz_license_number());
formData.put("licenseDtStart", shopMerchEntry.getBiz_license_period_begin());
formData.put("licenseDtEnd", shopMerchEntry.getBiz_license_period_end());
}
formData.put("contactMobile", mchMobile);
formData.put("contactName", shopMerchEntry.getContact_name());
formData.put("openningBankCode", shopMerchEntry.getBank_code());//结算账户开户
formData.put("openningBankName", shopMerchEntry.getBank_name());//结算账户开户名称
formData.put("clearingBankCode", shopMerchEntry.getClearing_bank_code());//结算账户清算
formData.put("accountNo", shopMerchEntry.getAccount_number()); //结算人银行卡号
formData.put("accountName", shopMerchEntry.getAccount_holder_name()); //结算人账户名称
formData.put("accountIdCard", shopMerchEntry.getLegal_person_id_number());//结算证件号码(身份证)
formData.put("settleType", "D1"); //结算类型D0秒到D1次日结算
formData.put("settlementType", "AUTOMATIC"); // 结算方式MANUAL:手动结算(结算至拉卡拉APP钱包),AUTOMATIC:自动结算到银行卡,REGULAR:定时结算仅企业商户支持
formData.put("accountType", isQy ? "57" : "58"); //结算账户类型: 57 对公 58 对私
//结算信息省份代码
Map<String, String> bankAreaCode = getAreaCode(shopMerchEntry.getBank_area(), true);
if (ObjectUtil.isNotEmpty(bankAreaCode)) {
formData.put("settleProvinceCode", bankAreaCode.get("provinceCode"));
formData.put("settleCityCode", bankAreaCode.get("cityCode"));
String[] bankAreaName = shopMerchEntry.getBank_area().split(",");
if (bankAreaName.length >= 2) {
formData.put("settleProvinceName", bankAreaName[0]);
formData.put("settleCityName", bankAreaName[1]);
}
}
JSONObject bizContent = new JSONObject();
bizContent.put("activityId", 687);
bizContent.put("termNum", "1");
bizContent.put("mcc", "1");
bizContent.put("fees", new JSONArray() {{
put(new JSONObject() {{
put("feeCode", "WECHAT");
put("feeValue", 0.38);
}});
}});
formData.put("bizContent", bizContent);
JSONArray attachments = new JSONArray();
JSONObject ID_CARD_FRONT = updatePhoto(shopMerchEntry.getIndividual_id_images(), "ID_CARD_FRONT", true);
if (ID_CARD_FRONT != null) {
attachments.put(ID_CARD_FRONT); // 身份证正面
}
JSONObject ID_CARD_BEHIND = updatePhoto(shopMerchEntry.getIndividual_id_images2(), "ID_CARD_BEHIND", true);
if (ID_CARD_BEHIND != null) {
attachments.put(ID_CARD_BEHIND); // 身份证国徽面
}
JSONObject SETTLE_ID_CARD_FRONT = updatePhoto(shopMerchEntry.getLegal_person_id_images(), "SETTLE_ID_CARD_FRONT", true);
if (SETTLE_ID_CARD_FRONT != null) {
attachments.put(SETTLE_ID_CARD_FRONT); // 结算人身份证正面
}
JSONObject SETTLE_ID_CARD_BEHIND = updatePhoto(shopMerchEntry.getLegal_person_id_images2(), "SETTLE_ID_CARD_BEHIND", true);
if (SETTLE_ID_CARD_BEHIND != null) {
attachments.put(SETTLE_ID_CARD_BEHIND); // 结算人身份证国徽面
}
JSONObject BUSINESS_LICENCE = updatePhoto(shopMerchEntry.getBiz_license_image(), "BUSINESS_LICENCE", true);
if (BUSINESS_LICENCE != null) {
attachments.put(BUSINESS_LICENCE); // 营业执照
}
JSONObject SHOP_OUTSIDE_IMG = updatePhoto(shopMerchEntry.getFront_facade_image(), "SHOP_OUTSIDE_IMG", false);
if (SHOP_OUTSIDE_IMG != null) {
attachments.put(SHOP_OUTSIDE_IMG); // 门店门面图片
}
JSONObject SHOP_INSIDE_IMG = updatePhoto(shopMerchEntry.getEnvironment_image(), "SHOP_INSIDE_IMG", false);
if (SHOP_INSIDE_IMG != null) {
attachments.put(SHOP_INSIDE_IMG); // 门店内部图片
}
JSONObject BANK_CARD = updatePhoto(shopMerchEntry.getBank_image(), "BANK_CARD", true);
if (BANK_CARD != null) {
attachments.put(BANK_CARD); // 银行卡图片
}
formData.put("attchments", attachments);
String urlPath = "/sit/htkregistration/merchant";
if (isProd()) {
urlPath = "/registration/merchant";
}
ResponseEntity<JSONObject> response = RestTemplateHttpUtil.sendPostFormDataBackEntity(buildLklTkUrl(urlPath), header, formData, JSONObject.class);
if (ObjectUtil.isEmpty(response) || response.getStatusCode() != HttpStatus.OK) {
String errMsg = "请求分账系统出错!";
if (ObjectUtil.isNotEmpty(response.getBody()) && ObjectUtil.isNotEmpty(response.getBody().getStr("message"))) {
errMsg = response.getBody().getStr("message");
}
return Pair.of(false, "进件失败:" + errMsg);
}
// 根据入驻商家的代理商或平台方顺便新增一个接收方记录
// TODO 新增 lkl_ledger_member 数据 等待异步审核通知更改状态
String merchantNo = response.getBody().getStr("merchantNo"); //拉卡拉内部商户号
return Pair.of(true, "进件成功!");
}
/**
* 获取拉卡拉省市区编码
*
* @param areaName 省份/城市/乡县
* @return
*/
public Map<String, String> getAreaCode(String areaName, Boolean isBankArea) {
if (StrUtil.isBlank(areaName)) {
return new HashMap<String, String>() {{
put("provinceCode", "");
put("cityCode", "");
put("countyCode", "");
}};
}
String[] areaNames = areaName.split("/");
if (areaNames.length < 2) {
return new HashMap<String, String>() {{
put("provinceCode", "");
put("cityCode", "");
put("countyCode", "");
}};
}
String provinceName = areaNames[0];
String cityName = areaNames[1];
String countryName = "";
if (areaNames.length >= 3) {
countryName = areaNames[2];
}
String urlPath = "/organization";
if (isBankArea) {
urlPath = "/organization/bank";
}
String authorization = getLklTkAuthorization();
if (StrUtil.isBlank(authorization)) {
log.error("获取拉卡拉token失败");
return new HashMap<String, String>() {{
put("provinceCode", "");
put("cityCode", "");
put("countyCode", "");
}};
}
JSONObject header = new JSONObject();
header.put("Authorization", getLklTkAuthorization());
Map<String, String> areaCodeMap = new HashMap<>();
// 省份列表
ResponseEntity<JSONArray> response = RestTemplateHttpUtil.sendGetWithHeader(buildLklTkUrl(urlPath + "/1"), header, JSONArray.class);
if (ObjectUtil.isNotEmpty(response) && response.getStatusCode() == HttpStatus.OK) {
String provinceCode = "";
String cityCode = "";
String countyCode = "";
JSONArray jsonArray = response.getBody();
if (CollUtil.isNotEmpty(jsonArray)) {
for (JSONObject jsonObject : jsonArray.jsonIter()) {
if (StrUtil.contains(jsonObject.getStr("name"), provinceName)) {
provinceCode = jsonObject.getStr("code");
areaCodeMap.put("provinceCode", provinceCode);
break;
}
}
// 城市列表
if (StrUtil.isNotBlank(provinceCode)) {
response = RestTemplateHttpUtil.sendGetWithHeader(buildLklTkUrl(urlPath + "/" + provinceCode), header, JSONArray.class);
jsonArray = response.getBody();
if (CollUtil.isNotEmpty(jsonArray)) {
for (JSONObject jsonObject : jsonArray.jsonIter()) {
if (StrUtil.contains(jsonObject.getStr("name"), cityName)) {
cityCode = jsonObject.getStr("code");
areaCodeMap.put("cityCode", cityCode);
break;
}
}
}
}
// 乡列表
if (StrUtil.isNotBlank(cityCode)) {
response = RestTemplateHttpUtil.sendGetWithHeader(buildLklTkUrl(urlPath + "/" + cityCode), header, JSONArray.class);
jsonArray = response.getBody();
if (CollUtil.isNotEmpty(jsonArray)) {
for (JSONObject jsonObject : jsonArray.jsonIter()) {
if (StrUtil.contains(jsonObject.getStr("name"), countryName)) {
countyCode = jsonObject.getStr("code");
areaCodeMap.put("countyCode", countyCode);
break;
}
}
}
}
}
}
return areaCodeMap;
}
public JSONObject updatePhoto(String fileUrl, String imgType, Boolean isOcr) {
if (StrUtil.isBlank(fileUrl)) {
return null;
}
JSONObject header = new JSONObject();
header.put("Authorization", getLklTkAuthorization());
JSONObject formData = new JSONObject();
File file = UploadUtil.downloadImageFromUrl(fileUrl);
formData.put("file", file);
formData.put("imgType", imgType);
formData.put("sourcechnl", "0");
formData.put("isOcr", isOcr);
String urlPath = "/file/upload";
ResponseEntity<JSONObject> response = RestTemplateHttpUtil.sendPostFormDataBackEntity(buildLklTkUrl(urlPath), header, formData, JSONObject.class);
if (ObjectUtil.isEmpty(response) || response.getStatusCode() != HttpStatus.OK) {
return null;
}
JSONObject result = response.getBody();
if (result == null) {
return null;
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", result.get("url"));
jsonObject.put("type", imgType);
return jsonObject;
}
}

View File

@ -0,0 +1,117 @@
/*
* 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.lakala.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.modules.lakala.LklBanks;
import com.suisung.mall.common.utils.JiebaUtils;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.lakala.mapper.LklBanksMapper;
import com.suisung.mall.shop.lakala.service.LklBanksService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class LklBanksServiceImpl extends BaseServiceImpl<LklBanksMapper, LklBanks> implements LklBanksService {
@Resource
private JiebaUtils jiebaUtils;
@Resource
private LklBanksMapper lklBanksMapper;
/**
* 根据关键字查询有效记录分页列表
*
* @param keyword
* @param pageNum
* @param pageSize
* @return
*/
@Override
public Page<LklBanks> searchBranchBanksPageList(String keyword, Integer pageNum, Integer pageSize) {
if (pageNum == null || pageNum < 1) {
pageNum = 1;
}
if (pageSize == null || pageSize < 1) {
pageSize = 10;
}
QueryWrapper<LklBanks> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("status", CommonConstant.Enable).orderByAsc("branch_bank_no");
if (StrUtil.isNotBlank(keyword)) {
List<String> keywordList = jiebaUtils.segmentForSearch(keyword);
log.info("分词后的关键词:{}", keywordList);
queryWrapper.and(wrapper -> {
// wrapper.like("branch_bank_name", keyword)
// .or()
// .like("branch_bank_no", keyword)
// .or()
// .like("clear_no", keyword)
// .or()
// .like("bank_no", keyword);
// 再添加分词后的关键词条件
for (String kw : keywordList) {
wrapper.like("branch_bank_name", kw);
}
});
}
return lists(queryWrapper, pageNum, pageSize);
}
/**
* @param bankNo
* @param branchBankNo
* @param type
* @param keyword
* @param pageNum
* @param pageSize
* @return
*/
@Override
public IPage<Map> pageBranchBanksList(String bankNo, String branchBankNo, 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));
}
/**
* 根据支行号查询支行信息带省市地区
*
* @param branchBankNo 支行号
* @return
*/
@Override
public Map<String, Object> GetLklBankByBranchBankNo(String branchBankNo) {
if (StrUtil.isBlank(branchBankNo)) {
return null;
}
IPage<Map> list = lklBanksMapper.pageBranchBanksList(new Page<>(1, 1), null, branchBankNo, 2, null);
if (list == null || CollectionUtil.isEmpty(list.getRecords())) {
return null;
}
return list.getRecords().get(0);
}
}

View File

@ -0,0 +1,161 @@
/*
* 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.lakala.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.suisung.mall.common.modules.lakala.LklLedgerEc;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.esign.service.EsignPlatformInfoService;
import com.suisung.mall.shop.lakala.mapper.LklLedgerEcMapper;
import com.suisung.mall.shop.lakala.service.LakalaApiService;
import com.suisung.mall.shop.lakala.service.LklLedgerEcService;
import com.suisung.mall.shop.store.service.ShopMchEntryService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class LklLedgerEcServiceImpl extends BaseServiceImpl<LklLedgerEcMapper, LklLedgerEc> implements LklLedgerEcService {
@Resource
private EsignPlatformInfoService esignPlatformInfoService;
@Lazy
@Resource
private LakalaApiService lakalaApiService;
@Lazy
@Resource
private ShopMchEntryService shopMchEntryService;
/**
* 根据商家Id新增或更新记录
*
* @param record
* @return
*/
@Override
public Boolean saveOrUpdateByMchId(LklLedgerEc record) {
if (record == null || (ObjectUtil.isEmpty(record.getMch_id()) && StrUtil.isBlank(record.getMch_mobile()))) {
return false;
}
QueryWrapper<LklLedgerEc> queryWrapper = new QueryWrapper<>();
if (ObjectUtil.isEmpty(record.getMch_id())) {
queryWrapper.eq("mch_id", record.getMch_id());
}
if (ObjectUtil.isEmpty(record.getMch_mobile())) {
queryWrapper.eq("mch_mobile", record.getMch_mobile());
}
List<LklLedgerEc> existsRecordList = list(queryWrapper);
if (CollectionUtil.isNotEmpty(existsRecordList)
&& existsRecordList.get(0) != null
&& existsRecordList.get(0).getId() > 0) {
// 更新记录
record.setId(existsRecordList.get(0).getId());
return updateById(record);
}
return add(record);
}
/**
* 根据applyId更新记录
*
* @param record
* @return
*/
@Override
public Boolean updateByApplyId(LklLedgerEc record) {
if (record == null || ObjectUtil.isEmpty(record.getEc_apply_id())) {
return false;
}
QueryWrapper<LklLedgerEc> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("ec_apply_id", record.getEc_apply_id());
LklLedgerEc existsRecord = getOne(queryWrapper);
if (existsRecord == null) {
return false;
}
// 更新记录
record.setId(existsRecord.getId());
return updateById(record);
}
/**
* 根据接applyId查询记录
*
* @param applyId
* @param ecStatus
* @param status
* @return
*/
@Override
public LklLedgerEc getByApplyId(Long applyId, String ecStatus, Integer status) {
if (ObjectUtil.isEmpty(applyId)) {
return null;
}
QueryWrapper<LklLedgerEc> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("ec_apply_id", applyId);
if (ObjectUtil.isNotEmpty(status)) {
queryWrapper.eq("status", status);
}
if (StrUtil.isNotEmpty(ecStatus)) {
queryWrapper.eq("ec_status", ecStatus);
}
return getOne(queryWrapper);
}
/**
* 根据商户手机号查询记录
*
* @param mchMobile
* @param ecStatus
* @param status
* @return
*/
@Override
public LklLedgerEc getByMchMobile(String mchMobile, String ecStatus, Integer status) {
if (ObjectUtil.isEmpty(mchMobile)) {
return null;
}
QueryWrapper<LklLedgerEc> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mch_mobile", mchMobile).orderByDesc("id");
if (ObjectUtil.isNotEmpty(status)) {
queryWrapper.eq("status", status);
}
if (StrUtil.isNotEmpty(ecStatus)) {
queryWrapper.eq("ec_status", ecStatus);
}
List<LklLedgerEc> lklLedgerEcList = list(queryWrapper);
if (CollectionUtil.isEmpty(lklLedgerEcList)) {
return null;
}
return lklLedgerEcList.get(0);
}
}

View File

@ -0,0 +1,127 @@
/*
* 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.lakala.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.modules.lakala.LklLedgerMember;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.lakala.mapper.LklLedgerMemberMapper;
import com.suisung.mall.shop.lakala.service.LklLedgerMemberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class LklLedgerMemberServiceImpl extends BaseServiceImpl<LklLedgerMemberMapper, LklLedgerMember> implements LklLedgerMemberService {
/**
* 根据银联商户号查询记录
*
* @param merCupNo
* @return
*/
@Override
public LklLedgerMember getByMerCupNo(String merCupNo) {
if (StrUtil.isBlank(merCupNo)) {
return null;
}
QueryWrapper<LklLedgerMember> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mer_cup_no", merCupNo);
queryWrapper.orderByAsc("id");
return getOne(queryWrapper);
}
/**
* 根据申请单号和审核状态查询记录
*
* @param applyId
* @param auditStatus
* @return
*/
@Override
public LklLedgerMember getByApplyId(String applyId, Integer auditStatus) {
if (StrUtil.isBlank(applyId) || auditStatus == null) {
return null;
}
QueryWrapper<LklLedgerMember> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("apply_id", applyId);
queryWrapper.eq("audit_status", auditStatus);
return getOne(queryWrapper);
}
/**
* 根据银联商户号新增或修改记录
*
* @param record
* @return
*/
@Override
public Boolean saveOrUpdateByMerCupNo(LklLedgerMember record) {
if (record == null || StrUtil.isBlank(record.getMer_cup_no())) {
return false;
}
QueryWrapper<LklLedgerMember> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mer_cup_no", record.getMer_cup_no()).eq("mch_id", record.getMch_id());
List<LklLedgerMember> existsRecordList = list(queryWrapper);
if (!CollectionUtil.isEmpty(existsRecordList)
&& existsRecordList.get(0) != null
&& existsRecordList.get(0).getId() > 0) {
// update
record.setId(existsRecordList.get(0).getId());
return updateById(record);
}
return add(record);
}
/**
* 更新审核结果
*
* @param applyId
* @param merInnerNo
* @param merCupNo
* @param entrustFileName
* @param entrustFilePath
* @param auditStatus
* @param auditStatusText
* @param remark
* @return
*/
@Override
public Boolean updateAuditResult(String applyId, String merInnerNo, String merCupNo, String entrustFileName, String entrustFilePath, String auditStatus, String auditStatusText, String remark) {
if (StrUtil.isBlank(applyId) || StrUtil.isBlank(merCupNo) || StrUtil.isBlank(auditStatus)) {
log.error("缺少参数applyId={}, merCupNo={}, auditStatus={}", applyId, merCupNo, auditStatus);
return false;
}
UpdateWrapper<LklLedgerMember> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("apply_id", applyId);
updateWrapper.set("mer_inner_no", merInnerNo);
updateWrapper.set("mer_cup_no", merCupNo);
updateWrapper.set("split_entrust_file_name", entrustFileName);
updateWrapper.set("split_entrust_file_path", entrustFilePath);
updateWrapper.set("audit_status", auditStatus);
updateWrapper.set("audit_status_text", auditStatusText);
updateWrapper.set("has_esigned", CommonConstant.Enable); // 电子合同签署完成之后才能做分账申请
updateWrapper.set("has_apply_split", CommonConstant.Enable);
updateWrapper.set("remark", remark);
return update(updateWrapper);
}
}

View File

@ -0,0 +1,117 @@
/*
* 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.lakala.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.modules.lakala.LklLedgerMerReceiverBind;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.lakala.mapper.LklLedgerMerReceiverBindMapper;
import com.suisung.mall.shop.lakala.service.LklLedgerMerReceiverBindService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class LklLedgerMerReceiverBindServiceImpl extends BaseServiceImpl<LklLedgerMerReceiverBindMapper, LklLedgerMerReceiverBind> implements LklLedgerMerReceiverBindService {
/**
* 根据接收方编号新增或更新记录
*
* @param record
* @return
*/
@Override
public Boolean saveOrUpdateByMerCupNoReceiverNo(LklLedgerMerReceiverBind record) {
if (record == null || StrUtil.isBlank(record.getMer_cup_no()) || StrUtil.isBlank(record.getReceiver_no())) {
return false;
}
QueryWrapper<LklLedgerMerReceiverBind> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mer_cup_no", record.getMer_cup_no())
.eq("receiver_no", record.getReceiver_no())
.eq("audit_status", CommonConstant.Enable);
List<LklLedgerMerReceiverBind> existsRecordList = list(queryWrapper);
if (!CollectionUtil.isEmpty(existsRecordList)
&& existsRecordList.get(0) != null
&& existsRecordList.get(0).getId() > 0) {
// update
record.setId(existsRecordList.get(0).getId());
return updateById(record);
}
return add(record);
}
public LklLedgerMerReceiverBind getByCondition(String merCupNo, String receiverNo) {
if (StrUtil.isBlank(merCupNo) || StrUtil.isBlank(receiverNo)) {
return null;
}
QueryWrapper<LklLedgerMerReceiverBind> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mer_cup_no", merCupNo)
.eq("receiver_no", receiverNo)
.eq("audit_status", CommonConstant.Enable);
return getOne(queryWrapper);
}
/**
* 更新审核结果
*
* @param applyId
* @param merInnerNo
* @param merCupNo
* @param receiverNo
* @param entrustFileName
* @param entrustFilePath
* @param auditStatus
* @param auditStatusText
* @param remark
* @return
*/
@Override
public Boolean updateAuditResult(String applyId, String merInnerNo, String merCupNo, String receiverNo, String entrustFileName, String entrustFilePath, String auditStatus, String auditStatusText, String remark) {
if (StrUtil.isBlank(applyId) || StrUtil.isBlank(merCupNo) || StrUtil.isBlank(receiverNo) || StrUtil.isBlank(auditStatus)) {
return false;
}
UpdateWrapper<LklLedgerMerReceiverBind> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("apply_id", applyId);
if (StrUtil.isNotBlank(merInnerNo)) {
updateWrapper.set("mer_inner_no", merInnerNo);
}
if (StrUtil.isNotBlank(merCupNo)) {
updateWrapper.set("mer_cup_no", merCupNo);
}
if (StrUtil.isNotBlank(receiverNo)) {
updateWrapper.set("receiver_no", receiverNo);
}
if (StrUtil.isNotBlank(entrustFileName)) {
updateWrapper.set("entrust_file_name", entrustFileName);
}
if (StrUtil.isNotBlank(entrustFilePath)) {
updateWrapper.set("entrust_file_path", entrustFilePath);
}
if (StrUtil.isNotBlank(auditStatus)) {
updateWrapper.set("audit_status", auditStatus);
}
if (StrUtil.isNotBlank(auditStatusText)) {
updateWrapper.set("audit_status_text", auditStatusText);
}
if (StrUtil.isNotBlank(remark)) {
updateWrapper.set("remark", remark);
}
return update(updateWrapper);
}
}

View File

@ -0,0 +1,314 @@
/*
* 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.lakala.service.impl;
import cn.hutool.core.collection.CollectionUtil;
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.QueryWrapper;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.api.ResultCode;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.modules.esign.EsignPlatformInfo;
import com.suisung.mall.common.modules.lakala.LklLedgerReceiver;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.esign.service.EsignPlatformInfoService;
import com.suisung.mall.shop.lakala.mapper.LklLedgerReceiverMapper;
import com.suisung.mall.shop.lakala.service.LakalaApiService;
import com.suisung.mall.shop.lakala.service.LklLedgerMemberService;
import com.suisung.mall.shop.lakala.service.LklLedgerReceiverService;
import com.suisung.mall.shop.store.service.ShopMchEntryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
public class LklLedgerReceiverServiceImpl extends BaseServiceImpl<LklLedgerReceiverMapper, LklLedgerReceiver> implements LklLedgerReceiverService {
@Resource
private EsignPlatformInfoService esignPlatformInfoService;
@Lazy
@Resource
private LakalaApiService lakalaApiService;
@Lazy
@Resource
private LklLedgerMemberService lklLedgerMemberService;
@Autowired
private ShopMchEntryService shopMchEntryService;
/**
* 根据接收方编号新增或更新记录
*
* @param record
* @return
*/
@Override
public Boolean saveOrUpdateByReceiverNo(LklLedgerReceiver record) {
if (record == null || (StrUtil.isBlank(record.getLicense_no()) && StrUtil.isBlank(record.getContact_mobile()))) {
return false;
}
QueryWrapper<LklLedgerReceiver> queryWrapper = new QueryWrapper<>();
if (StrUtil.isNotBlank(record.getLicense_no())) {
queryWrapper.eq("license_no", record.getLicense_no());
}
if (StrUtil.isNotBlank(record.getContact_mobile())) {
queryWrapper.eq("contact_mobile", record.getContact_mobile());
}
Long platformId = record.getPlatform_id();
if (ObjectUtil.isEmpty(platformId)) {
platformId = 0L;
}
queryWrapper.eq("platform_id", platformId).eq("status", CommonConstant.Enable);
List<LklLedgerReceiver> existsRecordList = list(queryWrapper);
if (CollectionUtil.isNotEmpty(existsRecordList)
&& existsRecordList.get(0) != null
&& existsRecordList.get(0).getId() > 0) {
// 更新记录
record.setId(existsRecordList.get(0).getId());
return updateById(record);
}
return add(record);
}
/**
* 根据接收方编号查询记录
*
* @param receiverNo
* @return
*/
@Override
public LklLedgerReceiver getByReceiverNo(String receiverNo) {
if (StrUtil.isBlank(receiverNo)) {
return null;
}
QueryWrapper<LklLedgerReceiver> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("receiver_no", receiverNo).eq("status", CommonConstant.Enable);
queryWrapper.orderByAsc("id");
return getOne(queryWrapper);
}
/**
* 通过平台方代理商 ID 查询记录
*
* @param platformId
* @return
*/
@Override
public LklLedgerReceiver getByPlatformId(Long platformId) {
if (ObjectUtil.isEmpty(platformId)) {
return null;
}
QueryWrapper<LklLedgerReceiver> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("platform_id", platformId).eq("status", CommonConstant.Enable).orderByAsc("id");
List<LklLedgerReceiver> lklLedgerReceivers = list(queryWrapper);
if (CollectionUtil.isEmpty(lklLedgerReceivers)) {
return null;
}
return lklLedgerReceivers.get(0);
}
/**
* 通过平台方代理商 ID 记录信息转成 Lakala 接收方记录
* 平台方一定要获取如果有代理商也要获取
*
* @param platformId
* @return
*/
@Override
public JSONArray buildApplyLedgerReceiverReqParams(Long platformId) {
List<Long> ids = new ArrayList<>();
if (platformId != null && platformId > 0) {
ids.add(platformId);
}
List<EsignPlatformInfo> esignPlatformInfoList = esignPlatformInfoService.getDistributorAndPlatformByIds(ids.toArray(new Long[0]));
if (CollectionUtil.isEmpty(esignPlatformInfoList)) {
return null;
}
JSONArray reqParams = new JSONArray();
for (EsignPlatformInfo esignPlatformInfo : esignPlatformInfoList) {
JSONObject reqParam = new JSONObject();
reqParam.put("receiverName", esignPlatformInfo.getLicense_company());
reqParam.put("contactMobile", esignPlatformInfo.getLegal_person_mobile());
reqParam.put("platformId", esignPlatformInfo.getId());
reqParam.put("licenseNo", esignPlatformInfo.getLicense_number());
reqParam.put("licenseName", esignPlatformInfo.getLicense_company());
reqParam.put("legalPersonName", esignPlatformInfo.getLegal_person_name());
reqParam.put("legalPersonCertificateType", "17");
reqParam.put("legalPersonCertificateNo", esignPlatformInfo.getLegal_person_id_card());
reqParam.put("acctNo", esignPlatformInfo.getRec_acc_card_no());
reqParam.put("acctName", esignPlatformInfo.getRec_acc_bank_name());
reqParam.put("acctTypeCode", "57");
reqParam.put("acctCertificateType", "17");
reqParam.put("acctCertificateNo", esignPlatformInfo.getLegal_person_id_card());
reqParam.put("acctOpenBankCode", esignPlatformInfo.getRec_acc_bank_no());
reqParam.put("acctOpenBankName", esignPlatformInfo.getRec_acc_bank_name());
reqParam.put("acctClearBankCode", esignPlatformInfo.getRec_acc_clear_bank_no());
//文件类型参考https://o.lakala.com/#/home/document/detail?id=90
JSONArray attachList = new JSONArray();
if (StrUtil.isNotBlank(esignPlatformInfo.getLicense_image())) {
JSONObject BUSINESS_LICENCE = new JSONObject();
BUSINESS_LICENCE.put("attachType", "BUSINESS_LICENCE").put("attachName", "营业执照")
.put("attachStoreFile", esignPlatformInfo.getLicense_image());
attachList.add(BUSINESS_LICENCE);
}
if (StrUtil.isNotBlank(esignPlatformInfo.getLegal_person_id_card_image1())) {
JSONObject FR_ID_CARD_FRONT = new JSONObject();
FR_ID_CARD_FRONT.put("attachType", "FR_ID_CARD_FRONT").put("attachName", "法人身份证正面")
.put("attachStoreFile", esignPlatformInfo.getLegal_person_id_card_image1());
attachList.add(FR_ID_CARD_FRONT);
}
if (StrUtil.isNotBlank(esignPlatformInfo.getLegal_person_id_card_image2())) {
JSONObject FR_ID_CARD_BEHIND = new JSONObject();
FR_ID_CARD_BEHIND.put("attachType", "FR_ID_CARD_BEHIND").put("attachName", "法人身份证反面")
.put("attachStoreFile", esignPlatformInfo.getLegal_person_id_card_image2());
attachList.add(FR_ID_CARD_BEHIND);
}
if (CollectionUtil.isNotEmpty(attachList)) {
reqParam.put("attachList", attachList);
}
reqParams.add(reqParam);
}
return reqParams;
}
/**
* 内部调用申请一个或多个分账接收方平台方和代理商
*
* @param platformId
* @return
*/
@Override
public Boolean innerApplyLedgerReceiver(String merCupNo, Long platformId) {
// 接收方至少有一个平台方
JSONArray buildApplyLedgerReceiverReqParams = buildApplyLedgerReceiverReqParams(platformId);
if (buildApplyLedgerReceiverReqParams == null || buildApplyLedgerReceiverReqParams.isEmpty()) {
log.error("获取不到平台或代理商信息");
return false;
}
int successCnt = 0;
for (JSONObject reqParam : buildApplyLedgerReceiverReqParams.jsonIter()) {
log.debug("申请分账接收方参数:{}", reqParam.toString());
CommonResult result = lakalaApiService.applyLedgerReceiver(reqParam);
if (result == null || result.getStatus() != ResultCode.SUCCESS.getStatus()) {
log.error("申请分账接收方失败:{}", result.getMsg());
continue;
}
successCnt += 1;
}
boolean success = successCnt > 0;
if (success) {
// 更新多个状态
shopMchEntryService.updateMulStatus("", merCupNo, 0, 0, 1, 0);
}
return success;
}
/**
* 是否存在平台方的相关记录信息
*
* @return
*/
@Override
public LklLedgerReceiver hasPlatformMch() {
QueryWrapper<LklLedgerReceiver> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("platform_id", 0).eq("status", CommonConstant.Enable).orderByAsc("id");
List<LklLedgerReceiver> lklLedgerReceivers = list(queryWrapper);
if (CollectionUtil.isEmpty(lklLedgerReceivers)) {
return null;
}
return lklLedgerReceivers.get(0);
}
/**
* 根据条件查询记录
*
* @param LicenseNo
* @param ContactMobile
* @param platformId
* @return
*/
@Override
public LklLedgerReceiver getByCondition(String LicenseNo, String ContactMobile, Long platformId) {
if (ObjectUtil.isEmpty(platformId)) {
platformId = 0L;
}
if (StrUtil.isBlank(LicenseNo) && StrUtil.isBlank(ContactMobile)) {
return null;
}
QueryWrapper<LklLedgerReceiver> queryWrapper = new QueryWrapper<>();
if (StrUtil.isNotBlank(LicenseNo)) {
queryWrapper.eq("license_no", LicenseNo);
}
if (StrUtil.isNotBlank(ContactMobile)) {
queryWrapper.eq("contact_mobile", ContactMobile);
}
queryWrapper.eq("platform_id", platformId)
.eq("status", CommonConstant.Enable);
return getOne(queryWrapper);
}
@Override
public List<LklLedgerReceiver> getByCondition(String LicenseNo, String ContactMobile) {
if (StrUtil.isBlank(LicenseNo) && StrUtil.isBlank(ContactMobile)) {
return null;
}
QueryWrapper<LklLedgerReceiver> queryWrapper = new QueryWrapper<>();
if (StrUtil.isNotBlank(LicenseNo)) {
queryWrapper.eq("license_no", LicenseNo);
}
if (StrUtil.isNotBlank(ContactMobile)) {
queryWrapper.eq("contact_mobile", ContactMobile);
}
queryWrapper.eq("status", CommonConstant.Enable);
return list(queryWrapper);
}
}

View File

@ -0,0 +1,838 @@
/*
* 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.lakala.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.api.ResultCode;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import com.suisung.mall.common.utils.RestTemplateHttpUtil;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.common.utils.UploadUtil;
import com.suisung.mall.core.web.service.RedisService;
import com.suisung.mall.shop.lakala.service.LklBanksService;
import com.suisung.mall.shop.lakala.service.LklLedgerReceiverService;
import com.suisung.mall.shop.lakala.utils.LakalaUtil;
import com.suisung.mall.shop.page.service.impl.OssServiceImpl;
import com.suisung.mall.shop.store.service.ShopMchEntryService;
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
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.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
@Service
public class LklTkServiceImpl {
private static final Logger logger = LoggerFactory.getLogger(LklTkServiceImpl.class);
@Value("${lakala.tk.server_url}")
private String tkServerUrl;
@Value("${lakala.tk.client_id}")
private String clientId;
@Value("${lakala.tk.client_secret}")
private String clientSecret;
@Value("${lakala.tk.user_no}")
private String userNo;
@Value("${lakala.tk.notify_pub_key_path}")
private String notifyPubKeyPath;
@Value("${spring.profiles.active}")
private String profile;
@Value("${lakala.is_prod}")
private Boolean isLklProd;
@Lazy
@Resource
private ShopMchEntryService shopMchEntryService;
@Lazy
@Resource
private LklLedgerReceiverService lklLedgerReceiverService;
// @Lazy
// @Resource
// private EsignContractService esignContractService;
//
// @Lazy
// @Resource
// private EsignContractFillingFileService esignContractFillingFileService;
@Lazy
@Resource
private ShopStoreBaseService shopStoreBaseService;
@Lazy
@Resource
private LakalaApiServiceImpl lakalaApiService;
@Lazy
@Resource
private LklBanksService lklBanksService;
@Lazy
@Resource
private OssServiceImpl ossService;
@Autowired
private RedisService redisService;
protected String buildLklTkUrl(String urlPath) {
return tkServerUrl + urlPath;
}
protected boolean isProdProject() {
// 生产环境的时候启动该配置
return "prod".equalsIgnoreCase(profile);
}
/**
* 上传文件图片到拉卡拉 OCR识别卡信息身份证信息营业执照信息
*
* @param file 图片URL地址
* @param imgType 法人身份证正面图FR_ID_CARD_FRONT
* 法人身份证反面FR_ID_CARD_BEHIND
* 身份证正面ID_CARD_FRONT
* 身份证反面ID_CARD_BEHIND
* 营业执照BUSINESS_LICENCE
* 银行卡BANK_CARD
* @return
*/
public CommonResult uploadOcrImg(MultipartFile file, String imgType) {
UserDto currentUser = getCurrentUser();
if (currentUser == null) {
currentUser = new UserDto();
}
if (file == null || StrUtil.isBlank(imgType)) {
return CommonResult.failed("上传文件或图片类型不能为空");
}
CommonResult ossImgInfo = ossService.uploadFile(file, currentUser);
if (ossImgInfo == null) {
return CommonResult.failed("上传文件失败");
}
if (ossImgInfo.getStatus() != ResultCode.SUCCESS.getStatus() || ossImgInfo.getData() == null) {
return CommonResult.failed(ossImgInfo.getMsg());
}
String imgURL = JSONUtil.parseObj(ossImgInfo.getData()).getStr("url");
String authorization = getLklTkAuthorization();
if (StrUtil.isBlank(authorization)) {
return CommonResult.failed("获取拉卡拉token失败");
}
JSONObject header = new JSONObject();
header.put("Authorization", authorization);
String fileBase64 = UploadUtil.multipartFileToBase64(file);
if (StrUtil.isBlank(fileBase64)) {
return CommonResult.failed("解析文件转换失败");
}
// 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");
String urlPath = "/sit/htkregistration/file/base/upload";
if (isLklProd) {
// 生产环境启用
urlPath = "/registration/file/base/upload";
}
try {
ResponseEntity<JSONObject> updResponse = RestTemplateHttpUtil.sendPostBodyBackEntity(buildLklTkUrl(urlPath), header, requestBody, JSONObject.class);
if (ObjectUtil.isEmpty(updResponse)
|| updResponse.getStatusCode() != HttpStatus.OK
|| ObjectUtil.isEmpty(updResponse.getBody())) {
return CommonResult.failed("上传文件返回值有误");
}
// {batchNo,status,url,showUrl,result{} }
JSONObject updObj = updResponse.getBody();
String batchNo = updObj.getStr("batchNo");
if (StrUtil.isBlank(batchNo)) {
return CommonResult.failed("上传文件返回值有误");
}
updObj.put("cosURL", imgURL);
return CommonResult.success(updObj);
} catch (Exception e) {
logger.error("上传文件失败: ", e.getMessage());
return CommonResult.failed("上传文件失败:" + e.getMessage());
}
}
/**
* 根据上传的图片的批次号获取 OCR 识别结果
*
* @param batchNo
* @param imgType * ID_CARD_FRONT 身份证正
* * ID_CARD_BEHIND 身份证反
* * BUSINESS_LICENCE 营业执照照
* * BANK_CARD 银行卡企业对公不需要传
* * AGREE_MENT 协议
* * OPENING_PERMIT 开户许可证企业对公需要传
* * CHECKSTAND_IMG 收银台照片(必传)
* * SHOP_OUTSIDE_IMG 上传门头照片(必传)
* * SHOP_INSIDE_IMG 商铺内部照片(必传)
* * OTHERS 其他 无对应类型图片请传其他类型
* * SETTLE_ID_CARD_FRONT 结算人身份证人像面
* * SETTLE_ID_CARD_BEHIND 结算人身份证国徽面
* * LETTER_OF_AUTHORIZATION 法人授权涵
* @return
*/
public CommonResult imgOcrResult(String batchNo, String imgType) {
if (StrUtil.isBlank(batchNo) || StrUtil.isBlank(imgType)) {
return CommonResult.failed("批次号或图片类型不能为空");
}
// 调用 OCR 识别接口
String authorization = getLklTkAuthorization();
if (StrUtil.isBlank(authorization)) {
return CommonResult.failed("获取拉卡拉token失败");
}
JSONObject header = new JSONObject();
header.put("Authorization", authorization);
JSONObject ocrRequestBody = new JSONObject();
ocrRequestBody.put("batchNo", batchNo);
ocrRequestBody.put("imgType", imgType);
logger.info("ocr请求参数{}", ocrRequestBody);
String urlPath = "/sit/htkregistration/ocr/result";
if (isLklProd) {
// 生产环境启用
urlPath = "/registration/ocr/result";
}
try {
ResponseEntity<JSONObject> ocrResponse = RestTemplateHttpUtil.sendPostBodyBackEntity(buildLklTkUrl(urlPath), header, ocrRequestBody, JSONObject.class);
if (ObjectUtil.isEmpty(ocrResponse)
|| ocrResponse.getStatusCode() != HttpStatus.OK
|| ObjectUtil.isEmpty(ocrResponse.getBody())) {
return CommonResult.failed("OCR响应数据有误");
}
JSONObject ocrObj = ocrResponse.getBody().get("result", JSONObject.class);
logger.info("ocr返回结果{}", ocrResponse);
if (ObjectUtil.isEmpty(ocrObj)) {
return CommonResult.failed("OCR返回结果有误");
}
return CommonResult.success(ocrObj);
} catch (Exception e) {
logger.error("OCR识别失败: ", e.getMessage());
return CommonResult.failed("OCR识别失败:" + e.getMessage());
}
}
/**
* 商户进件前请求获取token
*
* @return AuthorizationKey
*/
public String getLklTkAuthorization() {
String authorizationKey = "lkl_tk_authorization";
Object lklTkToken = redisService.get(authorizationKey);
if (ObjectUtil.isNotEmpty(lklTkToken)) {
return lklTkToken.toString();
}
Map<String, String> formData = new HashMap<>();
formData.put("grant_type", "client_credentials");
formData.put("client_id", clientId);
formData.put("client_secret", clientSecret);
String urlPath = "/sit/htkauth/oauth/token";
if (isLklProd) {
// 生产环境启用
urlPath = "/auth/oauth/token";
}
String response = RestTemplateHttpUtil.sendPostFormData(buildLklTkUrl(urlPath), null, formData, String.class);
if (ObjectUtil.isEmpty(response)) {
return "";
}
JSONObject jsonObj = JSONUtil.parseObj(response);
if (jsonObj == null || StrUtil.isBlank(jsonObj.getStr("access_token"))) {
return "";
}
String token = jsonObj.getStr("token_type") + " " + jsonObj.getStr("access_token");
redisService.set(authorizationKey, token, jsonObj.getLong("expires_in"));
return token;
}
/**
* (重要) 请求拉卡拉进件
* <p>
* 参考拉卡拉给的独立文档2拓客SAAS商户管理接口().docx
*
* @param mchMobile 商家手机号
* @return
*/
public Pair<Boolean, String> registrationMerchant(String mchMobile, String bizLicenseNumber) {
String authorization = getLklTkAuthorization();
if (StrUtil.isBlank(authorization)) {
return Pair.of(false, "获取拉卡拉token失败");
}
JSONObject header = new JSONObject();
header.put("Authorization", getLklTkAuthorization());
// 获取商家入驻信息组成请求参数
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByCondition(mchMobile, bizLicenseNumber);
if (ObjectUtil.isEmpty(shopMchEntry)) {
return Pair.of(false, "商家入驻信息不存在");
}
JSONObject formData = new JSONObject();
formData.put("userNo", userNo);
formData.put("busiCode", "WECHAT_PAY");// WECHAT_PAY:专业化扫码;B2B_SYT:B2B收银台;
formData.put("email", shopMchEntry.getEmail());
formData.put("merRegName", shopMchEntry.getStore_name());
formData.put("merName", shopMchEntry.getStore_name());
formData.put("merAddr", StringUtils.removeProvinceCityDistrict(shopMchEntry.getStore_address()));
// 是企业类型商家
Boolean isQy = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type());
formData.put("merType", isQy ? "TP_MERCHANT" : "TP_PERSONAL");
formData.put("longtude", shopMchEntry.getStore_longitude()); //longitude 经度
formData.put("latitude", shopMchEntry.getStore_latitude());
formData.put("source", "H5");
formData.put("larIdType", "01"); // 01 身份证 02 护照03 港澳通行证04 台胞证10 外国人永久居留身份证11 港妨澳居民居住证12 台湾居民居住证13 执行事务合伙人99 其它证件
String larName = isQy ? shopMchEntry.getLegal_person_name() : shopMchEntry.getContact_name();
String larIdCard = isQy ? shopMchEntry.getLegal_person_id_number() : shopMchEntry.getIndividual_id_number();
String larIdCardStart = isQy ? shopMchEntry.getLegal_person_id_period_begin() : shopMchEntry.getIndividual_id_period_begin();
String larIdCardEnd = isQy ? shopMchEntry.getLegal_person_id_period_end() : shopMchEntry.getIndividual_id_period_end();
// 法人相关信息
formData.put("larName", larName);
formData.put("larIdCard", larIdCard);
formData.put("larIdCardStart", larIdCardStart); // 身份证有效期开始时间
formData.put("larIdCardEnd", larIdCardEnd); // 身份证有效期结束时间长期9999-12-31
// 营业执照上的经营内容
formData.put("businessContent", shopMchEntry.getBiz_license_content());
// 营业执照信息
if (isQy) {
formData.put("licenseName", shopMchEntry.getBiz_license_company());
formData.put("licenseNo", shopMchEntry.getBiz_license_number());
formData.put("licenseDtStart", shopMchEntry.getBiz_license_period_begin());
formData.put("licenseDtEnd", shopMchEntry.getBiz_license_period_end()); // 长期9999-12-31
}
formData.put("contactMobile", mchMobile);
formData.put("contactName", shopMchEntry.getContact_name());// 联系人姓名
formData.put("contractNo", shopMchEntry.getLkl_ec_no()); // 拉卡拉入网合同编号
// 银行账号关键字段
formData.put("openningBankCode", shopMchEntry.getOpenning_bank_code());//结算账户开户
formData.put("openningBankName", shopMchEntry.getBank_name());//结算账户开户名称
formData.put("clearingBankCode", shopMchEntry.getClearing_bank_code());//结算账户清算
formData.put("accountType", isQy ? "57" : "58"); //结算账户类型: 57 对公 58 对私
formData.put("accountNo", shopMchEntry.getAccount_number()); //结算人银行卡号
formData.put("accountName", shopMchEntry.getAccount_holder_name()); //结算人账户名称
formData.put("accountIdCard", shopMchEntry.getLegal_person_id_number());//结算证件号码(身份证)
formData.put("settleType", "D1"); //结算类型D0秒到D1次日结算
// formData.put("settlementType", "AUTOMATIC"); // 结算方式MANUAL:手动结算(结算至拉卡拉APP钱包),AUTOMATIC:自动结算到银行卡,REGULAR:定时结算仅企业商户支持
// 店铺省市区信息
Map<String, String> areaCode = getAreaCode(shopMchEntry.getStore_area(), false);
if (ObjectUtil.isNotEmpty(areaCode)) {
formData.put("provinceCode", areaCode.get("provinceCode"));
formData.put("cityCode", areaCode.get("cityCode"));
formData.put("countyCode", areaCode.get("countyCode"));
}
//结算信息省市信息
if (StrUtil.isBlank(shopMchEntry.getBank_district()) || StrUtil.isBlank(shopMchEntry.getBank_area())) {
Map<String, Object> bankInfo = lklBanksService.GetLklBankByBranchBankNo(shopMchEntry.getOpenning_bank_code());
if (ObjectUtil.isNotEmpty(bankInfo)) {
shopMchEntry.setBank_district(bankInfo.get("district").toString());
shopMchEntry.setBank_area(bankInfo.get("area").toString());
}
}
if (StrUtil.isNotBlank(shopMchEntry.getBank_district()) && StrUtil.isNotBlank(shopMchEntry.getBank_area())) {
// 直接分解取值
String[] bankAreaCodes = shopMchEntry.getBank_district().split("/");
String[] bankAreaNames = shopMchEntry.getBank_area().split("/");
if (bankAreaCodes.length >= 2 && bankAreaNames.length >= 2) {
formData.put("settleProvinceCode", bankAreaCodes[0]);
formData.put("settleProvinceName", bankAreaCodes[1]);
formData.put("settleCityCode", bankAreaNames[0]);
formData.put("settleCityName", bankAreaNames[1]);
}
} else {
Map<String, String> bankAreaCode = getAreaCode(shopMchEntry.getBank_area(), true);
if (ObjectUtil.isNotEmpty(bankAreaCode)) {
formData.put("settleProvinceCode", bankAreaCode.get("provinceCode"));
formData.put("settleCityCode", bankAreaCode.get("cityCode"));
String[] bankAreaName = shopMchEntry.getBank_area().split("/");
if (bankAreaName.length >= 2) {
formData.put("settleProvinceName", bankAreaName[0]);
formData.put("settleCityName", bankAreaName[1]);
}
}
}
// 费率和设备活动
JSONObject bizContent = new JSONObject();
bizContent.put("activityId", 687);
bizContent.put("termNum", "1");
bizContent.put("mcc", "12015"); // 超市的 code
bizContent.put("fees", new JSONArray() {{
put(new JSONObject() {
{
put("feeCode", "WECHAT");
put("feeValue", 0.6);
}
});
}});
formData.put("bizContent", bizContent);
// 附件文件相关开始
JSONArray attachments = new JSONArray();
if (isQy) {
JSONObject SETTLE_ID_CARD_FRONT = updatePhoto(shopMchEntry.getLegal_person_id_images(), "FR_ID_CARD_FRONT", false);
if (SETTLE_ID_CARD_FRONT != null) {
attachments.put(SETTLE_ID_CARD_FRONT); // 法人身份证正面
}
JSONObject SETTLE_ID_CARD_BEHIND = updatePhoto(shopMchEntry.getLegal_person_id_images2(), "FR_ID_CARD_BEHIND", false);
if (SETTLE_ID_CARD_BEHIND != null) {
attachments.put(SETTLE_ID_CARD_BEHIND); // 法人身份证国徽面
}
JSONObject BUSINESS_LICENCE = updatePhoto(shopMchEntry.getBiz_license_image(), "BUSINESS_LICENCE", false);
if (BUSINESS_LICENCE != null) {
attachments.put(BUSINESS_LICENCE); // 营业执照
}
} else {
JSONObject ID_CARD_FRONT = updatePhoto(shopMchEntry.getIndividual_id_images(), "ID_CARD_FRONT", false);
if (ID_CARD_FRONT != null) {
attachments.put(ID_CARD_FRONT); // 身份证正面
}
JSONObject ID_CARD_BEHIND = updatePhoto(shopMchEntry.getIndividual_id_images2(), "ID_CARD_BEHIND", false);
if (ID_CARD_BEHIND != null) {
attachments.put(ID_CARD_BEHIND); // 身份证国徽面
}
}
JSONObject SHOP_OUTSIDE_IMG = updatePhoto(shopMchEntry.getFront_facade_image(), "SHOP_OUTSIDE_IMG", false);
if (SHOP_OUTSIDE_IMG != null) {
attachments.put(SHOP_OUTSIDE_IMG); // 门店门面图片
}
JSONObject SHOP_INSIDE_IMG = updatePhoto(shopMchEntry.getEnvironment_image(), "SHOP_INSIDE_IMG", false);
if (SHOP_INSIDE_IMG != null) {
attachments.put(SHOP_INSIDE_IMG); // 门店内部图片
}
JSONObject BANK_CARD = updatePhoto(shopMchEntry.getBank_image(), "BANK_CARD", false);
if (BANK_CARD != null) {
attachments.put(BANK_CARD); // 银行卡图片
}
formData.put("attchments", attachments);
// 附件文件相关结束
String urlPath = "/sit/htkregistration/merchant";
if (isLklProd) {
// 生产环境启用
urlPath = "/registration/merchant";
}
// String urlPath = isProd() ? "/registration/merchant" : "/sit/htkregistration/merchant";
try {
logger.info("进件请求参数:{}", JSONUtil.toJsonStr(formData));
ResponseEntity<JSONObject> response = RestTemplateHttpUtil.sendPostBodyBackEntity(buildLklTkUrl(urlPath), header, formData, JSONObject.class);
if (ObjectUtil.isEmpty(response)) {
return Pair.of(false, "请求进件服务无返回值");
}
JSONObject respBody = response.getBody();
if (response.getStatusCode() != HttpStatus.OK && ObjectUtil.isNotEmpty(respBody)) {
String errMsg = respBody.getStr("message") == null ? "返回状态有误" : respBody.getStr("message");
return Pair.of(false, "进件失败:" + errMsg);
}
// 更改入驻记录的拉卡拉内部商户号和进件请求参数
String lklMerInnerNo = respBody.getStr("merchantNo"); //拉卡拉内部商户号
// 表中的内部外部商户号暂时都传同一个内部商户号以便异步通知更改记录
Boolean success = shopMchEntryService.updateMerchEntryLklMerCupNo(mchMobile, CommonConstant.Disable2, lklMerInnerNo, lklMerInnerNo, formData.toString(), respBody.toString());
if (!success) {
return Pair.of(false, "请求进件成功,但更新商户号失败!");
}
} catch (Exception e) {
logger.error("拉卡拉进件异常:{}", e.getMessage());
return Pair.of(false, "进件失败:" + e.getMessage());
}
return Pair.of(true, "提交进件成功,请等待审核!");
}
/**
* 重要拉卡拉进件异步通知
*
* @param request
* @return
*/
@Transactional
public JSONObject registrationMerchantNotify(HttpServletRequest request) {
logger.debug("拉卡拉进件异步通知开始");
// 解密请求参数
String requestBody = LakalaUtil.getBody(request);
logger.debug("拉卡拉进件异步通知返回参数:{}", requestBody);
if (StrUtil.isBlank(requestBody)) {
return new JSONObject().set("code", "400").set("message", "返回参数为空");
}
JSONObject reqBodyJSON = JSONUtil.parseObj(requestBody);
if (reqBodyJSON.isEmpty() || reqBodyJSON.get("data") == null) {
return new JSONObject().set("code", "400").set("message", "参数格式有误,无法解析");
}
String srcData = reqBodyJSON.getStr("data");
if (StrUtil.isBlank(srcData)) {
return new JSONObject().set("code", "400").set("message", "关键参数为空值");
}
// 公钥解密出来的数据
String notifyPubKey = LakalaUtil.getResourceFile(notifyPubKeyPath, false, false);
String data = LakalaUtil.decryptNotifyData(notifyPubKey, srcData);
if (StrUtil.isBlank(data)) {
return new JSONObject().set("code", "400").set("message", "密文解密出错!");
}
logger.debug("拉卡拉进件异步通知data解密成功开始处理逻辑");
// 逻辑处理
JSONObject dataJSON = JSONUtil.parseObj(data);
if (dataJSON.isEmpty() || StrUtil.isBlank(dataJSON.getStr("externalCustomerNo")) || StrUtil.isBlank(dataJSON.getStr("status"))) {
return new JSONObject().set("code", "500").set("message", "参数解析出错");
}
String auditStatus = dataJSON.getStr("status");
if (!"SUCCESS".equals(auditStatus) && !"REVIEW_PASS".equals(auditStatus)) {
return new JSONObject().set("code", "FAIL").set("message", "返回审核状态有误");
}
// RMK 拉卡拉进价提交成功,边处理周边的数据边等待审核异步通知
// 给商家入驻表增加拉卡拉的商户号和拉卡拉返回的数据
String merCupNo = dataJSON.getStr("externalCustomerNo"); //拉卡拉外部商户号
String merInnerNo = dataJSON.getStr("customerNo"); //拉卡拉内部商户号
String termNos = dataJSON.getStr("termNos"); //拉卡拉分配的业务终端号
if (StrUtil.isBlank(merInnerNo) || StrUtil.isBlank(merCupNo)) {
return new JSONObject().set("code", "500").set("message", "返回数据有误");
}
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerInnerNo(merInnerNo);
if (ObjectUtil.isEmpty(shopMchEntry)) {
logger.error("拉卡拉进件异步通知:返回的内部商户号:{} 入驻信息不存在!", merInnerNo);
return new JSONObject().put("code", "500").put("message", "内部商户号:" + merInnerNo + " 入驻信息不存在");
}
Boolean success = shopMchEntryService.updateMerchEntryLklAuditStatusByLklMerCupNo(merInnerNo, merCupNo, termNos, CommonConstant.Enable, null, data);
if (!success) {
return new JSONObject().set("code", "500").set("message", "更新商户号失败");
// throw new ApiException("更新商户号失败");
}
// 备注RMK 采用拉卡拉的入网电子合同签署流程暂停e签宝的电子合同生成流程
// logger.debug("###开始异步执行生成电子合同模版和填充模版数据,并生该商家和平台方签署的未盖章合同文件###");
// // 生成电子合同模版和填充模版数据并生该商家和平台方签署的未盖章合同文件
// Boolean genSuccess = esignContractFillingFileService.fillDocTemplate(shopMchEntry.getLogin_mobile(), "");
// if (!genSuccess) {
// logger.error("###商家入驻电子合同生成失败###");
// }
//
// // 1发起E签宝合同签署签署完成之后生成分账盖章协议书下一步才能申请分账功能权限
// Pair<Boolean, String> resPair = esignContractService.innerSignFlowCreateByFile(shopMchEntry.getLogin_mobile());
// if (!resPair.getFirst()) {
// logger.error("###商家发起电子签名失败:{}###", resPair.getSecond());
// }
// 给商家申请分账功能使用务必检查是否申请过申请过忽略
if (success && StrUtil.isNotBlank(shopMchEntry.getContract_download_url())) {
// TODO 新建一个正式的已审核通过的店铺 新建之前判断是否已经新建过了
// 新建一个正式的已审核通过的店铺
// ShopMchEntry shopEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(merCupNo);
// if (shopEntry != null && !CommonConstant.Enable.equals(shopEntry.getStore_status())) {
// String mchMobile = shopEntry.getLogin_mobile();
// Pair<Integer, String> retPair = shopStoreBaseService.merchEntryInfo2StoreInfo(mchMobile);
// if (retPair.getFirst() > 0) {
// // 2025-05-17暂停e签宝电子合同生成流程
// // 更改合同记录表的店铺id
// // esignContractService.updateContractStoreId(mchMobile, retPair.getFirst());
// // 填充合同模版表的店铺Id
// // esignContractFillingFileService.updateContractFillingStoreId(mchMobile, retPair.getFirst());
// // 店铺创建状态已完成
// shopMchEntryService.updateMerchEntryStoreStatus(mchMobile, CommonConstant.Enable);
// } else {
// throw new ApiException("商家进件:初始化店铺失败!");
// }
// }
// 1电子合同给商家申请分账功能使用务必检查是否申请过申请过忽略
// 下一步等待拉卡拉审核通过再绑定接收方和商家的关系
Pair<Boolean, String> retPair = lakalaApiService.innerApplyLedgerMer(merCupNo);
// 2新增一个接收方记录起码要一个平台方代理商根据入驻信息新增
Boolean genSuccess = lklLedgerReceiverService.innerApplyLedgerReceiver(merCupNo, shopMchEntry.getDistributor_id());
if (retPair.getFirst() && genSuccess) {
return new JSONObject().put("code", "200").put("message", "处理成功");
}
if (!retPair.getFirst()) {
String message = "商家申请分账功能失败:" + retPair.getSecond();
logger.error(message);
return new JSONObject().set("code", "500").set("message", message);
}
if (!genSuccess) {
logger.error("申请分账接收方失败");
return new JSONObject().set("code", "500").set("message", "申请分账接收方失败");
}
}
return new JSONObject().set("code", "500").set("message", "进件回调处理失败");
}
/**
* 获取拉卡拉店铺的(或银行的)省市区编码
*
* @param areaName 省份/城市/乡县
* @return
*/
public Map<String, String> getAreaCode(String areaName, Boolean isBankArea) {
Map retMap = new HashMap<String, String>() {{
put("provinceCode", "");
put("cityCode", "");
put("countyCode", "");
}};
String[] areaNames = areaName.split("/");
if (StrUtil.isBlank(areaName) || areaNames.length < 2) {
return retMap;
}
String provinceName = areaNames[0];
// 因为5个自治区需要简称所以去掉 壮族回族维吾尔族
provinceName = StrUtil.replace(provinceName, "壮族", "")
.replace("回族", "")
.replace("维吾尔族", "").replace("自治区", "");
String cityName = areaNames[1];
String countryName = "";
if (areaNames.length >= 3) {
countryName = areaNames[2];
}
String authorization = getLklTkAuthorization();
if (StrUtil.isBlank(authorization)) {
logger.error("获取拉卡拉token失败");
return retMap;
}
JSONObject header = new JSONObject();
header.put("Authorization", getLklTkAuthorization());
String urlPath = "/sit/htkregistration/organization";
if (isLklProd) {
// 生产环境启用
urlPath = "/registration/organization";
}
urlPath = isBankArea ? urlPath + "/bank" : urlPath; // 银行地区
// 省份列表
ResponseEntity<JSONArray> response = RestTemplateHttpUtil.sendGetWithHeader(buildLklTkUrl(urlPath + "/1"), header, JSONArray.class);
if (ObjectUtil.isNotEmpty(response) && response.getStatusCode() == HttpStatus.OK) {
String provinceCode = "";
String cityCode = "";
String countyCode = "";
JSONArray jsonArray = response.getBody();
if (CollUtil.isNotEmpty(jsonArray)) {
// logger.info("省份列表:{}", jsonArray.toString());
// 省份列表
for (JSONObject jsonObject : jsonArray.jsonIter()) {
if (StrUtil.contains(jsonObject.getStr("name"), provinceName)) {
provinceCode = jsonObject.getStr("code");
retMap.put("provinceCode", provinceCode);
break;
}
}
// 城市列表
if (StrUtil.isNotBlank(provinceCode)) {
response = RestTemplateHttpUtil.sendGetWithHeader(buildLklTkUrl(urlPath + "/" + provinceCode), header, JSONArray.class);
jsonArray = response.getBody();
if (CollUtil.isNotEmpty(jsonArray)) {
// logger.info("城市列表:{}", jsonArray.toString());
for (JSONObject jsonObject : jsonArray.jsonIter()) {
if (StrUtil.contains(jsonObject.getStr("name"), cityName)) {
cityCode = jsonObject.getStr("code");
retMap.put("cityCode", cityCode);
break;
}
}
}
}
// 乡县列表
if (StrUtil.isNotBlank(cityCode)) {
response = RestTemplateHttpUtil.sendGetWithHeader(buildLklTkUrl(urlPath + "/" + cityCode), header, JSONArray.class);
jsonArray = response.getBody();
if (CollUtil.isNotEmpty(jsonArray)) {
// logger.info("区列表:{}", jsonArray.toString());
for (JSONObject jsonObject : jsonArray.jsonIter()) {
if (StrUtil.contains(jsonObject.getStr("name"), countryName)) {
countyCode = jsonObject.getStr("code");
retMap.put("countyCode", countyCode);
break;
}
}
}
}
}
}
return retMap;
}
/**
* 上传进件相关图片和类型返回图片ID和类型
*
* @param fileUrl
* @param imgType ID_CARD_FRONT 身份证正
* ID_CARD_BEHIND 身份证反
* FR_ID_CARD_FRONT 身份证正
* FR_ID_CARD_BEHIND 身份证反
* BUSINESS_LICENCE 营业执照照
* BANK_CARD 银行卡企业对公不需要传
* AGREE_MENT 协议
* OPENING_PERMIT 开户许可证企业对公需要传
* CHECKSTAND_IMG 收银台照片(必传)
* SHOP_OUTSIDE_IMG 上传门头照片(必传)
* SHOP_INSIDE_IMG 商铺内部照片(必传)
* OTHERS 其他 无对应类型图片请传其他类型
* SETTLE_ID_CARD_FRONT 结算人身份证人像面
* SETTLE_ID_CARD_BEHIND 结算人身份证国徽面
* LETTER_OF_AUTHORIZATION 法人授权涵
* @param isOcr
* @return
*/
public JSONObject updatePhoto(String fileUrl, String imgType, Boolean isOcr) {
if (StrUtil.isBlank(fileUrl) || StrUtil.isBlank(imgType)) {
return null;
}
JSONObject header = new JSONObject();
header.put("Authorization", getLklTkAuthorization());
String fileBase64 = UploadUtil.fileUrlToBase64(fileUrl);
if (StrUtil.isBlank(fileBase64)) {
logger.error("文件转换失败");
return null;
}
// 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");
String urlPath = "/sit/htkregistration/file/base/upload";
if (isLklProd) {
// 生产环境启用
urlPath = "/registration/file/base/upload";
}
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", imgType);
} catch (Exception e) {
logger.error("上传文件异常:{}", e.getMessage());
return null;
}
}
}

View File

@ -0,0 +1,406 @@
/*
* 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.lakala.utils;
import cn.hutool.core.util.StrUtil;
import com.lkl.laop.sdk.Config2;
import com.lkl.laop.sdk.LKLSDK;
import com.suisung.mall.common.exception.ApiException;
import com.suisung.mall.common.utils.I18nUtil;
import com.suisung.mall.common.utils.RSAUtil;
import com.suisung.mall.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.core.io.ClassPathResource;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class LakalaUtil {
/**
* 初始化 拉卡拉 SDK全局只需设置一次
*
* @return
*/
public static boolean initLKLSDK(String appId, String serialNo, String priKeyPath, String lklCerPath, String lklNotifyCerPath, String serverUrl) {
Config2 config = new Config2();
config.setAppId(appId);
config.setSerialNo(serialNo);
config.setPriKey(getResourceFile(priKeyPath));
config.setLklCer(getResourceFile(lklCerPath));
config.setLklNotifyCer(getResourceFile(lklNotifyCerPath));
config.setServerUrl(serverUrl);
return LKLSDK.init(config);
}
/**
* 读取证书文件内容
* 末尾会有换行符
*
* @param fileName recource 文件夹下的路径palyKey/wx/lakala_public_key.cer
* @return
*/
public static String getResourceFile(String fileName) {
return getResourceFile(fileName, true, false);
}
/**
* 获取配置文件内容
*
* @param fileName recource 文件夹下的路径palyKey/wx/lakala_public_key.cer
* @param keepLineBreaks 保留换行符
* @return
*/
public static String getResourceFile(String fileName, boolean keepLineBreaks, boolean stripPemHeaders) {
StringBuilder stringBuilder = new StringBuilder();
try (InputStream inputStream = new ClassPathResource(fileName).getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
String line;
String endSeq = keepLineBreaks ? "\n" : "";
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append(endSeq);
}
if (stripPemHeaders) {
return stripPemHeaders(stringBuilder.toString());
}
return stringBuilder.toString();
} catch (IOException e) {
// 记录异常信息
log.error(e.getMessage());
return "";
}
}
/**
* 拉卡拉使用私钥加密数据
*/
public static String encryptNotifyData(String priKey, String data) {
ByteArrayOutputStream out = null;
try {
log.debug("拉卡拉tk加密私钥{}", priKey);
log.debug("拉卡拉tk待加密data数据{}", data);
// 解码私钥
byte[] keyBytes = java.util.Base64.getDecoder().decode(priKey);
// 生成私钥对象
PrivateKey privateKey = KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
// 初始化加密器
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
// 分段加密
byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
out = new ByteArrayOutputStream();
for (int offset = 0; offset < dataBytes.length; offset += 117) {
int blockSize = Math.min(117, dataBytes.length - offset);
byte[] encryptedBlock = cipher.doFinal(dataBytes, offset, blockSize);
out.write(encryptedBlock);
}
// 编码为Base64字符串
String encryptDataStr = java.util.Base64.getEncoder().encodeToString(out.toByteArray());
log.debug("拉卡拉tk数据加密结果{}", encryptDataStr);
return encryptDataStr;
} catch (Exception e) {
throw new RuntimeException("私钥加密失败", e);
} finally {
closeQuietly(out);
}
}
/**
* 安全关闭流
*/
private static void closeQuietly(ByteArrayOutputStream out) {
if (out != null) {
try {
out.close();
} catch (Exception e) {
// 忽略异常
}
}
}
public static String stripPemHeaders(String key) {
if (key == null || key.isEmpty()) {
return key;
}
// 定义正则表达式匹配标签行任意数量连字符和空白字符
// 1. 包含BEGIN或END的标签行无论连字符数量
// 2. 单独的连字符不在标签行中的
// 3. 空白字符(空格制表符换行等)
Pattern pattern = Pattern.compile(
"-*BEGIN[^-]*-*|-*END[^-]*-*|-|\\s");
// 执行替换
Matcher matcher = pattern.matcher(key);
return matcher.replaceAll("");
}
/**
* 获取 body 请求数据
*
* @param request
* @return
*/
public static String getBody(HttpServletRequest request) {
InputStreamReader in = null;
try {
in = new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8);
StringBuffer bf = new StringBuffer();
int len;
char[] chs = new char[1024];
while ((len = in.read(chs)) != -1) {
bf.append(new String(chs, 0, len));
}
return bf.toString();
} catch (Exception e) {
log.error("请求头部取数据异常:{}", e);
throw new ApiException(I18nUtil._("获取请求数据失败!"), e);
} finally {
if (null != in) {
try {
in.close();
} catch (Exception e) {
log.error("流关闭异常:{}", e);
}
}
}
}
/**
* 获取证书信息
*
* @param inputStream
* @return
*/
public static X509Certificate loadCertificate(InputStream inputStream) {
try {
CertificateFactory cf = CertificateFactory.getInstance("X509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream);
// String publicKeyBase64 = Base64.encodeBase64String(cert.getPublicKey().getEncoded());
// System.out.println(publicKeyBase64);
cert.checkValidity();
return cert;
} catch (CertificateExpiredException e) {
throw new RuntimeException("证书已过期", e);
} catch (CertificateNotYetValidException e) {
throw new RuntimeException("证书尚未生效", e);
} catch (CertificateException e) {
throw new RuntimeException("无效的证书", e);
}
}
/**
* 签名验证
*
* @param certificate
* @param message
* @param signature
* @return
*/
public static boolean verify(X509Certificate certificate, byte[] message, String signature) {
try {
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initVerify(certificate);
sign.update(message);
byte[] signatureB = Base64.decodeBase64(signature);
return sign.verify(signatureB);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("当前Java环境不支持SHA256withRSA", e);
} catch (SignatureException e) {
throw new RuntimeException("签名验证过程发生了错误", e);
} catch (InvalidKeyException e) {
throw new RuntimeException("无效的证书", e);
}
}
/**
* 签名校验
*
* @param authorization
* @param reqBody
* @param lklNotifyCerPath
* @return
*/
public static boolean verify(String authorization, String reqBody, String lklNotifyCerPath) {
try {
log.debug("拉卡拉 Authorization 内容:{}", authorization);
Map<String, String> headerMap = getLakalaAuthorizationMap(authorization);
String timestamp = headerMap.get("timestamp");
String nonceStr = headerMap.get("nonce_str");
String signature = headerMap.get("signature");
X509Certificate lklNotifyCer = loadCertificate(new ClassPathResource(lklNotifyCerPath).getInputStream());
if (StrUtil.isBlank(timestamp) || StrUtil.isBlank(nonceStr) || StrUtil.isBlank(signature) || lklNotifyCer == null) {
return false;
}
String preSignDataStr = timestamp + "\n" +
nonceStr + "\n" +
reqBody + "\n";
log.debug("拉卡拉签名明文内容:{}", preSignDataStr);
if (verify(lklNotifyCer, preSignDataStr.getBytes(StandardCharsets.UTF_8), signature)) {
log.debug("验签成功");
return true;
}
log.debug("验签失败");
return false;
} catch (Exception e) {
log.error("验签发生异常:{}", e);
return false;
}
}
/**
* 解析请求头中的认证签名等信息
* 参考https://o.lakala.com/#/home/document/detail?id=36
*
* @param authorization 格式如下
* LKLAPI-SHA256withRSA timestamp="1643271327",
* nonce_str="rQCbASKattHx",
* signature="
* iPSycbakMt7AgjmwbtaweDVI/RLsQnGvOGiVM93haFkPpT/BxUprYx/GKFLQZebSQMvBfbeWinmnOJlqd3bXgye41BUAVmbItSTOzaQhNyS2kbDwXXGJWmT84aeJWHUB05BWB8ng
* /+X7jrPtsenC6aO7Xgh8jNylJlkU59TKCi7BPGbyHo6pAWJl/Bus0IQps1ay+Eo6Ks3Ins3COV7
* /lmu5p5FD7TAZsfP+ZvMFObLJOrDQeBTMFKFFWj4ZkjNzNlQqZWlfLv4yLns
* /dKTDLDy5tRO5zwunW+li5YLcwOVf3tbevNFtg53WoBhQnwf838WNvY9zfRhOpCc4fBlWAA=="
* @return
*/
public static Map<String, String> getLakalaAuthorizationMap(String authorization) {
Map<String, String> map = new HashMap();
authorization = authorization.trim();
int bpos = authorization.indexOf(" ");
String authType = authorization.substring(0, bpos);
String[] typeArr = authType.split("-");
if (typeArr.length > 1) {
map.put("signSystemCode", typeArr[0]);
map.put("signAlgorithm", typeArr[1]);
}
String signInfo = authorization.substring(bpos + 1);
String[] infoArr = signInfo.split(",");
String[] var7 = infoArr;
int var8 = infoArr.length;
for (int var9 = 0; var9 < var8; ++var9) {
String info = var7[var9];
if (info.contains("=")) {
int fpos = info.indexOf("=");
String value = info.substring(fpos + 1).trim();
value = value.substring(1, value.length() - 1);
map.put(info.substring(0, fpos).trim(), value);
}
}
return map;
}
/**
* 拼接拉卡拉header中的Authorization字段
* 参考文档https://o.lakala.com/#/home/document/detail?id=33
*
* @param privateKey
* @param appId
* @param serialNo
* @param reqBody
* @return
*/
public static String genAuthorization(String privateKey, String appId, String serialNo, String reqBody) {
if (StrUtil.isBlank(privateKey) || StrUtil.isBlank(appId) || StrUtil.isBlank(serialNo) || StrUtil.isBlank(reqBody)) {
log.error("生产拉卡拉签名时缺少参数");
return "";
}
//待签字符串格式${appid}\n+${serialNo}\n+${timeStamp}\n+${nonceStr}\n+${body}\n
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
String nonceStr = StringUtils.genRandomNumber(12);
String builder = appId + "\n" +
serialNo + "\n" +
timestamp + "\n" +
nonceStr + "\n" +
reqBody + "\n";
String signature = RSAUtil.signSHA256withRSA(builder, privateKey);
return String.format("LKLAPI-SHA256withRSA appid=\"%s\",serial_no=\"%s\",timestamp=\"%s\",nonce_str=\"%s\",signature=\"%s\"",
appId, serialNo, timestamp, nonceStr, signature);
}
/**
* 拉卡拉异步通知数据公钥解密
*
* @param pubKey Base64公钥
* @param data Base64数据
* @return 解密字符串
*/
public static String decryptNotifyData(String pubKey, String data) {
ByteArrayOutputStream out = null;
try {
log.debug("拉卡拉tk解密公钥{}", pubKey);
log.debug("拉卡拉tk待解密data数据{}", data);
java.util.Base64.Decoder decoder = java.util.Base64.getDecoder();
byte[] keyBytes = decoder.decode(pubKey.getBytes(StandardCharsets.UTF_8));
byte[] dataBytes = decoder.decode(data.getBytes(StandardCharsets.UTF_8));
Cipher cipher = Cipher.getInstance("RSA");
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyBytes));
cipher.init(Cipher.DECRYPT_MODE, publicKey);
out = new ByteArrayOutputStream();
byte[] cache;
for (int i = 0, offset = 0, length = dataBytes.length; length - offset > 0; i++, offset = i * 128) {
if (length - offset > 128) {
cache = cipher.doFinal(dataBytes, offset, 128);
} else {
cache = cipher.doFinal(dataBytes, offset, length - offset);
}
out.write(cache, 0, cache.length);
}
String decodedDataStr = out.toString("UTF-8");
log.debug("拉卡拉tk数据解密结果{}", decodedDataStr);
return decodedDataStr;
} catch (IllegalArgumentException e) {
log.error("Base64解码失败: {}", e.getMessage(), e);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
log.error("RSA算法初始化失败: {}", e.getMessage(), e);
} catch (InvalidKeySpecException | InvalidKeyException e) {
log.error("私钥格式或类型错误: {}", e.getMessage(), e);
} catch (BadPaddingException | IllegalBlockSizeException e) {
log.error("解密数据块大小或填充错误: {}", e.getMessage(), e);
} catch (Exception e) {
log.error("解密过程中出现未知异常: {}", e.getMessage(), e);
} finally {
closeQuietly(out);
}
return null;
}
}

View File

@ -307,7 +307,7 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
smsDto.setContent(message_row.getMessage_sms());
smsDto.setParamMap(args); //传入模板对应参数
smsDto.setTengxunTemplateId(NumberUtil.parseInt(message_row.getMessage_tpl_id(), 0));
smsDto.setTengxunTemplateId(NumberUtil.parseInt(message_row.getMessage_tpl_id()));
try {
ThirdUtil.send(smsDto);

View File

@ -24,6 +24,7 @@ import com.suisung.mall.shop.page.service.ShopPageBaseService;
import com.suisung.mall.shop.product.service.ShopPageUserFormService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -44,6 +45,7 @@ import java.util.Map;
* @author Xinze
* @since 2021-06-11
*/
@Slf4j
@Api(tags = "后台页面管理")
@RestController
@RequestMapping("/admin/shop/shop-page-base")
@ -230,6 +232,8 @@ public class ShopPageBaseController extends BaseControllerImpl {
throw new ApiUserException(I18nUtil._("用户信息异常!"));
}
log.info("ShopPageBaseController 用户信息:{}", JSONUtil.toJsonStr(user));
ModelAndView view = new ModelAndView("diy");
Integer subsite_id = user.getSite_id();
@ -244,6 +248,7 @@ public class ShopPageBaseController extends BaseControllerImpl {
//Integer tpl_id = getParameter("tpl_id", 1012);
Integer app_type = 3;
log.info("ShopPageBaseController 模版修改参数:{},{},{},{}", subsite_id, store_id, tpl_id, app_type);
shopPageAppService.getModel(view, subsite_id, store_id, tpl_id, app_type);
Map<String, Object> res = new HashMap<>();

View File

@ -553,8 +553,9 @@ public class OssServiceImpl implements OssService {
* @return
*/
private String getUserDirName(UserDto user) {
if (user.getId() == null) {
if (user == null || user.getId() == null) {
//throw new ApiException(I18nUtil._("获取用户信息失败!"));
logger.error("cos 文件上传,获取用户信息失败!");
return "media/plantform/default/";
}

View File

@ -11,7 +11,7 @@ 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.service.impl.BaseControllerImpl;
import com.suisung.mall.shop.store.service.ShopMerchEntryService;
import com.suisung.mall.shop.store.service.ShopMchEntryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestBody;
@ -24,10 +24,10 @@ import javax.annotation.Resource;
@Api(tags = "店铺基础信息表")
@RestController
@RequestMapping("/admin/shop/merch")
public class ShopMerchEntryAdminController extends BaseControllerImpl {
public class ShopMchEntryAdminController extends BaseControllerImpl {
@Resource
private ShopMerchEntryService shopMerchEntryService;
private ShopMchEntryService shopMchEntryService;
/**
* 商家申请入驻商城平台
@ -38,20 +38,20 @@ public class ShopMerchEntryAdminController extends BaseControllerImpl {
@ApiOperation(value = "后台-商家申请入驻分页列表", notes = "商家申请入驻分页列表")
@RequestMapping(value = "/list", method = RequestMethod.POST)
public CommonResult shopMerchEntryList(@RequestBody JSONObject shopMerchEntryJSON) {
return shopMerchEntryService.shopMerchEntryList(shopMerchEntryJSON.getStr("keyword"), shopMerchEntryJSON.getInt("page"), shopMerchEntryJSON.getInt("pageSize"));
return shopMchEntryService.shopMerchEntryList(shopMerchEntryJSON.getStr("keyword"), shopMerchEntryJSON.getInt("page"), shopMerchEntryJSON.getInt("pageSize"));
}
@ApiOperation(value = "后台-获取商家入驻资料详情", notes = "后台-获取商家入驻资料详情")
@RequestMapping(value = "/detail", method = RequestMethod.POST)
public CommonResult shopMerchEntryDetail(@RequestBody JSONObject jsonParam) {
return shopMerchEntryService.shopMerchEntryDetail(jsonParam.getLong("id"), "", null);
return shopMchEntryService.shopMerchEntryDetail(jsonParam.getLong("id"), "", null);
}
@ApiOperation(value = "商家入驻审批", notes = "商家入驻审批")
@RequestMapping(value = "/approval", method = RequestMethod.POST)
public CommonResult shopMerchEntryApproval(@RequestBody JSONObject jsonParam) {
// approvalStatus 入驻商家的审批状态1-已通过2-未通过3-待审核
return shopMerchEntryService.shopMerchEntryApproval(jsonParam.getLong("id"), jsonParam.getInt("approvalStatus"), jsonParam.getStr("approvalRemark"), jsonParam.getStr("approvalInvalidCol"));
return shopMchEntryService.shopMerchEntryApproval(jsonParam.getLong("id"), jsonParam.getInt("approvalStatus"), jsonParam.getStr("approvalRemark"), jsonParam.getStr("approvalInvalidCol"));
}

View File

@ -10,11 +10,11 @@ package com.suisung.mall.shop.store.controller.mobile;
import cn.hutool.json.JSONObject;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.modules.merch.ShopMerchEntry;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import com.suisung.mall.common.service.impl.BaiduMapServiceImpl;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.shop.esign.service.EsignContractFillingFileService;
import com.suisung.mall.shop.store.service.ShopMerchEntryService;
import com.suisung.mall.shop.store.service.ShopMchEntryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
@ -26,10 +26,10 @@ import java.util.Map;
@Api(tags = "店铺基础信息表")
@RestController
@RequestMapping("/mobile/shop/merch")
public class ShopMerchEntryController extends BaseControllerImpl {
public class ShopMchEntryController extends BaseControllerImpl {
@Resource
private ShopMerchEntryService shopMerchEntryService;
private ShopMchEntryService shopMchEntryService;
@Resource
private EsignContractFillingFileService esignContractFillingFileService;
@ -47,26 +47,26 @@ public class ShopMerchEntryController extends BaseControllerImpl {
@ApiOperation(value = "店铺主营分类(类目)", notes = "店铺主营分类(类目)")
@RequestMapping(value = "/business/category", method = RequestMethod.POST)
public CommonResult shopStoreBusinessCategoryList() {
return shopMerchEntryService.storeBusinessCategoryList();
return shopMchEntryService.storeBusinessCategoryList();
}
@ApiOperation(value = "商家申请入驻商城平台", notes = "商家申请入驻商城平台")
@RequestMapping(value = "/apply", method = RequestMethod.POST)
public CommonResult shopMerchEntryApply(@RequestBody JSONObject shopMerchEntryJSON) {
return shopMerchEntryService.shopMerchEntryApply(shopMerchEntryJSON);
return shopMchEntryService.shopMerchEntryApply(shopMerchEntryJSON);
}
@ApiOperation(value = "获取商家入驻资料详情", notes = "获取商家入驻资料详情")
@RequestMapping(value = "/detail", method = RequestMethod.POST)
public CommonResult shopMerchEntryDetail(@RequestBody JSONObject jsonParam) {
return shopMerchEntryService.shopMerchEntryDetail(null, jsonParam.getStr("mobile"), null);
return shopMchEntryService.shopMerchEntryDetail(null, jsonParam.getStr("mobile"), null);
}
@ApiOperation(value = "通过手机号mobile获取商家入驻审核状态", notes = "通过手机号获取商家入驻审核状态,远程调用用途")
@RequestMapping(value = "/approval/status", method = RequestMethod.POST)
public Integer shopMerchEntryApprovalStatus(@RequestBody JSONObject jsonParam) {
// approvalStatus 入驻商家的审批状态1-已通过2-未通过3-待审核4-未申请
ShopMerchEntry record = shopMerchEntryService.shopMerchEntryApprovalInfo(jsonParam.getStr("mobile"));
ShopMchEntry record = shopMchEntryService.shopMerchEntryApprovalInfo(jsonParam.getStr("mobile"));
if (record == null || record.getApproval_status() == null) {
return 4;
}
@ -78,7 +78,7 @@ public class ShopMerchEntryController extends BaseControllerImpl {
@RequestMapping(value = "/fresh/approval/status", method = RequestMethod.POST)
public CommonResult shopMerchEntryApprovalStatus2(@RequestBody JSONObject jsonParam) {
// approvalStatus 入驻商家的审批状态1-已通过2-未通过3-待审核4-未申请
ShopMerchEntry record = shopMerchEntryService.shopMerchEntryApprovalInfo(jsonParam.getStr("mobile"));
ShopMchEntry record = shopMchEntryService.shopMerchEntryApprovalInfo(jsonParam.getStr("mobile"));
Map<String, Object> result = new HashMap<>();
if (record == null || record.getApproval_status() == null) {
// 配合前端的要求没有申请过入驻商城平台的时候返回未申请状态
@ -103,7 +103,7 @@ public class ShopMerchEntryController extends BaseControllerImpl {
@ApiOperation(value = "商家重新申请入驻商城平台", notes = "商家申请入驻材料被驳回的时候,修正材料,重新申请入驻")
@RequestMapping(value = "/re-apply", method = RequestMethod.POST)
public CommonResult shopMerchEntryReApply(@RequestBody JSONObject shopMerchEntryJSON) {
return shopMerchEntryService.shopMerchEntryReApply(shopMerchEntryJSON);
return shopMchEntryService.shopMerchEntryReApply(shopMerchEntryJSON);
}
/**

View File

@ -9,9 +9,9 @@
package com.suisung.mall.shop.store.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.merch.ShopMerchEntry;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import org.springframework.stereotype.Component;
@Component
public interface ShopMerchEntryMapper extends BaseMapper<ShopMerchEntry> {
public interface ShopMchEntryMapper extends BaseMapper<ShopMchEntry> {
}

View File

@ -10,12 +10,12 @@ package com.suisung.mall.shop.store.service;
import cn.hutool.json.JSONObject;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.modules.merch.ShopMerchEntry;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import org.springframework.data.util.Pair;
import java.util.List;
public interface ShopMerchEntryService {
public interface ShopMchEntryService {
/**
* 获取店铺的经营类目列表
@ -96,17 +96,34 @@ public interface ShopMerchEntryService {
* @param loginMobile
* @return
*/
ShopMerchEntry shopMerchEntryApprovalInfo(String loginMobile);
ShopMchEntry shopMerchEntryApprovalInfo(String loginMobile);
/**
* 根据商家手机号营业执照审批状态获取有效的商家入驻申请记录
*
* @param loginMobile
* @param bizLicenseNumber
* @param approvalStatus
* @param approvalStatusList
* @return
*/
ShopMerchEntry getShopMerchEntryByCondition(String loginMobile, String bizLicenseNumber, Integer approvalStatus);
ShopMchEntry getShopMerchEntryByCondition(String loginMobile, String bizLicenseNumber, Integer... approvalStatusList);
/**
* 根据拉卡拉外部商户号获取有效的商家入驻申请记录
*
* @param merCupNo
* @return
*/
ShopMchEntry getShopMerchEntryByMerCupNo(String merCupNo);
/**
* 根据拉卡拉内部商户号获取有效的商家入驻申请记录
*
* @param merInnerNo
* @return
*/
ShopMchEntry getShopMerchEntryByMerInnerNo(String merInnerNo);
/**
* 根据商家注册的手机号更新合同签署状态和合同下载地址
@ -127,6 +144,33 @@ public interface ShopMerchEntryService {
*/
Boolean updateMerchEntryStoreStatus(String loginMobile, Integer storeStatus);
/**
* 更新商家入驻申请的拉卡拉商户号
*
* @param loginMobile 商家注册的手机号
* @param lklAuditStatus 拉卡拉审核状态
* @param lklMerCupNo 拉卡拉银联商户号
* @param lklMerInnerNo 拉卡拉内部商户号
* @param lklTkRegParams 进件请求参数
* @param lklTkRegResp 进件返回的数据
* @return
*/
Boolean updateMerchEntryLklMerCupNo(String loginMobile, Integer lklAuditStatus, String lklMerCupNo, String lklMerInnerNo, String lklTkRegParams, String lklTkRegResp);
/**
* 根据拉卡拉内部商户号更新商家入驻申请的拉卡拉审核状态和响应数据
*
* @param lklInnerMerNo 拉卡拉内部商户号
* @param lklMerCupNo 拉卡拉外部商户号
* @param termNos 拉卡拉分配的业务终端号
* @param lklAuditStatus 拉卡拉审核状态
* @param approvalStatus 入驻材料审核状态
* @param lklTkRegNotifyReq lklTkRegResp 异步请求参数
* @return
*/
Boolean updateMerchEntryLklAuditStatusByLklMerCupNo(String lklInnerMerNo, String lklMerCupNo, String termNos, Integer lklAuditStatus, Integer approvalStatus, String lklTkRegNotifyReq);
/**
* 更新商家入驻申请的店铺 ID
*
@ -136,5 +180,41 @@ public interface ShopMerchEntryService {
*/
Boolean updateMerchEntryStoreId(Long id, Integer storeId);
/**
* 更新拉卡拉入网电子合同合同名称签署COS地址, LKL文件相对路径
*
* @param id
* @param lklEcNo
* @param lklEcName
* @param lklEcResultUrl
* @param ecDownloadUrl
* @param ecLklFilePath
* @return
*/
Boolean updateMerchEntryLklEcNo(Long id, String lklEcNo, String lklEcName, String lklEcResultUrl, String ecDownloadUrl, String ecLklFilePath);
/**
* 更新商家入驻申请的审批状态和审批备注
*
* @param mchId 商家入驻申请 IDmchId和mchMobile至少必填一个
* @param mchMobile 商家注册的手机号 mchId和mchMobile至少必填一个
* @param approvalStatus 入驻审批状态1-已通过2-未通过3-待审核4-未申请过5-已提交拉卡拉审核21-拉卡拉审核未通过
* @param approvalRemark 审批备注
* @return
*/
Boolean updateMerchEntryApprovalByMchId(Long mchId, String mchMobile, Integer approvalStatus, String approvalRemark);
/**
* 根据商户号或商家手机号修改商户分账多个状态
*
* @param mchMobile
* @param merCupNo
* @param hasEcSigned
* @param hasApplySplit
* @param hasApplyReceiver
* @param hasBindReceiver
* @return
*/
Boolean updateMulStatus(String mchMobile, String merCupNo, Integer hasEcSigned, Integer hasApplySplit, Integer hasApplyReceiver, Integer hasBindReceiver);
}

View File

@ -19,7 +19,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.modules.merch.ShopMerchEntry;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import com.suisung.mall.common.utils.BankUtil;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.common.utils.phone.PhoneNumberUtils;
@ -30,9 +30,11 @@ import com.suisung.mall.shop.components.TaskService;
import com.suisung.mall.shop.esign.service.EsignContractFillingFileService;
import com.suisung.mall.shop.esign.service.EsignContractService;
import com.suisung.mall.shop.esign.service.EsignPlatformInfoService;
import com.suisung.mall.shop.lakala.service.impl.LakalaApiServiceImpl;
import com.suisung.mall.shop.lakala.service.impl.LklTkServiceImpl;
import com.suisung.mall.shop.message.service.ShopMessageTemplateService;
import com.suisung.mall.shop.store.mapper.ShopMerchEntryMapper;
import com.suisung.mall.shop.store.service.ShopMerchEntryService;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -41,17 +43,14 @@ import org.springframework.data.util.Pair;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* 商家入驻申请表
*/
@Slf4j
@Service
public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMapper, ShopMerchEntry> implements ShopMerchEntryService {
public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper, ShopMchEntry> implements ShopMchEntryService {
@Resource
private AccountBaseConfigService accountBaseConfigService;
@ -76,9 +75,17 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
@Resource
private ShopBaseStoreCategoryService shopBaseStoreCategoryService;
@Lazy
@Resource
private LklTkServiceImpl lklTkService;
@Autowired
private TaskService taskService;
@Lazy
@Resource
private LakalaApiServiceImpl lakalaApiService;
/**
* 获取店铺的经营类目列表
@ -106,7 +113,7 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
}
/**
* 商家重新申请入驻商城平台
* 商家申请入驻商城平台
*
* @param shopMerchEntryJSON
* @return
@ -127,9 +134,9 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return CommonResult.failed("缺少必要参数!");
}
ShopMerchEntry record = JSONUtil.toBean(shopMerchEntryJSON, ShopMerchEntry.class);
ShopMchEntry record = JSONUtil.toBean(shopMerchEntryJSON, ShopMchEntry.class);
if (record == null || StrUtil.isBlank(record.getLogin_mobile())) {
log.error("###商家入驻参数转换失败###");
log.error("###商家入驻参数转换失败###{}", shopMerchEntryJSON);
return CommonResult.failed("参数转换失败,请联系管理员!");
}
@ -147,22 +154,15 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return CommonResult.failed("请填写联系人!");
}
// 校验身份证手机号格式
if (StrUtil.isNotBlank(record.getLegal_person_id_number()) && !StringUtils.validateIDCard(record.getLegal_person_id_number())) {
return CommonResult.failed("法人身份证号码有误!");
if (StrUtil.isBlank(record.getStore_area()) || StrUtil.isBlank(record.getBank_area())) {
return CommonResult.failed("请指定店铺或银行的省市区!");
}
if (StrUtil.isNotBlank(record.getIndividual_id_number()) && !StringUtils.validateIDCard(record.getIndividual_id_number())) {
return CommonResult.failed("个人身份证号码有误!");
}
if (StrUtil.isNotBlank(record.getLogin_mobile()) && !PhoneNumberUtils.checkPhoneNumber(record.getLogin_mobile())) {
return CommonResult.failed("申请人手机号码有误!");
}
if (StrUtil.isNotBlank(record.getLegal_person_mobile()) && !PhoneNumberUtils.checkPhoneNumber(record.getLegal_person_mobile())) {
return CommonResult.failed("法人手机号码有误!");
}
// 检查企业法人或个人的营业执照或身份证
if (ObjectUtil.isNotEmpty(record.getEntity_type()) && record.getEntity_type().equals(2)) {
@ -171,6 +171,10 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return CommonResult.failed("缺少个人身份证信息!");
}
if (StrUtil.isNotBlank(record.getIndividual_id_number()) && !StringUtils.validateIDCard(record.getIndividual_id_number())) {
return CommonResult.failed("个人身份证号码有误!");
}
} else {
// 企业
if (StrUtil.isBlank(record.getBiz_license_number()) || StrUtil.isBlank(record.getBiz_license_image())) {
@ -182,7 +186,15 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
}
if (StrUtil.isBlank(record.getLegal_person_id_images()) || StrUtil.isBlank(record.getLegal_person_id_images2())) {
return CommonResult.failed("缺少企业法人身份证信息!");
return CommonResult.failed("法人身份证信息!");
}
if (StrUtil.isNotBlank(record.getLegal_person_id_number()) && !StringUtils.validateIDCard(record.getLegal_person_id_number())) {
return CommonResult.failed("法人身份证号码有误!");
}
if (StrUtil.isNotBlank(record.getLegal_person_mobile()) && !PhoneNumberUtils.checkPhoneNumber(record.getLegal_person_mobile())) {
return CommonResult.failed("法人手机号码有误!");
}
}
@ -192,7 +204,14 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
}
if (!BankUtil.isValidZHBankAccount(record.getAccount_number())) {
return CommonResult.failed("收款账号(银行卡号)格式有误!");
return CommonResult.failed("银行卡号格式有误!");
}
if (StrUtil.isBlank(record.getOpenning_bank_code())) {
return CommonResult.failed("请填写结算账户清算⾏号!");
} else {
// 对公对私结算账户清算号和结算账户开户号一定一致
record.setClearing_bank_code(record.getOpenning_bank_code());
}
if (StrUtil.isNotBlank(record.getStore_name()) && shopStoreBaseService.isExistsByStoreName(record.getStore_name())) {
@ -205,6 +224,14 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return CommonResult.failed(isApplied.getSecond());
}
// 营业执照经营范围内容
if (ObjectUtil.isEmpty(record.getSales_info())) {
record.setSales_info(record.getBiz_license_content());
}
// 重要备注自动计算商家分成比例
record.setSplit_ratio(shopBaseStoreCategoryService.getStoreCategoryRatio(record.getBiz_category()));
record.setCreated_by(userId);
record.setApproval_status(CommonConstant.MCH_APPR_STA_PADDING);
record.setApproval_remark("您的申请入驻平台材料已提交,待审中,请耐心等待!");
@ -251,7 +278,7 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
}
// 验证合同签署状态如果已经签署不能再次申请
ShopMerchEntry oldRecord = getById(shopMerchEntryJSON.getInt("id"));
ShopMchEntry oldRecord = getById(shopMerchEntryJSON.getInt("id"));
if (oldRecord == null) {
return CommonResult.failed("未找到入驻记录!");
}
@ -260,36 +287,60 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return CommonResult.failed("合同签署进行中(或已签署),不能再次申请!");
}
ShopMerchEntry record = JSONUtil.toBean(shopMerchEntryJSON, ShopMerchEntry.class);
ShopMchEntry record = JSONUtil.toBean(shopMerchEntryJSON, ShopMchEntry.class);
if (record == null) {
log.error("###商家入驻参数转换失败###");
return CommonResult.failed("参数转换失败,请联系管理员!");
}
// 验证企业营业执照号码
if (StrUtil.isNotBlank(record.getBiz_license_number()) && !StringUtils.verifyBusinessLicense(record.getBiz_license_number())) {
return CommonResult.failed("营业执照号码有误!");
// 检查企业法人或个人的营业执照或身份证
if (ObjectUtil.isNotEmpty(record.getEntity_type()) && record.getEntity_type().equals(2)) {
// 个人
if (StrUtil.isBlank(record.getIndividual_id_number()) || StrUtil.isBlank(record.getIndividual_id_images()) || StrUtil.isBlank(record.getIndividual_id_images2())) {
return CommonResult.failed("缺少个人身份证信息!");
}
if (StrUtil.isNotBlank(record.getIndividual_id_number()) && !StringUtils.validateIDCard(record.getIndividual_id_number())) {
return CommonResult.failed("个人身份证号码有误!");
}
} else {
// 企业
if (StrUtil.isBlank(record.getBiz_license_number()) || StrUtil.isBlank(record.getBiz_license_image())) {
return CommonResult.failed("缺少企业营业执照信息!");
}
if (!StringUtils.verifyBusinessLicense(record.getBiz_license_number())) {
return CommonResult.failed("营业执照号码有误!");
}
if (StrUtil.isBlank(record.getLegal_person_id_images()) || StrUtil.isBlank(record.getLegal_person_id_images2())) {
return CommonResult.failed("法人身份证信息!");
}
if (StrUtil.isNotBlank(record.getLegal_person_id_number()) && !StringUtils.validateIDCard(record.getLegal_person_id_number())) {
return CommonResult.failed("法人身份证号码有误!");
}
if (StrUtil.isNotBlank(record.getLegal_person_mobile()) && !PhoneNumberUtils.checkPhoneNumber(record.getLegal_person_mobile())) {
return CommonResult.failed("法人手机号码有误!");
}
}
// 校验身份证手机号格式
if (StrUtil.isNotBlank(record.getLegal_person_id_number()) && !StringUtils.validateIDCard(record.getLegal_person_id_number())) {
return CommonResult.failed("法人身份证号码有误!");
}
if (StrUtil.isNotBlank(record.getIndividual_id_number()) && !StringUtils.validateIDCard(record.getIndividual_id_number())) {
return CommonResult.failed("个人身份证号码有误!");
}
if (StrUtil.isNotBlank(record.getLogin_mobile()) && !PhoneNumberUtils.checkPhoneNumber(record.getLogin_mobile())) {
return CommonResult.failed("申请人手机号码有误!");
}
if (StrUtil.isNotBlank(record.getLegal_person_mobile()) && !PhoneNumberUtils.checkPhoneNumber(record.getLegal_person_mobile())) {
return CommonResult.failed("法人手机号码有误!");
// 检查银行账号
if (StrUtil.isBlank(record.getBank_name()) || StrUtil.isBlank(record.getAccount_number()) || StrUtil.isBlank(record.getAccount_holder_name())) {
return CommonResult.failed("缺少银行账号信息!");
}
if (StrUtil.isNotBlank(record.getAccount_number()) && !BankUtil.isValidZHBankAccount(record.getAccount_number())) {
return CommonResult.failed("收款账号(银行卡号)格式有误!");
return CommonResult.failed("银行卡号格式有误!");
}
if (StrUtil.isBlank(record.getOpenning_bank_code())) {
return CommonResult.failed("请填写结算账户开户⾏号!");
} else {
// 对公对私结算账户清算号和结算账户开户号一定一致
record.setClearing_bank_code(record.getOpenning_bank_code());
}
if (StrUtil.isNotBlank(record.getStore_name()) && shopStoreBaseService.isExistsByStoreName(record.getStore_name())) {
@ -338,7 +389,7 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
// return CommonResult.failed("权限不足!");
// }
QueryWrapper<ShopMerchEntry> queryWrapper = new QueryWrapper<>();
QueryWrapper<ShopMchEntry> queryWrapper = new QueryWrapper<>();
if (StrUtil.isNotBlank(keyword)) {
queryWrapper.like("store_name", keyword);
}
@ -353,7 +404,7 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
pageSize = 20;
}
Page<ShopMerchEntry> listPage = lists(queryWrapper, pageIndex, pageSize);
Page<ShopMchEntry> listPage = lists(queryWrapper, pageIndex, pageSize);
return CommonResult.success(listPage);
}
@ -375,7 +426,7 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return CommonResult.failed("缺少必要参数!");
}
QueryWrapper<ShopMerchEntry> queryWrapper = new QueryWrapper<>();
QueryWrapper<ShopMchEntry> queryWrapper = new QueryWrapper<>();
if (ObjectUtil.isNotEmpty(recordId)) {
queryWrapper.eq("id", recordId);
}
@ -389,12 +440,16 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
queryWrapper.in("approval_status", approvalStatusList);
}
queryWrapper.orderByDesc("id");
List<ShopMerchEntry> recordList = list(queryWrapper);
List<ShopMchEntry> recordList = list(queryWrapper);
if (CollectionUtil.isEmpty(recordList)) {
return CommonResult.success(null, "暂无申请记录!");
}
ShopMerchEntry record = recordList.get(0);
ShopMchEntry record = recordList.get(0);
// 审核意见空值返回"[]"
if (StrUtil.isBlank(record.getApproval_invalid_col())) {
record.setApproval_invalid_col("[]");
}
// 试试更新入驻表的合同下载地址和合同签署状态
updateMerchEntrySignedStatusAndContractDownloadUrl(record);
@ -407,7 +462,7 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
*
* @param record
*/
private void updateMerchEntrySignedStatusAndContractDownloadUrl(ShopMerchEntry record) {
private void updateMerchEntrySignedStatusAndContractDownloadUrl(ShopMchEntry record) {
if (record == null) {
return;
}
@ -435,7 +490,7 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
* 商家入驻审批
*
* @param id
* @param approvalStatus 入驻商家的审批状态1-已通过2-未通过3-待审核4-未申请
* @param approvalStatus 入驻商家的审批状态1-已通过2-未通过3-待审核4-未申请5-已提交拉卡拉审核
* @param approvalRemark 审批备注
* @param approvalInvalidCol 审批无效字段
* @return
@ -455,26 +510,29 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return CommonResult.failed("缺少必要参数!");
}
if (!approvalStatus.equals(CommonConstant.Enable) && !approvalStatus.equals(CommonConstant.Disable2)) {
if (!approvalStatus.equals(CommonConstant.MCH_APPR_STA_LKL_PADDING) && !approvalStatus.equals(CommonConstant.MCH_APPR_STA_NOPASS)) {
return CommonResult.failed("审批状态有误!");
}
ShopMerchEntry record = getById(id);
ShopMchEntry record = getById(id);
if (record == null) {
return CommonResult.failed("未找到入驻记录");
return CommonResult.failed("商家入驻记录不存在");
}
// TODO 已经审核通过的不能再审核了
UpdateWrapper<ShopMerchEntry> updateWrapper = new UpdateWrapper<>();
if (approvalStatus.equals(CommonConstant.Enable) && StrUtil.isBlank(approvalRemark)) {
UpdateWrapper<ShopMchEntry> updateWrapper = new UpdateWrapper<>();
if (approvalStatus.equals(CommonConstant.MCH_APPR_STA_LKL_PADDING) && StrUtil.isBlank(approvalRemark)) {
// 审核通过
approvalRemark = "审核通过,后续将向您发起签署电子合同流程。";
approvalRemark = "初步审核通过,等待进一步审核。";//"审核通过,后续将向您发起签署电子合同流程。";
updateWrapper.set("signed_status", CommonConstant.CONTRACT_SIGN_STA_ING);
} else if (approvalStatus.equals(CommonConstant.Disable2) && StrUtil.isBlank(approvalRemark)) {
updateWrapper.set("approval_status", CommonConstant.MCH_APPR_STA_LKL_PADDING); // 进入拉卡拉审核中
log.info("准备提交给拉卡拉进件审核。");
} else if (approvalStatus.equals(CommonConstant.MCH_APPR_STA_NOPASS) && StrUtil.isBlank(approvalRemark)) {
approvalRemark = "审核未通过,请继续完善入驻资料信息。";
}
// 自动计算商家分成比例
// 重要备注自动计算商家分成比例
record.setSplit_ratio(shopBaseStoreCategoryService.getStoreCategoryRatio(record.getBiz_category()));
updateWrapper.eq("id", id)
@ -491,21 +549,33 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return CommonResult.failed("系统处理审批出错,请联系管理员!");
}
// TODO 审核通过后去拉卡拉进件即时发送短信给商家通知准备去签电子合同
if (approvalStatus.equals(CommonConstant.Enable)) {
// 多线程执行电子合同生成和填充
taskService.executeTask(() -> {
log.debug("###开始异步执行生成电子合同模版和填充模版数据,并生该商家和平台方签署的未盖章合同文件###");
// 生成电子合同模版和填充模版数据并生该商家和平台方签署的未盖章合同文件
Boolean genSuccess = esignContractFillingFileService.fillDocTemplate(record.getLogin_mobile(), "");
if (!genSuccess) {
log.error("###商家入驻电子合同生成失败###");
}
// 发短信通知商家入驻申请已通过审核
});
if (approvalStatus.equals(CommonConstant.MCH_APPR_STA_NOPASS)) {
return CommonResult.success(null, "驳回成功!");
}
// 审批通过的时候进行下一步工作触发去拉卡拉商家入网电子合同签署
// 平台人工审核通过后触发去拉卡拉商家入网电子合同签署
// 下一步商家入网电子合同签署完毕后收到异步通知触发拉卡拉商家进件重要环节
Pair<Boolean, String> resultPair = lakalaApiService.applyLedgerMerEc(record.getLogin_mobile());
if (!resultPair.getFirst()) {
return CommonResult.failed(resultPair.getSecond());
}
// if (approvalStatus.equals(CommonConstant.Enable)) {
// // 多线程执行电子合同生成和填充
// taskService.executeTask(() -> {
// log.debug("###开始异步执行生成电子合同模版和填充模版数据,并生该商家和平台方签署的未盖章合同文件###");
// // 生成电子合同模版和填充模版数据并生该商家和平台方签署的未盖章合同文件
// Boolean genSuccess = esignContractFillingFileService.fillDocTemplate(record.getLogin_mobile(), "");
// if (!genSuccess) {
// log.error("###商家入驻电子合同生成失败###");
// }
//
// // 发短信通知商家入驻申请已通过审核
// });
// }
return CommonResult.success();
}
@ -524,7 +594,7 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return Pair.of(false, msg);
}
QueryWrapper<ShopMerchEntry> queryWrapper = new QueryWrapper<>();
QueryWrapper<ShopMchEntry> queryWrapper = new QueryWrapper<>();
if (StrUtil.isNotBlank(mobile) && StrUtil.isBlank(bizLicenseNumber)) {
queryWrapper.eq("login_mobile", mobile);
boolean isApplied = count(queryWrapper) > 0;
@ -561,9 +631,9 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return 0;
}
QueryWrapper<ShopMerchEntry> queryWrapper = new QueryWrapper<>();
QueryWrapper<ShopMchEntry> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("login_mobile", mobile).select("approval_status").orderByAsc("id");
List<ShopMerchEntry> recordList = list(queryWrapper);
List<ShopMchEntry> recordList = list(queryWrapper);
if (CollectionUtil.isEmpty(recordList)) {
return 0;
}
@ -579,22 +649,22 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
* @return
*/
@Override
public ShopMerchEntry shopMerchEntryApprovalInfo(String loginMobile) {
public ShopMchEntry shopMerchEntryApprovalInfo(String loginMobile) {
if (StrUtil.isBlank(loginMobile)) {
return null;
}
QueryWrapper<ShopMerchEntry> queryWrapper = new QueryWrapper<>();
QueryWrapper<ShopMchEntry> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("login_mobile", loginMobile)
.select("id", "approval_status", "approval_remark", "login_mobile", "approval_invalid_col", "signed_status", "contract_download_url", "store_status")
.orderByAsc("id");
List<ShopMerchEntry> recordList = list(queryWrapper);
List<ShopMchEntry> recordList = list(queryWrapper);
if (CollectionUtil.isEmpty(recordList)) {
return null;
}
ShopMerchEntry record = recordList.get(0);
ShopMchEntry record = recordList.get(0);
// 试试更新入驻表的合同下载地址和合同签署状态
updateMerchEntrySignedStatusAndContractDownloadUrl(record);
@ -607,16 +677,16 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
*
* @param loginMobile
* @param bizLicenseNumber
* @param approvalStatus
* @param approvalStatusList
* @return
*/
@Override
public ShopMerchEntry getShopMerchEntryByCondition(String loginMobile, String bizLicenseNumber, Integer approvalStatus) {
if (StrUtil.isBlank(loginMobile) && StrUtil.isBlank(bizLicenseNumber) && ObjectUtil.isEmpty(approvalStatus)) {
public ShopMchEntry getShopMerchEntryByCondition(String loginMobile, String bizLicenseNumber, Integer... approvalStatusList) {
if (StrUtil.isBlank(loginMobile) && StrUtil.isBlank(bizLicenseNumber) && ObjectUtil.isEmpty(approvalStatusList)) {
return null;
}
QueryWrapper<ShopMerchEntry> queryWrapper = new QueryWrapper<>();
QueryWrapper<ShopMchEntry> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("status", CommonConstant.Enable).orderByAsc("id");
if (StrUtil.isNotBlank(loginMobile)) {
queryWrapper.eq("login_mobile", loginMobile);
@ -626,13 +696,50 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
queryWrapper.eq("biz_license_number", bizLicenseNumber);
}
if (ObjectUtil.isEmpty(approvalStatus)) {
queryWrapper.eq("approval_status", approvalStatus);
if (ObjectUtil.isNotEmpty(approvalStatusList)) {
queryWrapper.in("approval_status", Arrays.stream(approvalStatusList).toArray());
}
// todo 合同签署状态条件
List<ShopMchEntry> recordList = list(queryWrapper);
if (CollectionUtil.isEmpty(recordList)) {
return null;
}
List<ShopMerchEntry> recordList = list(queryWrapper);
return recordList.get(0);
}
/**
* 根据拉卡拉外部商户号获取有效的商家入驻申请记录
*
* @param merCupNo
* @return
*/
@Override
public ShopMchEntry getShopMerchEntryByMerCupNo(String merCupNo) {
if (StrUtil.isBlank(merCupNo)) {
return null;
}
QueryWrapper<ShopMchEntry> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("lkl_mer_cup_no", merCupNo).eq("status", CommonConstant.Enable).orderByAsc("id");
List<ShopMchEntry> recordList = list(queryWrapper);
if (CollectionUtil.isEmpty(recordList)) {
return null;
}
return recordList.get(0);
}
@Override
public ShopMchEntry getShopMerchEntryByMerInnerNo(String merInnerNo) {
if (StrUtil.isBlank(merInnerNo)) {
return null;
}
QueryWrapper<ShopMchEntry> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("lkl_mer_inner_no", merInnerNo).eq("status", CommonConstant.Enable).orderByAsc("id");
List<ShopMchEntry> recordList = list(queryWrapper);
if (CollectionUtil.isEmpty(recordList)) {
return null;
}
@ -654,7 +761,7 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return null;
}
UpdateWrapper<ShopMerchEntry> updateWrapper = new UpdateWrapper<>();
UpdateWrapper<ShopMchEntry> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("login_mobile", loginMobile);
if (ObjectUtil.isNotEmpty(signedStatus)) {
@ -678,14 +785,91 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
@Override
public Boolean updateMerchEntryStoreStatus(String loginMobile, Integer storeStatus) {
if (StrUtil.isBlank(loginMobile) && ObjectUtil.isEmpty(storeStatus)) {
return null;
return false;
}
UpdateWrapper<ShopMerchEntry> updateWrapper = new UpdateWrapper<>();
UpdateWrapper<ShopMchEntry> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("login_mobile", loginMobile).set("store_status", storeStatus);
return update(updateWrapper);
}
@Override
public Boolean updateMerchEntryLklMerCupNo(String loginMobile, Integer lklAuditStatus, String lklMerCupNo, String lklMerInnerNo, String lklTkRegParams, String lklTkRegResp) {
if (StrUtil.isBlank(loginMobile) && StrUtil.isBlank(lklMerCupNo)) {
return false;
}
UpdateWrapper<ShopMchEntry> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("login_mobile", loginMobile);
if (ObjectUtil.isNotEmpty(lklAuditStatus)) {
updateWrapper.set("lkl_tk_audit_status", lklAuditStatus);
}
if (StrUtil.isNotBlank(lklMerCupNo)) {
updateWrapper.set("lkl_mer_cup_no", lklMerCupNo); // 银联商户号
}
if (StrUtil.isNotBlank(lklMerInnerNo)) {
updateWrapper.set("lkl_mer_inner_no", lklMerInnerNo); //内部商户号
}
if (StrUtil.isNotBlank(lklTkRegParams)) {
updateWrapper.set("lkl_tk_reg_params", lklTkRegParams);
}
if (StrUtil.isNotBlank(lklTkRegResp)) {
updateWrapper.set("lkl_tk_reg_resp", lklTkRegResp);
}
updateWrapper.set("approval_remark", "拉卡拉进件准备进入审核");
updateWrapper.set("approval_invalid_col", "[]");
return update(updateWrapper);
}
/**
* 根据拉卡拉内部商户号更新商家入驻申请的拉卡拉审核状态和响应数据
*
* @param lklInnerMerNo 拉卡拉内部商户号
* @param lklMerCupNo 拉卡拉外部商户号
* @param termNos 拉卡拉分配的业务终端号
* @param lklAuditStatus 拉卡拉审核状态
* @param approvalStatus 入驻材料审核状态
* @param lklTkRegNotifyReq 异步通知返回的请求数据
* @return
*/
@Override
public Boolean updateMerchEntryLklAuditStatusByLklMerCupNo(String lklInnerMerNo, String lklMerCupNo, String termNos, Integer lklAuditStatus, Integer approvalStatus, String lklTkRegNotifyReq) {
if (StrUtil.isBlank(lklInnerMerNo)) {
return false;
}
UpdateWrapper<ShopMchEntry> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("lkl_mer_inner_no", lklInnerMerNo);
if (StrUtil.isNotBlank(lklMerCupNo)) {
updateWrapper.set("lkl_mer_cup_no", lklMerCupNo);
}
if (StrUtil.isNotBlank(termNos)) {
updateWrapper.set("lkl_term_no", termNos);
}
if (ObjectUtil.isNotEmpty(lklAuditStatus)) {
updateWrapper.set("lkl_tk_audit_status", lklAuditStatus);
}
if (ObjectUtil.isNotEmpty(approvalStatus)) {
updateWrapper.set("approval_status", approvalStatus);
}
if (StrUtil.isNotBlank(lklTkRegNotifyReq)) {
updateWrapper.set("lkl_tk_reg_notify_req", lklTkRegNotifyReq);
}
return update(updateWrapper);
}
/**
* 更新商家入驻申请的店铺 ID
*
@ -699,8 +883,135 @@ public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMap
return false;
}
return update(new UpdateWrapper<ShopMerchEntry>()
return update(new UpdateWrapper<ShopMchEntry>()
.eq("id", id)
.set("store_id", storeId));
}
/**
* 更新拉卡拉入网电子合同和签署地址
*
* @param id
* @param lklEcNo
* @param lklEcResultUrl
* @param ecDownloadUrl
* @param ecLklFilePath
* @return
*/
@Override
public Boolean updateMerchEntryLklEcNo(Long id, String lklEcNo, String lklEcName, String lklEcResultUrl, String ecDownloadUrl, String ecLklFilePath) {
if (ObjectUtil.isEmpty(id) && StrUtil.isBlank(lklEcNo)) {
return false;
}
UpdateWrapper<ShopMchEntry> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", id);
updateWrapper.set("lkl_ec_no", lklEcNo);
if (StrUtil.isNotBlank(lklEcName)) {
updateWrapper.set("lkl_ec_name", lklEcName);
}
if (StrUtil.isNotBlank(lklEcResultUrl)) {
updateWrapper.set("lkl_ec_result_url", lklEcResultUrl);
}
if (StrUtil.isNotBlank(ecDownloadUrl)) {
updateWrapper.set("contract_download_url", ecDownloadUrl);
// updateWrapper.set("signed_status", CommonConstant.CONTRACT_SIGN_STA_FINISH);
updateWrapper.set("has_ec_signed", CommonConstant.Enable);
}
if (StrUtil.isNotBlank(ecLklFilePath)) {
updateWrapper.set("lkl_ec_file_path", ecLklFilePath);
}
return update(updateWrapper);
}
/**
* 更新商家入驻申请的审批状态和审批备注
*
* @param mchId 商家入驻申请 IDmchId和mchMobile至少必填一个
* @param mchMobile 商家注册的手机号 mchId和mchMobile至少必填一个
* @param approvalStatus 入驻商家的审批状态1-已通过2-未通过3-待审核4-未申请过5-已提交拉卡拉审核
* @param approvalRemark 审批备注
* @return
*/
@Override
public Boolean updateMerchEntryApprovalByMchId(Long mchId, String mchMobile, Integer approvalStatus, String approvalRemark) {
if (ObjectUtil.isEmpty(mchId) && StrUtil.isBlank(mchMobile)) {
log.error("更新入驻审批状态和备注失败,缺少必要参数");
return false;
}
UpdateWrapper<ShopMchEntry> updateWrapper = new UpdateWrapper<>();
if (ObjectUtil.isNotEmpty(mchId)) {
updateWrapper.eq("id", mchId);
}
if (StrUtil.isNotBlank(mchMobile)) {
updateWrapper.eq("login_mobile", mchMobile);
}
if (ObjectUtil.isNotEmpty(approvalStatus)) {
updateWrapper.set("approval_status", approvalStatus);
}
if (StrUtil.isNotBlank(approvalRemark)) {
updateWrapper.set("approval_remark", approvalRemark);
}
return update(updateWrapper);
}
/**
* 根据商户号或商家手机号修改商户分账多个状态
*
* @param mchMobile
* @param merCupNo
* @param hasEcSigned
* @param hasApplySplit
* @param hasApplyReceiver
* @param hasBindReceiver
* @return
*/
@Override
public Boolean updateMulStatus(String mchMobile, String merCupNo, Integer hasEcSigned,
Integer hasApplySplit, Integer hasApplyReceiver, Integer hasBindReceiver) {
// 参数校验
if (StrUtil.isAllBlank(merCupNo, mchMobile)) {
log.error("缺少merCupNo或mchMobile参数");
return false;
}
UpdateWrapper<ShopMchEntry> updateWrapper = new UpdateWrapper<>();
// 设置查询条件
Optional.ofNullable(mchMobile)
.filter(StrUtil::isNotBlank)
.ifPresent(mobile -> updateWrapper.eq("login_mobile", mobile));
Optional.ofNullable(merCupNo)
.filter(StrUtil::isNotBlank)
.ifPresent(cupNo -> updateWrapper.eq("lkl_mer_cup_no", cupNo));
// 流式构建更新字段
Map<String, Integer> fieldMap = new LinkedHashMap<>();
fieldMap.put("has_ec_signed", hasEcSigned);
fieldMap.put("has_apply_split", hasApplySplit);
fieldMap.put("has_apply_receiver", hasApplyReceiver);
fieldMap.put("has_bind_receiver", hasBindReceiver);
// 过滤有效字段并设置
fieldMap.entrySet().stream()
.filter(entry -> entry.getValue() != null && entry.getValue() > 0)
.forEach(entry -> updateWrapper.set(entry.getKey(), entry.getValue()));
try {
return update(updateWrapper);
} catch (Exception e) {
log.error("更新商家分账业务多个状态失败", e);
return false;
}
}
}

View File

@ -31,11 +31,13 @@ import com.suisung.mall.common.feignService.PayService;
import com.suisung.mall.common.modules.account.AccountUserBase;
import com.suisung.mall.common.modules.account.AccountUserInfo;
import com.suisung.mall.common.modules.account.AccountUserSns;
import com.suisung.mall.common.modules.base.*;
import com.suisung.mall.common.modules.base.ShopBaseProductTag;
import com.suisung.mall.common.modules.base.ShopBaseStoreCategory;
import com.suisung.mall.common.modules.base.ShopBaseStoreGrade;
import com.suisung.mall.common.modules.base.ShopPageModule;
import com.suisung.mall.common.modules.distribution.ShopDistributionPlantformUser;
import com.suisung.mall.common.modules.invoicing.InvoicingCustomerLevel;
import com.suisung.mall.common.modules.invoicing.InvoicingWarehouseBase;
import com.suisung.mall.common.modules.merch.ShopMerchEntry;
import com.suisung.mall.common.modules.page.ShopPageBase;
import com.suisung.mall.common.modules.pay.PayUserResource;
import com.suisung.mall.common.modules.plantform.ShopPlantformSubsite;
@ -171,7 +173,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
private ShopBaseDistrictService shopBaseDistrictService;
@Lazy
@Autowired
private ShopMerchEntryService shopMerchEntryService;
private ShopMchEntryService shopMchEntryService;
@Autowired
private ThreadPoolExecutor executor;
@ -3006,13 +3008,13 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
return Pair.of(0, "商家账号异常!");
}
ShopMerchEntry shopMerchEntry = shopMerchEntryService.getShopMerchEntryByCondition(mchMobile, "", CommonConstant.MCH_APPR_STA_PASS);
if (ObjectUtil.isEmpty(shopMerchEntry)) {
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByCondition(mchMobile, "");
if (ObjectUtil.isEmpty(shopMchEntry)) {
logger.error("生成店铺:入驻信息不能为空");
return Pair.of(0, "入驻信息不能为空");
}
if (isExistsByStoreName(shopMerchEntry.getStore_name())) {
if (isExistsByStoreName(shopMchEntry.getStore_name())) {
logger.error("生成店铺:店铺名称已存在");
return Pair.of(0, "店铺名称已存在");
}
@ -3023,26 +3025,36 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
// shop_store_base
ShopStoreBase shopStoreBase = new ShopStoreBase();
shopStoreBase.setUser_id(userId); // 店铺管理员用户Id
shopStoreBase.setStore_name(shopMerchEntry.getStore_name());
shopStoreBase.setStore_category_id(shopMerchEntry.getBiz_category()); // 重要店铺分类id对应 shop_base_store_category 表的分类
shopStoreBase.setSplit_ratio(shopMerchEntry.getSplit_ratio()); // 分账比例
String storeFacadeImage = shopMerchEntry.getFront_facade_image();
shopStoreBase.setStore_logo(storeFacadeImage); // 临时使用门面照片做logo
shopStoreBase.setStore_name(shopMchEntry.getStore_name());
shopStoreBase.setStore_category_id(shopMchEntry.getBiz_category()); // 重要店铺分类id对应 shop_base_store_category 表的分类
shopStoreBase.setSplit_ratio(shopMchEntry.getSplit_ratio()); // 分账比例
String storeFacadeImage = shopMchEntry.getFront_facade_image();
String storeLogoImage = shopMchEntry.getStore_logo();
if (StrUtil.isBlank(storeLogoImage)) {
storeLogoImage = storeFacadeImage;
}
shopStoreBase.setStore_logo(storeLogoImage); // 临时使用门面照片做logo
// 省市区记录有序列表
List<ShopBaseDistrict> districtList = shopBaseDistrictService.getFullDistrictByDistrictCode(shopMerchEntry.getCounty_id());
shopStoreBase.setStore_district_id(shopBaseDistrictService.joinDistrict(districtList, 1, true, "/"));
shopStoreBase.setStore_area(shopBaseDistrictService.joinDistrict(districtList, 2, true, "/"));
shopStoreBase.setStore_address(shopMerchEntry.getStore_address());
shopStoreBase.setStore_longitude(shopMerchEntry.getStore_longitude());
shopStoreBase.setStore_latitude(shopMerchEntry.getStore_latitude());
// List<ShopBaseDistrict> districtList = shopBaseDistrictService.getFullDistrictByDistrictCode(shopMchEntry.getCounty_id());
//shopStoreBase.setStore_district_id(shopBaseDistrictService.joinDistrict(districtList, 1, true, "/"));
// shopStoreBase.setStore_area(shopBaseDistrictService.joinDistrict(districtList, 2, true, "/"));
shopStoreBase.setStore_district_id(shopMchEntry.getStore_district());
shopStoreBase.setStore_area(shopMchEntry.getStore_area());
shopStoreBase.setStore_address(shopMchEntry.getStore_address());
shopStoreBase.setStore_longitude(shopMchEntry.getStore_longitude());
shopStoreBase.setStore_latitude(shopMchEntry.getStore_latitude());
shopStoreBase.setStore_grade_id(1001); // 店铺等级默认为普通店铺
shopStoreBase.setStore_type(1);//店铺类型(ENUM): 1-卖家店铺; 2-供应商店铺
shopStoreBase.setStore_is_open(1);
shopStoreBase.setStore_is_selfsupport(0);
shopStoreBase.setStore_o2o_flag(0);
shopStoreBase.setSubsite_id(0);
// 拉卡拉外部商户号
shopStoreBase.setLkl_merchant_no(shopMchEntry.getLkl_mer_cup_no());
// 拉卡拉分配的终端号
shopStoreBase.setLkl_term_no(shopMchEntry.getLkl_term_no());
shopStoreBase.setStore_state_id(StateCode.STORE_STATE_YES);//店铺资料信息状态(ENUM):3210-待完善资料; 3220-等待审核 ; 3230-资料审核没有通过;3240-资料审核通过,待付款
shopStoreBase.setStore_time(DateUtil.date());
shopStoreBase.setStore_end_time(System.currentTimeMillis() + 1000L * 60 * 60 * 24 * 365 * 5); // 5年
@ -3062,7 +3074,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
shopStoreInfo.setStore_opening_hours("08:00");
shopStoreInfo.setStore_close_hours("22:00");
shopStoreInfo.setStore_discount(BigDecimal.valueOf(10));// 原价
shopStoreInfo.setStore_tel(shopMerchEntry.getLogin_mobile());
shopStoreInfo.setStore_tel(shopMchEntry.getLogin_mobile());
shopStoreInfo.setStore_banner(storeFacadeImage);
JSONArray list = new JSONArray();
@ -3074,16 +3086,16 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
slide.put("url", "https://www.gpsxcs.cn");
list.put(slide);
}
if (StrUtil.isNotBlank(shopMerchEntry.getEnvironment_image())) {
if (StrUtil.isNotBlank(shopMchEntry.getEnvironment_image())) {
JSONObject slide = new JSONObject();
slide.put("img", shopMerchEntry.getEnvironment_image());
slide.put("img", shopMchEntry.getEnvironment_image());
slide.put("name", "店铺环境照片");
slide.put("check", true);
slide.put("url", "https://www.gpsxcs.cn");
list.put(slide);
}
shopStoreInfo.setStore_slide(list.toString());
shopStoreInfo.setStore_address(shopMerchEntry.getStore_address()); // 包含省市区的详细地址
shopStoreInfo.setStore_address(shopMchEntry.getStore_address()); // 包含省市区的详细地址
shopStoreInfo.setStore_state_id(StateCode.STORE_STATE_YES);
if (!shopStoreInfoService.save(shopStoreInfo)) {
logger.error("生成店铺新增店铺info失败");
@ -3097,28 +3109,28 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
shopStoreCompany.setStore_id(storeId);
// 联系人
shopStoreCompany.setContacts_name(shopMerchEntry.getContact_name());
shopStoreCompany.setContacts_phone(shopMerchEntry.getLogin_mobile());
shopStoreCompany.setContacts_name(shopMchEntry.getContact_name());
shopStoreCompany.setContacts_phone(shopMchEntry.getLogin_mobile());
// 公司名
String companyName = StrUtil.isBlank(shopMerchEntry.getBiz_license_company()) ? shopMerchEntry.getStore_name() : shopMerchEntry.getBiz_license_company();
String companyName = StrUtil.isBlank(shopMchEntry.getBiz_license_company()) ? shopMchEntry.getStore_name() : shopMchEntry.getBiz_license_company();
shopStoreCompany.setCompany_name(companyName);
shopStoreCompany.setCompany_area(shopStoreBase.getStore_area());
shopStoreCompany.setCompany_address(shopMerchEntry.getStore_address());
shopStoreCompany.setCompany_address(shopMchEntry.getStore_address());
// 营业执照
shopStoreCompany.setBusiness_id(shopMerchEntry.getBiz_license_number());
shopStoreCompany.setBusiness_license_electronic(shopMerchEntry.getBiz_license_image());
shopStoreCompany.setBusiness_id(shopMchEntry.getBiz_license_number());
shopStoreCompany.setBusiness_license_electronic(shopMchEntry.getBiz_license_image());
// 企业法人
shopStoreCompany.setLegal_person(shopMerchEntry.getLegal_person_name());
shopStoreCompany.setLegal_person_number(shopMerchEntry.getLegal_person_id_number());
shopStoreCompany.setLegal_person_electronic(shopMerchEntry.getLegal_person_id_images());
shopStoreCompany.setLegal_person(shopMchEntry.getLegal_person_name());
shopStoreCompany.setLegal_person_number(shopMchEntry.getLegal_person_id_number());
shopStoreCompany.setLegal_person_electronic(shopMchEntry.getLegal_person_id_images());
// 银行对公账号
shopStoreCompany.setBank_account_name(shopMerchEntry.getAccount_holder_name());
shopStoreCompany.setBank_account_number(shopMerchEntry.getAccount_number());
shopStoreCompany.setBank_name(shopMerchEntry.getBank_name());
shopStoreCompany.setBank_account_name(shopMchEntry.getAccount_holder_name());
shopStoreCompany.setBank_account_number(shopMchEntry.getAccount_number());
shopStoreCompany.setBank_name(shopMchEntry.getBank_name());
Date today = new Date(); // 当前时间
shopStoreCompany.setOrganization_code_start(today);
@ -3127,7 +3139,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
shopStoreCompany.setBusiness_licence_start(today);
shopStoreCompany.setBusiness_licence_end(DateUtil.offsetDay(today, 365 * 10));
shopStoreCompany.setCompany_description(shopMerchEntry.getStore_name());
shopStoreCompany.setCompany_description(shopMchEntry.getStore_name());
shopStoreCompany.setStore_class_ids("");
shopStoreCompany.setStore_class_names("");
shopStoreCompany.setStore_class_commission("");
@ -3162,7 +3174,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
initStoreExtraInfo(userId, storeId);
// 更改店铺Id
shopMerchEntryService.updateMerchEntryStoreId(shopMerchEntry.getId(), storeId);
shopMchEntryService.updateMerchEntryStoreId(shopMchEntry.getId(), storeId);
return Pair.of(storeId, "新增成功");
} catch (Exception e) {

View File

@ -66,7 +66,7 @@ public class ShopStoreMediaServiceImpl extends BaseServiceImpl<ShopStoreMediaMap
Long gallery_id = getParameter("gallery_id", 0L);
String gallery_type = getParameter("gallery_type", "image");
if (user.isStore()) {
if (user != null && user.isStore()) {
ShopStoreMedia media_data = Convert.convert(ShopStoreMedia.class, mediaDTO);
media_data.setMedia_type(gallery_type); // todo 目前默认 image
media_data.setStore_id(Convert.toInt(user.getStore_id()));
@ -79,7 +79,7 @@ public class ShopStoreMediaServiceImpl extends BaseServiceImpl<ShopStoreMediaMap
}
} else {
// 平台用户
if (user.isPlatform()) {
if (user != null && user.isPlatform()) {
ShopPlantformMedia plantformMedia = Convert.convert(ShopPlantformMedia.class, mediaDTO);
plantformMedia.setMedia_type(gallery_type); // todo 目前默认 image
plantformMedia.setMedia_order(1);
@ -92,8 +92,6 @@ public class ShopStoreMediaServiceImpl extends BaseServiceImpl<ShopStoreMediaMap
mediaGallery.setGallery_num(mediaGallery.getGallery_num() + 1);
shopPlantformMediaGalleryService.edit(mediaGallery);
}
} else {
}
}
}

View File

@ -129,6 +129,8 @@ getui:
masterSecret: ybdUcVJJKw5bAcQB4DpC0A
logstash:
host: @logstash.host@
project:
domain: @project.domain@
feieyun:
url: http://api.feieyun.cn/Api/Open/
user: 17777525395@163.com
@ -141,13 +143,36 @@ sf-express:
enable: 2
#拉卡拉进件配置
lakala:
#服务地址
server_url: https://test.wsmsd.cn
#应用Id
app_id: OP00000003
#商户证书序列号
serial_no: 00dfba8194c41b84cf
#商户证书
api_cert_path: payKey/lakala/dev/OP00000003_cert.cer
#商户私钥
api_pri_key_path: payKey/lakala/dev/OP00000003_private_key.pem
#拉卡拉平台证书
lkl_platform_cer_path: payKey/lakala/dev/lkl_notify_cert_v2.cer
#机构代码
org_code: 1
#商户号
merchant_no: 82229007392000A
#终端号
term_no: D9296400
# 拉卡拉拓客进件配置
tk:
#服务地址
server_url: https://test.wsmsd.cn/sit/htkauth
client_id: lsycs
client_secret: XPa1HB5d55Ig0qV8
user_no: 29153396
ratio: 70.00
api_pub_key_path: payKey/lakala/dev/tk_api_public_key.txt
api_pri_key_path: payKey/lakala/dev/tk_api_private_key.txt
notify_pub_key_path: payKey/lakala/dev/tk_notify_public_key.txt
notify_pri_key_path: payKey/lakala/dev/tk_notify_private_key.txt
#e签宝配置
esign:
server_url: https://smlopenapi.esign.cn

View File

@ -129,6 +129,8 @@ getui:
masterSecret: ybdUcVJJKw5bAcQB4DpC0A
logstash:
host: @logstash.host@
project:
domain: @project.domain@
feieyun:
url: http://api.feieyun.cn/Api/Open/
user: 17777525395@163.com
@ -141,13 +143,37 @@ sf-express:
enable: 2
#拉卡拉进件配置
lakala:
#服务地址
server_url: https://test.wsmsd.cn/sit
#应用Id
app_id: OP00000003
#商户证书序列号
serial_no: 00dfba8194c41b84cf
#商户证书
api_cert_path: payKey/lakala/dev/OP00000003_cert.cer
#商户私钥
api_pri_key_path: payKey/lakala/dev/OP00000003_private_key.pem
#拉卡拉平台证书
lkl_platform_cer_path: payKey/lakala/dev/lkl_notify_cert_v2.cer
#机构代码
org_code: 1
#商户号, 测试商户号未开通分账功能的8222900539908Q9
merchant_no: 82229007392000A
#终端号
term_no: D9296400
is_prod: false
# 拉卡拉拓客进件配置
tk:
#服务地址
server_url: https://test.wsmsd.cn/sit/htkauth
server_url: https://test.wsmsd.cn
client_id: lsycs
client_secret: XPa1HB5d55Ig0qV8
user_no: 29153396
split_lowest_ratio: 70.00
api_pub_key_path: payKey/lakala/dev/tk_api_public_key.txt
api_pri_key_path: payKey/lakala/dev/tk_api_private_key.txt
notify_pub_key_path: payKey/lakala/dev/tk_notify_public_key.txt
notify_pri_key_path: payKey/lakala/dev/tk_notify_private_key.txt
#e签宝配置
esign:
server_url: https://smlopenapi.esign.cn

View File

@ -135,6 +135,8 @@ getui:
masterSecret: ybdUcVJJKw5bAcQB4DpC0A
logstash:
host: @logstash.host@
project:
domain: @project.domain@
feieyun:
url: http://api.feieyun.cn/Api/Open/
user: 17777525395@163.com
@ -150,13 +152,55 @@ sf-express:
enable: 2
#拉卡拉进件配置
lakala:
# #服务地址
# server_url: https://s2.lakala.com
# #应用Id
# app_id: OP10000439
# #商户证书序列号
# serial_no: 1737359895636
# #商户证书
# api_cert_path: payKey/lakala/prod/api_cert.cer
# #商户私钥
# api_pri_key_path: payKey/lakala/prod/api_private_key.pem
# #拉卡拉平台证书
# lkl_platform_cer_path: payKey/lakala/prod/lkl_platform.cer
# #机构代码
# org_code: 980688
# #商户号
# merchant_no: 8226330599900LN
# #终端号码M0780629B2B收银台 M0780798专业化扫码
# term_no: M0780798
#服务地址
server_url: https://test.wsmsd.cn/sit
#应用Id
app_id: OP00000003
#商户证书序列号
serial_no: 00dfba8194c41b84cf
#商户证书
api_cert_path: payKey/lakala/dev/OP00000003_cert.cer
#商户私钥
api_pri_key_path: payKey/lakala/dev/OP00000003_private_key.pem
#拉卡拉平台证书
lkl_platform_cer_path: payKey/lakala/dev/lkl_notify_cert_v2.cer
#机构代码
org_code: 1
#商户号, 测试商户号未开通分账功能的8222900539908Q9
merchant_no: 82229007392000A
#终端号
term_no: D9296400
is_prod: false
#拉卡拉拓客进件配置
tk:
#服务地址
server_url: https://test.wsmsd.cn/sit/htkauth
server_url: https://test.wsmsd.cn
client_id: lsycs
client_secret: XPa1HB5d55Ig0qV8
user_no: 29153396
split_lowest_ratio: 70.00
api_pub_key_path: payKey/lakala/dev/tk_api_public_key.txt
api_pri_key_path: payKey/lakala/dev/tk_api_private_key.txt
notify_pub_key_path: payKey/lakala/dev/tk_notify_public_key.txt
notify_pri_key_path: payKey/lakala/dev/tk_notify_private_key.txt
#e签宝配置
esign:
server_url: https://smlopenapi.esign.cn

View File

@ -133,6 +133,8 @@ getui:
masterSecret: ybdUcVJJKw5bAcQB4DpC0A
logstash:
host: @logstash.host@
project:
domain: @project.domain@
feieyun:
url: http://api.feieyun.cn/Api/Open/
user: 17777525395@163.com
@ -145,13 +147,36 @@ sf-express:
enable: 2
#拉卡拉进件配置
lakala:
#服务地址
server_url: https://test.wsmsd.cn
#应用Id
app_id: OP00000003
#商户证书序列号
serial_no: 00dfba8194c41b84cf
#商户证书
api_cert_path: payKey/lakala/dev/OP00000003_cert.cer
#商户私钥
api_pri_key_path: payKey/lakala/dev/OP00000003_private_key.pem
#拉卡拉平台证书
lkl_platform_cer_path: payKey/lakala/dev/lkl_notify_cert_v2.cer
#机构代码
org_code: 1
#商户号
merchant_no: 82229007392000A
#终端号
term_no: D9296400
# 拉卡拉拓客进件配置
tk:
#服务地址
server_url: https://test.wsmsd.cn/sit/htkauth
client_id: lsycs
client_secret: XPa1HB5d55Ig0qV8
user_no: 29153396
ratio: 70.00
api_pub_key_path: payKey/lakala/dev/tk_api_public_key.txt
api_pri_key_path: payKey/lakala/dev/tk_api_private_key.txt
notify_pub_key_path: payKey/lakala/dev/tk_notify_public_key.txt
notify_pri_key_path: payKey/lakala/dev/tk_notify_private_key.txt
#e签宝配置
esign:
server_url: https://smlopenapi.esign.cn

View File

@ -133,6 +133,8 @@ getui:
masterSecret: ybdUcVJJKw5bAcQB4DpC0A
logstash:
host: @logstash.host@
project:
domain: @project.domain@
feieyun:
url: http://api.feieyun.cn/Api/Open/
user: 17777525395@163.com
@ -145,13 +147,36 @@ sf-express:
enable: 2
#拉卡拉进件配置
lakala:
#服务地址
server_url: https://test.wsmsd.cn
#应用Id
app_id: OP00000003
#商户证书序列号
serial_no: 00dfba8194c41b84cf
#商户证书
api_cert_path: payKey/lakala/dev/OP00000003_cert.cer
#商户私钥
api_pri_key_path: payKey/lakala/dev/OP00000003_private_key.pem
#拉卡拉平台证书
lkl_platform_cer_path: payKey/lakala/dev/lkl_notify_cert_v2.cer
#机构代码
org_code: 1
#商户号
merchant_no: 82229007392000A
#终端号
term_no: D9296400
# 拉卡拉拓客进件配置
tk:
#服务地址
server_url: https://test.wsmsd.cn/sit/htkauth
client_id: lsycs
client_secret: XPa1HB5d55Ig0qV8
user_no: 29153396
ratio: 70.00
api_pub_key_path: payKey/lakala/dev/tk_api_public_key.txt
api_pri_key_path: payKey/lakala/dev/tk_api_private_key.txt
notify_pub_key_path: payKey/lakala/dev/tk_notify_public_key.txt
notify_pri_key_path: payKey/lakala/dev/tk_notify_private_key.txt
#e签宝配置
esign:
server_url: https://smlopenapi.esign.cn

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.suisung.mall.shop.lakala.mapper.LklBanksMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
*
</sql>
<select id="pageBranchBanksList" resultType="Map">
SELECT c.area_code province_code,c.area_name province_name,
b.area_code city_code,b.area_name city_name,
CONCAT(c.area_code, '/', b.area_code) as district,
CONCAT(c.area_name, '/', b.area_name) as area,
a.bank_no,a.branch_bank_no,a.branch_bank_name,a.branch_bank_no,a.clear_no
FROM lkl_banks a
JOIN lkl_area b on b.area_code=a.area_code
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}
</if>
<if test="branchBankNo!=null and branchBankNo!=''">
and branch_bank_no = #{branchBankNo}
</if>
<if test="branchBankNo!=null and branchBankNo!=''">
and branch_bank_no = #{branchBankNo}
</if>
<choose>
<when test="type!=null and type>0">
and b.type = #{type}
</when>
<otherwise>
and b.type = 2
</otherwise>
</choose>
<if test="keywords!=null and keywords.size>0">
AND (
<foreach collection="keywords" item="keyword" separator="AND">
branch_bank_name LIKE CONCAT('%', #{keyword}, '%')
</foreach>
)
</if>
</where>
</select>
</mapper>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.suisung.mall.shop.store.mapper.ShopMerchEntryMapper">
<mapper namespace="com.suisung.mall.shop.lakala.mapper.LklLedgerEcMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
*

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.suisung.mall.shop.lakala.mapper.LklLedgerMemberMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
*
</sql>
</mapper>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.suisung.mall.shop.lakala.mapper.LklLedgerMerReceiverBindMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
*
</sql>
</mapper>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.suisung.mall.shop.lakala.mapper.LklLedgerReceiverMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
*
</sql>
</mapper>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.suisung.mall.shop.lakala.mapper.LklOrderSeparateMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
*
</sql>
</mapper>

View File

@ -625,7 +625,9 @@
SELECT
ob.order_id,
ob.order_time,
oi.order_time + #{expireSeconds}*1000 as arrival_time,
<if test="delivery!=null and delivery==1">
oi.order_time + #{expireSeconds}*1000 as arrival_time,
</if>
ob.order_product_amount,
ob.order_payment_amount,
ob.currency_id,
@ -714,12 +716,12 @@
<!--进行中-->
<if test="status!=null and status==1 and expireSeconds!=null and expireSeconds>0">
and arrival_time <![CDATA[>=]]> UNIX_TIMESTAMP() * 1000
and (oi.order_time + #{expireSeconds}*1000) <![CDATA[>=]]> UNIX_TIMESTAMP() * 1000
</if>
<!--超时异常-->
<if test="status!=null and status==2 and expireSeconds!=null and expireSeconds>0">
and arrival_time <![CDATA[<]]> UNIX_TIMESTAMP() * 1000
and (oi.order_time + #{expireSeconds}*1000) <![CDATA[<]]> UNIX_TIMESTAMP() * 1000
</if>
<!--退款订单-->

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.suisung.mall.shop.store.mapper.ShopMchEntryMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
*
</sql>
</mapper>

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDYTCCAkmgAwIBAgIJAN+6gZTEG4TPMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
BAYTAlVTMREwDwYDVQQIEwhzaGFuZ2hhaTERMA8GA1UEBxMIc2hhbmdoYWkxFDAS
BgNVBAMUC2xha2FsYV8yMDIxMB4XDTIxMDYxODA3MjEzNFoXDTMxMDYxOTA3MjEz
NFowSTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCHNoYW5naGFpMREwDwYDVQQHEwhz
aGFuZ2hhaTEUMBIGA1UEAxQLbGFrYWxhXzIwMjEwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQDvDBZyHUDndAGxrIcsCV2njhNO3vCEZotTaWYSYwtDvkcA
b1EjsBFabXZaKigpqFXk5XXNI3NIHP9M8XKzIgGvc65NpLAfRjVql8JiTvLyYd1g
IUcOXMInabu+oX7dQSI1mS8XzqaoVRhDZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si
+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbWdhZ+NHwitnQwAJTLBFvfk28INM39G7XO
sXdVLfsooFdglVTOHpNuRiQAj9gShCCNrpGsNQxDiJIxE43qRsNsRwigyo6DPJk/
klgDJa417E2wgP8VrwiXparO4FMzOGK15quuoD7DAgMBAAGjTDBKMAkGA1UdEwQC
MAAwEQYJYIZIAYb4QgEBBAQDAgTwMAsGA1UdDwQEAwIFoDAdBgNVHSUEFjAUBggr
BgEFBQcDAgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAI21YYAlH+Pc1ISv
nbQrGqL8suGL0Hh/8hGaFfrJEJEKr9OeC8jElUhck2MTmfu/Y1lB7r8RBrhGPXi4
kTXmB6ADs/9+ezNW3WXyFj7fhs3JcZ3mo33T9wyQySDKd//JrEtrTsc/s2PZ602y
qNmPomXSzjrlugaMyC7LI9sR44mc7sQnchjHoxrQFD5/usTFW72UQfYCORsQWYMt
0KKEyAcpRL51RE3xbX1WDtduFYGP62PbwLAn2nCL/j1wlF5hltWj7sditWqKgso5
F8BTffn2Bb0RdsNxqwMy1cTPrWLeXVOqMDu3ge7hvoav8lZKTjk5Kmqhs7wNAQXK
mg9qSwo=
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx
rIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M
8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD
ZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW
dhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN
rpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1
5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4
mE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7
qCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK
NXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X
3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK
TPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk
9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH
STTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0
Zr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv
AtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI
RgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke
MzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4
8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP
scd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi
bEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn
Ll2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz
NzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j
Aylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq
CHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6
QsFLQgFyXgvDnzr/o+hQJelW
-----END PRIVATE KEY-----

View File

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEMTCCAxmgAwIBAgIGAXRTgcMnMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNVBAYT
AkNOMRAwDgYDVQQIDAdCZWlKaW5nMRAwDgYDVQQHDAdCZWlKaW5nMRcwFQYDVQQK
DA5MYWthbGEgQ28uLEx0ZDEqMCgGA1UEAwwhTGFrYWxhIE9yZ2FuaXphdGlvbiBW
YWxpZGF0aW9uIENBMB4XDTIwMTAxMDA1MjQxNFoXDTMwMTAwODA1MjQxNFowZTEL
MAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaUppbmcxEDAOBgNVBAcMB0JlaUppbmcx
FzAVBgNVBAoMDkxha2FsYSBDby4sTHRkMRkwFwYDVQQDDBBBUElHVy5MQUtBTEEu
Q09NMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt1zHL54HiI8d2sLJ
lwoQji3/ln0nsvfZ/XVpOjuB+1YR6/0LdxEDMC/hxI6iH2Rm5MjwWz3dmN/6BZeI
gwGeTOWJUZFARo8UduKrlhC6gWMRpAiiGC8wA8stikc5gYB+UeFVZi/aJ0WN0cpP
JYCvPBhxhMvhVDnd4hNohnR1L7k0ypuWg0YwGjC25FaNAEFBYP9EYUyCJjE//9Z7
sMzHR9SJYCqqo6r9bOH9G6sWKuEp+osuAh+kJIxJMHfipw7w3tEcWG0hce9u/el4
cYJtg8/PPMVoccKmeCzMvarr7jdKP4lenJbtwlgyfs+JgNu60KMUJH8RS72wC9NY
uFz09wIDAQABo4HVMIHSMIGSBgNVHSMEgYowgYeAFCnH4DkZPR6CZxRn/kIqVsMo
dJHpoWekZTBjMQswCQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpSmluZzEQMA4GA1UE
BwwHQmVpSmluZzEXMBUGA1UECgwOTGFrYWxhIENvLixMdGQxFzAVBgNVBAMMDkxh
a2FsYSBSb290IENBggYBaiUALIowHQYDVR0OBBYEFJ2Kx9YZfmWpkKFnC33C0r5D
K3rFMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUA
A4IBAQBZoeU0XyH9O0LGF9R+JyGwfU/O5amoB97VeM+5n9v2z8OCiIJ8eXVGKN9L
tl9QkpTEanYwK30KkpHcJP1xfVkhPi/cCMgfTWQ5eKYC7Zm16zk7n4CP6IIgZIqm
TVGsIGKk8RzWseyWPB3lfqMDR52V1tdA1S8lJ7a2Xnpt5M2jkDXoArl3SVSwCb4D
AmThYhak48M++fUJNYII9JBGRdRGbfJ2GSFdPXgesUL2CwlReQwbW4GZkYGOg9LK
CNPK6XShlNdvgPv0CCR08KCYRwC3HZ0y1F0NjaKzYdGNPrvOq9lA495ONZCvzYDo
gmsu/kd6eqxTs/JwdaIYr4sCMg8Z
-----END CERTIFICATE-----

View File

@ -0,0 +1 @@
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKnlpXdmJcbZHxh3w3Ghy/5wXtUBQcFzRMXgw2d7uYjzAzbIQ/ZCAj6srWoN/obtkU+G62kgcpByGmiVtK4LS+BoelKM705SzV+mcr8mNmr2jwNq1SwDSfgVxx5z00FtXl3LnKvCujvGYOmx6+nX8h6IiyyLX6IP6cFaqpUXHsZVAgMBAAECgYA4NpeM7etJ48T6H4Y3LsWEJkH6UDQlgbIblsaQkstMmLtTgOebrzN28UNfd8njcu9FVOrHGclOKbK7L+1cOLiduWsZKc/c/gAy9wAR4EhoLvlerH9EEPiPWFxdEDbMxPqlkpqLOo+PxHrhTn4vU4CaPdJtL2ujKn7nmsUdUDWo8QJBANS1TlM6nhPt2XlzN5kGfsJ4kBYNjuLXNA2YdNuC2ttYvEXHJ9T70FN/GnRBBIZu47uHH3Ie5nfep+qMk6a8RP8CQQDMecIyI0z1kVt+tOfWKw2ZFLsi74708qTaeR4W1ABtkngj1+bxoWWXr3KqhjqJkWxnhioSfXqu7CScNzjdM1CrAkAQd+ESjI1EmbumrYb2cAxMXi05p98SLPs4uj8B58WuCda5yEuLL9vXOxX/PjFtfxRepn2GxmGtki2J+UxNMnJdAkAFoORjlO0tZU7rcfdfwdeh+xwbnhSFUZiQGv1lC3jnizybX/oPdK3jOwUhBIjf+IzPXLYTxDh4UC/BzRNXo235AkEAhgYBk6H7RU2iIuvwz1c6CtE1gJ8DvEp1F0KOMWMFB0KCpDXUToix0dlMz962FozYENi4X4zYQo6nFwlXeS3Pfw==

View File

@ -0,0 +1 @@
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp5aV3ZiXG2R8Yd8Nxocv+cF7VAUHBc0TF4MNne7mI8wM2yEP2QgI+rK1qDf6G7ZFPhutpIHKQchpolbSuC0vgaHpSjO9OUs1fpnK/JjZq9o8DatUsA0n4Fccec9NBbV5dy5yrwro7xmDpsevp1/IeiIssi1+iD+nBWqqVFx7GVQIDAQAB

View File

@ -0,0 +1 @@
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALKb2r7+J9aS9/aiDblUUlkMfU6XdIasmEm/GWVOAoIS+CGV+qItHrZ2uIxbdHGlQY0HBGGnPYNUDGipzQtgrEpzWFXvBkmO1tVLdUE5ZuQ6/6pzFgGJTOi9+ujSKE4hbPbTJ4y+/1qqVLypSV51j7m2QZREns8biKzuxKNRzDZFAgMBAAECgYAXLWtq+n8/9I1x92CRirQu8xR1tOi9qzsN4tsQTtm7eGuzrAs8rV89bVWQfTO0pa3Gd8ElTPcKCkeb82D014Qz4z7sLz3reNeYXay8PbCCegQxUn7xzykwckziydKw4cCBZQkmyCYtUZcyf+C2Z+0dX6dTO3Z7+/se0ndJleAbFwJBAO9omFP3+lxxXQgyv99+IJTRFp+xWZnfjWREU8aZQXy+QU1LYCxMafpaIJMOu4qwo1XwfLKelAuLc2kLQMhrEkcCQQC+/Jie67sp744bw2dBWo8LrghvIaPxkH9Sgkce3qHUPx4cK+tF/GtfujB4kKDhpQb4nEJtLhPEBjslL0bWkc0TAkAoRHBylx/+EncyXM7W+XDjdvOWMo8+iVJPzgpFOhvAroNvS8FGUif1GtmlwnGa1zDx0Hw40uFVu8PSpDjmPNQbAkEAsHBpiv/aVB6kmY+HF8BSwIaR8iEQ9Tz58z6595HTzWJWLc6BN5G/nJtE5k0u4+byrsClOXpE9maPQ4YOmnHuEwJAIEYvcN2Ju3on5wglbH2b9889zzg1P9z/1GbFPpi2kZeOZre2HQfojoU686oGBdvDe0BK6+jgir1hzwfJBB7fvQ==

View File

@ -0,0 +1 @@
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCym9q+/ifWkvf2og25VFJZDH1Ol3SGrJhJvxllTgKCEvghlfqiLR62driMW3RxpUGNBwRhpz2DVAxoqc0LYKxKc1hV7wZJjtbVS3VBOWbkOv+qcxYBiUzovfro0ihOIWz20yeMvv9aqlS8qUledY+5tkGURJ7PG4is7sSjUcw2RQIDAQAB

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDoDCCAoigAwIBAgIGAZSCuCxUMA0GCSqGSIb3DQEBBQUAMGAxFDASBgNVBAMM
C0xBS0FMQS1MQU9QMQswCQYDVQQGEwJDTjEXMBUGA1UECgwOTGFrYWxhIENvLixM
dGQxDzANBgNVBAsMBkxLTC1ZRjERMA8GA1UEBwwIc2hhbmdoYWkwHhcNMjUwMTIw
MDc1ODE1WhcNMzUwMTIwMDc1ODE1WjBgMRQwEgYDVQQDDAtMQUtBTEEtTEFPUDEL
MAkGA1UEBhMCQ04xFzAVBgNVBAoMDkxha2FsYSBDby4sTHRkMQ8wDQYDVQQLDAZM
S0wtWUYxETAPBgNVBAcMCHNoYW5naGFpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAksIeSx7qKgmI7yFSglMBsty3ZoyC8qsCbLSWANwUPYikd5TPojB8
43wJGJxOBOtDV8FL55q0zX3eQOE4BOVGcDMMUsZsAhy4ST46ne4e8CFVFHmM6TON
tS5Kla0hLjETpUjYStR8En534uoLYvnNPAI1CvmvWiUo+QGd3yc2SmyE+XB/8bKk
wiLjAauGyfb8m2BgCaoBIai+0IImInX2Xb85L0TAu0eYC6fX1T8BCupA4EVOpvLL
cM5P8nye4mibgS46lzlve1soC73W1vGAHnMw4epzk89NHKIMYEmZPoCU6jKuDbR0
K73QwU0QZt9MSJnTdnWt/PeUJ8PzkhV0RQIDAQABo2AwXjAPBgNVHRMECDAGAQH/
AgEAMB8GA1UdIwQYMBaAFG1rabju/OE7B3cPuQFZhs77ku5qMB0GA1UdDgQWBBRt
a2m47vzhOwd3D7kBWYbO+5LuajALBgNVHQ8EBAMCBsAwDQYJKoZIhvcNAQEFBQAD
ggEBACzdFsulR2X6HPKX+D2VU7msJyXRVWrAi06SV/zds8lPYUwSTEksbpWejD5L
ABftyv5DL7bU66vL80she2r5d+DbY+gB2hAgRHW+ymzfAqQJOcpciAXZHxc4orf+
V4YtmLIRT0lg9rfU93D4S9fPe+HHMAmKFQXjnZNiv7DOar62MP0RrI74hWevaZao
gK8cMspxUW7H9VFvJvgGZRTRXVFHIvaPOpvlsdCYfUDomH2sWVLIiaSQoAVXxoET
c0HJB0er7Df2PSBSF/8bl9cVmp5HDB2YgtlfNKaFneGNN2WQtO3gl56heud8hGAe
F4YZkE8ML2mh83QqVSY4AkfWo+0=
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCSwh5LHuoqCYjv
IVKCUwGy3LdmjILyqwJstJYA3BQ9iKR3lM+iMHzjfAkYnE4E60NXwUvnmrTNfd5A
4TgE5UZwMwxSxmwCHLhJPjqd7h7wIVUUeYzpM421LkqVrSEuMROlSNhK1HwSfnfi
6gti+c08AjUK+a9aJSj5AZ3fJzZKbIT5cH/xsqTCIuMBq4bJ9vybYGAJqgEhqL7Q
giYidfZdvzkvRMC7R5gLp9fVPwEK6kDgRU6m8stwzk/yfJ7iaJuBLjqXOW97WygL
vdbW8YAeczDh6nOTz00cogxgSZk+gJTqMq4NtHQrvdDBTRBm30xImdN2da3895Qn
w/OSFXRFAgMBAAECggEACN60qAOpUXscDJ/t9bSAoMfYSdlqPLJ7RgiwHEMw8fsl
PZj/56SYl8MyZYtk58U0X8RuCwR9swHNggxar2kQFc3wC7y0YHhN5xdcwZjXw9mv
47no+1tDUFUI6vz4yWrr7gx2DifDi/aa1lsg7w18CwlzHUO0BnXCgTJI0Wj0ThEj
k3AxCv41a4dwQW2EejaikMdzkWv7p9cG1cjJocBvaURg8RZrw2v1lqXx9iZb5Ywv
XkQP907AAnUn40bLgQ7hyUruxjKPzIM5ZjIER6PTtvGk1Uzt7Kj2YZZ4egYp0PXv
5fEJIcppeIyGfatEZ4U/ZmfA0L7+xtSY8kICndPSTQKBgQDHy5n6N6JdYyyrVFH/
x4xTHwyiReOzw5Pz2K9uSxZM6pmDWfZexAxkpMycQotZYOk6GYDqml5XAiXAYVKn
i9FCEC6PnFRZ/v7TN3ag3k8eXwLrQu589+X0ppOizIp01IQ8AWAUr1tA/UcqLt8T
5XSHnoEDo9SY9Aw1kskY5TWoowKBgQC8CwRxfFNWk3Na+U4HgvVv8CSrB7rbkLUI
L11jNKFx4xms8uIjBrIencHsRAazoG73wMsY7MzbPtJKIFcXmSKjLFClJ6luN9np
1tYkWXF/nyo6L2IhCG7N28sxYa56XTR0lDnfkW+LiI7iaC1Z+XUtxoY3ZIL+0Dbv
wCfYS2I19wKBgQCtoRjtRJALzHYzZpHkUQx36BHYrBgYTy0yyuqaVRLKQU6rwfDD
pmiGxlkyqvni8L9+yE8qkoDN6IXaTDnCdVWjreBo2ZjMpTfbYuXrI4dqg3NL9NzB
KcZj+Kdw4YSpx04rv546G7KYJgREentPFSdR/MNt4GCPk/dQT4IH6pnZNQKBgQC2
esKPFqURCPoSuIf+RhnDzPjoeBHe7KihDsXDddmN2WKbMQA+GUtU5qa/jqwqOHA3
QQJWZ8XMpUQQ5x1dKyAv1NtVyg1jhhOUFwWsNJgtztl9qWnCwJo2byrZ+v8Eg9pZ
n1YiHNJwR87Q62PHQotyJossyf9NI+WL958zCMR/tQKBgCTDIKnfjq4riVLEOLxl
oGzGMowFTp9v8dyvrYj71C0ZDzLg/EH1tTQ4K46GIXJfyZvIATAIisC6R37KNmUA
w8f6YAOSS+iZBSZo36DoGIqJTYGyYgQDDftMsj/gxthgwRO5Zhwbn63ayJkWYyPy
C1RJ27LO8qX+3/s5pV7G9GlO
-----END PRIVATE KEY-----

View File

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEMTCCAxmgAwIBAgIGAXUrc4b4MA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNVBAYT
AkNOMRAwDgYDVQQIDAdCZWlKaW5nMRAwDgYDVQQHDAdCZWlKaW5nMRcwFQYDVQQK
DA5MYWthbGEgQ28uLEx0ZDEqMCgGA1UEAwwhTGFrYWxhIE9yZ2FuaXphdGlvbiBW
YWxpZGF0aW9uIENBMB4XDTIwMTAxNTA4NDk1MloXDTMwMTAxMzA4NDk1MlowZTEL
MAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaUppbmcxEDAOBgNVBAcMB0JlaUppbmcx
FzAVBgNVBAoMDkxha2FsYSBDby4sTHRkMRkwFwYDVQQDDBBBUElHVy5MQUtBTEEu
Q09NMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwAXZw9lupWcFXouC
Nhm0DQT47Zf4KOIRF8rqT8Ps3pYzT8odROJ8rq4P+lciGrg29czpqrRM22yQktFr
itvcM7JlE6jFbGH3rycnvGvhRYU/j1N9k0ozm8oVwmKX357/OtGzNivBECGSnU9L
Bkp4Nm9M1K4cOwEuZ0xsQEthZjQYF0mDpnlWmVJL5i1Lq834atN2qrb/mzMHBNtD
JnqRV7rPL39lKpe7LJiitsC2JuW1UbWZZU1NNwA/rz2d83C+KD1DLJ0+sMYY2Q3T
OQ4BPAowDEwOH7XAXrHM/0kRm+ZeIFlwevEGIQWmMt1Ogz+AW4Iq0slINc4wOINK
vH9tHwIDAQABo4HVMIHSMIGSBgNVHSMEgYowgYeAFCnH4DkZPR6CZxRn/kIqVsMo
dJHpoWekZTBjMQswCQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpSmluZzEQMA4GA1UE
BwwHQmVpSmluZzEXMBUGA1UECgwOTGFrYWxhIENvLixMdGQxFzAVBgNVBAMMDkxh
a2FsYSBSb290IENBggYBaiUALIowHQYDVR0OBBYEFIya0Yc4OSBer55JLyA0AYe9
m8mTMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUA
A4IBAQCBEwOlk3mXigNv94Drn3dcaY2ml/y+8yNpAIuUhuBE00WFoqEX5lOatFy5
fzdXuC12lBVQ8SjSm3aH7k2X0eXqDzkOHiur2ZBRKmJ++J4TeenuSUOjSIbQK/DT
vxaqFUjYwFSVCyizpy7wfU4wKt+jOuFb9LyULJ9lkM1dV9Kh7Lmd9+nlJYYuPEPU
LJkkVZqSALSiiJudXnTwlISjZTXEAkJpdIlMw+hvPTAkoG95B95M+OV/uLbItGK+
qT4+RHWo8EbBDPQYo6J4QYHOxRlfMoGBMyrz6XDt7ELLmT7ld4aE02w6KQPfK3gq
kLDT+/STozvaNmXzBJh7J6KqxJBH
-----END CERTIFICATE-----

View File

@ -0,0 +1 @@
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKnlpXdmJcbZHxh3w3Ghy/5wXtUBQcFzRMXgw2d7uYjzAzbIQ/ZCAj6srWoN/obtkU+G62kgcpByGmiVtK4LS+BoelKM705SzV+mcr8mNmr2jwNq1SwDSfgVxx5z00FtXl3LnKvCujvGYOmx6+nX8h6IiyyLX6IP6cFaqpUXHsZVAgMBAAECgYA4NpeM7etJ48T6H4Y3LsWEJkH6UDQlgbIblsaQkstMmLtTgOebrzN28UNfd8njcu9FVOrHGclOKbK7L+1cOLiduWsZKc/c/gAy9wAR4EhoLvlerH9EEPiPWFxdEDbMxPqlkpqLOo+PxHrhTn4vU4CaPdJtL2ujKn7nmsUdUDWo8QJBANS1TlM6nhPt2XlzN5kGfsJ4kBYNjuLXNA2YdNuC2ttYvEXHJ9T70FN/GnRBBIZu47uHH3Ie5nfep+qMk6a8RP8CQQDMecIyI0z1kVt+tOfWKw2ZFLsi74708qTaeR4W1ABtkngj1+bxoWWXr3KqhjqJkWxnhioSfXqu7CScNzjdM1CrAkAQd+ESjI1EmbumrYb2cAxMXi05p98SLPs4uj8B58WuCda5yEuLL9vXOxX/PjFtfxRepn2GxmGtki2J+UxNMnJdAkAFoORjlO0tZU7rcfdfwdeh+xwbnhSFUZiQGv1lC3jnizybX/oPdK3jOwUhBIjf+IzPXLYTxDh4UC/BzRNXo235AkEAhgYBk6H7RU2iIuvwz1c6CtE1gJ8DvEp1F0KOMWMFB0KCpDXUToix0dlMz962FozYENi4X4zYQo6nFwlXeS3Pfw==

View File

@ -0,0 +1 @@
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp5aV3ZiXG2R8Yd8Nxocv+cF7VAUHBc0TF4MNne7mI8wM2yEP2QgI+rK1qDf6G7ZFPhutpIHKQchpolbSuC0vgaHpSjO9OUs1fpnK/JjZq9o8DatUsA0n4Fccec9NBbV5dy5yrwro7xmDpsevp1/IeiIssi1+iD+nBWqqVFx7GVQIDAQAB

View File

@ -0,0 +1 @@
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJDy8KWN4t65ifbOrCx+oChGorxzTVzh5RCeOCSS/0LJ57Qoc8BZ+xLyphtITtHtcIRY39cYFmSfjTLnNMV/Y+FC47EeBbDKiiIKg06o3/X+/sW+J9FNQs+6H7L15o9j1P0P0h8bo/cs3T88m9r57JMr3Vb3P/iTE4+6XT4HHRXvAgMBAAECgYAeZCGaxKYVxtcrfWfSKHaSG0VRt+c3m1F464Of/4Yvzb+cIYMriHJBJck4HTARifQ2e5/rLGy9ikqDqsCAzFX3e0/OG9wvvyodCoWYwVy37Zus5HqmYyndhdQGpTvw8lNVA90iOU5q5z8DxKc9iuiPLW0MCpgvQ6Xjsv/vBN3KqQJBAMTODXlM8kfsRaSs5YzSyamrcxruD3x0+vrHtkyR9e5Q+KWu1WcsFeRcRRXwtJYg8+9KiRB/fFOKRCowhzKYciUCQQC8i/18QEAPL3jczJsYe/Zt9lRK9qJjwXdgsPAsm5iwsv8oPUtWEykI+ct89twzbdXJYK4M1AM6d0qwit8rK+mDAkEAhlNJWQCO4U4/no0vxDVe1UKjNr9DrKO/ZgmHwK1jGT0E6TjyiQ/LBWmA8d+vskRdmnbaJHuPJQnbSpyCuqLYTQJBAIv3dC6n16YuPI/UyBIN/Cs3YO3hVz2soj1CPJkwzNHnnyk1D1cPlDfYj+ntrBv1nm4G+k4FmXvukKCsBu2ahJcCQBMBld8cpapoiou+oCeMay+W1W8kxsvwI4pW602FCecE2XJwWjvc/eht0D3j5F8wIvVxlzvX9lkZ5GYpEQBsIuw=

View File

@ -0,0 +1 @@
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQ8vCljeLeuYn2zqwsfqAoRqK8c01c4eUQnjgkkv9Cyee0KHPAWfsS8qYbSE7R7XCEWN/XGBZkn40y5zTFf2PhQuOxHgWwyooiCoNOqN/1/v7FvifRTULPuh+y9eaPY9T9D9IfG6P3LN0/PJva+eyTK91W9z/4kxOPul0+Bx0V7wIDAQAB