feat: persist account group display order and backup preferences

This commit is contained in:
陈煜 committed 2026-10-03 12:29:35 +08:00
1 parent 20643b366f
commit 1af5edbadc
28 files changed
+379 -47

No files matched your search

+2
View File
@@ -170,11 +170,13 @@ export class AuthController {
hiddenMenus: true,
showNotes: true,
idleMinutes: true,
accountGroupOrder: true,
},
});
const session = await this.db.session.findUniqueOrThrow({ where: { id: req.sessionId } });
return {
...user,
accountGroupOrder: user.accountGroupOrder || [],
hiddenMenus: user.hiddenMenus.split(',').filter(Boolean),
revealed: req.revealed,
revealUntil: session.revealUntil,
+11 -1
View File
@@ -35,6 +35,7 @@ import {
revisionInput,
rateInput,
hiddenMenus,
accountGroupOrder,
transferInput,
} from './validation';
import { createHash } from 'node:crypto';
@@ -77,6 +78,7 @@ const backupSchema = z
.object({
showSidebar: z.boolean().optional(),
hiddenMenus: hiddenMenus.optional(),
accountGroupOrder: accountGroupOrder.optional(),
showNotes: z.boolean().optional(),
idleMinutes: z.number().int().min(0).max(1440),
})
@@ -301,7 +303,13 @@ export class BackupController implements OnModuleDestroy, OnModuleInit {
const [user, ps, rates] = await Promise.all([
client.user.findUniqueOrThrow({
where: { id: userId },
select: { baseCurrency: true, hiddenMenus: true, showNotes: true, idleMinutes: true },
select: {
baseCurrency: true,
hiddenMenus: true,
showNotes: true,
idleMinutes: true,
accountGroupOrder: true,
},
}),
client.position.findMany({
where: { userId },
@@ -360,6 +368,7 @@ export class BackupController implements OnModuleDestroy, OnModuleInit {
hiddenMenus: user.hiddenMenus.split(',').filter(Boolean),
showNotes: user.showNotes,
idleMinutes: user.idleMinutes,
accountGroupOrder: accountGroupOrder.parse(user.accountGroupOrder || []),
},
currencies: [
...new Set([
@@ -707,6 +716,7 @@ export class BackupController implements OnModuleDestroy, OnModuleInit {
idleMinutes: b.preferences?.idleMinutes,
hiddenMenus: b.preferences?.hiddenMenus?.join(','),
showNotes: b.preferences?.showNotes,
accountGroupOrder: b.preferences?.accountGroupOrder,
},
});
return { ok: true, positions: b.positions.length };
+2
View File
@@ -11,6 +11,7 @@ import {
transferInput,
currency,
hiddenMenus,
accountGroupOrder,
} from './validation';
export function setupOpenApi(app: INestApplication) {
const document = SwaggerModule.createDocument(
@@ -45,6 +46,7 @@ export function setupOpenApi(app: INestApplication) {
.object({
baseCurrency: currency.optional(),
hiddenMenus: hiddenMenus.optional(),
accountGroupOrder: accountGroupOrder.optional(),
showNotes: z.boolean().optional(),
idleMinutes: z.number().int().min(0).max(1440).optional(),
})
+4 -1
View File
@@ -13,7 +13,7 @@ import {
} from '@nestjs/common';
import { Database } from './database';
import { UserRequest } from './auth';
import { currency, date, rateValue, today, hiddenMenus } from './validation';
import { currency, date, rateValue, today, hiddenMenus, accountGroupOrder } from './validation';
import { z } from 'zod';
import Decimal from 'decimal.js';
// Fixed public request; no user currency choices, identifiers or amounts leave the server.
@@ -176,10 +176,12 @@ export class SettingsController {
hiddenMenus: true,
showNotes: true,
idleMinutes: true,
accountGroupOrder: true,
},
});
return {
...u,
accountGroupOrder: u.accountGroupOrder || [],
hiddenMenus: u.hiddenMenus.split(',').filter(Boolean),
lastActivity: (await this.db.session.findUniqueOrThrow({ where: { id: r.sessionId } }))
.lastActivity,
@@ -203,6 +205,7 @@ export class SettingsController {
.object({
baseCurrency: currency.optional(),
hiddenMenus: hiddenMenus.optional(),
accountGroupOrder: accountGroupOrder.optional(),
showNotes: z.boolean().optional(),
idleMinutes: z.number().int().min(0).max(1440).optional(),
})
+5
View File
@@ -182,3 +182,8 @@ export const credentialChange = z
})
.strict()
.refine((v) => !!v.username || !!v.newPassword, '请填写新的账号或密码');
export const accountGroupOrder = z
.array(z.string().trim().max(60))
.max(1000)
.refine((v) => new Set(v).size === v.length, '分组不可重复');
+2
View File
@@ -4,6 +4,7 @@ import { createHash } from 'node:crypto';
import { BadRequestException } from '@nestjs/common';
import { z } from 'zod';
import type { Backup } from './backup';
import { accountGroupOrder } from './validation';
export const MAX_UPLOAD_BYTES = 512 * 1024 * 1024;
const MAX_EXPANDED_BYTES = 1024 * 1024 * 1024;
const files = [
@@ -149,6 +150,7 @@ export async function readBackupZip(input: string | Buffer): Promise<unknown> {
.object({
showSidebar: z.boolean().optional(),
hiddenMenus: z.array(z.string()).optional(),
accountGroupOrder: accountGroupOrder.optional(),
showNotes: z.boolean().optional(),
idleMinutes: z.number().int().min(0).max(1440),
})