feat(market): 我的发布记录按发生时间统一倒序

PublishRecordItem 加 occurredAt(草稿=createTime/申请=submittedAt),
listMyPublishRecords 合并 draft+request 后按 occurredAt 倒序(nullsLast),
对齐 market 其它列表 orderByDesc;前端 MyPublishRecord 同步 occurredAt 契约。

验证:market 模块 test 绿(mock 时间 null,nullsLast 稳定保序不破坏断言)、
前端 tsc+vitest 绿、page.request 真后端直查证列表倒序生效(最新在首页)。

注:market-publish:65 e2e 仍 fail,真根因是前端提交后列表写后读慢一拍
(非排序,详见进度总账),属 market 工作线专项。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
lili 2026-06-21 11:44:21 -07:00
parent a1a7cd8379
commit d8ed40dc4d
6 changed files with 21 additions and 5 deletions

View File

@ -77,6 +77,7 @@ public interface MarketPublishService {
*/
record PublishRecordItem(String assetId, String assetName, String assetType, String version,
String status, String nextAction, String governanceStatus,
String appealStatus, String exposureRange, String marketAssetId) {
String appealStatus, String exposureRange, String marketAssetId,
LocalDateTime occurredAt) {
}
}

View File

@ -29,6 +29,7 @@ import org.springframework.util.StringUtils;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -326,6 +327,10 @@ public class MarketPublishServiceImpl implements MarketPublishService {
.map(request -> toRecordItem(tenantId, loginUserId, assetType, request))
.filter(Objects::nonNull)
.forEach(list::add);
// 草稿(分页)与申请(全量)合并后按发生时间统一倒序(最新在前),修复"最新发布记录落到首页外"——
// 原直接拼接无统一排序,与 market 其它列表 orderByDesc 不一致;occurredAt 为 null 时排末尾且保持稳定序。
list.sort(Comparator.comparing(PublishRecordItem::occurredAt,
Comparator.nullsLast(Comparator.reverseOrder())));
log.info("[listMyPublishRecords][Market 我的发布记录查询完成,tenantId={}, userId={}, total={}]",
tenantId, loginUserId, list.size());
return new PageResult<>(list, (long) list.size());
@ -561,7 +566,9 @@ public class MarketPublishServiceImpl implements MarketPublishService {
null,
"publisher_only",
// 草稿阶段尚无物化市场资产,申诉入口不放开。
null);
null,
// 草稿态以创建时间为发生时间,供列表统一倒序。
draft.getCreateTime());
}
private PublishRecordItem toRecordItem(Long tenantId, Long loginUserId, String assetType,
@ -577,7 +584,7 @@ public class MarketPublishServiceImpl implements MarketPublishService {
return assetType == null ? new PublishRecordItem(String.valueOf(request.getId()),
String.valueOf(request.getAssetId()), null, String.valueOf(request.getDraftVersion()),
request.getStatus(), nextAction(request.getStatus()), null, appealStatus, "publisher_only",
marketAssetId) : null;
marketAssetId, firstNonNull(request.getSubmittedAt(), request.getCreateTime())) : null;
}
if (StringUtils.hasText(assetType) && !assetType.equals(draft.getAssetType())) {
return null;
@ -593,7 +600,8 @@ public class MarketPublishServiceImpl implements MarketPublishService {
null,
appealStatus,
"publisher_only",
marketAssetId);
marketAssetId,
firstNonNull(request.getSubmittedAt(), draft.getCreateTime()));
}
/**

View File

@ -161,6 +161,7 @@ public class AppMuseMarketPublishController {
respVO.setAppealStatus(item.appealStatus());
respVO.setExposureRange(item.exposureRange());
respVO.setMarketAssetId(item.marketAssetId());
respVO.setOccurredAt(item.occurredAt());
return respVO;
}
}

View File

@ -3,6 +3,8 @@ package cn.iocoder.muse.module.market.controller.app.muse.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* Market 我的发布记录条目。
*/
@ -21,4 +23,6 @@ public class MarketPublishRecordItemRespVO {
private String exposureRange;
/** 已物化 muse_market_asset.id(资产已物化且归属当前发布者时非空);申诉(appeal)需以此为 assetId,UI 据此放开「发起申诉」。 */
private String marketAssetId;
/** 记录发生时间(草稿=创建时间、申请=提交时间);列表按此统一倒序,UI 可据此展示时间。 */
private LocalDateTime occurredAt;
}

View File

@ -185,7 +185,7 @@ class AppMuseMarketPublishControllerTest extends BaseMockitoUnitTest {
setLoginUser(9001L);
when(publishService.listMyPublishRecords(9001L, "1", 1, 20, "work", "draft"))
.thenReturn(new PageResult<>(List.of(new MarketPublishService.PublishRecordItem("8101",
"可发布作品", "work", "2", "draft", "run_check", null, null, "publisher_only", null)), 1L));
"可发布作品", "work", "2", "draft", "run_check", null, null, "publisher_only", null, null)), 1L));
mockMvc.perform(get("/muse/marketplace/my-publish-records")
.header("X-API-Version", "1")

View File

@ -14,6 +14,8 @@ export interface MyPublishRecord {
exposureRange: string | null;
/** 已物化 muse_market_asset.id(资产已物化且归属当前发布者时非空);申诉以此为 assetId,仅此时放开「发起申诉」入口。 */
marketAssetId: string | null;
/** 记录发生时间(草稿=创建、申请=提交);后端已按此统一倒序,最新在前。 */
occurredAt?: string | null;
}
export interface MyPublishRecordsResult {