mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: add projection for discussion
This commit is contained in:
1 parent
71aabe38b5
commit
2344a41816
5 files changed
+99
-46
No files matched your search
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hydrooj",
|
||||
"version": "2.20.10",
|
||||
"version": "2.20.11",
|
||||
"bin": "bin/hydrooj.js",
|
||||
"main": "dist/loader.js",
|
||||
"typings": "dist/loader.d.ts",
|
||||
|
||||
@@ -162,13 +162,19 @@ export interface SampleContentNode {
|
||||
export type ContentNode = PlainContentNode | TextContentNode | SampleContentNode;
|
||||
export type Content = string | ContentNode[] | Record<string, ContentNode[]>;
|
||||
|
||||
export interface Document {
|
||||
_id: ObjectID,
|
||||
docId: any,
|
||||
docType: number,
|
||||
domainId: string,
|
||||
owner: number,
|
||||
}
|
||||
|
||||
declare module './model/problem' {
|
||||
interface Pdoc {
|
||||
domainId: string,
|
||||
docType: 10,
|
||||
docType: document['TYPE_PROBLEM'],
|
||||
docId: number,
|
||||
pid: string,
|
||||
owner: number,
|
||||
title: string,
|
||||
content: Content,
|
||||
nSubmit: number,
|
||||
@@ -202,14 +208,6 @@ export interface StatusDoc {
|
||||
uid: number,
|
||||
}
|
||||
|
||||
export interface Document {
|
||||
_id: ObjectID,
|
||||
docId: any,
|
||||
docType: number,
|
||||
domainId: string,
|
||||
owner: number,
|
||||
}
|
||||
|
||||
export interface ProblemStatusDoc extends StatusDoc {
|
||||
docId: number,
|
||||
docType: 10,
|
||||
@@ -339,20 +337,23 @@ export interface HistoryDoc {
|
||||
}
|
||||
|
||||
// Discussion
|
||||
export interface Ddoc extends Document {
|
||||
docType: document['TYPE_DISCUSSION'],
|
||||
docId: ObjectID,
|
||||
parentType: number,
|
||||
parentId: ObjectID | number | string,
|
||||
title: string,
|
||||
content: string,
|
||||
ip: string,
|
||||
pin: boolean,
|
||||
highlight: boolean,
|
||||
updateAt: Date,
|
||||
nReply: number,
|
||||
views: number,
|
||||
history: HistoryDoc[],
|
||||
export { Ddoc } from './model/discussion';
|
||||
declare module './model/discussion' {
|
||||
interface Ddoc {
|
||||
docType: document['TYPE_DISCUSSION'],
|
||||
docId: ObjectID,
|
||||
parentType: number,
|
||||
parentId: ObjectID | number | string,
|
||||
title: string,
|
||||
content: string,
|
||||
ip: string,
|
||||
pin: boolean,
|
||||
highlight: boolean,
|
||||
updateAt: Date,
|
||||
nReply: number,
|
||||
views: number,
|
||||
history: HistoryDoc[],
|
||||
}
|
||||
}
|
||||
|
||||
// Discussion reply
|
||||
|
||||
@@ -4,9 +4,57 @@ import * as contest from './contest';
|
||||
import * as training from './training';
|
||||
import * as document from './document';
|
||||
import { DocumentNotFoundError } from '../error';
|
||||
import { Ddoc, Drdoc, Drrdoc } from '../interface';
|
||||
import { Drdoc, Drrdoc, Document } from '../interface';
|
||||
import { buildProjection } from '../utils';
|
||||
import * as bus from '../service/bus';
|
||||
|
||||
export interface Ddoc extends Document { }
|
||||
export namespace Ddoc {
|
||||
export type Field = keyof Ddoc;
|
||||
export const fields: Field[] = [];
|
||||
type Getter = () => Partial<Ddoc>;
|
||||
const getters: Getter[] = [];
|
||||
export function extend(getter: Getter) {
|
||||
getters.push(getter);
|
||||
fields.push(...Object.keys(getter()) as any);
|
||||
}
|
||||
|
||||
extend(() => ({
|
||||
_id: new ObjectID(),
|
||||
domainId: 'system',
|
||||
docType: document.TYPE_DISCUSSION,
|
||||
docId: new ObjectID(),
|
||||
owner: 1,
|
||||
title: '*',
|
||||
content: '',
|
||||
parentId: new ObjectID(),
|
||||
ip: '1.1.1.1',
|
||||
pin: false,
|
||||
highlight: false,
|
||||
updateAt: new Date(),
|
||||
nReply: 0,
|
||||
views: 0,
|
||||
history: [],
|
||||
}));
|
||||
|
||||
export function create() {
|
||||
const result = {} as Ddoc;
|
||||
for (const getter of getters) {
|
||||
Object.assign(result, getter());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export const PROJECTION_LIST: Ddoc.Field[] = [
|
||||
'_id', 'domainId', 'docType', 'docId', 'highlight',
|
||||
'nReply', 'views', 'pin', 'updateAt', 'owner',
|
||||
'parentId', 'parentType',
|
||||
];
|
||||
export const PROJECTION_PUBLIC: Ddoc.Field[] = [
|
||||
...PROJECTION_LIST, 'content', 'history',
|
||||
];
|
||||
|
||||
export const typeDisplay = {
|
||||
[document.TYPE_PROBLEM]: 'problem',
|
||||
[document.TYPE_CONTEST]: 'contest',
|
||||
@@ -35,8 +83,9 @@ export function add(
|
||||
);
|
||||
}
|
||||
|
||||
export function get(domainId: string, did: ObjectID): Promise<Ddoc | null> {
|
||||
return document.get(domainId, document.TYPE_DISCUSSION, did);
|
||||
// FIXME typings doesn't work
|
||||
export function get<T extends Ddoc.Field>(domainId: string, did: ObjectID, projection: T[] = PROJECTION_PUBLIC as any): Promise<Pick<Ddoc, T>> {
|
||||
return document.get(domainId, document.TYPE_DISCUSSION, did, projection);
|
||||
}
|
||||
|
||||
export function edit(
|
||||
@@ -48,23 +97,24 @@ export function edit(
|
||||
});
|
||||
}
|
||||
|
||||
export function del(domainId: string, did: ObjectID) {
|
||||
export function del(domainId: string, did: ObjectID): Promise<never> {
|
||||
return Promise.all([
|
||||
document.deleteOne(domainId, document.TYPE_DISCUSSION, did),
|
||||
document.deleteMulti(domainId, document.TYPE_DISCUSSION_REPLY, {
|
||||
parentType: document.TYPE_DISCUSSION, parentId: did,
|
||||
}),
|
||||
document.deleteMultiStatus(domainId, document.TYPE_DISCUSSION, { docId: did }),
|
||||
]);
|
||||
]) as any;
|
||||
}
|
||||
|
||||
export function count(domainId: string, query: FilterQuery<Ddoc>) {
|
||||
return document.count(domainId, document.TYPE_DISCUSSION, query);
|
||||
}
|
||||
|
||||
export function getMulti(domainId: string, query: FilterQuery<Ddoc> = {}) {
|
||||
export function getMulti(domainId: string, query: FilterQuery<Ddoc> = {}, projection = PROJECTION_LIST) {
|
||||
return document.getMulti(domainId, document.TYPE_DISCUSSION, query)
|
||||
.sort({ pin: -1, updateAt: -1 });
|
||||
.sort({ pin: -1, updateAt: -1 })
|
||||
.project(buildProjection(projection));
|
||||
}
|
||||
|
||||
export async function addReply(
|
||||
@@ -234,6 +284,10 @@ bus.on('problem/delete', async (domainId, docId) => {
|
||||
|
||||
global.Hydro.model.discussion = {
|
||||
typeDisplay,
|
||||
Ddoc,
|
||||
PROJECTION_LIST,
|
||||
PROJECTION_PUBLIC,
|
||||
|
||||
add,
|
||||
get,
|
||||
edit,
|
||||
|
||||
@@ -17,15 +17,15 @@ type DocID = ObjectID | string | number;
|
||||
export const coll = db.collection('document');
|
||||
export const collStatus = db.collection('document.status');
|
||||
|
||||
export const TYPE_PROBLEM = 10;
|
||||
export const TYPE_PROBLEM_SOLUTION = 11;
|
||||
export const TYPE_PROBLEM_LIST = 12;
|
||||
export const TYPE_DISCUSSION_NODE = 20;
|
||||
export const TYPE_DISCUSSION = 21;
|
||||
export const TYPE_DISCUSSION_REPLY = 22;
|
||||
export const TYPE_CONTEST = 30;
|
||||
export const TYPE_TRAINING = 40;
|
||||
export const TYPE_HOMEWORK = 60;
|
||||
export const TYPE_PROBLEM: 10 = 10;
|
||||
export const TYPE_PROBLEM_SOLUTION: 11 = 11;
|
||||
export const TYPE_PROBLEM_LIST: 12 = 12;
|
||||
export const TYPE_DISCUSSION_NODE: 20 = 20;
|
||||
export const TYPE_DISCUSSION: 21 = 21;
|
||||
export const TYPE_DISCUSSION_REPLY: 22 = 22;
|
||||
export const TYPE_CONTEST: 30 = 30;
|
||||
export const TYPE_TRAINING: 40 = 40;
|
||||
export const TYPE_HOMEWORK: 60 = 60;
|
||||
|
||||
export interface DocType {
|
||||
[TYPE_PROBLEM]: Pdoc,
|
||||
|
||||
@@ -5,16 +5,14 @@ import { STATUS } from './builtin';
|
||||
import * as document from './document';
|
||||
import * as domain from './domain';
|
||||
import { buildProjection } from '../utils';
|
||||
import { ProblemStatusDoc, Pdict } from '../interface';
|
||||
import type { ProblemStatusDoc, Pdict, Document } from '../interface';
|
||||
import { Content } from '../loader';
|
||||
import { ArrayKeys, NumberKeys, Projection } from '../typeutils';
|
||||
import { ProblemNotFoundError } from '../error';
|
||||
import storage from '../service/storage';
|
||||
import * as bus from '../service/bus';
|
||||
|
||||
export interface Pdoc {
|
||||
_id: ObjectID
|
||||
}
|
||||
export interface Pdoc extends Document { }
|
||||
export namespace Pdoc {
|
||||
export type Field = keyof Pdoc;
|
||||
export const fields: Field[] = [];
|
||||
|
||||
Reference in new issue
Block a user