Files
smartDriveEE/src/main/java/com/rj/service/HxrAdminOrderSelectService.java
2026-05-19 07:29:43 +08:00

184 lines
7.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.rj.service;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.rj.config.HxrAdminProperties;
import com.rj.dto.hxr.HxrOrderRow;
import com.rj.dto.hxr.HxrOrderSelectResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Optional;
/**
* 调用 hxrd 后台订单列表接口并解析 JSON。
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class HxrAdminOrderSelectService {
private static final ObjectMapper JSON = new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
private final HxrAdminProperties properties;
/**
* 拉取订单列表;配置未就绪或 HTTP 非 2xx 时返回 empty。
* <p>使用 {@link HxrAdminProperties#getOrderSelectUrl()} 原样请求(与定时任务一致)。
*/
public Optional<HxrOrderSelectResponse> fetchOrderSelect() throws Exception {
return fetchOrderSelectInternal(properties.getOrderSelectUrl());
}
/**
* 拉取未支付订单,使用 {@link HxrAdminProperties#getOrderSelectUnPayUrl()}。
*/
public Optional<HxrOrderSelectResponse> fetchUnpaidOrderSelect() throws Exception {
return fetchOrderSelectInternal(properties.getOrderSelectUnPayUrl());
}
/**
* 按购买时间区间、转卖状态等条件拉取订单列表(在配置的 {@code orderSelectUrl} 上覆盖查询参数)。
*
* @param buyTimeStart 购买时间起,对应 {@code buy_time[0]},可为 null 或空串表示不限制
* @param buyTimeEnd 购买时间止,对应 {@code buy_time[1]}
* @param isResell 转卖筛选,对应 {@code is_resell};为 null 时不改写该参数
*/
public Optional<HxrOrderSelectResponse> fetchOrderSelect(
String buyTimeStart, String buyTimeEnd, Integer isResell) throws Exception {
return fetchOrderSelect(buyTimeStart, buyTimeEnd, isResell, 1);
}
/**
* 按购买时间区间、转卖状态及页码拉取订单列表。
*
* @param page 页码,从 1 开始;与配置 URL 中的 {@code limit} 配合分页
*/
public Optional<HxrOrderSelectResponse> fetchOrderSelect(
String buyTimeStart, String buyTimeEnd, Integer isResell, int page) throws Exception {
return fetchOrderSelectInternal(buildOrderSelectUrl(buyTimeStart, buyTimeEnd, isResell, page));
}
/**
* 按购买时间区间及页码拉取未支付订单({@code status=0},基于 {@link HxrAdminProperties#getOrderSelectUnPayUrl()})。
*/
public Optional<HxrOrderSelectResponse> fetchUnpaidOrderSelect(
String buyTimeStart, String buyTimeEnd, int page) throws Exception {
return fetchOrderSelectInternal(
buildStatusOrderSelectUrl(properties.getOrderSelectUnPayUrl(), buyTimeStart, buyTimeEnd, page));
}
/**
* 按购买时间区间及页码拉取已支付订单({@code status=1},基于 {@link HxrAdminProperties#getOrderSelectPaidUrl()})。
*/
public Optional<HxrOrderSelectResponse> fetchPaidOrderSelect(
String buyTimeStart, String buyTimeEnd, int page) throws Exception {
return fetchOrderSelectInternal(
buildStatusOrderSelectUrl(properties.getOrderSelectPaidUrl(), buyTimeStart, buyTimeEnd, page));
}
private Optional<HxrOrderSelectResponse> fetchOrderSelectInternal(String requestUri) throws Exception {
String cookieHeader = properties.resolveCookieHeader();
if (cookieHeader == null || cookieHeader.isBlank()) {
log.warn("hxr.admin 未配置 cookie 或 phpsid跳过拉取");
return Optional.empty();
}
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(35))
.followRedirects(HttpClient.Redirect.NORMAL)
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(requestUri))
.timeout(Duration.ofSeconds(160))
.header("Accept", "application/json, text/javascript, */*; q=0.01")
.header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
.header("Cookie", cookieHeader)
.header("Priority", "u=1, i")
.header("Referer", "https://hxrdhoutai.hxrdsm.cn/app/admin/order/index")
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36 Edg/148.0.0.0")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
int status = response.statusCode();
if (status < 200 || status >= 300) {
log.warn("hxr admin order/select HTTP {} bodyPrefix={}", status, abbreviate(response.body(), 500));
return Optional.empty();
}
HxrOrderSelectResponse body = JSON.readValue(response.body(), HxrOrderSelectResponse.class);
if (body.code() != 0) {
log.warn("hxr admin order/select api code={} msg={}", body.code(), body.msg());
return Optional.empty();
}
return Optional.of(body);
}
/**
* 在 {@link HxrAdminProperties#getOrderSelectUrl()} 上覆盖 {@code buy_time[0]}、{@code buy_time[1]}、{@code is_resell}。
*/
private String buildOrderSelectUrl(String buyTimeStart, String buyTimeEnd, Integer isResell, int page) {
UriComponentsBuilder b = UriComponentsBuilder.fromUriString(properties.getOrderSelectUrl());
b.replaceQueryParam("buy_time[0]", buyTimeStart == null ? "" : buyTimeStart);
b.replaceQueryParam("buy_time[1]", buyTimeEnd == null ? "" : buyTimeEnd);
if (isResell != null) {
b.replaceQueryParam("is_resell", isResell);
}
b.replaceQueryParam("page", Math.max(1, page));
return b.build().encode().toUriString();
}
private String buildStatusOrderSelectUrl(String baseUrl, String buyTimeStart, String buyTimeEnd, int page) {
UriComponentsBuilder b = UriComponentsBuilder.fromUriString(baseUrl);
b.replaceQueryParam("buy_time[0]", buyTimeStart == null ? "" : buyTimeStart);
b.replaceQueryParam("buy_time[1]", buyTimeEnd == null ? "" : buyTimeEnd);
b.replaceQueryParam("page", Math.max(1, page));
return b.build().encode().toUriString();
}
/**
* 拉取并逐条打日志(一行一条 JSON
*/
public void fetchAndLogEachOrder() throws Exception {
fetchAndLogEachOrder(fetchOrderSelect(), "未寄卖");
}
/**
* 拉取未支付订单({@code status=0})并逐条打日志。
*/
public void fetchAndLogUnpaidOrders() throws Exception {
fetchAndLogEachOrder(fetchUnpaidOrderSelect(), "未支付");
}
private void fetchAndLogEachOrder(
Optional<HxrOrderSelectResponse> opt, String label) throws Exception {
if (opt.isEmpty()) {
return;
}
HxrOrderSelectResponse body = opt.get();
log.info("{} order/select ok count={} allMoney={}", label, body.count(), body.allMoney());
// for (HxrOrderRow row : body.data()) {
// log.info("hxr order row {}", JSON.writeValueAsString(row));
// }
}
private static String abbreviate(String s, int maxLen) {
if (s == null) {
return "";
}
return s.length() <= maxLen ? s : s.substring(0, maxLen) + "...";
}
}