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() {