解决循环依赖问题,异步方法引起的,独立文件出来

This commit is contained in:
Jack 2025-09-02 10:26:22 +08:00
parent e45a1df7a1
commit 5a913ce465
5 changed files with 197 additions and 37 deletions

View File

@ -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;

View File

@ -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;
// }
// }
}

View File

@ -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&&currentUser.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();

View File

@ -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;
}
}
}

View File

@ -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 {