格式修改
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
package com.baiyue.file.client;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.export.ExportContracts.ExportBatchRequest;
|
||||
import com.baiyue.common.core.export.ExportContracts.ExportBatchResponse;
|
||||
@@ -12,15 +15,17 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
public class ExportProviderClient {
|
||||
private final Map<String, ExportProviderFeignClient> clients;
|
||||
private final MeterRegistry meters;
|
||||
|
||||
public ExportProviderClient(IamExportProviderClient iam, OrderExportProviderClient order,
|
||||
WarehouseExportProviderClient warehouse, FirstlegExportProviderClient firstleg,
|
||||
MeterRegistry meters) {
|
||||
private Map<String, ExportProviderFeignClient> clients;
|
||||
@Resource private IamExportProviderClient iam;
|
||||
@Resource private OrderExportProviderClient order;
|
||||
@Resource private WarehouseExportProviderClient warehouse;
|
||||
@Resource private FirstlegExportProviderClient firstleg;
|
||||
@Resource
|
||||
private MeterRegistry meters;
|
||||
@PostConstruct
|
||||
void initializeClients() {
|
||||
this.clients = Map.of("iam-service", iam, "order-service", order,
|
||||
"warehouse-service", warehouse, "firstleg-service", firstleg);
|
||||
this.meters = meters;
|
||||
}
|
||||
|
||||
public ApiResponse<ExportBatchResponse> batch(String internalToken, String exportType,
|
||||
|
||||
+11
-7
@@ -1,5 +1,8 @@
|
||||
package com.baiyue.file.controller;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
@@ -27,14 +30,15 @@ import org.springframework.http.ResponseEntity;
|
||||
@RestController
|
||||
@RequestMapping("/internal/file/v1/measurement-images")
|
||||
public class InternalMeasurementImageController {
|
||||
private final MeasurementImageService images;
|
||||
private final byte[] expectedToken;
|
||||
@Resource
|
||||
private MeasurementImageService images;
|
||||
@Value("${baiyue.security.internal-service-token}")
|
||||
private String internalToken;
|
||||
private byte[] expectedToken;
|
||||
|
||||
public InternalMeasurementImageController(
|
||||
MeasurementImageService images,
|
||||
@Value("${baiyue.security.internal-service-token}") String token) {
|
||||
this.images = images;
|
||||
this.expectedToken = token.getBytes(StandardCharsets.UTF_8);
|
||||
@PostConstruct
|
||||
void initializeToken() {
|
||||
expectedToken = internalToken.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/{tenantId}/{inboundId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.controller;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
@@ -27,9 +29,8 @@ import java.time.LocalDate;
|
||||
@RequestMapping("/api/platform/v1/files/export-tasks")
|
||||
@Validated
|
||||
public class PlatformExportTaskController {
|
||||
private final ExportTaskService service;
|
||||
|
||||
public PlatformExportTaskController(ExportTaskService service) { this.service = service; }
|
||||
@Resource
|
||||
private ExportTaskService service;
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
|
||||
+4
-5
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.controller;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
@@ -29,11 +31,8 @@ import java.nio.charset.StandardCharsets;
|
||||
@RequestMapping("/api/platform/v1/files/measurements")
|
||||
@Tag(name = "平台入库测量图片")
|
||||
public class PlatformMeasurementImageController {
|
||||
private final MeasurementImageService images;
|
||||
|
||||
public PlatformMeasurementImageController(MeasurementImageService images) {
|
||||
this.images = images;
|
||||
}
|
||||
@Resource
|
||||
private MeasurementImageService images;
|
||||
|
||||
@PostMapping(value = "/{tenantId}/{inboundId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
@PreAuthorize("hasAuthority('platform:firstleg:inbound:weight:edit')")
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.baiyue.file.mq;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import com.baiyue.common.core.export.ExportContracts.ExportCommand;
|
||||
import com.baiyue.file.service.ExportTaskExecutor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -21,20 +24,18 @@ import java.nio.charset.StandardCharsets;
|
||||
selectorExpression="EXPORT_TASK", messageModel= MessageModel.CLUSTERING, consumeThreadNumber=4,
|
||||
consumeThreadMax=4, consumeTimeout=90, maxReconsumeTimes=2)
|
||||
public class ExportCommandConsumer implements RocketMQListener<MessageExt>, RocketMQPushConsumerLifecycleListener {
|
||||
private final ObjectMapper objectMapper;
|
||||
private final ExportTaskExecutor executor;
|
||||
private final String instance;
|
||||
private final int concurrency;
|
||||
private final long consumeTimeoutMinutes;
|
||||
private final int maxReconsumeTimes;
|
||||
public ExportCommandConsumer(ObjectMapper objectMapper, ExportTaskExecutor executor,
|
||||
@Value("${baiyue.file.export.instance-id:${HOSTNAME:${random.uuid}}}") String instance,
|
||||
@Value("${baiyue.file.export.consumer.concurrency:4}") int concurrency,
|
||||
@Value("${baiyue.file.export.consumer.consume-timeout-minutes:90}") long consumeTimeoutMinutes,
|
||||
@Value("${baiyue.file.export.consumer.max-reconsume-times:2}") int maxReconsumeTimes) {
|
||||
this.objectMapper=objectMapper;this.executor=executor;this.instance=instance;
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
@Resource
|
||||
private ExportTaskExecutor executor;
|
||||
@Value("${baiyue.file.export.instance-id:${HOSTNAME:${random.uuid}}}") private String instance;
|
||||
@Value("${baiyue.file.export.consumer.concurrency:4}") private int concurrency;
|
||||
@Value("${baiyue.file.export.consumer.consume-timeout-minutes:90}") private long consumeTimeoutMinutes;
|
||||
@Value("${baiyue.file.export.consumer.max-reconsume-times:2}") private int maxReconsumeTimes;
|
||||
|
||||
@PostConstruct
|
||||
void validateConfiguration() {
|
||||
if (concurrency < 1 || concurrency > 64) throw new IllegalArgumentException("Export consumer concurrency must be between 1 and 64");
|
||||
this.concurrency=concurrency;this.consumeTimeoutMinutes=consumeTimeoutMinutes;this.maxReconsumeTimes=maxReconsumeTimes;
|
||||
}
|
||||
@Override public void prepareStart(DefaultMQPushConsumer consumer) {
|
||||
consumer.setConsumeThreadMin(concurrency);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.mq;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.file.service.ExportStateService;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
@@ -18,9 +20,10 @@ import org.springframework.stereotype.Service;
|
||||
consumeThreadNumber=1, consumeThreadMax=1, maxReconsumeTimes=Integer.MAX_VALUE)
|
||||
public class ExportDlqHandler implements RocketMQListener<MessageExt> {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ExportDlqHandler.class);
|
||||
private final ExportStateService states;
|
||||
private final MeterRegistry meters;
|
||||
public ExportDlqHandler(ExportStateService states, MeterRegistry meters) { this.states=states; this.meters=meters; }
|
||||
@Resource
|
||||
private ExportStateService states;
|
||||
@Resource
|
||||
private MeterRegistry meters;
|
||||
@Override public void onMessage(MessageExt message) {
|
||||
meters.counter("export_dlq_messages").increment();
|
||||
String eventId=message.getUserProperty("eventId"), taskId=message.getUserProperty("taskId");
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.mq;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.file.entity.FileExportOutbox;
|
||||
import com.baiyue.file.repository.ExportOutboxRepository;
|
||||
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||
@@ -17,17 +19,13 @@ import org.springframework.stereotype.Service;
|
||||
public class ExportOutboxPublisher {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ExportOutboxPublisher.class);
|
||||
private static final int[] BACKOFF = {5, 15, 60, 300, 900};
|
||||
private final ExportOutboxRepository outbox;
|
||||
private final RocketMQTemplate rocketMQ;
|
||||
private final String owner;
|
||||
private final int batchSize;
|
||||
private final int leaseSeconds;
|
||||
public ExportOutboxPublisher(ExportOutboxRepository outbox, RocketMQTemplate rocketMQ,
|
||||
@Value("${baiyue.file.export.instance-id:${HOSTNAME:${random.uuid}}}") String owner,
|
||||
@Value("${baiyue.file.export.publisher.batch-size:50}") int batchSize,
|
||||
@Value("${baiyue.file.export.publisher.lease-seconds:60}") int leaseSeconds) {
|
||||
this.outbox=outbox;this.rocketMQ=rocketMQ;this.owner=owner;this.batchSize=batchSize;this.leaseSeconds=leaseSeconds;
|
||||
}
|
||||
@Resource
|
||||
private ExportOutboxRepository outbox;
|
||||
@Resource
|
||||
private RocketMQTemplate rocketMQ;
|
||||
@Value("${baiyue.file.export.instance-id:${HOSTNAME:${random.uuid}}}") private String owner;
|
||||
@Value("${baiyue.file.export.publisher.batch-size:50}") private int batchSize;
|
||||
@Value("${baiyue.file.export.publisher.lease-seconds:60}") private int leaseSeconds;
|
||||
@Scheduled(fixedDelayString="${baiyue.file.export.publisher.poll-interval-ms:5000}")
|
||||
public void publish() {
|
||||
for (Long id : outbox.publishableIds(batchSize)) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.repository;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.file.entity.FileExportOutbox;
|
||||
import com.baiyue.file.mapper.FileExportOutboxMapper;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
@@ -9,8 +11,8 @@ import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class ExportOutboxRepository {
|
||||
private final FileExportOutboxMapper mapper;
|
||||
public ExportOutboxRepository(FileExportOutboxMapper mapper) { this.mapper = mapper; }
|
||||
@Resource
|
||||
private FileExportOutboxMapper mapper;
|
||||
public boolean insert(FileExportOutbox row) {
|
||||
try { return mapper.insertCommand(row) == 1; }
|
||||
catch (DuplicateKeyException ignored) { return false; }
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.repository;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.file.entity.FileExportTask;
|
||||
import com.baiyue.file.mapper.FileExportTaskMapper;
|
||||
@@ -16,11 +18,8 @@ import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class ExportTaskRepository {
|
||||
private final FileExportTaskMapper mapper;
|
||||
|
||||
public ExportTaskRepository(FileExportTaskMapper mapper) {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
@Resource
|
||||
private FileExportTaskMapper mapper;
|
||||
|
||||
@PostConstruct
|
||||
void validateCreationGuard() {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.export.ExportContracts.ExportCommand;
|
||||
import com.baiyue.file.entity.FileExportOutbox;
|
||||
import com.baiyue.file.entity.FileExportTask;
|
||||
@@ -15,13 +17,10 @@ import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class ExportCommandFactory {
|
||||
private final ObjectMapper objectMapper;
|
||||
private final String topic;
|
||||
public ExportCommandFactory(ObjectMapper objectMapper,
|
||||
@Value("${baiyue.file.export.rocketmq.topic:test-baiyue-file-export-command-v1}") String topic) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.topic = topic;
|
||||
}
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
@Value("${baiyue.file.export.rocketmq.topic:test-baiyue-file-export-command-v1}")
|
||||
private String topic;
|
||||
public FileExportOutbox create(FileExportTask task, int dispatchVersion) {
|
||||
String eventId = UUID.randomUUID().toString();
|
||||
ExportCommand command = new ExportCommand(1, eventId, String.valueOf(task.getId()), task.getExportType(),
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.baiyue.file.service;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import io.micrometer.core.instrument.Gauge;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -7,9 +10,11 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ExportMetrics {
|
||||
private final MeterRegistry registry;
|
||||
public ExportMetrics(MeterRegistry registry, JdbcTemplate jdbc) {
|
||||
this.registry=registry;
|
||||
@Resource private MeterRegistry registry;
|
||||
@Resource private JdbcTemplate jdbc;
|
||||
|
||||
@PostConstruct
|
||||
void registerGauges() {
|
||||
Gauge.builder("export_task_queue_age_seconds",jdbc,j->number(j,"SELECT COALESCE(TIMESTAMPDIFF(SECOND,MIN(requested_at),CURRENT_TIMESTAMP(3)),0) FROM file_export_task WHERE status='PENDING'")).register(registry);
|
||||
Gauge.builder("export_outbox_pending",jdbc,j->number(j,"SELECT COUNT(*) FROM file_export_outbox WHERE status IN ('PENDING','CLAIMED')")).register(registry);
|
||||
Gauge.builder("export_outbox_oldest_age_seconds",jdbc,j->number(j,"SELECT COALESCE(TIMESTAMPDIFF(SECOND,MIN(created_at),CURRENT_TIMESTAMP(3)),0) FROM file_export_outbox WHERE status IN ('PENDING','CLAIMED')")).register(registry);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.file.entity.FileExportTask;
|
||||
import com.baiyue.file.repository.ExportOutboxRepository;
|
||||
import com.baiyue.file.repository.ExportTaskRepository;
|
||||
@@ -16,18 +18,14 @@ import java.time.Duration;
|
||||
@ConditionalOnProperty(prefix="baiyue.file.export.reconciler", name="enabled", havingValue="true")
|
||||
public class ExportReconciler {
|
||||
private static final Logger LOGGER= LoggerFactory.getLogger(ExportReconciler.class);
|
||||
private final ExportTaskRepository tasks; private final ExportOutboxRepository outbox;
|
||||
private final ExportStateService states; private final ExportStorage storage; private final MeterRegistry meters;
|
||||
private final int graceSeconds, sentStaleSeconds;
|
||||
private final int retentionDays;
|
||||
public ExportReconciler(ExportTaskRepository tasks, ExportOutboxRepository outbox, ExportStateService states,
|
||||
ExportStorage storage, MeterRegistry meters,
|
||||
@Value("${baiyue.file.export.reconciler.redispatch-grace-seconds:60}") int graceSeconds,
|
||||
@Value("${baiyue.file.export.reconciler.sent-stale-seconds:600}") int sentStaleSeconds,
|
||||
@Value("${baiyue.file.export.retention-days:7}") int retentionDays) {
|
||||
this.tasks=tasks;this.outbox=outbox;this.states=states;this.storage=storage;this.meters=meters;
|
||||
this.graceSeconds=graceSeconds;this.sentStaleSeconds=sentStaleSeconds;this.retentionDays=retentionDays;
|
||||
}
|
||||
@Resource private ExportTaskRepository tasks;
|
||||
@Resource private ExportOutboxRepository outbox;
|
||||
@Resource private ExportStateService states;
|
||||
@Resource private ExportStorage storage;
|
||||
@Resource private MeterRegistry meters;
|
||||
@Value("${baiyue.file.export.reconciler.redispatch-grace-seconds:60}") private int graceSeconds;
|
||||
@Value("${baiyue.file.export.reconciler.sent-stale-seconds:600}") private int sentStaleSeconds;
|
||||
@Value("${baiyue.file.export.retention-days:7}") private int retentionDays;
|
||||
@Scheduled(cron="${baiyue.file.export.reconciler.outbox-cleanup-cron:0 15 3 * * *}")
|
||||
public void cleanupRetainedOutbox() {
|
||||
count("outbox_clean",outbox.deleteRetainedSent(retentionDays,5000));
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.file.entity.FileExportTask;
|
||||
@@ -11,14 +13,12 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class ExportStateService {
|
||||
private final ExportTaskRepository tasks;
|
||||
private final ExportOutboxRepository outbox;
|
||||
private final ExportCommandFactory commands;
|
||||
private final ExportMetrics metrics;
|
||||
public ExportStateService(ExportTaskRepository tasks, ExportOutboxRepository outbox, ExportCommandFactory commands,
|
||||
ExportMetrics metrics) {
|
||||
this.tasks = tasks; this.outbox = outbox; this.commands = commands; this.metrics = metrics;
|
||||
}
|
||||
@Resource
|
||||
private ExportTaskRepository tasks;
|
||||
@Resource
|
||||
private ExportOutboxRepository outbox;
|
||||
@Resource private ExportCommandFactory commands;
|
||||
@Resource private ExportMetrics metrics;
|
||||
@Transactional
|
||||
public CreationResult createConstrained(FileExportTask task) {
|
||||
tasks.lockCreationGuard();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.file.config.ExportDefinitionRegistry;
|
||||
import com.baiyue.file.entity.FileExportTask;
|
||||
import com.baiyue.file.repository.ExportTaskRepository;
|
||||
@@ -16,27 +18,22 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@Service
|
||||
public class ExportTaskExecutor {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ExportTaskExecutor.class);
|
||||
private final ExportTaskRepository tasks;
|
||||
private final ExportDefinitionRegistry definitions;
|
||||
private final GenericXlsxExportRunner runner;
|
||||
private final ExportStateService states;
|
||||
private final ExportStorage storage;
|
||||
private final MeterRegistry meters;
|
||||
private final int leaseSeconds, heartbeatSeconds, maxDurationMinutes, retentionDays;
|
||||
@Resource
|
||||
private ExportTaskRepository tasks;
|
||||
@Resource
|
||||
private ExportDefinitionRegistry definitions;
|
||||
@Resource private GenericXlsxExportRunner runner;
|
||||
@Resource private ExportStateService states;
|
||||
@Resource private ExportStorage storage;
|
||||
@Resource private MeterRegistry meters;
|
||||
@Value("${baiyue.file.export.task.lease-seconds:300}") private int leaseSeconds;
|
||||
@Value("${baiyue.file.export.task.heartbeat-seconds:60}") private int heartbeatSeconds;
|
||||
@Value("${baiyue.file.export.task.max-duration-minutes:30}") private int maxDurationMinutes;
|
||||
@Value("${baiyue.file.export.retention-days:7}") private int retentionDays;
|
||||
private final ScheduledExecutorService watchdogs = Executors.newScheduledThreadPool(4, runnable -> {
|
||||
Thread thread = new Thread(runnable, "file-export-watchdog"); thread.setDaemon(true); return thread;
|
||||
});
|
||||
|
||||
public ExportTaskExecutor(ExportTaskRepository tasks, ExportDefinitionRegistry definitions,
|
||||
GenericXlsxExportRunner runner, ExportStateService states, ExportStorage storage, MeterRegistry meters,
|
||||
@Value("${baiyue.file.export.task.lease-seconds:300}") int leaseSeconds,
|
||||
@Value("${baiyue.file.export.task.heartbeat-seconds:60}") int heartbeatSeconds,
|
||||
@Value("${baiyue.file.export.task.max-duration-minutes:30}") int maxDurationMinutes,
|
||||
@Value("${baiyue.file.export.retention-days:7}") int retentionDays) {
|
||||
this.tasks=tasks;this.definitions=definitions;this.runner=runner;this.states=states;this.storage=storage;this.meters=meters;
|
||||
this.leaseSeconds=leaseSeconds;this.heartbeatSeconds=heartbeatSeconds;this.maxDurationMinutes=maxDurationMinutes;this.retentionDays=retentionDays;
|
||||
}
|
||||
|
||||
public void execute(long taskId, int dispatchVersion, String owner) {
|
||||
if (!tasks.claim(taskId, dispatchVersion, owner, leaseSeconds, maxDurationMinutes)) return;
|
||||
FileExportTask task = tasks.find(taskId);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
@@ -22,23 +24,12 @@ import java.util.TreeMap;
|
||||
|
||||
@Service
|
||||
public class ExportTaskService {
|
||||
private final ExportTaskRepository repository;
|
||||
private final ExportStorage storage;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final ExportDefinitionRegistry registry;
|
||||
private final ExportStateService stateService;
|
||||
private final ExportMetrics metrics;
|
||||
|
||||
public ExportTaskService(ExportTaskRepository repository, ExportStorage storage,
|
||||
ObjectMapper objectMapper, ExportDefinitionRegistry registry,
|
||||
ExportStateService stateService, ExportMetrics metrics) {
|
||||
this.repository = repository;
|
||||
this.storage = storage;
|
||||
this.objectMapper = objectMapper;
|
||||
this.registry = registry;
|
||||
this.stateService = stateService;
|
||||
this.metrics = metrics;
|
||||
}
|
||||
@Resource private ExportTaskRepository repository;
|
||||
@Resource private ExportStorage storage;
|
||||
@Resource private ObjectMapper objectMapper;
|
||||
@Resource private ExportDefinitionRegistry registry;
|
||||
@Resource private ExportStateService stateService;
|
||||
@Resource private ExportMetrics metrics;
|
||||
|
||||
public ExportTaskResponse create(AuthenticatedUser user, CreateExportTaskRequest request) {
|
||||
requirePlatform(user);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.baiyue.file.service;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.export.ExportContracts.ExportBatchRequest;
|
||||
import com.baiyue.common.core.export.ExportContracts.ExportBatchResponse;
|
||||
@@ -31,17 +34,16 @@ public class GenericXlsxExportRunner {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(GenericXlsxExportRunner.class);
|
||||
public static final String CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
private static final int EXCEL_SHEET_ROWS = 1_048_575;
|
||||
private final ExportProviderClient provider;
|
||||
private final ExportStorage storage;
|
||||
private final ObjectMapper objectMapper;
|
||||
private final String internalToken;
|
||||
private final long maxFileBytes;
|
||||
@Resource private ExportProviderClient provider;
|
||||
@Resource private ExportStorage storage;
|
||||
@Resource private ObjectMapper objectMapper;
|
||||
@Value("${baiyue.security.internal-service-token}") private String internalToken;
|
||||
@Value("${baiyue.file.export.task.max-file-size-mb:50}") private long maxFileSizeMb;
|
||||
private long maxFileBytes;
|
||||
|
||||
public GenericXlsxExportRunner(ExportProviderClient provider, ExportStorage storage, ObjectMapper objectMapper,
|
||||
@Value("${baiyue.security.internal-service-token}") String internalToken,
|
||||
@Value("${baiyue.file.export.task.max-file-size-mb:50}") long maxFileSizeMb) {
|
||||
this.provider = provider; this.storage = storage; this.objectMapper = objectMapper;
|
||||
this.internalToken = internalToken; this.maxFileBytes = Math.max(1, maxFileSizeMb) * 1024L * 1024L;
|
||||
@PostConstruct
|
||||
void initializeLimits() {
|
||||
maxFileBytes = Math.max(1, maxFileSizeMb) * 1024L * 1024L;
|
||||
}
|
||||
|
||||
public Result run(FileExportTask task, Definition definition, AtomicBoolean abort, LongConsumer progress) {
|
||||
|
||||
@@ -21,16 +21,14 @@ import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class LocalExportStorage implements ExportStorage {
|
||||
private final Path root;
|
||||
private final Path exportRoot;
|
||||
|
||||
public LocalExportStorage(@Value("${baiyue.file.storage-root}") String root) {
|
||||
this.root = Path.of(root).toAbsolutePath().normalize();
|
||||
this.exportRoot = this.root.resolve("exports").normalize();
|
||||
}
|
||||
@Value("${baiyue.file.storage-root}") private String configuredRoot;
|
||||
private Path root;
|
||||
private Path exportRoot;
|
||||
|
||||
@PostConstruct
|
||||
void initialize() {
|
||||
root = Path.of(configuredRoot).toAbsolutePath().normalize();
|
||||
exportRoot = root.resolve("exports").normalize();
|
||||
try {
|
||||
Files.createDirectories(exportRoot);
|
||||
if (!exportRoot.startsWith(root) || !Files.isDirectory(exportRoot) || !Files.isWritable(exportRoot)) {
|
||||
|
||||
@@ -26,17 +26,15 @@ public class LocalQualificationStorage {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(LocalQualificationStorage.class);
|
||||
private static final long MAX_SIZE = 5L * 1024 * 1024;
|
||||
private static final Set<String> TYPES = Set.of("image/jpeg", "image/png", "application/pdf");
|
||||
private final Path root;
|
||||
private final Path qualificationRoot;
|
||||
|
||||
public LocalQualificationStorage(@Value("${baiyue.file.storage-root}") String root) {
|
||||
this.root = Path.of(root).toAbsolutePath().normalize();
|
||||
this.qualificationRoot = this.root.resolve("qualifications").normalize();
|
||||
}
|
||||
@Value("${baiyue.file.storage-root}") private String configuredRoot;
|
||||
private Path root;
|
||||
private Path qualificationRoot;
|
||||
|
||||
/** 服务启动时校验存储根目录,避免健康检查正常但首次上传才暴露挂载或权限问题。 */
|
||||
@PostConstruct
|
||||
public void initialize() {
|
||||
root = Path.of(configuredRoot).toAbsolutePath().normalize();
|
||||
qualificationRoot = root.resolve("qualifications").normalize();
|
||||
try {
|
||||
Files.createDirectories(root);
|
||||
Files.createDirectories(qualificationRoot);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.baiyue.file.service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
@@ -20,19 +22,10 @@ import java.time.LocalDateTime;
|
||||
|
||||
@Service
|
||||
public class MeasurementImageService {
|
||||
private final MeasurementImageStorage storage;
|
||||
private final FileObjectMapper files;
|
||||
private final WeightOcrClient ocr;
|
||||
private final String internalToken;
|
||||
|
||||
public MeasurementImageService(MeasurementImageStorage storage, FileObjectMapper files,
|
||||
WeightOcrClient ocr,
|
||||
@Value("${baiyue.security.internal-service-token}") String internalToken) {
|
||||
this.storage = storage;
|
||||
this.files = files;
|
||||
this.ocr = ocr;
|
||||
this.internalToken = internalToken;
|
||||
}
|
||||
@Resource private MeasurementImageStorage storage;
|
||||
@Resource private FileObjectMapper files;
|
||||
@Resource private WeightOcrClient ocr;
|
||||
@Value("${baiyue.security.internal-service-token}") private String internalToken;
|
||||
|
||||
@Transactional
|
||||
public UploadResult upload(long tenantId, long inboundId, long operatorId, MultipartFile file) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.baiyue.file.service;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@@ -22,11 +23,11 @@ import java.util.UUID;
|
||||
public class MeasurementImageStorage {
|
||||
private static final long MAX_SIZE = 5L * 1024 * 1024;
|
||||
private static final Set<String> TYPES = Set.of("image/jpeg", "image/png", "image/bmp");
|
||||
private final Path root;
|
||||
@Value("${baiyue.file.storage-root}") private Path configuredRoot;
|
||||
private Path root;
|
||||
|
||||
public MeasurementImageStorage(@Value("${baiyue.file.storage-root}") Path root) {
|
||||
this.root = root.toAbsolutePath().normalize();
|
||||
}
|
||||
@PostConstruct
|
||||
void initializeRoot() { root = configuredRoot.toAbsolutePath().normalize(); }
|
||||
|
||||
public Stored store(long tenantId, long inboundId, MultipartFile file) {
|
||||
if (file == null || file.isEmpty()) throw bad("称重图片不能为空");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.baiyue.file.service;
|
||||
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
@@ -18,11 +19,11 @@ import java.util.UUID;
|
||||
@Service
|
||||
public class QualificationFileStorage {
|
||||
private static final Set<String> CONTENT_TYPES = Set.of("image/jpeg", "image/png");
|
||||
private final Path root;
|
||||
@Value("${baiyue.file.storage-root}") private String configuredRoot;
|
||||
private Path root;
|
||||
|
||||
public QualificationFileStorage(@Value("${baiyue.file.storage-root}") String root) {
|
||||
this.root = Path.of(root).toAbsolutePath().normalize().resolve("qualifications");
|
||||
}
|
||||
@PostConstruct
|
||||
void initializeRoot() { root = Path.of(configuredRoot).toAbsolutePath().normalize().resolve("qualifications"); }
|
||||
|
||||
public StoredFile store(long tenantId, MultipartFile file) {
|
||||
if (file == null || file.isEmpty()) throw new BizException("One qualification image is required");
|
||||
|
||||
@@ -103,6 +103,6 @@ logging:
|
||||
rollingpolicy:
|
||||
file-name-pattern: "${LOGGING_ROLLING_FILE_NAME_PATTERN:${LOG_PATH:./logs}/${spring.application.name}.%d{yyyy-MM-dd}.%i.log.gz}"
|
||||
max-file-size: "${LOGGING_ROLLING_MAX_FILE_SIZE:100MB}"
|
||||
max-history: "${LOGGING_ROLLING_MAX_HISTORY:30}"
|
||||
max-history: "${LOGGING_ROLLING_MAX_HISTORY:7}"
|
||||
total-size-cap: "${LOGGING_ROLLING_TOTAL_SIZE_CAP:5GB}"
|
||||
clean-history-on-start: "${LOGGING_ROLLING_CLEAN_HISTORY_ON_START:false}"
|
||||
|
||||
Reference in New Issue
Block a user