diff --git a/src/features/cp-config/api.ts b/src/features/cp-config/api.ts index cc20a60..ada3cd6 100644 --- a/src/features/cp-config/api.ts +++ b/src/features/cp-config/api.ts @@ -16,6 +16,7 @@ export interface CPRelationConfigDto { displayName: string; maxCountPerUser: number; applicationExpireHours: number; + breakupCostCoins: number; status: string; levels: CPLevelDto[]; updatedAtMs?: number; @@ -32,6 +33,7 @@ export interface CPConfigPayload { relationType: CPRelationType; maxCountPerUser: number; applicationExpireHours: number; + breakupCostCoins: number; status: string; levels: Array<{ level: number; @@ -74,6 +76,7 @@ function normalizeRelation(raw: unknown): CPRelationConfigDto { displayName: stringValue(item.displayName ?? item.display_name) || relationLabel(relationType), maxCountPerUser: numberValue(item.maxCountPerUser ?? item.max_count_per_user), applicationExpireHours: numberValue(item.applicationExpireHours ?? item.application_expire_hours), + breakupCostCoins: numberValue(item.breakupCostCoins ?? item.breakup_cost_coins), status: stringValue(item.status) || "active", levels: arrayValue(item.levels).map(normalizeLevel), updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms), diff --git a/src/features/cp-config/cp-config.module.css b/src/features/cp-config/cp-config.module.css index e40fc2e..409ebd9 100644 --- a/src/features/cp-config/cp-config.module.css +++ b/src/features/cp-config/cp-config.module.css @@ -214,7 +214,7 @@ .relationControls { display: grid; - grid-template-columns: repeat(2, minmax(220px, 1fr)); + grid-template-columns: repeat(3, minmax(180px, 1fr)); gap: var(--space-3); } diff --git a/src/features/cp-config/hooks/useCPConfigPage.js b/src/features/cp-config/hooks/useCPConfigPage.js index 4f98674..062526f 100644 --- a/src/features/cp-config/hooks/useCPConfigPage.js +++ b/src/features/cp-config/hooks/useCPConfigPage.js @@ -149,6 +149,7 @@ export function defaultRelations() { displayName: cpRelationLabels[relationType], maxCountPerUser: relationType === "cp" ? 1 : 5, applicationExpireHours: defaultExpireHours, + breakupCostCoins: 0, status: "active", levels: defaultLevels(), updatedAtMs: 0, @@ -194,6 +195,7 @@ function relationToForm(relation) { displayName: relation.displayName || cpRelationLabels[relation.relationType], maxCountPerUser: relation.relationType === "cp" ? "1" : String(relation.maxCountPerUser || 5), applicationExpireHours: String(relation.applicationExpireHours || defaultExpireHours), + breakupCostCoins: String(relation.breakupCostCoins || 0), status: relation.status || "active", levels: completeLevels(relation.levels || []).map(levelToForm), }; @@ -214,6 +216,7 @@ function payloadFromForm(form) { const relationType = relation.relationType; const maxCountPerUser = relationType === "cp" ? 1 : Number(relation.maxCountPerUser || 0); const applicationExpireHours = Number(relation.applicationExpireHours || 0); + const breakupCostCoins = Number(relation.breakupCostCoins || 0); const status = relation.status === "disabled" ? "disabled" : "active"; if (!Number.isInteger(maxCountPerUser) || maxCountPerUser <= 0) { throw new Error(`${cpRelationLabels[relationType]}数量必须大于 0`); @@ -221,10 +224,14 @@ function payloadFromForm(form) { if (!Number.isInteger(applicationExpireHours) || applicationExpireHours <= 0) { throw new Error(`${cpRelationLabels[relationType]}申请过期小时必须大于 0`); } + if (!Number.isInteger(breakupCostCoins) || breakupCostCoins < 0) { + throw new Error(`${cpRelationLabels[relationType]}解除费用不能小于 0`); + } return { relationType, maxCountPerUser, applicationExpireHours, + breakupCostCoins, status, levels: completeFormLevels(relation.levels || [], relationType), }; diff --git a/src/features/cp-config/pages/CPConfigPage.jsx b/src/features/cp-config/pages/CPConfigPage.jsx index a383e6c..9190145 100644 --- a/src/features/cp-config/pages/CPConfigPage.jsx +++ b/src/features/cp-config/pages/CPConfigPage.jsx @@ -27,6 +27,7 @@ export function CPConfigPage() { {page.activeRelationCount} {relationMax(relations, "brother")} {relationMax(relations, "sister")} + {relationBreakupCost(relations, "cp")}
{(relation.levels || []).map((level) => ( @@ -254,10 +263,16 @@ function cpConfigColumns() { width: "minmax(130px, 0.45fr)", render: (item) => `${formatNumber(item.applicationExpireHours)} 小时`, }, + { + key: "breakupCost", + label: "解除费用", + width: "minmax(130px, 0.45fr)", + render: (item) => `${formatNumber(item.breakupCostCoins)} 金币`, + }, { key: "levels", label: "等级亲密值", - width: "minmax(360px, 1.3fr)", + width: "minmax(360px, 1.2fr)", render: (item) => , }, { @@ -310,6 +325,11 @@ function relationMax(relations, relationType) { return relation ? formatNumber(relation.maxCountPerUser) : "-"; } +function relationBreakupCost(relations, relationType) { + const relation = relations.find((item) => item.relationType === relationType); + return relation ? `${formatNumber(relation.breakupCostCoins)} 金币` : "-"; +} + function resourceGroupLabel(group, value) { if (group) { return group.name || group.groupCode || `资源组 #${group.groupId}`;