Foro: selector para fijar el personaje del autor
- Modal "Cambiar personaje" (diseño de la web) con filtro, avatar de raza, nombre en color de clase y subtítulo nivel/raza/clase. - Barra "Publicas como: X · Cambiar personaje" sobre el formulario de respuesta (solo con sesión iniciada). - Preferencia persistente en acore_web.forum_character (por cuenta), validada. - resolvePosters usa el personaje fijado si existe; si no, el de más nivel. - API /api/forum/character (GET lista + actual, POST fijar), gated por sesión. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+79
-1
@@ -413,8 +413,21 @@ export async function resolvePosters(ids: number[]): Promise<Map<number, PosterI
|
||||
if (!byAcc.has(acc)) byAcc.set(acc, [])
|
||||
byAcc.get(acc)!.push(c)
|
||||
}
|
||||
// Personaje fijado por el usuario (si lo hay y sigue siendo suyo); si no, el de más nivel.
|
||||
const pickByAcc = new Map<number, number>()
|
||||
try {
|
||||
const [picks] = await db(DB.web).query<RowDataPacket[]>(
|
||||
`SELECT account, guid FROM forum_character WHERE account IN (${placeholders})`,
|
||||
unique,
|
||||
)
|
||||
for (const p of picks) pickByAcc.set(Number(p.account), Number(p.guid))
|
||||
} catch {
|
||||
/* sin tabla de preferencias */
|
||||
}
|
||||
for (const [acc, list] of byAcc) {
|
||||
const c = list.reduce((best, cur) => (Number(cur.level) > Number(best.level) ? cur : best), list[0])
|
||||
const pg = pickByAcc.get(acc)
|
||||
const picked = pg ? list.find((x) => Number(x.guid) === pg) : undefined
|
||||
const c = picked || list.reduce((best, cur) => (Number(cur.level) > Number(best.level) ? cur : best), list[0])
|
||||
charByAccount.set(acc, {
|
||||
guid: Number(c.guid), name: String(c.name), race: Number(c.race),
|
||||
gender: Number(c.gender), class: Number(c.class), level: Number(c.level),
|
||||
@@ -500,3 +513,68 @@ export async function resolvePosters(ids: number[]): Promise<Map<number, PosterI
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
export interface ForumCharOption {
|
||||
guid: number
|
||||
name: string
|
||||
race: number
|
||||
gender: number
|
||||
class: number
|
||||
level: number
|
||||
}
|
||||
|
||||
/** Personajes de la cuenta para el selector del foro. */
|
||||
export async function getAccountCharactersForForum(accountId: number): Promise<ForumCharOption[]> {
|
||||
if (!accountId) return []
|
||||
try {
|
||||
const [rows] = await db(DB.characters).query<RowDataPacket[]>(
|
||||
'SELECT guid, name, race, gender, class, level FROM characters WHERE account = ? ORDER BY level DESC, name ASC',
|
||||
[accountId],
|
||||
)
|
||||
return rows.map((r) => ({
|
||||
guid: Number(r.guid), name: String(r.name), race: Number(r.race),
|
||||
gender: Number(r.gender), class: Number(r.class), level: Number(r.level),
|
||||
}))
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
/** GUID del personaje fijado por la cuenta para el foro (validado), o null. */
|
||||
export async function getForumCharacterPick(accountId: number): Promise<number | null> {
|
||||
if (!accountId) return null
|
||||
try {
|
||||
const [rows] = await db(DB.web).query<RowDataPacket[]>(
|
||||
'SELECT guid FROM forum_character WHERE account = ?',
|
||||
[accountId],
|
||||
)
|
||||
const guid = rows[0] ? Number(rows[0].guid) : 0
|
||||
if (!guid) return null
|
||||
const [ok] = await db(DB.characters).query<RowDataPacket[]>(
|
||||
'SELECT 1 FROM characters WHERE guid = ? AND account = ? LIMIT 1',
|
||||
[guid, accountId],
|
||||
)
|
||||
return ok.length ? guid : null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/** Fija el personaje del foro para la cuenta (valida que le pertenece). */
|
||||
export async function setForumCharacterPick(accountId: number, guid: number): Promise<boolean> {
|
||||
if (!accountId || !guid) return false
|
||||
try {
|
||||
const [ok] = await db(DB.characters).query<RowDataPacket[]>(
|
||||
'SELECT 1 FROM characters WHERE guid = ? AND account = ? LIMIT 1',
|
||||
[guid, accountId],
|
||||
)
|
||||
if (!ok.length) return false
|
||||
await db(DB.web).query(
|
||||
'INSERT INTO forum_character (account, guid) VALUES (?, ?) ON DUPLICATE KEY UPDATE guid = VALUES(guid)',
|
||||
[accountId, guid],
|
||||
)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user