|
|
@@ -2,35 +2,49 @@ package com.ylx.point.service.impl;
|
|
|
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.ObjUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.TypeReference;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.ylx.common.core.domain.model.WxLoginUser;
|
|
|
import com.ylx.common.exception.ServiceException;
|
|
|
+import com.ylx.common.utils.SecurityUtils;
|
|
|
+import com.ylx.lottery.domain.vo.LotteryCountResponseVO;
|
|
|
import com.ylx.massage.domain.TWxUser;
|
|
|
import com.ylx.massage.service.TWxUserService;
|
|
|
import com.ylx.point.domain.PointActivity;
|
|
|
import com.ylx.point.domain.PointActivityExpirePolicy;
|
|
|
import com.ylx.point.domain.PointUserLog;
|
|
|
import com.ylx.point.domain.dto.ApiAddPointsDTO;
|
|
|
-import com.ylx.point.enums.TaskNameEnum;
|
|
|
import com.ylx.point.enums.PointActivityExpirePolicyEnum;
|
|
|
+import com.ylx.point.enums.TaskNameEnum;
|
|
|
import com.ylx.point.mapper.PointUserLogMapper;
|
|
|
import com.ylx.point.service.IPointAccountService;
|
|
|
import com.ylx.point.service.IPointActivityExpirePolicyService;
|
|
|
import com.ylx.point.service.IPointActivityService;
|
|
|
import com.ylx.point.service.IPointUserLogService;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
import java.time.LocalDateTime;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Optional;
|
|
|
+import java.util.*;
|
|
|
|
|
|
@Slf4j
|
|
|
@Service
|
|
|
public class PointAccountServiceImpl implements IPointAccountService {
|
|
|
|
|
|
+ @Value("${remote.local-live.base-url}")
|
|
|
+ private String localLiveBaseUrl;
|
|
|
+
|
|
|
+ // 定义接口路径常量
|
|
|
+ private static final String POINT_SEND_PATH = "/lottery/lotteryActivity/sendGYYPoint";
|
|
|
+ private static final int DEFAULT_TIMEOUT = 5000; // 5秒超时
|
|
|
+
|
|
|
@Resource
|
|
|
private IPointUserLogService pointUserLogService;
|
|
|
@Resource
|
|
|
@@ -252,6 +266,46 @@ public class PointAccountServiceImpl implements IPointAccountService {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void draw() {
|
|
|
+
|
|
|
+ WxLoginUser loginUser = SecurityUtils.getWxLoginUser();
|
|
|
+ if (ObjectUtil.isNull(loginUser)) {
|
|
|
+ throw new ServiceException("用户未登录或登录已过期");
|
|
|
+ }
|
|
|
+
|
|
|
+ String localLiveUserId = loginUser.getLocalLiveUserId();
|
|
|
+ Integer isBind = loginUser.getIsBind();
|
|
|
+ String openId = loginUser.getCOpenid();
|
|
|
+
|
|
|
+ if (ObjectUtil.isNotNull(isBind) && (ObjectUtil.equals(isBind, 1) && ObjectUtil.isNotNull(localLiveUserId))) {
|
|
|
+ Integer points = pointSend(localLiveUserId);
|
|
|
+ // 1. 获取当前余额 (变动前)
|
|
|
+ Integer currentBalance = getBalance(openId);
|
|
|
+
|
|
|
+ // 2. 写入积分流水表 (point_user_log)
|
|
|
+ PointUserLog log = new PointUserLog();
|
|
|
+ log.setOpenId(openId);
|
|
|
+ log.setTaskType(3);
|
|
|
+ log.setPoints(points);
|
|
|
+ log.setOpType(1); // 1-收入
|
|
|
+ log.setIsExpired(0);
|
|
|
+ log.setActivityName(TaskNameEnum.LOCAL_LIVE_LOTTERY.getInfo());
|
|
|
+ log.setMonth(DateUtil.format(new Date(), "yyyyMM"));
|
|
|
+
|
|
|
+ // 计算变动后余额 (快照)
|
|
|
+ Integer newBalance = currentBalance + points;
|
|
|
+ log.setBalanceAfter(newBalance);
|
|
|
+
|
|
|
+ boolean saveSuccess = pointUserLogService.save(log);
|
|
|
+ if (!saveSuccess) {
|
|
|
+ throw new ServiceException("积分流水记录失败");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new ServiceException("用户未绑定本地生活账号");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 获取用户当前可用积分余额
|
|
|
* 逻辑:未过期收入总和 + 支出总和(支出为负数,直接相加)
|
|
|
@@ -324,4 +378,51 @@ public class PointAccountServiceImpl implements IPointAccountService {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ private Integer pointSend(String userId) {
|
|
|
+ try {
|
|
|
+ // 1. 构建请求参数
|
|
|
+ String url = localLiveBaseUrl + POINT_SEND_PATH;
|
|
|
+ Map<String, Object> params = Collections.singletonMap("userId", userId);
|
|
|
+
|
|
|
+ // 2. 发送请求
|
|
|
+ String resultJson = HttpUtil.get(url, params, DEFAULT_TIMEOUT);
|
|
|
+
|
|
|
+ // 3. 校验结果
|
|
|
+ if (StrUtil.isEmpty(resultJson)) {
|
|
|
+ throw new RuntimeException("广誉源领取积分接口失败:接口返回空结果");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 解析结果
|
|
|
+ LotteryCountResponseVO<Integer> response = JSON.parseObject(
|
|
|
+ resultJson,
|
|
|
+ new TypeReference<LotteryCountResponseVO<Integer>>() {
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ // 5. 处理业务状态
|
|
|
+ if (ObjUtil.isNull(response) || !response.isSuccess()) {
|
|
|
+ String msg = ObjUtil.isNotNull(response) ? response.getMessage() : "未知错误";
|
|
|
+ Integer code = ObjUtil.isNotNull(response) ? response.getCode() : -1;
|
|
|
+
|
|
|
+ log.warn("广誉源领取积分接口业务失败: code={}, msg={}", code, msg);
|
|
|
+ throw new ServiceException("远程接口返回失败: " + msg);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 获取数据列表
|
|
|
+ Integer points = response.getResult();
|
|
|
+
|
|
|
+ log.info("成功获取广誉源领取积分,数量: {}", points);
|
|
|
+
|
|
|
+ return points;
|
|
|
+
|
|
|
+ } catch (ServiceException e) {
|
|
|
+ // 透传业务异常,不要重复包装
|
|
|
+ throw e;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("广誉源领取积分接口发生系统异常", e);
|
|
|
+ // 优化点:只抛出消息,不要直接把整个 Exception 对象 toString() 拼接到字符串里
|
|
|
+ throw new ServiceException("广誉源领取积分接口异常: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|