解决循环依赖问题,异步方法引起的,独立文件出来
This commit is contained in:
parent
e45a1df7a1
commit
5a913ce465
@ -48,9 +48,11 @@ import java.util.Map;
|
||||
@RequestMapping("/mobile/account/login")
|
||||
public class LoginController extends BaseControllerImpl {
|
||||
|
||||
// @Lazy
|
||||
@Autowired
|
||||
private AccountUserBaseService accountUserBaseService;
|
||||
|
||||
// @Lazy
|
||||
@Autowired
|
||||
private AccountUserInfoService accountUserInfoService;
|
||||
|
||||
|
||||
@ -68,7 +68,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -109,8 +108,6 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
@Autowired
|
||||
private ShopService shopService;
|
||||
@Autowired
|
||||
private PayService payService;
|
||||
@ -140,11 +137,15 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
|
||||
private AccountUserChannelCodeService accountUserChannelCodeService;
|
||||
@Autowired
|
||||
private AccountUserBaseMapper accountUserBaseMapper;
|
||||
@Autowired
|
||||
private I18nUtil i18nUtil;
|
||||
@Resource
|
||||
private AccountUserBindGeTuiService accountUserBindGeTuiService;
|
||||
|
||||
@Autowired
|
||||
private AsyncTaskService asyncTaskService;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
|
||||
@Override
|
||||
public CommonResult login(Map<String, String> params) {
|
||||
@ -2995,7 +2996,7 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
|
||||
CommonResult result = doMobileBindLogin(verifyMobile, CommonConstant.USER_TYPE_MCH, cid, osType);
|
||||
if (result.getStatus() == 200) {
|
||||
// 登录成功之后,异步检查并修复商户店铺信息
|
||||
checkAndFixMchStoreInfo(PhoneNumberUtils.cleanPhoneNumber(user_mobile));
|
||||
asyncTaskService.checkAndFixMchStoreInfo(PhoneNumberUtils.cleanPhoneNumber(user_mobile));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -3819,21 +3820,21 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
|
||||
* @param loginMobile 登录手机号
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Async
|
||||
protected Boolean checkAndFixMchStoreInfo(String loginMobile) {
|
||||
try {
|
||||
// 调用shop服务检查并修复商户店铺信息
|
||||
Boolean result = shopService.checkAndFixMchStoreInfo(loginMobile);
|
||||
// 记录处理结果日志
|
||||
logger.info("商户店铺信息检查与修复完成,手机号: {},结果: {}", loginMobile, result);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
// 捕获所有异常,防止影响主流程
|
||||
logger.error("检查并修复商户店铺信息时发生异常,手机号: {}", loginMobile, e);
|
||||
// 发生异常时返回false,不影响主流程
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// @Async
|
||||
// public Boolean checkAndFixMchStoreInfo(String loginMobile) {
|
||||
// try {
|
||||
// // 调用shop服务检查并修复商户店铺信息
|
||||
// Boolean result = shopService.checkAndFixMchStoreInfo(loginMobile);
|
||||
// // 记录处理结果日志
|
||||
// logger.info("商户店铺信息检查与修复完成,手机号: {},结果: {}", loginMobile, result);
|
||||
// return result;
|
||||
// } catch (Exception e) {
|
||||
// // 捕获所有异常,防止影响主流程
|
||||
// logger.error("检查并修复商户店铺信息时发生异常,手机号: {}", loginMobile, e);
|
||||
// // 发生异常时返回false,不影响主流程
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ import io.seata.spring.annotation.GlobalTransactional;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -56,38 +57,29 @@ import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
|
||||
@Service
|
||||
public class AccountUserInfoServiceImpl extends BaseServiceImpl<AccountUserInfoMapper, AccountUserInfo> implements AccountUserInfoService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AccountUserInfoServiceImpl.class);
|
||||
@Autowired
|
||||
private AccountUserBaseService accountUserBaseService;
|
||||
|
||||
@Autowired
|
||||
private AccountUserLoginService accountUserLoginServicel;
|
||||
|
||||
@Autowired
|
||||
private AccountUserLevelLogService accountUserLevelLogService;
|
||||
|
||||
@Autowired
|
||||
private AccountBaseUserLevelService accountBaseUserLevelService;
|
||||
|
||||
@Autowired
|
||||
private AccountBaseConfigService accountBaseConfigService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopService shopService;
|
||||
|
||||
@Autowired
|
||||
private AccountUserSnsService accountUserSnsService;
|
||||
|
||||
@Autowired
|
||||
private ShopUserExpHistoryService shopUserExpHistoryService;
|
||||
|
||||
@Autowired
|
||||
private AccountUserInfoService accountUserInfoService;
|
||||
|
||||
@Autowired
|
||||
private PayService payService;
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(AccountUserInfoServiceImpl.class);
|
||||
|
||||
/**
|
||||
* 实名认证页面
|
||||
*
|
||||
@ -749,7 +741,7 @@ public class AccountUserInfoServiceImpl extends BaseServiceImpl<AccountUserInfoM
|
||||
|
||||
// 当前积分
|
||||
AccountUserInfo user_info_row = get(user_id);
|
||||
Long user_exp_total = ObjectUtil.defaultIfNull(user_info_row.getUser_exp_total(), 0l);
|
||||
Long user_exp_total = ObjectUtil.defaultIfNull(user_info_row.getUser_exp_total(), 0L);
|
||||
|
||||
expHistory.setUser_exp(user_exp_total);
|
||||
if (!shopUserExpHistoryService.saveOrUpdate(expHistory)) {
|
||||
@ -811,7 +803,7 @@ public class AccountUserInfoServiceImpl extends BaseServiceImpl<AccountUserInfoM
|
||||
|
||||
UserDto currentUser = getCurrentUser();
|
||||
|
||||
if ((currentUser!=null&¤tUser.getClient_id().equals(AuthConstant.ADMIN_CLIENT_ID)) && ConfigConstant.URL_BASE.equals("https://demo.lancerdt.com")) {
|
||||
if ((currentUser != null && currentUser.getClient_id().equals(AuthConstant.ADMIN_CLIENT_ID)) && ConfigConstant.URL_BASE.equals("https://demo.lancerdt.com")) {
|
||||
for (AccountUserInfo it : list) {
|
||||
if (ObjectUtil.isNotEmpty(it)) {
|
||||
String phoneNumber = it.getUser_mobile();
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.account.service.impl;
|
||||
|
||||
import com.suisung.mall.common.feignService.ShopService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class AsyncTaskService {
|
||||
|
||||
private final ShopService shopService;
|
||||
private final Logger logger = LoggerFactory.getLogger(AsyncTaskService.class);
|
||||
|
||||
/**
|
||||
* 异步检查并修复商户店铺信息
|
||||
*
|
||||
* @param loginMobile 登录手机号
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Async
|
||||
public Boolean checkAndFixMchStoreInfo(String loginMobile) {
|
||||
try {
|
||||
// 调用shop服务检查并修复商户店铺信息
|
||||
Boolean result = shopService.checkAndFixMchStoreInfo(loginMobile);
|
||||
// 记录处理结果日志
|
||||
logger.info("商户店铺信息检查与修复完成,手机号: {},结果: {}", loginMobile, result);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
// 捕获所有异常,防止影响主流程
|
||||
logger.error("检查并修复商户店铺信息时发生异常,手机号: {}", loginMobile, e);
|
||||
// 发生异常时返回false,不影响主流程
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,7 +5,9 @@ import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSON;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.nacos.common.util.Md5Utils;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
@ -36,6 +38,7 @@ import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -187,7 +190,6 @@ public class WxQrCodeServiceImpl implements WxQrCodeService {
|
||||
byte[] bytes = outputStream.toByteArray();
|
||||
if (bytes.length < 9999) {
|
||||
return Pair.of("", I18nUtil._("图片生成失败,参数有误!"));
|
||||
// return CommonResult.failed(I18nUtil._("图片生成失败,参数有误!"));
|
||||
}
|
||||
|
||||
|
||||
@ -217,7 +219,6 @@ public class WxQrCodeServiceImpl implements WxQrCodeService {
|
||||
resultMap.put("wxQrCodeUrl", wxQrCodeUrl);
|
||||
resultMap.put("fileName", fileName);
|
||||
return Pair.of(wxQrCodeUrl, "");
|
||||
// return CommonResult.success(resultMap);
|
||||
}
|
||||
|
||||
// 存入本地文件
|
||||
@ -227,12 +228,129 @@ public class WxQrCodeServiceImpl implements WxQrCodeService {
|
||||
resultMap.put("fileName", fileName);
|
||||
return Pair.of(poster_path + fileName, "");
|
||||
} catch (Exception e) {
|
||||
// return CommonResult.failed(I18nUtil._("图片生成错误!"));
|
||||
return Pair.of("", I18nUtil._("图片生成错误"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成永久微信公众号二维码(无过期时间)
|
||||
* <p>
|
||||
* 官方文档地址:https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html
|
||||
*
|
||||
* @param sceneId 场景值ID(整数形式的ID),范围是1-100000
|
||||
* scene_id: 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)
|
||||
* 说明:
|
||||
* 1. 每次创建二维码ticket需要提供一个开发者自行设定的参数(scene_id 或 scene_str)
|
||||
* 2. 永久二维码的scene_id参数值必须是大于0且小于100000的整数
|
||||
* 3. 同一个access_token和scene_id或scene_str生成的二维码ticket是相同的,扫描后推送的事件中的eventkey值也相同
|
||||
* 4. 开发者可通过事件推送接口接收用户扫描二维码的事件,并根据scene_id或scene_str做相应的业务处理
|
||||
* @return Pair<二维码图片URL, 错误信息>
|
||||
*/
|
||||
public Pair<String, String> genWechatLimitQrCode(Integer sceneId) {
|
||||
try {
|
||||
// 参数校验
|
||||
if (sceneId == null || sceneId <= 0 || sceneId > 100000) {
|
||||
return Pair.of("", I18nUtil._("场景值ID必须是1-100000之间的整数"));
|
||||
}
|
||||
|
||||
// 获取access_token
|
||||
String accessToken = wxUtil.getAccessToken();
|
||||
if (StrUtil.isBlank(accessToken)) {
|
||||
return Pair.of("", I18nUtil._("获取微信access_token失败"));
|
||||
}
|
||||
|
||||
// 微信生成二维码的接口URL(使用A接口-永久二维码)
|
||||
String reqUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + accessToken;
|
||||
|
||||
// 构造请求参数
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("action_name", "QR_LIMIT_SCENE"); // 永久整数参数二维码
|
||||
|
||||
Map<String, Object> actionInfo = new HashMap<>();
|
||||
Map<String, Object> scene = new HashMap<>();
|
||||
scene.put("scene_id", sceneId);
|
||||
actionInfo.put("scene", scene);
|
||||
params.put("action_info", actionInfo);
|
||||
|
||||
String paramStr = JSONUtil.toJsonStr(params);
|
||||
|
||||
// 发送请求获取ticket
|
||||
String responseStr = HttpUtil.post(reqUrl, paramStr);
|
||||
JSONObject responseJson = JSONUtil.parseObj(responseStr);
|
||||
|
||||
if (responseJson.containsKey("errcode") && responseJson.getInt("errcode") != 0) {
|
||||
String errorMsg = responseJson.getStr("errmsg", I18nUtil._("生成二维码失败"));
|
||||
log.error("生成微信永久二维码失败,错误码:{},错误信息:{}", responseJson.getInt("errcode"), errorMsg);
|
||||
return Pair.of("", errorMsg);
|
||||
}
|
||||
|
||||
String ticket = responseJson.getStr("ticket");
|
||||
if (StrUtil.isBlank(ticket)) {
|
||||
return Pair.of("", I18nUtil._("获取二维码ticket失败"));
|
||||
}
|
||||
|
||||
// 使用ticket换取二维码图片
|
||||
String qrCodeUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + URLEncoder.encode(ticket, "UTF-8");
|
||||
|
||||
// 生成文件名
|
||||
String fileName = "limit_" + sceneId + "_qrcode.jpg";
|
||||
|
||||
// 下载二维码图片
|
||||
byte[] qrCodeBytes = HttpUtil.downloadBytes(qrCodeUrl);
|
||||
|
||||
if (qrCodeBytes == null || qrCodeBytes.length == 0) {
|
||||
return Pair.of("", I18nUtil._("下载二维码图片失败"));
|
||||
}
|
||||
|
||||
// 保存二维码图片
|
||||
Map<String, Object> resultMap = new HashMap<>();
|
||||
String wxQrCodeUrl = "";
|
||||
|
||||
if (!ConfigConstant.FILE_STORAGE_DISK) {
|
||||
// 存入第三方文件存储服务
|
||||
InputStream stream = new ByteArrayInputStream(qrCodeBytes);
|
||||
String dir = "/media/plantform";
|
||||
|
||||
Integer uploadType = accountBaseConfigService.getConfig("upload", 1);
|
||||
|
||||
if (uploadType.equals(1)) {
|
||||
wxQrCodeUrl = ConfigConstant.URL_BASE + "/admin/oss/upload" + dir + "/" + fileName;
|
||||
} else if (uploadType.equals(2)) {
|
||||
// oss 服务
|
||||
String folder = ALIYUN_OSS_DIR_PREFIX.concat("/").concat(dir).concat("/qrcode/");
|
||||
wxQrCodeUrl = ossService.uploadObject2OSS(null, folder + fileName, stream, fileName, Convert.toLong(qrCodeBytes.length));
|
||||
} else if (uploadType.equals(4)) {
|
||||
String qrcodePath = String.format("%s/media/plantform/qrcode/%s/", ConfigConstant.STATIC_FILE_PATH, 2);
|
||||
IoUtil.write(FileUtil.getOutputStream(qrcodePath + fileName), true, qrCodeBytes);
|
||||
File qrcodeFile = FileUtil.file(qrcodePath + fileName);
|
||||
wxQrCodeUrl = ossService.uploadObject4OSS(qrcodeFile, TENGXUN_DEFAULT_DIR.concat(dir).concat("/").concat(fileName));
|
||||
}
|
||||
} else {
|
||||
// 存入本地文件
|
||||
String qrcodePath = String.format("%s/media/plantform/qrcode/%s/", ConfigConstant.STATIC_FILE_PATH, 2);
|
||||
File qrcodeDir = new File(qrcodePath);
|
||||
if (!qrcodeDir.exists()) {
|
||||
qrcodeDir.mkdirs();
|
||||
}
|
||||
IoUtil.write(FileUtil.getOutputStream(qrcodePath + fileName), true, qrCodeBytes);
|
||||
wxQrCodeUrl = ConfigConstant.URL_BASE + "/media/plantform/qrcode/" + 2 + "/" + fileName;
|
||||
}
|
||||
|
||||
resultMap.put("wxQrCodeUrl", wxQrCodeUrl);
|
||||
resultMap.put("fileName", fileName);
|
||||
resultMap.put("ticket", ticket);
|
||||
|
||||
log.info("成功生成微信永久二维码,sceneId: {}, 二维码URL: {}", sceneId, wxQrCodeUrl);
|
||||
return Pair.of(wxQrCodeUrl, "");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("生成微信永久二维码时发生异常,sceneId: {}", sceneId, e);
|
||||
return Pair.of("", I18nUtil._("生成二维码错误: ") + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map genUnlimitedWxQrCode(String preparedUrl, Map param) {
|
||||
try {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user