首次提交:初始化后端、数据库结构与文档代码

This commit is contained in:
Peter
2026-03-23 16:10:29 +08:00
commit 86f384c2d3
95 changed files with 10090 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
package com.chuyishidai.datahub;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.*;
/**
* 诊断: item_id 比对
* 拉取3条最近订单的原始JSON打印每个商品的 item_id + title
*
* Run: mvn -q compile exec:java -Dexec.mainClass="com.chuyishidai.datahub.ItemIdDiagTest"
* Output: item_id_diag_output.txt
*/
public class ItemIdDiagTest {
static final String CLIENT_ID = "f6eb734c712329dc5e";
static final String CLIENT_SECRET = "f7fd462479075645d38a460ceb1c2e47";
static final String GRANT_ID = "154234003";
static final String BASE_URL = "https://open.youzanyun.com";
static final String OUTPUT_FILE = "item_id_diag_output.txt";
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
RestTemplate rest = new RestTemplate();
StringBuilder sb = new StringBuilder();
String accessToken = getToken(rest, mapper);
sb.append("access_token: ").append(accessToken.substring(0, 10)).append("...\n\n");
// 拉取最近7天的前5条订单
String startTime = LocalDate.now().minusDays(7) + " 00:00:00";
String endTime = LocalDate.now().plusDays(1) + " 00:00:00";
sb.append("=" .repeat(70)).append("\n");
sb.append("Part 1: 有赞API返回的订单中每个商品明细的 item_id + title\n");
sb.append("=" .repeat(70)).append("\n");
String url = BASE_URL + "/api/youzan.trades.sold.get/4.0.4"
+ "?access_token=" + accessToken
+ "&start_created=" + startTime.replace(" ", "%20")
+ "&end_created=" + endTime.replace(" ", "%20")
+ "&page_no=1&page_size=5";
try {
java.net.URI uri = new java.net.URI(url);
String body = rest.getForObject(uri, String.class);
JsonNode root = mapper.readTree(body);
JsonNode data = root.get("data");
if (data == null) {
sb.append("data is null!\n");
} else {
JsonNode list = data.get("full_order_info_list");
if (list != null) {
for (int i = 0; i < list.size(); i++) {
JsonNode fullOrder = list.get(i).get("full_order_info");
if (fullOrder == null) continue;
JsonNode orderInfo = fullOrder.get("order_info");
String tid = orderInfo != null ? getText(orderInfo, "tid") : "?";
sb.append(String.format("\n--- 订单 #%d tid=%s ---\n", i + 1, tid));
JsonNode orders = fullOrder.get("orders");
if (orders != null) {
for (JsonNode item : orders) {
long itemId = item.has("item_id") ? item.get("item_id").asLong() : 0;
long skuId = item.has("sku_id") ? item.get("sku_id").asLong() : 0;
String title = getText(item, "title");
String outerItemId = getText(item, "outer_item_id");
String outerSkuId = getText(item, "outer_sku_id");
int num = item.has("num") ? item.get("num").asInt() : 0;
sb.append(String.format(
" item_id=%-15d sku_id=%-15d title=%-30s outer_item_id=%-15s outer_sku_id=%-15s num=%d\n",
itemId, skuId,
title != null ? title : "(null)",
outerItemId != null ? outerItemId : "(null)",
outerSkuId != null ? outerSkuId : "(null)",
num));
}
}
}
}
}
} catch (Exception e) {
sb.append("API调用异常: ").append(e.getMessage()).append("\n");
}
// Part 2: 同时把第一条订单的完整JSON也打印出来供人工检查
sb.append("\n\n");
sb.append("=" .repeat(70)).append("\n");
sb.append("Part 2: 第1条订单的完整原始JSON (供比对字段结构)\n");
sb.append("=" .repeat(70)).append("\n");
try {
java.net.URI uri = new java.net.URI(BASE_URL + "/api/youzan.trades.sold.get/4.0.4"
+ "?access_token=" + accessToken
+ "&start_created=" + startTime.replace(" ", "%20")
+ "&end_created=" + endTime.replace(" ", "%20")
+ "&page_no=1&page_size=1");
String body = rest.getForObject(uri, String.class);
JsonNode root = mapper.readTree(body);
JsonNode data = root.get("data");
if (data != null) {
JsonNode list = data.get("full_order_info_list");
if (list != null && !list.isEmpty()) {
String prettyJson = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(list.get(0));
sb.append(prettyJson);
}
}
} catch (Exception e) {
sb.append("Error: ").append(e.getMessage());
}
writeOutput(sb);
}
static String getText(JsonNode node, String field) {
return (node != null && node.has(field) && !node.get(field).isNull())
? node.get(field).asText() : null;
}
static String getToken(RestTemplate restTemplate, ObjectMapper mapper) throws Exception {
String url = BASE_URL + "/auth/token";
Map<String, Object> body = Map.of(
"client_id", CLIENT_ID,
"client_secret", CLIENT_SECRET,
"authorize_type", "silent",
"grant_id", GRANT_ID,
"refresh", false);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<>(mapper.writeValueAsString(body), headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
JsonNode root = mapper.readTree(response.getBody());
return root.get("data").get("access_token").asText();
}
static void writeOutput(StringBuilder sb) throws Exception {
String output = sb.toString();
try (Writer w = new OutputStreamWriter(new FileOutputStream(OUTPUT_FILE), StandardCharsets.UTF_8)) {
w.write(output);
}
System.out.println("Output written to " + OUTPUT_FILE);
System.out.println(output);
}
}