|
@@ -10,11 +10,21 @@ import com.adx.tencent.conversionsync.RetryService;
|
|
|
import org.springframework.data.redis.core.Cursor;
|
|
import org.springframework.data.redis.core.Cursor;
|
|
|
import org.springframework.data.redis.core.ScanOptions;
|
|
import org.springframework.data.redis.core.ScanOptions;
|
|
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
|
|
+import org.springframework.http.ContentDisposition;
|
|
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
import org.springframework.http.HttpStatus;
|
|
import org.springframework.http.HttpStatus;
|
|
|
|
|
+import org.springframework.http.MediaType;
|
|
|
|
|
+import org.springframework.http.ResponseEntity;
|
|
|
import org.springframework.lang.Nullable;
|
|
import org.springframework.lang.Nullable;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
import org.springframework.web.server.ResponseStatusException;
|
|
import org.springframework.web.server.ResponseStatusException;
|
|
|
|
|
+import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
|
|
|
|
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
|
|
+import java.time.ZoneId;
|
|
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
|
|
+import java.time.format.DateTimeParseException;
|
|
|
import java.time.Duration;
|
|
import java.time.Duration;
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
@@ -37,6 +47,7 @@ public class AdminController {
|
|
|
private final RetryService retryService;
|
|
private final RetryService retryService;
|
|
|
private final ManualTencentCallbackService manualTencentCallbackService;
|
|
private final ManualTencentCallbackService manualTencentCallbackService;
|
|
|
private final StringRedisTemplate redisTemplate;
|
|
private final StringRedisTemplate redisTemplate;
|
|
|
|
|
+ private final HonorOaidExportService honorOaidExportService;
|
|
|
|
|
|
|
|
public AdminController(ConversionClient conversionClient,
|
|
public AdminController(ConversionClient conversionClient,
|
|
|
@Nullable ConversionSyncRunner conversionSyncRunner,
|
|
@Nullable ConversionSyncRunner conversionSyncRunner,
|
|
@@ -44,7 +55,8 @@ public class AdminController {
|
|
|
@Nullable ConversionSyncService conversionSyncer,
|
|
@Nullable ConversionSyncService conversionSyncer,
|
|
|
@Nullable RetryService retryService,
|
|
@Nullable RetryService retryService,
|
|
|
@Nullable ManualTencentCallbackService manualTencentCallbackService,
|
|
@Nullable ManualTencentCallbackService manualTencentCallbackService,
|
|
|
- @Nullable StringRedisTemplate redisTemplate) {
|
|
|
|
|
|
|
+ @Nullable StringRedisTemplate redisTemplate,
|
|
|
|
|
+ HonorOaidExportService honorOaidExportService) {
|
|
|
this.conversionClient = conversionClient;
|
|
this.conversionClient = conversionClient;
|
|
|
this.conversionSyncRunner = conversionSyncRunner;
|
|
this.conversionSyncRunner = conversionSyncRunner;
|
|
|
this.backfillJobService = backfillJobService;
|
|
this.backfillJobService = backfillJobService;
|
|
@@ -52,6 +64,39 @@ public class AdminController {
|
|
|
this.retryService = retryService;
|
|
this.retryService = retryService;
|
|
|
this.manualTencentCallbackService = manualTencentCallbackService;
|
|
this.manualTencentCallbackService = manualTencentCallbackService;
|
|
|
this.redisTemplate = redisTemplate;
|
|
this.redisTemplate = redisTemplate;
|
|
|
|
|
+ this.honorOaidExportService = honorOaidExportService;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Browser download endpoint for the fixed jlt68/Honor/activation OAID file.
|
|
|
|
|
+ * Only the data date is configurable, so this endpoint cannot be used as a
|
|
|
|
|
+ * general-purpose conversion-table export.
|
|
|
|
|
+ */
|
|
|
|
|
+ @GetMapping(value = "/exports/honor/jlt68/oaids", produces = "text/csv")
|
|
|
|
|
+ public ResponseEntity<StreamingResponseBody> exportHonorJlt68Oaids(
|
|
|
|
|
+ @RequestParam(value = "date", required = false) String date) {
|
|
|
|
|
+ LocalDate exportDate = parseExportDate(date);
|
|
|
|
|
+ long count = honorOaidExportService.countExportRows(exportDate);
|
|
|
|
|
+ String filename = "jlt68_honor_act1_oaid_" + DateTimeFormatter.BASIC_ISO_DATE.format(exportDate) + ".csv";
|
|
|
|
|
+ StreamingResponseBody body = outputStream -> honorOaidExportService.writeCsv(exportDate, outputStream);
|
|
|
|
|
+
|
|
|
|
|
+ return ResponseEntity.ok()
|
|
|
|
|
+ .contentType(new MediaType("text", "csv", StandardCharsets.UTF_8))
|
|
|
|
|
+ .header(HttpHeaders.CONTENT_DISPOSITION,
|
|
|
|
|
+ ContentDisposition.attachment().filename(filename, StandardCharsets.UTF_8).build().toString())
|
|
|
|
|
+ .header("X-OAID-Count", Long.toString(count))
|
|
|
|
|
+ .body(body);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static LocalDate parseExportDate(String value) {
|
|
|
|
|
+ if (value == null || value.isBlank()) {
|
|
|
|
|
+ return LocalDate.now(ZoneId.of("Asia/Shanghai")).minusDays(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ return LocalDate.parse(value, DateTimeFormatter.BASIC_ISO_DATE);
|
|
|
|
|
+ } catch (DateTimeParseException e) {
|
|
|
|
|
+ throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "date must be YYYYMMDD");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@PostMapping("/conversions/query")
|
|
@PostMapping("/conversions/query")
|