56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { WritableDbService } from '../db/writable-db.service';
|
|
import { levelFor } from './levels';
|
|
|
|
@Injectable()
|
|
export class CommunityService {
|
|
constructor(private readonly wdb: WritableDbService) {}
|
|
|
|
/** 贡献榜(公开):按积分降序。*/
|
|
leaderboard(limit = 20) {
|
|
const rows = this.wdb.db
|
|
.prepare(
|
|
`SELECT id, display_name, role, contribution_points
|
|
FROM users WHERE contribution_points > 0
|
|
ORDER BY contribution_points DESC, id ASC LIMIT ?`,
|
|
)
|
|
.all(limit) as any[];
|
|
return rows.map((r, i) => ({
|
|
rank: i + 1,
|
|
id: r.id,
|
|
displayName: r.display_name,
|
|
role: r.role,
|
|
points: r.contribution_points,
|
|
title: levelFor(r.contribution_points).title,
|
|
}));
|
|
}
|
|
|
|
/** 某车型的维护者署名列表。*/
|
|
maintainers(modelId: number) {
|
|
return this.wdb.db
|
|
.prepare(
|
|
`SELECT u.id, u.display_name AS displayName, u.role, m.created_at AS since
|
|
FROM model_maintainers m JOIN users u ON u.id = m.user_id
|
|
WHERE m.model_id = ? ORDER BY m.created_at ASC`,
|
|
)
|
|
.all(modelId);
|
|
}
|
|
|
|
claim(modelId: number, userId: number) {
|
|
this.wdb.db
|
|
.prepare(
|
|
`INSERT INTO model_maintainers (model_id, user_id) VALUES (?, ?)
|
|
ON CONFLICT(model_id, user_id) DO NOTHING`,
|
|
)
|
|
.run(modelId, userId);
|
|
return this.maintainers(modelId);
|
|
}
|
|
|
|
unclaim(modelId: number, userId: number) {
|
|
this.wdb.db
|
|
.prepare('DELETE FROM model_maintainers WHERE model_id = ? AND user_id = ?')
|
|
.run(modelId, userId);
|
|
return this.maintainers(modelId);
|
|
}
|
|
}
|