讨论置顶功能,修复setup

This commit is contained in:
undefined committed 2020-08-02 23:14:58 +08:00
1 parent 32a6d2de13
commit d184ca9ea1
20 files changed
+136 -173

No files matched your search

+15
View File
@@ -46,6 +46,7 @@ export const PERM = {
PERM_VIEW_DISCUSSION: 1n << 27n,
PERM_CREATE_DISCUSSION: 1n << 28n,
PERM_HIGHLIGHT_DISCUSSION: 1n << 29n,
PERM_PIN_DISCUSSION: 1n << 59n,
PERM_EDIT_DISCUSSION: 1n << 30n,
PERM_EDIT_DISCUSSION_SELF: 1n << 31n,
PERM_DELETE_DISCUSSION: 1n << 32n,
@@ -603,6 +604,20 @@ export const USER_GENDER_ICONS = {
[USER_GENDER_OTHER]: '?',
};
export const CONSTANT = {
PROBLEM_PER_PAGE: 100,
CONTEST_PER_PAGE: 20,
DISCUSSION_PER_PAGE: 50,
RECORD_PER_PAGE: 100,
SOLUTION_PER_PAGE: 20,
TRAINING_PER_PAGE: 10,
REPLY_PER_PAGE: 50,
HOMEWORK_ON_MAIN: 5,
DISCUSSION_ON_MAIN: 20,
CONTEST_ON_MAIN: 10,
TRAINING_ON_MAIN: 10,
};
global.Hydro.model.builtin = {
Permission,
PERM,
+14 -11
View File
@@ -3,7 +3,6 @@ import * as problem from './problem';
import * as contest from './contest';
import * as training from './training';
import * as document from './document';
import { PERM } from './builtin';
import { DocumentNotFoundError } from '../error';
import { Ddoc, Drdoc, Drrdoc } from '../interface';
@@ -18,7 +17,7 @@ export const typeDisplay = {
export function add(
domainId: string, parentType: number, parentId: ObjectID | number | string,
owner: number, title: string, content: string,
ip: string | null = null, highlight: boolean = false,
ip: string | null = null, highlight: boolean, pin: boolean,
): Promise<ObjectID> {
return document.add(
domainId, content, owner, document.TYPE_DISCUSSION,
@@ -26,8 +25,9 @@ export function add(
{
title,
ip,
highlight,
nReply: 0,
highlight,
pin,
updateAt: new Date(),
views: 0,
},
@@ -40,9 +40,11 @@ export function get(domainId: string, did: ObjectID): Promise<Ddoc | null> {
export function edit(
domainId: string, did: ObjectID,
title: string, content: string, highlight: boolean,
title: string, content: string, highlight: boolean, pin: boolean,
): Promise<Ddoc | null> {
return document.set(domainId, document.TYPE_DISCUSSION, did, { title, content, highlight });
return document.set(domainId, document.TYPE_DISCUSSION, did, {
title, content, highlight, pin,
});
}
export function del(domainId: string, did: ObjectID) {
@@ -60,7 +62,8 @@ export function count(domainId: string, query: any) {
}
export function getMulti(domainId: string, query: any = {}) {
return document.getMulti(domainId, document.TYPE_DISCUSSION, query).sort('updateAt', -1);
return document.getMulti(domainId, document.TYPE_DISCUSSION, query)
.sort({ pin: -1, updateAt: -1 });
}
export async function addReply(
@@ -158,13 +161,12 @@ export function getNode(domainId: string, _id: string) {
return document.get(domainId, document.TYPE_DISCUSSION_NODE, _id);
}
export async function getVnode(domainId: string, type: number, id: string, handler: any) {
export async function getVnode(domainId: string, type: number, id: string) {
if (type === document.TYPE_PROBLEM) {
// @ts-ignore
if (Number.isSafeInteger(parseInt(id, 10))) id = parseInt(id, 10);
const pdoc = await problem.get(domainId, id);
if (!pdoc) return null;
if (pdoc.hidden && handler) handler.checkPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN);
return { ...pdoc, type, id };
}
if (type === document.TYPE_CONTEST) {
@@ -199,12 +201,13 @@ export function getNodes(domainId: string) {
return document.getMulti(domainId, document.TYPE_DISCUSSION_NODE).toArray();
}
export async function getListVnodes(domainId: string, ddocs: any, handler: any) {
export async function getListVnodes(domainId: string, ddocs: any, getHidden: boolean) {
const tasks = [];
const res = {};
async function task(ddoc) {
const vnode = await getVnode(domainId, ddoc.parentType, ddoc.parentId, handler);
async function task(ddoc: Ddoc) {
const vnode = await getVnode(domainId, ddoc.parentType, ddoc.parentId.toString());
if (!res[ddoc.parentType]) res[ddoc.parentType] = {};
if (vnode.hidden && !getHidden) return;
res[ddoc.parentType][ddoc.parentId] = vnode;
}
for (const ddoc of ddocs) tasks.push(task(ddoc));
+23 -49
View File
@@ -328,66 +328,40 @@ export async function revSetStatus(
return await collStatus.updateOne(filter, update);
}
/* eslint-disable object-curly-newline */
async function ensureIndexes() {
await coll.createIndex({ domainId: 1, docType: 1, docId: 1 }, { unique: true });
await coll.createIndex({
domainId: 1, docType: 1, owner: 1, docId: -1,
});
const ic = coll.createIndex.bind(coll);
const is = collStatus.createIndex.bind(coll);
const u = { unique: true };
const s = { sparse: true };
await ic({ domainId: 1, docType: 1, docId: 1 }, u);
await ic({ domainId: 1, docType: 1, owner: 1, docId: -1 });
// For problem
await coll.createIndex({
domainId: 1, docType: 1, category: 1, docId: 1,
}, { sparse: true });
await coll.createIndex({
domainId: 1, docType: 1, hidden: 1, category: 1, docId: 1,
}, { sparse: true });
await coll.createIndex({
domainId: 1, docType: 1, tag: 1, docId: 1,
}, { sparse: true });
await coll.createIndex({
domainId: 1, docType: 1, hidden: 1, tag: 1, docId: 1,
}, { sparse: true });
await ic({ domainId: 1, docType: 1, category: 1, docId: 1 }, s);
await ic({ domainId: 1, docType: 1, hidden: 1, category: 1, docId: 1 }, s);
await ic({ domainId: 1, docType: 1, tag: 1, docId: 1 }, s);
await ic({ domainId: 1, docType: 1, hidden: 1, tag: 1, docId: 1 }, s);
// For problem solution
await coll.createIndex({
domainId: 1, docType: 1, parentType: 1, parentId: 1, vote: -1, docId: -1,
}, { sparse: true });
await ic({ domainId: 1, docType: 1, parentType: 1, parentId: 1, vote: -1, docId: -1 }, s);
// For discussion
await coll.createIndex({
domainId: 1, docType: 1, updateAt: -1, docId: -1,
}, { sparse: true });
await coll.createIndex({
domainId: 1, docType: 1, parentType: 1, parentId: 1, updateAt: -1, docId: -1,
}, { sparse: true });
await ic({ domainId: 1, docType: 1, pin: -1, updateAt: -1, docId: -1 }, s);
await ic({ domainId: 1, docType: 1, parentType: 1, parentId: 1, updateAt: -1, docId: -1 }, s);
// Hidden doc
await coll.createIndex({
domainId: 1, docType: 1, hidden: 1, docId: -1,
}, { sparse: true });
await ic({ domainId: 1, docType: 1, hidden: 1, docId: -1 }, s);
// For contest
await coll.createIndex({ domainId: 1, docType: 1, pids: 1 }, { sparse: true });
await coll.createIndex({
domainId: 1, docType: 1, rule: 1, docId: -1,
}, { sparse: true });
await ic({ domainId: 1, docType: 1, pids: 1 }, s);
await ic({ domainId: 1, docType: 1, rule: 1, docId: -1 }, s);
// For training
await coll.createIndex({ domainId: 1, docType: 1, 'dag.pids': 1 }, { sparse: true });
await collStatus.createIndex({
domainId: 1, docType: 1, uid: 1, docId: 1,
}, { unique: true });
await ic({ domainId: 1, docType: 1, 'dag.pids': 1 }, s);
await is({ domainId: 1, docType: 1, uid: 1, docId: 1 }, u);
// For rp system
await collStatus.createIndex({
domainId: 1, docType: 1, docId: 1, status: 1, rid: 1, rp: 1,
}, { sparse: true });
await is({ domainId: 1, docType: 1, docId: 1, status: 1, rid: 1, rp: 1 }, s);
// For contest rule OI
await collStatus.createIndex({
domainId: 1, docType: 1, docId: 1, score: -1,
}, { sparse: true });
await is({ domainId: 1, docType: 1, docId: 1, score: -1 }, s);
// For contest rule ACM
await collStatus.createIndex({
domainId: 1, docType: 1, docId: 1, accept: -1, time: 1,
}, { sparse: true });
await is({ domainId: 1, docType: 1, docId: 1, accept: -1, time: 1 }, s);
// For training
await collStatus.createIndex({
domainId: 1, docType: 1, uid: 1, enroll: 1, docId: 1,
}, { sparse: true });
await is({ domainId: 1, docType: 1, uid: 1, enroll: 1, docId: 1 }, s);
}
global.Hydro.postInit.push(ensureIndexes);
+11 -10
View File
@@ -7,9 +7,16 @@ const coll = db.collection('domain');
const collUser = db.collection('domain.user');
export async function add(domainId: string, owner: number, name: string, bulletin: string) {
await coll.insertOne({
_id: domainId, owner, name, bulletin, roles: {},
});
const ddoc: DomainDoc = {
_id: domainId,
owner,
name,
bulletin,
roles: {},
gravatar: '',
pidCounter: 0,
};
await coll.insertOne(ddoc);
return domainId;
}
@@ -17,11 +24,6 @@ export function get(domainId: string): Promise<DomainDoc | null> {
return coll.findOne({ _id: domainId });
}
export function getMany(query: any, sort: any, page: number, limit: number): Promise<DomainDoc[]> {
return coll.find(query).sort(sort).skip((page - 1) * limit).limit(limit)
.toArray();
}
export function getMulti(query: any = {}) {
return coll.find(query);
}
@@ -36,7 +38,7 @@ export async function inc(domainId: string, field: string, n: number): Promise<n
{ $inc: { [field]: n } },
{ returnOriginal: false },
);
return res.value.field;
return res.value[field];
}
export async function getList(domainIds: string[]): Promise<Dictionary<DomainDoc>> {
@@ -155,7 +157,6 @@ global.Hydro.model.domain = {
add,
inc,
get,
getMany,
edit,
getMulti,
getList,
-11
View File
@@ -134,17 +134,6 @@ SystemSetting(
Setting('setting_oauth', 'oauth.googleappid', null, null, 'text', 'Google Oauth ClientID', null),
Setting('setting_oauth', 'oauth.googlesecret', null, null, 'text', 'Google Oauth Secret', null, FLAG_SECRET),
Setting('setting_proxy', 'proxy', null, null, 'text', 'Proxy Server URL'),
Setting('setting_storage', 'PROBLEM_PER_PAGE', null, 100, 'number', 'Problems per Page', null, FLAG_HIDDEN),
Setting('setting_storage', 'CONTEST_PER_PAGE', null, 20, 'number', 'Contests per Page', null, FLAG_HIDDEN),
Setting('setting_storage', 'DISCUSSION_PER_PAGE', null, 50, 'number', 'Discussion per Page', null, FLAG_HIDDEN),
Setting('setting_storage', 'RECORD_PER_PAGE', null, 100, 'number', 'Record per Page', null, FLAG_HIDDEN),
Setting('setting_storage', 'SOLUTION_PER_PAGE', null, 20, 'number', 'Solutions per Page', null, FLAG_HIDDEN),
Setting('setting_storage', 'TRAINING_PER_PAGE', null, 10, 'number', 'Training per Page', null, FLAG_HIDDEN),
Setting('setting_storage', 'REPLY_PER_PAGE', null, 50, 'number', 'Reply per Page', null, FLAG_HIDDEN),
Setting('setting_storage', 'HOMEWORK_ON_MAIN', null, 5, 'number', 'HOMEWORK_ON_MAIN', null, FLAG_HIDDEN),
Setting('setting_storage', 'DISCUSSION_ON_MAIN', null, 20, 'number', 'DISCUSSION_ON_MAIN', null, FLAG_HIDDEN),
Setting('setting_storage', 'CONTEST_ON_MAIN', null, 10, 'number', 'CONTEST_ON_MAIN', null, FLAG_HIDDEN),
Setting('setting_storage', 'TRAINING_ON_MAIN', null, 10, 'number', 'TRAINING_ON_MAIN', null, FLAG_HIDDEN),
Setting('setting_storage', 'db.ver', null, 1, 'number', 'Database version', null, FLAG_DISABLED | FLAG_HIDDEN),
Setting('setting_storage', 'user', null, 1, 'number', 'User Counter', null, FLAG_DISABLED | FLAG_HIDDEN),
);
+1 -1
View File
@@ -108,7 +108,7 @@ export async function getList(domainId: string, tids: ObjectID[]) {
}
export const getMulti = (domainId: string, query: any = {}) =>
document.getMulti(domainId, document.TYPE_TRAINING, query);
document.getMulti(domainId, document.TYPE_TRAINING, query).sort('_id', 1);
global.Hydro.model.training = {
getPids,