feat: merge market core user id flow

This commit is contained in:
admin123 2026-05-11 10:22:45 +08:00
parent 2e049ef718
commit 1de508f2c7
14 changed files with 90 additions and 4 deletions

View File

@ -396,7 +396,8 @@
return { return {
authors: options.records.map((record) => ({ authors: options.records.map((record) => ({
authorId: record.authorId, authorId: record.authorId,
authorName: record.authorName authorName: record.authorName,
...record.coreUserId ? { authorUid: record.coreUserId } : {}
})), })),
batchName, batchName,
createdAt: options.createdAt, createdAt: options.createdAt,
@ -442,6 +443,7 @@
return { return {
authorId: readString(readMarketFieldValue(row, attributeDatas, "star_id")) ?? readString(readMarketFieldValue(row, attributeDatas, "id")) ?? "", authorId: readString(readMarketFieldValue(row, attributeDatas, "star_id")) ?? readString(readMarketFieldValue(row, attributeDatas, "id")) ?? "",
authorName: readString(readMarketFieldValue(row, attributeDatas, "nickname")) ?? readString(readMarketFieldValue(row, attributeDatas, "nick_name")) ?? "", authorName: readString(readMarketFieldValue(row, attributeDatas, "nickname")) ?? readString(readMarketFieldValue(row, attributeDatas, "nick_name")) ?? "",
coreUserId: readString(readMarketFieldValue(row, attributeDatas, "core_user_id")) ?? void 0,
exportFields: buildMarketExportFieldFallbacks(row, attributeDatas), exportFields: buildMarketExportFieldFallbacks(row, attributeDatas),
hasDirectRatesSource: true, hasDirectRatesSource: true,
location: readMarketLocation(row, attributeDatas), location: readMarketLocation(row, attributeDatas),
@ -1737,6 +1739,7 @@
return { return {
authorId: readString2(record.authorId) ?? "", authorId: readString2(record.authorId) ?? "",
authorName: readString2(record.authorName) ?? "", authorName: readString2(record.authorName) ?? "",
coreUserId: readString2(record.coreUserId) ?? void 0,
exportFields: readSerializedExportFields(record), exportFields: readSerializedExportFields(record),
hasDirectRatesSource: Boolean(singleVideoAfterSearchRate), hasDirectRatesSource: Boolean(singleVideoAfterSearchRate),
location: readString2(record.location) ?? void 0, location: readString2(record.location) ?? void 0,
@ -1959,6 +1962,7 @@
return { return {
authorId: preferredRow.authorId || baseRow.authorId, authorId: preferredRow.authorId || baseRow.authorId,
authorName: preferredRow.authorName || baseRow.authorName, authorName: preferredRow.authorName || baseRow.authorName,
coreUserId: mergeNonEmptyString(baseRow.coreUserId, preferredRow.coreUserId),
exportFields: mergeExportFieldMaps(baseRow.exportFields, preferredRow.exportFields), exportFields: mergeExportFieldMaps(baseRow.exportFields, preferredRow.exportFields),
hasDirectRatesSource: preferredRow.hasDirectRatesSource || baseRow.hasDirectRatesSource, hasDirectRatesSource: preferredRow.hasDirectRatesSource || baseRow.hasDirectRatesSource,
location: mergeNonEmptyString(baseRow.location, preferredRow.location), location: mergeNonEmptyString(baseRow.location, preferredRow.location),
@ -2431,6 +2435,7 @@
...existingRecord, ...existingRecord,
...incomingRecord, ...incomingRecord,
authorName: mergeStringValue(existingRecord.authorName, incomingRecord.authorName) ?? "", authorName: mergeStringValue(existingRecord.authorName, incomingRecord.authorName) ?? "",
coreUserId: mergeStringValue(existingRecord.coreUserId, incomingRecord.coreUserId),
exportFields: mergeFieldMap( exportFields: mergeFieldMap(
existingRecord.exportFields, existingRecord.exportFields,
incomingRecord.exportFields incomingRecord.exportFields
@ -3218,6 +3223,7 @@
...existingRecord, ...existingRecord,
...incomingRecord, ...incomingRecord,
authorName: mergeStringValue2(existingRecord.authorName, incomingRecord.authorName) ?? "", authorName: mergeStringValue2(existingRecord.authorName, incomingRecord.authorName) ?? "",
coreUserId: mergeStringValue2(existingRecord.coreUserId, incomingRecord.coreUserId),
exportFields: mergeFieldMap2( exportFields: mergeFieldMap2(
existingRecord.exportFields, existingRecord.exportFields,
incomingRecord.exportFields incomingRecord.exportFields
@ -3308,6 +3314,10 @@
const existingRecord = records.get(row.authorId); const existingRecord = records.get(row.authorId);
if (existingRecord) { if (existingRecord) {
existingRecord.authorName = mergeStringValue3(existingRecord.authorName, row.authorName) ?? existingRecord.authorName; existingRecord.authorName = mergeStringValue3(existingRecord.authorName, row.authorName) ?? existingRecord.authorName;
existingRecord.coreUserId = mergeStringValue3(
existingRecord.coreUserId,
row.coreUserId
);
existingRecord.location = mergeStringValue3( existingRecord.location = mergeStringValue3(
existingRecord.location, existingRecord.location,
row.location row.location
@ -3925,6 +3935,10 @@
function toMarketRecord(rowSnapshot) { function toMarketRecord(rowSnapshot) {
const existingRecord = resultStore.getRecord(rowSnapshot.authorId); const existingRecord = resultStore.getRecord(rowSnapshot.authorId);
const authorName = mergeStringValue4(existingRecord?.authorName, rowSnapshot.authorName) ?? ""; const authorName = mergeStringValue4(existingRecord?.authorName, rowSnapshot.authorName) ?? "";
const coreUserId = mergeStringValue4(
existingRecord?.coreUserId,
rowSnapshot.coreUserId
);
const location2 = mergeStringValue4(existingRecord?.location, rowSnapshot.location); const location2 = mergeStringValue4(existingRecord?.location, rowSnapshot.location);
const price21To60s = mergeStringValue4( const price21To60s = mergeStringValue4(
existingRecord?.price21To60s, existingRecord?.price21To60s,
@ -3939,6 +3953,7 @@
rowSnapshot.backendMetrics rowSnapshot.backendMetrics
), ),
backendMetricsStatus: existingRecord?.backendMetricsStatus ?? "idle", backendMetricsStatus: existingRecord?.backendMetricsStatus ?? "idle",
coreUserId,
exportFields: withExportFieldFallbacks( exportFields: withExportFieldFallbacks(
mergeFieldMap4(existingRecord?.exportFields, rowSnapshot.exportFields), mergeFieldMap4(existingRecord?.exportFields, rowSnapshot.exportFields),
{ {

View File

@ -58,6 +58,7 @@
return { return {
authorId: readString(readMarketFieldValue(row, attributeDatas, "star_id")) ?? readString(readMarketFieldValue(row, attributeDatas, "id")) ?? "", authorId: readString(readMarketFieldValue(row, attributeDatas, "star_id")) ?? readString(readMarketFieldValue(row, attributeDatas, "id")) ?? "",
authorName: readString(readMarketFieldValue(row, attributeDatas, "nickname")) ?? readString(readMarketFieldValue(row, attributeDatas, "nick_name")) ?? "", authorName: readString(readMarketFieldValue(row, attributeDatas, "nickname")) ?? readString(readMarketFieldValue(row, attributeDatas, "nick_name")) ?? "",
coreUserId: readString(readMarketFieldValue(row, attributeDatas, "core_user_id")) ?? void 0,
exportFields: buildMarketExportFieldFallbacks(row, attributeDatas), exportFields: buildMarketExportFieldFallbacks(row, attributeDatas),
hasDirectRatesSource: true, hasDirectRatesSource: true,
location: readMarketLocation(row, attributeDatas), location: readMarketLocation(row, attributeDatas),
@ -504,6 +505,7 @@
return { return {
authorId: readString2(row.star_id) ?? readString2(attributeDatas.id) ?? "", authorId: readString2(row.star_id) ?? readString2(attributeDatas.id) ?? "",
authorName: readString2(attributeDatas.nickname) ?? readString2(row.nick_name) ?? "", authorName: readString2(attributeDatas.nickname) ?? readString2(row.nick_name) ?? "",
coreUserId: readString2(attributeDatas.core_user_id) ?? void 0,
singleVideoAfterSearchRate singleVideoAfterSearchRate
}; };
}).filter((row) => Boolean(row.authorId || row.authorName)); }).filter((row) => Boolean(row.authorId || row.authorName));

View File

@ -5,6 +5,7 @@ export interface BatchPayload {
authors: Array<{ authors: Array<{
authorId: string; authorId: string;
authorName: string; authorName: string;
authorUid?: string;
}>; }>;
batchName: string; batchName: string;
createdAt: string; createdAt: string;
@ -37,7 +38,8 @@ export function createBatchPayload(options: {
return { return {
authors: options.records.map((record) => ({ authors: options.records.map((record) => ({
authorId: record.authorId, authorId: record.authorId,
authorName: record.authorName authorName: record.authorName,
...(record.coreUserId ? { authorUid: record.coreUserId } : {})
})), })),
batchName, batchName,
createdAt: options.createdAt, createdAt: options.createdAt,

View File

@ -70,6 +70,7 @@ type RowOrderTarget = {
type MarketDataRow = { type MarketDataRow = {
authorId: string; authorId: string;
authorName: string; authorName: string;
coreUserId?: string;
exportFields?: Record<string, string>; exportFields?: Record<string, string>;
hasDirectRatesSource: boolean; hasDirectRatesSource: boolean;
location?: string; location?: string;
@ -1341,6 +1342,7 @@ function readSerializedMarketRows(
return { return {
authorId: readString(record.authorId) ?? "", authorId: readString(record.authorId) ?? "",
authorName: readString(record.authorName) ?? "", authorName: readString(record.authorName) ?? "",
coreUserId: readString(record.coreUserId) ?? undefined,
exportFields: readSerializedExportFields(record), exportFields: readSerializedExportFields(record),
hasDirectRatesSource: Boolean(singleVideoAfterSearchRate), hasDirectRatesSource: Boolean(singleVideoAfterSearchRate),
location: readString(record.location) ?? undefined, location: readString(record.location) ?? undefined,
@ -1662,6 +1664,7 @@ function mergeMarketDataRows(
return { return {
authorId: preferredRow.authorId || baseRow.authorId, authorId: preferredRow.authorId || baseRow.authorId,
authorName: preferredRow.authorName || baseRow.authorName, authorName: preferredRow.authorName || baseRow.authorName,
coreUserId: mergeNonEmptyString(baseRow.coreUserId, preferredRow.coreUserId),
exportFields: mergeExportFieldMaps(baseRow.exportFields, preferredRow.exportFields), exportFields: mergeExportFieldMaps(baseRow.exportFields, preferredRow.exportFields),
hasDirectRatesSource: hasDirectRatesSource:
preferredRow.hasDirectRatesSource || baseRow.hasDirectRatesSource, preferredRow.hasDirectRatesSource || baseRow.hasDirectRatesSource,

View File

@ -222,6 +222,7 @@ function mergeMarketRecord(
...existingRecord, ...existingRecord,
...incomingRecord, ...incomingRecord,
authorName: mergeStringValue(existingRecord.authorName, incomingRecord.authorName) ?? "", authorName: mergeStringValue(existingRecord.authorName, incomingRecord.authorName) ?? "",
coreUserId: mergeStringValue(existingRecord.coreUserId, incomingRecord.coreUserId),
exportFields: mergeFieldMap( exportFields: mergeFieldMap(
existingRecord.exportFields, existingRecord.exportFields,
incomingRecord.exportFields incomingRecord.exportFields

View File

@ -707,6 +707,10 @@ export function createMarketController(options: CreateMarketControllerOptions) {
const existingRecord = resultStore.getRecord(rowSnapshot.authorId); const existingRecord = resultStore.getRecord(rowSnapshot.authorId);
const authorName = const authorName =
mergeStringValue(existingRecord?.authorName, rowSnapshot.authorName) ?? ""; mergeStringValue(existingRecord?.authorName, rowSnapshot.authorName) ?? "";
const coreUserId = mergeStringValue(
existingRecord?.coreUserId,
rowSnapshot.coreUserId
);
const location = mergeStringValue(existingRecord?.location, rowSnapshot.location); const location = mergeStringValue(existingRecord?.location, rowSnapshot.location);
const price21To60s = mergeStringValue( const price21To60s = mergeStringValue(
existingRecord?.price21To60s, existingRecord?.price21To60s,
@ -721,6 +725,7 @@ export function createMarketController(options: CreateMarketControllerOptions) {
rowSnapshot.backendMetrics rowSnapshot.backendMetrics
), ),
backendMetricsStatus: existingRecord?.backendMetricsStatus ?? "idle", backendMetricsStatus: existingRecord?.backendMetricsStatus ?? "idle",
coreUserId,
exportFields: withExportFieldFallbacks( exportFields: withExportFieldFallbacks(
mergeFieldMap(existingRecord?.exportFields, rowSnapshot.exportFields), mergeFieldMap(existingRecord?.exportFields, rowSnapshot.exportFields),
{ {

View File

@ -57,6 +57,9 @@ export function mapMarketListRow(
readString(readMarketFieldValue(row, attributeDatas, "nickname")) ?? readString(readMarketFieldValue(row, attributeDatas, "nickname")) ??
readString(readMarketFieldValue(row, attributeDatas, "nick_name")) ?? readString(readMarketFieldValue(row, attributeDatas, "nick_name")) ??
"", "",
coreUserId:
readString(readMarketFieldValue(row, attributeDatas, "core_user_id")) ??
undefined,
exportFields: buildMarketExportFieldFallbacks(row, attributeDatas), exportFields: buildMarketExportFieldFallbacks(row, attributeDatas),
hasDirectRatesSource: true, hasDirectRatesSource: true,
location: readMarketLocation(row, attributeDatas), location: readMarketLocation(row, attributeDatas),

View File

@ -205,6 +205,7 @@ function readSerializedMarketRows() {
readString(row.star_id) ?? readString(attributeDatas.id) ?? "", readString(row.star_id) ?? readString(attributeDatas.id) ?? "",
authorName: authorName:
readString(attributeDatas.nickname) ?? readString(row.nick_name) ?? "", readString(attributeDatas.nickname) ?? readString(row.nick_name) ?? "",
coreUserId: readString(attributeDatas.core_user_id) ?? undefined,
singleVideoAfterSearchRate singleVideoAfterSearchRate
}; };
}) })

View File

@ -61,6 +61,10 @@ export function createMarketResultStore() {
existingRecord.authorName = existingRecord.authorName =
mergeStringValue(existingRecord.authorName, row.authorName) ?? mergeStringValue(existingRecord.authorName, row.authorName) ??
existingRecord.authorName; existingRecord.authorName;
existingRecord.coreUserId = mergeStringValue(
existingRecord.coreUserId,
row.coreUserId
);
existingRecord.location = mergeStringValue( existingRecord.location = mergeStringValue(
existingRecord.location, existingRecord.location,
row.location row.location

View File

@ -350,6 +350,7 @@ function mergeMarketRecord(
...existingRecord, ...existingRecord,
...incomingRecord, ...incomingRecord,
authorName: mergeStringValue(existingRecord.authorName, incomingRecord.authorName) ?? "", authorName: mergeStringValue(existingRecord.authorName, incomingRecord.authorName) ?? "",
coreUserId: mergeStringValue(existingRecord.coreUserId, incomingRecord.coreUserId),
exportFields: mergeFieldMap( exportFields: mergeFieldMap(
existingRecord.exportFields, existingRecord.exportFields,
incomingRecord.exportFields incomingRecord.exportFields

View File

@ -22,6 +22,7 @@ export interface MarketRowSnapshot {
authorId: string; authorId: string;
authorName: string; authorName: string;
backendMetrics?: BackendMetrics; backendMetrics?: BackendMetrics;
coreUserId?: string;
exportFields?: Record<string, string>; exportFields?: Record<string, string>;
hasDirectRatesSource?: boolean; hasDirectRatesSource?: boolean;
location?: string; location?: string;

View File

@ -16,14 +16,19 @@ describe("batch-payload", () => {
batchName: "618达人筛选第一批", batchName: "618达人筛选第一批",
createdAt: "2026-04-22T12:30:00.000Z", createdAt: "2026-04-22T12:30:00.000Z",
records: [ records: [
{ authorId: "111", authorName: "达人A", status: "success" }, {
authorId: "111",
authorName: "达人A",
coreUserId: "core-111",
status: "success"
},
{ authorId: "222", authorName: "达人B", status: "success" } { authorId: "222", authorName: "达人B", status: "success" }
] ]
}); });
expect(payload).toEqual({ expect(payload).toEqual({
authors: [ authors: [
{ authorId: "111", authorName: "达人A" }, { authorId: "111", authorName: "达人A", authorUid: "core-111" },
{ authorId: "222", authorName: "达人B" } { authorId: "222", authorName: "达人B" }
], ],
batchName: "618达人筛选第一批", batchName: "618达人筛选第一批",

View File

@ -126,4 +126,42 @@ describe("market-page-bridge", () => {
}) })
); );
}); });
test("serializes core user ids from the live market list", async () => {
const marketRoot = document.querySelector(".base-author-list") as HTMLElement & {
__vue__?: {
_setupState?: Record<string, unknown>;
};
};
marketRoot.__vue__ = {
_setupState: {
marketState: {
marketList: [
{
attribute_datas: {
avg_search_after_view_rate_30d: "0.1234",
core_user_id: "core-111",
nickname: "搜索达人"
},
star_id: "search-1"
}
]
}
}
};
await import("../src/content/market/page-bridge");
expect(
JSON.parse(
document.documentElement.getAttribute("data-sces-market-rows") ?? "[]"
)
).toEqual([
expect.objectContaining({
authorId: "search-1",
authorName: "搜索达人",
coreUserId: "core-111"
})
]);
});
}); });

View File

@ -50,6 +50,7 @@ describe("silent-export-controller", () => {
authors: [ authors: [
{ {
attribute_datas: { attribute_datas: {
core_user_id: `core-${pageNo}`,
nickname: `达人${pageNo}`, nickname: `达人${pageNo}`,
price_20_60: pageNo * 1000 price_20_60: pageNo * 1000
}, },
@ -93,6 +94,10 @@ describe("silent-export-controller", () => {
} }
]); ]);
expect(records?.map((record) => record.authorId)).toEqual(["2", "3"]); expect(records?.map((record) => record.authorId)).toEqual(["2", "3"]);
expect(records?.map((record) => record.coreUserId)).toEqual([
"core-2",
"core-3"
]);
}); });
test("replays paged exports when the page number is nested inside the request body", async () => { test("replays paged exports when the page number is nested inside the request body", async () => {