发布界面优化

This commit is contained in:
yml2213
2026-05-23 13:47:26 +08:00
parent d90f31360f
commit e6cc9f1255
12 changed files with 607 additions and 65 deletions
+138
View File
@@ -28,6 +28,42 @@ export interface PublishScreenshotSlot {
hint: string
}
export interface PublishPriceConfig {
deposit_placeholder: string
price_placeholder: string
ratio_description: string
}
export interface PublishInsuranceBaseRatio {
insurance: string
ratio: number
}
export interface PublishRatioConfigItem {
key: string
label: string
kind: string
group_key?: string
missing_penalty: number
}
export interface PublishCoinCorrection {
threshold_m: number
correction: number
}
export interface PublishRentRule {
threshold_m: number
days: number
}
export interface PublishRatioConfig {
insurance_base_ratios: PublishInsuranceBaseRatio[]
config_items: PublishRatioConfigItem[]
coin_corrections: PublishCoinCorrection[]
rent_rules: PublishRentRule[]
}
export interface ListingPublishOptions {
server_options: string[]
face_options: string[]
@@ -39,6 +75,10 @@ export interface ListingPublishOptions {
skin_groups: PublishOptionGroup[]
quantity_items: PublishQuantityItem[]
screenshot_slots: PublishScreenshotSlot[]
ban_record_options: string[]
ban_evidence_options: string[]
price_config: PublishPriceConfig
ratio_config: PublishRatioConfig
}
interface ApiResponse<T> {
@@ -58,6 +98,19 @@ export const emptyListingPublishOptions: ListingPublishOptions = {
skin_groups: [],
quantity_items: [],
screenshot_slots: [],
ban_record_options: [],
ban_evidence_options: [],
price_config: {
deposit_placeholder: '',
price_placeholder: '',
ratio_description: '',
},
ratio_config: {
insurance_base_ratios: [],
config_items: [],
coin_corrections: [],
rent_rules: [],
},
}
export async function fetchListingPublishOptions() {
@@ -77,6 +130,10 @@ export function mergeListingPublishOptions(options?: Partial<ListingPublishOptio
skin_groups: normalizeOptionGroups(options?.skin_groups),
quantity_items: normalizeQuantityItems(options?.quantity_items),
screenshot_slots: normalizeScreenshotSlots(options?.screenshot_slots),
ban_record_options: normalizeStringList(options?.ban_record_options),
ban_evidence_options: normalizeStringList(options?.ban_evidence_options),
price_config: normalizePriceConfig(options?.price_config),
ratio_config: normalizeRatioConfig(options?.ratio_config),
}
}
@@ -130,6 +187,87 @@ function normalizeScreenshotSlots(values?: unknown[]): PublishScreenshotSlot[] {
.filter((item) => item.key && item.label)
}
function normalizePriceConfig(value?: unknown): PublishPriceConfig {
const row = isRecord(value) ? value : {}
return {
deposit_placeholder: typeof row.deposit_placeholder === 'string' ? row.deposit_placeholder.trim() : '',
price_placeholder: typeof row.price_placeholder === 'string' ? row.price_placeholder.trim() : '',
ratio_description: typeof row.ratio_description === 'string' ? row.ratio_description.trim() : '',
}
}
function normalizeRatioConfig(value?: unknown): PublishRatioConfig {
const row = isRecord(value) ? value : {}
return {
insurance_base_ratios: normalizeInsuranceBaseRatios(
Array.isArray(row.insurance_base_ratios) ? row.insurance_base_ratios : [],
),
config_items: normalizeRatioConfigItems(
Array.isArray(row.config_items) ? row.config_items : [],
),
coin_corrections: normalizeCoinCorrections(
Array.isArray(row.coin_corrections) ? row.coin_corrections : [],
),
rent_rules: normalizeRentRules(Array.isArray(row.rent_rules) ? row.rent_rules : []),
}
}
function normalizeInsuranceBaseRatios(values: unknown[]): PublishInsuranceBaseRatio[] {
return values
.map((item) => {
const row = isRecord(item) ? item : {}
return {
insurance: typeof row.insurance === 'string' ? row.insurance.trim() : '',
ratio: readNumber(row.ratio),
}
})
.filter((item) => item.insurance && item.ratio > 0)
}
function normalizeRatioConfigItems(values: unknown[]): PublishRatioConfigItem[] {
return values
.map((item) => {
const row = isRecord(item) ? item : {}
return {
key: typeof row.key === 'string' ? row.key.trim() : '',
label: typeof row.label === 'string' ? row.label.trim() : '',
kind: typeof row.kind === 'string' ? row.kind.trim() : '',
group_key: typeof row.group_key === 'string' ? row.group_key.trim() : '',
missing_penalty: readNumber(row.missing_penalty),
}
})
.filter((item) => item.key && item.label && item.kind)
}
function normalizeCoinCorrections(values: unknown[]): PublishCoinCorrection[] {
return values
.map((item) => {
const row = isRecord(item) ? item : {}
return {
threshold_m: readNumber(row.threshold_m),
correction: readNumber(row.correction),
}
})
.filter((item) => item.threshold_m >= 0 && item.correction > 0)
}
function normalizeRentRules(values: unknown[]): PublishRentRule[] {
return values
.map((item) => {
const row = isRecord(item) ? item : {}
return {
threshold_m: readNumber(row.threshold_m),
days: Math.trunc(readNumber(row.days)),
}
})
.filter((item) => item.threshold_m >= 0 && item.days > 0)
}
function readNumber(value: unknown) {
const parsed = Number(value)
return Number.isFinite(parsed) ? parsed : 0
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null
}