This commit is contained in:
2026-05-11 16:15:48 +08:00
parent 0c9254502c
commit e30b733b17
87 changed files with 3527 additions and 1261 deletions

View File

@@ -182,7 +182,6 @@ export interface AdminUpsertProfileRedeemCodeRequest {
export interface AdminUpsertProfileInviteCodeRequest {
inviteCode: string;
metadata?: Record<string, unknown>;
grantedUserTags: string[];
startsAt?: string | null;
expiresAt?: string | null;
}
@@ -229,7 +228,6 @@ export interface ProfileInviteCodeAdminResponse {
userId: string;
inviteCode: string;
metadata: Record<string, unknown>;
grantedUserTags: string[];
startsAt?: string | null;
expiresAt?: string | null;
status: 'pending' | 'active' | 'expired';

View File

@@ -78,10 +78,13 @@ export function AdminInviteCodePage({
setIsSaving(true);
try {
const metadata = withMetadataUserTags(
parseMetadata(metadataText),
parseUserTags(grantedTagsText),
);
const payload: AdminUpsertProfileInviteCodeRequest = {
inviteCode: inviteCode.trim(),
metadata: parseMetadata(metadataText),
grantedUserTags: parseUserTags(grantedTagsText),
metadata,
startsAt: startsAt ? toIsoDateTime(startsAt) : null,
expiresAt: expiresAt ? toIsoDateTime(expiresAt) : null,
};
@@ -117,7 +120,7 @@ export function AdminInviteCodePage({
setInviteCode(entry.inviteCode);
setStartsAt(toDateTimeLocalValue(entry.startsAt));
setExpiresAt(toDateTimeLocalValue(entry.expiresAt));
setGrantedTagsText(entry.grantedUserTags.join('、'));
setGrantedTagsText(metadataUserTags(entry.metadata).join('、'));
setMetadataText(JSON.stringify(entry.metadata, null, 2));
}
@@ -252,7 +255,7 @@ export function AdminInviteCodePage({
</button>
</td>
<td>
<TagList tags={entry.grantedUserTags} />
<TagList tags={metadataUserTags(entry.metadata)} />
</td>
<td>
<span className={`admin-status ${inviteValidityClass(entry)}`}>
@@ -291,7 +294,7 @@ export function AdminInviteCodePage({
<div>
<dt></dt>
<dd>
<TagList tags={result.grantedUserTags} />
<TagList tags={metadataUserTags(result.metadata)} />
</dd>
</div>
<div>
@@ -338,6 +341,29 @@ function TagList({tags}: {tags: string[]}) {
);
}
function metadataUserTags(metadata: Record<string, unknown>) {
const raw = metadata.userTags ?? metadata.user_tags;
if (!Array.isArray(raw)) {
return [];
}
return parseUserTags(raw.filter((value): value is string => typeof value === 'string').join('、'));
}
function withMetadataUserTags(
metadata: Record<string, unknown>,
tags: string[],
): Record<string, unknown> {
const next = {...metadata};
delete next.user_tags;
if (tags.length) {
next.userTags = tags;
} else {
delete next.userTags;
}
return next;
}
function parseUserTags(value: string) {
const tags: string[] = [];
for (const raw of value.split(/[\n,;;、]+/)) {