CP增加解除费用

This commit is contained in:
zhx 2026-06-08 19:40:13 +08:00
parent ae8ae7db55
commit 4ad96f07be
4 changed files with 32 additions and 2 deletions

View File

@ -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),

View File

@ -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);
}

View File

@ -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),
};

View File

@ -27,6 +27,7 @@ export function CPConfigPage() {
<SummaryItem label="启用类型">{page.activeRelationCount}</SummaryItem>
<SummaryItem label="兄弟上限">{relationMax(relations, "brother")}</SummaryItem>
<SummaryItem label="姐妹上限">{relationMax(relations, "sister")}</SummaryItem>
<SummaryItem label="CP解除费">{relationBreakupCost(relations, "cp")}</SummaryItem>
</div>
<div className={styles.summaryActions}>
<Button
@ -154,6 +155,14 @@ function RelationEditor({ disabled, relation, resourceGroups, updateLevel, updat
value={relation.applicationExpireHours}
onChange={(event) => updateRelation(relationType, { applicationExpireHours: event.target.value })}
/>
<TextField
disabled={disabled}
inputProps={{ min: 0, step: 1 }}
label="解除费用金币"
type="number"
value={relation.breakupCostCoins}
onChange={(event) => updateRelation(relationType, { breakupCostCoins: event.target.value })}
/>
</div>
<div className={styles.levelEditorList}>
{(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) => <LevelPreview levels={item.levels || []} />,
},
{
@ -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}`;