feat: allow deleting standalone assets and debts

This commit is contained in:
陈煜 committed 2026-10-04 12:26:14 +08:00
1 parent 3edf611833
commit c0ad193c73
8 files changed
+212 -40

No files matched your search

+19 -18
View File
@@ -55,7 +55,7 @@ import { Calendar } from './Calendar';
import { SchedulePanel } from './SchedulePanel';
import { AgentConnections } from './AgentConnections';
import { AgentAuthorization, AgentOperation } from './AgentReview';
import { AccountDeletion } from './AccountDeletion';
import { PositionDeletion, deletionLabel } from './PositionDeletion';
import { IconPicker } from './IconPicker';
import { MetalPanel } from './MetalPanel';
import { QuickTransfer } from './QuickTransfer';
@@ -1367,15 +1367,13 @@ export default function App() {
</button>
</>
)}
{p.kind === 'account' && (
<button
className="secondary danger-text"
disabled={busy}
onClick={() => setModal({ kind: 'delete-account', p })}
>
删除账户
</button>
)}
<button
className="secondary danger-text"
disabled={busy}
onClick={() => setModal({ kind: 'delete-position', p })}
>
删除{deletionLabel(p)}
</button>
<button className="secondary" onClick={() => setModal({ kind: 'edit', p })}>
{tr('编辑资料')}
</button>
@@ -2607,8 +2605,8 @@ export default function App() {
? modal.p?.kind === 'debt'
? operationLabel(modal.p.side === 'asset' ? 'collect' : 'repay')
: tr('收款 / 还款')
: modal.kind === 'delete-account'
? '删除账户'
: modal.kind === 'delete-position'
? '删除' + deletionLabel(modal.p!)
: modal.kind === 'transfer'
? tr('转账')
: modal.kind === 'reveal'
@@ -2627,16 +2625,19 @@ export default function App() {
if (!busy) setModal(null);
}}
>
{modal.kind === 'delete-account' && modal.p ? (
<AccountDeletion
{modal.kind === 'delete-position' && modal.p ? (
<PositionDeletion
position={modal.p}
busy={busy}
cancel={() => setModal(null)}
remove={(confirmation) =>
void act(async () => {
await api('/positions/' + modal.p!.id, 'DELETE', { confirmation });
setSelected(null);
}, '账户已删除')
void act(
async () => {
await api('/positions/' + modal.p!.id, 'DELETE', { confirmation });
setSelected(null);
},
deletionLabel(modal.p!) + '已删除',
)
}
/>
) : ['transfer', 'debt-payment'].includes(modal.kind) ? (
@@ -9,7 +9,10 @@ type Impact = {
linkCount: number;
canDelete: boolean;
};
export function AccountDeletion({
export function deletionLabel(position: Pick<Position, 'kind'>) {
return position.kind === 'asset' ? '独立资产' : position.kind === 'debt' ? '债务' : '账户';
}
export function PositionDeletion({
position,
busy,
cancel,
@@ -35,6 +38,9 @@ export function AccountDeletion({
active = false;
};
}, [position.id]);
const label = deletionLabel(position);
const history =
position.kind === 'asset' ? '估值历史' : position.kind === 'debt' ? '借贷历史' : '余额历史';
return (
<form
onSubmit={(e) => {
@@ -42,26 +48,29 @@ export function AccountDeletion({
if (impact?.canDelete && name === impact.name && !busy) remove(name);
}}
>
<h3>删除账户「{position.name}」</h3>
<h3>
删除{label}「{position.name}」
</h3>
{!impact ? (
<p>正在检查关联记录…</p>
) : (
<>
<p>
删除后将移除该账户、{impact.historyCount} 条余额历史及 {impact.linkCount}{' '}
删除后将移除该{label}、{impact.historyCount} 条{history}及 {impact.linkCount}{' '}
个债务关联。资产总览、趋势和收支日历将同步更新,无法撤销。
</p>
{!impact.canDelete ? (
<div className="agent-warning" role="status">
<strong>请先处理账户引用</strong>
<strong>请先处理关联记录</strong>
<p>
还有 {impact.movementCount} 条资金往来、{impact.scheduleCount}{' '}
个定时计划。请先撤销相关资金往来并删除相关计划,再删除账户。若需要保留历史,可改用归档。
个定时计划。请先撤销相关资金往来并删除相关计划,再删除{label}
。若需要保留历史,可改用归档。
</p>
</div>
) : (
<label>
输入完整账户名称确认删除
输入完整{label}名称确认删除
<input
value={name}
onChange={(e) => setName(e.target.value)}
@@ -80,7 +89,7 @@ export function AccountDeletion({
className="primary danger"
disabled={busy || !impact?.canDelete || name !== impact.name}
>
删除账户
删除{label}
</button>
</div>
</form>