package com.rj.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.rj.entity.LbBuyAccount; import com.rj.mapper.LbBuyAccountMapper; import com.rj.service.ILbBuyAccountService; import com.rj.service.ILbGoodsService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.UUID; @Slf4j @Service public class LbBuyAccountServiceImpl extends ServiceImpl implements ILbBuyAccountService { /** 与表字段 rush_buy_result(TEXT)长度上限一致 */ private static final int RUSH_BUY_RESULT_MAX_LEN = 65535; private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Autowired private ILbGoodsService lbGoodsService; @Override public Map add(LbBuyAccount entity) { Map result = new HashMap<>(); try { Map validation = validateRequiredForAdd(entity); if (validation != null) { return validation; } trimStringFields(entity); defaultIntegerFields(entity); if (entity.getId() == null || entity.getId().trim().isEmpty()) { entity.setId(UUID.randomUUID().toString()); } LocalDateTime now = LocalDateTime.now(); if (entity.getCreateTime() == null) { entity.setCreateTime(now); } entity.setUpdateTime(now); boolean ok = this.save(entity); result.put("success", ok); result.put("message", ok ? "新增成功" : "新增失败"); if (ok) { result.put("data", entity); } return result; } catch (Exception e) { log.error("抢单账号配置新增异常", e); result.put("success", false); result.put("message", "新增异常:" + e.getMessage()); return result; } } @Override public Map update(LbBuyAccount entity) { Map result = new HashMap<>(); try { if (entity.getId() == null || entity.getId().trim().isEmpty()) { result.put("success", false); result.put("message", "id不能为空"); return result; } trimStringFields(entity); entity.setUpdateTime(LocalDateTime.now()); boolean ok = this.updateById(entity); result.put("success", ok); result.put("message", ok ? "编辑成功" : "编辑失败"); if (ok) { result.put("data", this.getById(entity.getId())); } return result; } catch (Exception e) { log.error("抢单账号配置编辑异常", e); result.put("success", false); result.put("message", "编辑异常:" + e.getMessage()); return result; } } @Override public Map deleteById(String id) { Map result = new HashMap<>(); try { if (id == null || id.trim().isEmpty()) { result.put("success", false); result.put("message", "id不能为空"); return result; } boolean ok = this.removeById(id.trim()); result.put("success", ok); result.put("message", ok ? "删除成功" : "删除失败"); return result; } catch (Exception e) { log.error("抢单账号配置删除异常", e); result.put("success", false); result.put("message", "删除异常:" + e.getMessage()); return result; } } @Override public Map pageQuery(Integer current, Integer size, String tenantId, String tenantName, String loginAccount, String nickname, String referrerPhone, String referrerName, String createTimeStart, String createTimeEnd) { Map result = new HashMap<>(); try { if (current == null || current < 1) { current = 1; } if (size == null || size < 1) { size = 10; } LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); if (tenantId != null && !tenantId.trim().isEmpty()) { queryWrapper.eq(LbBuyAccount::getTenantId, tenantId.trim()); } if (tenantName != null && !tenantName.trim().isEmpty()) { queryWrapper.like(LbBuyAccount::getTenantName, tenantName.trim()); } if (loginAccount != null && !loginAccount.trim().isEmpty()) { queryWrapper.like(LbBuyAccount::getLoginAccount, loginAccount.trim()); } if (nickname != null && !nickname.trim().isEmpty()) { queryWrapper.like(LbBuyAccount::getNickname, nickname.trim()); } if (referrerPhone != null && !referrerPhone.trim().isEmpty()) { queryWrapper.like(LbBuyAccount::getReferrerPhone, referrerPhone.trim()); } if (referrerName != null && !referrerName.trim().isEmpty()) { queryWrapper.like(LbBuyAccount::getReferrerName, referrerName.trim()); } LocalDateTime start = parseDateTime(createTimeStart); if (createTimeStart != null && !createTimeStart.trim().isEmpty() && start == null) { result.put("success", false); result.put("message", "createTimeStart 格式错误,请使用 yyyy-MM-dd HH:mm:ss"); return result; } LocalDateTime end = parseDateTime(createTimeEnd); if (createTimeEnd != null && !createTimeEnd.trim().isEmpty() && end == null) { result.put("success", false); result.put("message", "createTimeEnd 格式错误,请使用 yyyy-MM-dd HH:mm:ss"); return result; } if (start != null) { queryWrapper.ge(LbBuyAccount::getCreateTime, start); } if (end != null) { queryWrapper.le(LbBuyAccount::getCreateTime, end); } queryWrapper.orderByDesc(LbBuyAccount::getUpdateTime) .orderByDesc(LbBuyAccount::getCreateTime); Page page = this.page(new Page<>(current, size), queryWrapper); result.put("success", true); result.put("message", "查询成功"); result.put("data", page.getRecords()); result.put("total", page.getTotal()); result.put("current", page.getCurrent()); result.put("size", page.getSize()); result.put("pages", page.getPages()); return result; } catch (Exception e) { log.error("抢单账号配置查询异常", e); result.put("success", false); result.put("message", "查询异常:" + e.getMessage()); return result; } } @Override public Map rushBuyByIds(List ids) { Map result = new HashMap<>(); try { if (ids == null || ids.isEmpty()) { result.put("success", false); result.put("message", "ids不能为空"); return result; } List normalizedIds = new ArrayList<>(); for (String id : ids) { if (id != null && !id.trim().isEmpty()) { normalizedIds.add(id.trim()); } } if (normalizedIds.isEmpty()) { result.put("success", false); result.put("message", "ids不能为空"); return result; } List accounts = this.listByIds(normalizedIds); Map accountMap = new LinkedHashMap<>(); for (LbBuyAccount account : accounts) { if (account != null && account.getId() != null) { accountMap.put(account.getId(), account); } } List> accountResults = new ArrayList<>(); int successAccounts = 0; int failAccounts = 0; for (String id : normalizedIds) { Map item = new LinkedHashMap<>(); item.put("accountId", id); LbBuyAccount account = accountMap.get(id); if (account == null) { item.put("success", false); item.put("message", "抢单账号不存在"); accountResults.add(item); failAccounts++; continue; } item.put("loginAccount", account.getLoginAccount()); item.put("tenantId", account.getTenantId()); item.put("nickname", account.getNickname()); String resultMessage; Boolean rushSuccess = false; LocalDateTime rushBuyTime = LocalDateTime.now(); if (account.getEnabled() != null && account.getEnabled() == 0) { resultMessage = formatPreRushBuyFailure("账号未启用"); } else if (account.getTenantId() == null || account.getTenantId().trim().isEmpty()) { resultMessage = formatPreRushBuyFailure("tenantId不能为空"); } else if (account.getTokenFront() == null || account.getTokenFront().trim().isEmpty()) { resultMessage = formatPreRushBuyFailure("token_front不能为空"); } else { Integer maxGrabCount = account.getMaxGrabCount(); if (maxGrabCount == null || maxGrabCount <= 0) { resultMessage = formatPreRushBuyFailure("maxGrabCount必须大于0"); } else { Map rushBuyResult = lbGoodsService.rushBuy( account.getTenantId().trim(), account.getTokenFront().trim(), maxGrabCount); item.put("rushBuyResult", rushBuyResult); rushSuccess = rushBuyResult.get("success") instanceof Boolean ? (Boolean) rushBuyResult.get("success") : null; resultMessage = formatRushBuyResultMessage(rushBuyResult); } } item.put("success", Boolean.TRUE.equals(rushSuccess)); item.put("message", resultMessage); accountResults.add(item); persistRushBuyOutcome(account.getId(), resultMessage, rushBuyTime); if (Boolean.TRUE.equals(rushSuccess)) { successAccounts++; } else { failAccounts++; } } result.put("success", successAccounts > 0); result.put("message", successAccounts > 0 ? "批量抢购完成,成功账号 " + successAccounts + " 个,失败 " + failAccounts + " 个" : "批量抢购未成功"); result.put("totalAccounts", normalizedIds.size()); result.put("successAccounts", successAccounts); result.put("failAccounts", failAccounts); result.put("accountResults", accountResults); return result; } catch (Exception e) { log.error("抢单账号批量抢购异常", e); result.put("success", false); result.put("message", "批量抢购异常:" + e.getMessage()); return result; } } private Map validateRequiredForAdd(LbBuyAccount entity) { Map result = new HashMap<>(); if (entity.getTenantId() == null || entity.getTenantId().trim().isEmpty()) { result.put("success", false); result.put("message", "tenantId不能为空"); return result; } if (entity.getTenantName() == null || entity.getTenantName().trim().isEmpty()) { result.put("success", false); result.put("message", "tenantName不能为空"); return result; } if (entity.getLoginAccount() == null || entity.getLoginAccount().trim().isEmpty()) { result.put("success", false); result.put("message", "loginAccount不能为空"); return result; } if (entity.getLoginPassword() == null || entity.getLoginPassword().trim().isEmpty()) { result.put("success", false); result.put("message", "loginPassword不能为空"); return result; } return null; } private static void trimStringFields(LbBuyAccount entity) { if (entity.getTenantId() != null) { entity.setTenantId(entity.getTenantId().trim()); } if (entity.getTenantName() != null) { entity.setTenantName(entity.getTenantName().trim()); } if (entity.getLoginAccount() != null) { entity.setLoginAccount(entity.getLoginAccount().trim()); } if (entity.getLoginPassword() != null) { entity.setLoginPassword(entity.getLoginPassword().trim()); } if (entity.getNickname() != null) { entity.setNickname(entity.getNickname().trim()); } if (entity.getReferrerPhone() != null) { entity.setReferrerPhone(entity.getReferrerPhone().trim()); } if (entity.getReferrerName() != null) { entity.setReferrerName(entity.getReferrerName().trim()); } if (entity.getLoginUrl() != null) { entity.setLoginUrl(entity.getLoginUrl().trim()); } if (entity.getTokenFront() != null) { entity.setTokenFront(entity.getTokenFront().trim()); } } private static void defaultIntegerFields(LbBuyAccount entity) { if (entity.getMaxGrabAmount() == null) { entity.setMaxGrabAmount(0); } if (entity.getMaxGrabCount() == null) { entity.setMaxGrabCount(0); } if (entity.getLatestRechargePoints() == null) { entity.setLatestRechargePoints(0); } if (entity.getRemainingPoints() == null) { entity.setRemainingPoints(0); } if (entity.getTotalPoints() == null) { entity.setTotalPoints(0); } if (entity.getEnabled() == null) { entity.setEnabled(1); } } /** * 将本次抢单结果与抢单时间写入 lb_buy_account(rush_buy_result、last_rush_buy_time)。 */ private void persistRushBuyOutcome(String accountId, String resultMessage, LocalDateTime rushBuyTime) { if (accountId == null || accountId.trim().isEmpty()) { return; } String storedResult = truncateRushBuyResult( resultMessage != null && !resultMessage.isEmpty() ? resultMessage : "未知抢单结果"); LocalDateTime time = rushBuyTime != null ? rushBuyTime : LocalDateTime.now(); try { boolean ok = this.lambdaUpdate() .eq(LbBuyAccount::getId, accountId.trim()) .set(LbBuyAccount::getRushBuyResult, storedResult) .set(LbBuyAccount::getLastRushBuyTime, time) .set(LbBuyAccount::getUpdateTime, LocalDateTime.now()) .update(); if (!ok) { log.warn("抢单结果落库未更新任何行,accountId={}", accountId); } } catch (Exception e) { log.error("抢单结果落库异常,accountId={}", accountId, e); } } private static String formatPreRushBuyFailure(String reason) { return "【失败】原因:" + reason; } /** * 根据 rushBuy 返回结构生成落库文案:成功记录货品 ID 与金额;失败记录原因与接口返回信息。 */ private static String formatRushBuyResultMessage(Map rushBuyResult) { if (rushBuyResult == null || rushBuyResult.isEmpty()) { return formatPreRushBuyFailure("抢购未返回结果"); } Object summaryMsg = rushBuyResult.get("message"); Object detailsObj = rushBuyResult.get("details"); if (!(detailsObj instanceof List details) || details.isEmpty()) { return formatRushBuyWithoutDetails(rushBuyResult, summaryMsg); } List successLines = new ArrayList<>(); List failLines = new ArrayList<>(); for (Object detailObj : details) { if (!(detailObj instanceof Map detail)) { continue; } Object successFlag = detail.get("success"); boolean itemSuccess = Boolean.TRUE.equals(successFlag); if (itemSuccess) { successLines.add(formatRushBuySuccessDetail(detail)); } else { failLines.add(formatRushBuyFailDetail(detail)); } } StringBuilder sb = new StringBuilder(); if (summaryMsg != null) { sb.append("汇总:").append(summaryMsg); } Object successCount = rushBuyResult.get("successCount"); Object failCount = rushBuyResult.get("failCount"); if (successCount != null || failCount != null) { sb.append("(成功").append(successCount).append("笔,失败").append(failCount).append("笔)"); } if (!successLines.isEmpty()) { sb.append(" | 【成功】").append(String.join("; ", successLines)); } if (!failLines.isEmpty()) { sb.append(" | 【失败】").append(String.join("; ", failLines)); } if (successLines.isEmpty() && failLines.isEmpty()) { sb.append(" | 【失败】原因:无有效抢购明细"); if (summaryMsg != null) { sb.append(";返回信息:").append(summaryMsg); } } return truncateRushBuyResult(sb.toString()); } /** rushBuy 未产生逐笔明细(配置缺失、无可抢货品、异常等) */ private static String formatRushBuyWithoutDetails(Map rushBuyResult, Object summaryMsg) { Boolean overallSuccess = rushBuyResult.get("success") instanceof Boolean ? (Boolean) rushBuyResult.get("success") : null; String summary = summaryMsg != null ? summaryMsg.toString() : "无返回信息"; if (Boolean.TRUE.equals(overallSuccess)) { return truncateRushBuyResult("【成功】返回信息:" + summary); } return truncateRushBuyResult("【失败】原因:" + summary + ";返回信息:" + summary); } private static String formatRushBuySuccessDetail(Map detail) { return "货品ID=" + detail.get("id") + ",金额=" + detail.get("totalMoney"); } private static String formatRushBuyFailDetail(Map detail) { Object apiCode = detail.get("apiCode"); Object apiMsg = detail.get("message"); String reason = apiCode != null ? "接口返回码=" + apiCode + (apiMsg != null ? "," + apiMsg : "") : (apiMsg != null ? apiMsg.toString() : "未知原因"); return "货品ID=" + detail.get("id") + ",金额=" + detail.get("totalMoney") + ",原因=" + reason + ",返回信息=" + (apiMsg != null ? apiMsg : "无"); } private static String truncateRushBuyResult(String text) { if (text == null) { return null; } if (text.length() <= RUSH_BUY_RESULT_MAX_LEN) { return text; } return text.substring(0, RUSH_BUY_RESULT_MAX_LEN); } private static LocalDateTime parseDateTime(String text) { if (text == null || text.trim().isEmpty()) { return null; } try { return LocalDateTime.parse(text.trim(), DATE_TIME_FORMATTER); } catch (Exception e) { return null; } } }