feat: add mojia sku sync platform api

This commit is contained in:
2026-09-21 23:07:21 +08:00
parent 74ed71bfc0
commit 914c6fbebf
4 changed files with 216 additions and 0 deletions
@@ -0,0 +1,57 @@
package com.baiyue.firstleg.controller;
import com.baiyue.common.core.api.ApiResponse;
import com.baiyue.common.core.api.PageResult;
import com.baiyue.firstleg.dto.MojiaSkuSyncDtos;
import com.baiyue.firstleg.service.FirstlegScopeGuard;
import com.baiyue.firstleg.service.MojiaSkuSyncService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import com.baiyue.common.security.AuthenticatedUser;
@Tag(name = "墨家一件代发SKU同步")
@RestController
@RequestMapping("/api/platform/v1/firstleg/mojia-sku-sync")
public class PlatformMojiaSkuSyncController {
@Resource private MojiaSkuSyncService service;
@GetMapping
@PreAuthorize("hasAuthority('platform:mojia-sku-sync:list')")
@Operation(summary = "查询墨家一件代发SKU测量记录")
public ApiResponse<PageResult<MojiaSkuSyncDtos.Record>> page(
@AuthenticationPrincipal AuthenticatedUser user,
@RequestParam(required = false) String skuCode,
@RequestParam(required = false) String syncStatus,
@RequestParam(defaultValue = "1") @Min(1) long page,
@RequestParam(defaultValue = "20") @Min(1) @Max(200) long size) {
FirstlegScopeGuard.platform(user);
return ApiResponse.success(service.page(new MojiaSkuSyncDtos.Query(skuCode, syncStatus, page, size)));
}
@PutMapping("/{id}")
@PreAuthorize("hasAuthority('platform:mojia-sku-sync:edit')")
@Operation(summary = "编辑墨家一件代发SKU测量数据")
public ApiResponse<MojiaSkuSyncDtos.Record> update(
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable long id,
@Valid @RequestBody MojiaSkuSyncDtos.UpdateRequest request) {
FirstlegScopeGuard.platform(user);
return ApiResponse.success(service.update(id, request));
}
@PostMapping("/{id}/retry")
@PreAuthorize("hasAuthority('platform:mojia-sku-sync:retry')")
@Operation(summary = "重新推送失败的墨家一件代发SKU")
public ApiResponse<MojiaSkuSyncDtos.Record> retry(
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable long id,
@Valid @RequestBody MojiaSkuSyncDtos.RetryRequest request) {
FirstlegScopeGuard.platform(user);
return ApiResponse.success(service.retry(id, request));
}
}
@@ -0,0 +1,30 @@
package com.baiyue.firstleg.dto;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.math.BigDecimal;
import java.time.LocalDateTime;
public final class MojiaSkuSyncDtos {
private MojiaSkuSyncDtos() {}
public record Query(String skuCode, String syncStatus, long page, long size) {}
public record UpdateRequest(
@NotBlank @Size(max = 128) String skuCode,
@NotNull @DecimalMin("0.001") BigDecimal lengthCm,
@NotNull @DecimalMin("0.001") BigDecimal widthCm,
@NotNull @DecimalMin("0.001") BigDecimal heightCm,
@NotNull @DecimalMin("0.001") BigDecimal weightKg,
@NotNull Integer revision) {}
public record RetryRequest(@NotNull Integer revision) {}
public record Record(
Long id, String skuCode, BigDecimal lengthCm, BigDecimal widthCm, BigDecimal heightCm,
BigDecimal weightKg, Long imageFileId, LocalDateTime measuredAt, LocalDateTime receivedAt,
String syncStatus, String syncFailureCode, String syncFailureReason, String lingxingSkuId,
Integer revision, LocalDateTime updatedAt) {}
}
@@ -0,0 +1,63 @@
package com.baiyue.firstleg.repository;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baiyue.common.core.api.PageResult;
import com.baiyue.firstleg.entity.MojiaMeasurementReceiptEntity;
import com.baiyue.firstleg.mapper.MojiaMeasurementReceiptMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;
@Repository
public class MojiaSkuSyncRepository {
@Resource private MojiaMeasurementReceiptMapper mapper;
public PageResult<MojiaMeasurementReceiptEntity> page(String skuCode, String syncStatus,
long page, long size) {
return PageResult.from(mapper.selectPage(new Page<>(page, size),
new LambdaQueryWrapper<MojiaMeasurementReceiptEntity>()
.eq(MojiaMeasurementReceiptEntity::getMeasurementKind, "SKU")
.eq(StringUtils.hasText(syncStatus), MojiaMeasurementReceiptEntity::getSyncStatus, syncStatus)
.like(StringUtils.hasText(skuCode), MojiaMeasurementReceiptEntity::getBoxCode, skuCode.trim())
.orderByDesc(MojiaMeasurementReceiptEntity::getMeasuredAt)
.orderByDesc(MojiaMeasurementReceiptEntity::getId)));
}
public MojiaMeasurementReceiptEntity find(long id) {
return mapper.selectOne(new LambdaQueryWrapper<MojiaMeasurementReceiptEntity>()
.eq(MojiaMeasurementReceiptEntity::getId, id)
.eq(MojiaMeasurementReceiptEntity::getMeasurementKind, "SKU"));
}
public int updateMeasurement(MojiaMeasurementReceiptEntity value, int revision) {
return mapper.update(null, new LambdaUpdateWrapper<MojiaMeasurementReceiptEntity>()
.eq(MojiaMeasurementReceiptEntity::getId, value.getId())
.eq(MojiaMeasurementReceiptEntity::getMeasurementKind, "SKU")
.eq(MojiaMeasurementReceiptEntity::getRevision, revision)
.set(MojiaMeasurementReceiptEntity::getBoxCode, value.getBoxCode())
.set(MojiaMeasurementReceiptEntity::getLengthCm, value.getLengthCm())
.set(MojiaMeasurementReceiptEntity::getWidthCm, value.getWidthCm())
.set(MojiaMeasurementReceiptEntity::getHeightCm, value.getHeightCm())
.set(MojiaMeasurementReceiptEntity::getWeightKg, value.getWeightKg())
.set(MojiaMeasurementReceiptEntity::getSyncStatus, "PENDING")
.set(MojiaMeasurementReceiptEntity::getSyncFailureCode, null)
.set(MojiaMeasurementReceiptEntity::getSyncFailureReason, null)
.set(MojiaMeasurementReceiptEntity::getStatus, "SKU_PENDING_SYNC")
.set(MojiaMeasurementReceiptEntity::getRevision, revision + 1));
}
public int retry(long id, int revision) {
return mapper.update(null, new LambdaUpdateWrapper<MojiaMeasurementReceiptEntity>()
.eq(MojiaMeasurementReceiptEntity::getId, id)
.eq(MojiaMeasurementReceiptEntity::getMeasurementKind, "SKU")
.eq(MojiaMeasurementReceiptEntity::getRevision, revision)
.eq(MojiaMeasurementReceiptEntity::getSyncStatus, "FAILED")
.set(MojiaMeasurementReceiptEntity::getSyncStatus, "PENDING")
.set(MojiaMeasurementReceiptEntity::getSyncFailureCode, null)
.set(MojiaMeasurementReceiptEntity::getSyncFailureReason, null)
.set(MojiaMeasurementReceiptEntity::getStatus, "SKU_PENDING_SYNC")
.set(MojiaMeasurementReceiptEntity::getRevision, revision + 1));
}
}
@@ -0,0 +1,66 @@
package com.baiyue.firstleg.service;
import com.baiyue.common.core.api.PageResult;
import com.baiyue.common.core.api.ResultCode;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.firstleg.dto.MojiaSkuSyncDtos;
import com.baiyue.firstleg.entity.MojiaMeasurementReceiptEntity;
import com.baiyue.firstleg.repository.MojiaSkuSyncRepository;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class MojiaSkuSyncService {
@Resource private MojiaSkuSyncRepository repository;
public PageResult<MojiaSkuSyncDtos.Record> page(MojiaSkuSyncDtos.Query query) {
PageResult<MojiaMeasurementReceiptEntity> source = repository.page(
query.skuCode(), query.syncStatus(), query.page(), query.size());
return new PageResult<>(source.records().stream().map(MojiaSkuSyncService::view).toList(),
source.page(), source.size(), source.total(), source.pages());
}
@Transactional
public MojiaSkuSyncDtos.Record update(long id, MojiaSkuSyncDtos.UpdateRequest request) {
MojiaMeasurementReceiptEntity value = required(id);
if (repository.updateMeasurement(copy(value, request), request.revision()) != 1) {
throw conflict("SKU测量记录已被其他人修改,请刷新后重试");
}
return view(required(id));
}
@Transactional
public MojiaSkuSyncDtos.Record retry(long id, MojiaSkuSyncDtos.RetryRequest request) {
required(id);
if (repository.retry(id, request.revision()) != 1) {
throw conflict("仅同步失败记录可重新推送,或记录已被其他人修改");
}
return view(required(id));
}
private MojiaMeasurementReceiptEntity required(long id) {
MojiaMeasurementReceiptEntity value = repository.find(id);
if (value == null) throw new BizException(ResultCode.NOT_FOUND, "一件代发SKU测量记录不存在");
return value;
}
private static MojiaMeasurementReceiptEntity copy(MojiaMeasurementReceiptEntity value,
MojiaSkuSyncDtos.UpdateRequest request) {
value.setBoxCode(request.skuCode().trim());
value.setLengthCm(request.lengthCm()); value.setWidthCm(request.widthCm());
value.setHeightCm(request.heightCm()); value.setWeightKg(request.weightKg());
return value;
}
private static MojiaSkuSyncDtos.Record view(MojiaMeasurementReceiptEntity value) {
return new MojiaSkuSyncDtos.Record(value.getId(), value.getBoxCode(), value.getLengthCm(),
value.getWidthCm(), value.getHeightCm(), value.getWeightKg(), value.getImageFileId(),
value.getMeasuredAt(), value.getCreatedAt(), value.getSyncStatus(), value.getSyncFailureCode(),
value.getSyncFailureReason(), value.getLingxingSkuId(), value.getRevision(), value.getUpdatedAt());
}
private static BizException conflict(String message) {
return new BizException(ResultCode.CONFLICT, message);
}
}