优化
This commit is contained in:
+2
-4
@@ -44,9 +44,6 @@ public class OceanBookingPrintService {
|
||||
private GeneratedPdf generate(long id, String requestId, String template, String suffix) {
|
||||
Detail detail = bookings.detail(id);
|
||||
OceanBookingEntity booking = detail.oceanBooking();
|
||||
if (!"RELEASED".equals(booking.getStatus())) {
|
||||
throw new BizException(ResultCode.CONFLICT, "订舱放舱后才可打印正式单据");
|
||||
}
|
||||
String fileName = booking.getBookingNo() + "-" + suffix + ".pdf";
|
||||
PrintPdfClient.FreightA4PdfRequest request = new PrintPdfClient.FreightA4PdfRequest(
|
||||
template, A4, fileName, List.of(new PrintPdfClient.FreightDocument(
|
||||
@@ -97,7 +94,8 @@ public class OceanBookingPrintService {
|
||||
fields.put("containerSummary", requirementSummary(detail.containerRequirements()));
|
||||
fields.put("notes", text(booking.getRemark()));
|
||||
}
|
||||
fields.values().removeIf(String::isEmpty);
|
||||
// Missing booking data is displayed explicitly, including required PDF template fields.
|
||||
fields.replaceAll((key, value) -> value.isEmpty() ? "—" : value);
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
+7
-3
@@ -9,6 +9,10 @@ import com.baiyue.firstleg.terminaldrayage.dto.TerminalDrayageDtos.FleetSelectio
|
||||
import com.baiyue.firstleg.terminaldrayage.dto.TerminalDrayageDtos.History;
|
||||
import com.baiyue.firstleg.terminaldrayage.dto.TerminalDrayageDtos.PickupAppointmentRequest;
|
||||
import com.baiyue.firstleg.terminaldrayage.dto.TerminalDrayageDtos.View;
|
||||
import com.baiyue.firstleg.terminaldrayage.dto.TerminalDrayageDtos.EmailRequest;
|
||||
import com.baiyue.firstleg.terminaldrayage.service.TerminalDrayageMailService;
|
||||
import com.baiyue.firstleg.terminaldrayage.service.TerminalDrayageMailService.Mailbox;
|
||||
import jakarta.annotation.Resource;
|
||||
import com.baiyue.firstleg.terminaldrayage.service.TerminalDrayageService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -36,20 +40,20 @@ import java.util.List;
|
||||
@Tag(name = "目的港码头拖车")
|
||||
@RequestMapping("/api/platform/v1/terminal-drayages")
|
||||
public class PlatformTerminalDrayageController {
|
||||
@jakarta.annotation.Resource private com.baiyue.firstleg.terminaldrayage.service.TerminalDrayageMailService mails;
|
||||
@Resource private TerminalDrayageMailService mails;
|
||||
|
||||
@PostMapping("/{containerBookingId}/pickup-email")
|
||||
@PreAuthorize("hasAuthority('platform:firstleg:terminal-drayage:fleet:edit')")
|
||||
public ApiResponse<View> sendPickupEmail(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable @Positive long containerBookingId, @RequestHeader("Idempotency-Key") String key,
|
||||
@Valid @RequestBody com.baiyue.firstleg.terminaldrayage.dto.TerminalDrayageDtos.EmailRequest request) {
|
||||
@Valid @RequestBody EmailRequest request) {
|
||||
FirstlegScopeGuard.platform(user);
|
||||
return ApiResponse.success(service.authorize(service.sendPickupEmail(containerBookingId, user.userId(), user.username(), key, request), user.permissions()));
|
||||
}
|
||||
|
||||
@GetMapping("/{containerBookingId}/emails")
|
||||
@PreAuthorize("hasAuthority('platform:firstleg:terminal-drayage:list')")
|
||||
public ApiResponse<com.baiyue.firstleg.terminaldrayage.service.TerminalDrayageMailService.Mailbox> emails(
|
||||
public ApiResponse<Mailbox> emails(
|
||||
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable @Positive long containerBookingId) {
|
||||
FirstlegScopeGuard.platform(user); service.detail(containerBookingId);
|
||||
return ApiResponse.success(mails.list(containerBookingId));
|
||||
|
||||
+3
-3
@@ -125,17 +125,17 @@ public interface TerminalDrayageMapper extends BaseMapper<TerminalDrayageEntity>
|
||||
@Param("kind") String kind, @Param("subject") String subject, @Param("body") String body,
|
||||
@Param("operatorId") long operatorId);
|
||||
|
||||
@Select("SELECT * FROM fl_terminal_drayage_mail WHERE container_booking_id=#{containerId} ORDER BY id DESC LIMIT 100")
|
||||
@Select("SELECT id,container_booking_id AS containerBookingId,fleet_supplier_id AS fleetSupplierId,fleet_name AS fleetName,recipient,kind,subject,body,status,attempts,failure_reason AS failureReason,created_at AS createdAt,sent_at AS sentAt FROM fl_terminal_drayage_mail WHERE container_booking_id=#{containerId} ORDER BY id DESC LIMIT 100")
|
||||
List<MailTask> mails(@Param("containerId") long containerId);
|
||||
|
||||
@Select("""
|
||||
SELECT * FROM fl_terminal_drayage_mail WHERE container_booking_id=#{containerId}
|
||||
SELECT id,container_booking_id AS containerBookingId,fleet_supplier_id AS fleetSupplierId,fleet_name AS fleetName,recipient,kind,subject,body,status,attempts,failure_reason AS failureReason,created_at AS createdAt,sent_at AS sentAt FROM fl_terminal_drayage_mail WHERE container_booking_id=#{containerId}
|
||||
AND fleet_supplier_id=#{supplierId} AND kind='REQUEST_PICKUP' ORDER BY id DESC LIMIT 1
|
||||
""")
|
||||
MailTask lastPickupMail(@Param("containerId") long containerId, @Param("supplierId") long supplierId);
|
||||
|
||||
@Select("""
|
||||
SELECT m.* FROM fl_terminal_drayage_mail m WHERE m.status='PENDING'
|
||||
SELECT m.id,m.container_booking_id AS containerBookingId,m.fleet_supplier_id AS fleetSupplierId,m.fleet_name AS fleetName,m.recipient,m.kind,m.subject,m.body,m.status,m.attempts,m.failure_reason AS failureReason,m.created_at AS createdAt,m.sent_at AS sentAt FROM fl_terminal_drayage_mail m WHERE m.status='PENDING'
|
||||
AND NOT EXISTS(SELECT 1 FROM fl_terminal_drayage_mail earlier
|
||||
WHERE earlier.container_booking_id=m.container_booking_id AND earlier.id<m.id AND earlier.status<>'SENT')
|
||||
ORDER BY m.id LIMIT 20
|
||||
|
||||
+1
-2
@@ -43,14 +43,13 @@ public class TerminalDrayageMailDispatcher {
|
||||
@Scheduled(fixedDelayString="${baiyue.terminal-drayage.mail.scan-delay:10000}")
|
||||
public void dispatch() {
|
||||
mapper.expireMails();
|
||||
var sender = sender();
|
||||
for (var mail : mapper.pendingMails()) {
|
||||
if (mapper.claimMail(mail.id()) != 1) continue;
|
||||
try {
|
||||
var message = new SimpleMailMessage();
|
||||
message.setFrom(from); message.setTo(mail.recipient());
|
||||
message.setSubject(mail.subject()); message.setText(mail.body());
|
||||
sender.send(message);
|
||||
sender().send(message);
|
||||
if (mapper.completeMail(mail.id()) != 1) log.warn("Terminal drayage mail completion requires review: {}", mail.id());
|
||||
} catch (Exception exception) {
|
||||
// SMTP 超时不等于未送达,禁止自动重发;失败阻断同柜后续邮件,交由人工核对。
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public class TerminalDrayageMailService {
|
||||
|
||||
static void validateAddress(String email) {
|
||||
try {
|
||||
if (!StringUtils.hasText(email) || email.contains("\r") || email.contains("\n")) throw new IllegalArgumentException();
|
||||
if (!StringUtils.hasText(email) || email.length() > 254 || email.contains("\r") || email.contains("\n")) throw new IllegalArgumentException();
|
||||
InternetAddress[] parsed = InternetAddress.parse(email.trim(), true);
|
||||
if (parsed.length != 1 || parsed[0].isGroup() || !email.trim().equals(parsed[0].getAddress())) throw new IllegalArgumentException();
|
||||
parsed[0].validate();
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ import com.baiyue.firstleg.terminaldrayage.mapper.TerminalDrayageMapper.Context;
|
||||
import com.baiyue.firstleg.terminaldrayage.mapper.TerminalDrayageMapper.Operation;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.baiyue.firstleg.terminaldrayage.dto.TerminalDrayageDtos.EmailRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -204,7 +205,7 @@ public class TerminalDrayageService {
|
||||
|
||||
@Transactional
|
||||
public View sendPickupEmail(long containerBookingId, long operatorId, String operatorName, String key,
|
||||
com.baiyue.firstleg.terminaldrayage.dto.TerminalDrayageDtos.EmailRequest request) {
|
||||
EmailRequest request) {
|
||||
String action = "SEND_PICKUP_EMAIL";
|
||||
WorkContext context = requiredLockedContext(containerBookingId);
|
||||
View replay = replay(context, action, key, request);
|
||||
|
||||
Reference in New Issue
Block a user