core: 修复文件删除回显

This commit is contained in:
undefined committed 2021-01-26 12:38:40 +08:00
1 parent df0982c690
commit 85b12f245d
4 files changed
+29 -25

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "hydrooj", "name": "hydrooj",
"version": "2.17.3", "version": "2.17.4",
"bin": "bin/hydrooj.js", "bin": "bin/hydrooj.js",
"main": "dist/loader.js", "main": "dist/loader.js",
"typings": "dist/loader.d.ts", "typings": "dist/loader.d.ts",
+2 -5
View File
@@ -480,11 +480,8 @@ export class ProblemFilesHandler extends ProblemDetailHandler {
@post('type', Types.Range(['testdata', 'additional_file']), true) @post('type', Types.Range(['testdata', 'additional_file']), true)
async postDeleteFiles(domainId: string, files: string[], type = 'testdata') { async postDeleteFiles(domainId: string, files: string[], type = 'testdata') {
if (this.pdoc.owner !== this.user._id) this.checkPerm(PERM.PERM_EDIT_PROBLEM); if (this.pdoc.owner !== this.user._id) this.checkPerm(PERM.PERM_EDIT_PROBLEM);
if (type === 'testdata') { if (type === 'testdata') await problem.delTestdata(domainId, this.pdoc.docId, files);
await problem.delTestdata(domainId, this.pdoc.docId, files); else await problem.delAdditionalFile(domainId, this.pdoc.docId, files);
} else {
await storage.del(files.map((file) => `problem/${this.pdoc.domainId}/${this.pdoc.docId}/${type}/${file}`));
}
this.back(); this.back();
} }
} }
+8 -7
View File
@@ -200,13 +200,14 @@ export async function pull<K extends keyof DocType, T extends ArrayKeys<DocType[
return res.value; return res.value;
} }
export async function deleteSub<K extends keyof DocType>( export async function deleteSub<T extends keyof DocType, K extends ArrayKeys<DocType[T]>>(
domainId: string, docType: K, docId: DocType[K]['docId'], domainId: string, docType: T, docId: DocType[T]['docId'],
key: ArrayKeys<DocType[K]>, subId: ObjectID, key: K, subId: DocType[T][K][0]['_id'] | DocType[T][K][0]['_id'][],
): Promise<DocType[K]> { ): Promise<DocType[T]> {
subId = (subId instanceof Array) ? subId : [subId];
const res = await coll.findOneAndUpdate( const res = await coll.findOneAndUpdate(
{ domainId, docType, docId }, { domainId, docType, docId },
{ $pull: { [key]: { _id: subId } } }, { $pull: { [key]: { _id: { $in: subId } } } },
{ returnOriginal: false }, { returnOriginal: false },
); );
return res.value; return res.value;
@@ -214,8 +215,8 @@ export async function deleteSub<K extends keyof DocType>(
export async function getSub<T extends keyof DocType, K extends ArrayKeys<DocType[T]>>( export async function getSub<T extends keyof DocType, K extends ArrayKeys<DocType[T]>>(
domainId: string, docType: T, docId: DocType[T]['docId'], domainId: string, docType: T, docId: DocType[T]['docId'],
key: K, subId: ObjectID, key: K, subId: DocType[T][K][0]['_id'],
): Promise<[DocType[T], DocType[T][K]][0]> { ): Promise<[DocType[T], DocType[T][K][0]]> {
const doc = await coll.findOne({ const doc = await coll.findOne({
domainId, domainId,
docType, docType,
+18 -12
View File
@@ -1,6 +1,6 @@
import type { Readable } from 'stream'; import type { Readable } from 'stream';
import { ObjectID, FilterQuery } from 'mongodb'; import { ObjectID, FilterQuery } from 'mongodb';
import { Dictionary } from 'lodash'; import { Dictionary, pick } from 'lodash';
import { STATUS } from './builtin'; import { STATUS } from './builtin';
import * as document from './document'; import * as document from './document';
import * as domain from './domain'; import * as domain from './domain';
@@ -126,7 +126,7 @@ export function push<T extends ArrayKeys<Pdoc>>(domainId: string, _id: number, k
} }
export function pull<T extends ArrayKeys<Pdoc>>(domainId: string, pid: number, key: ArrayKeys<Pdoc>, values: Pdoc[T][0][]) { export function pull<T extends ArrayKeys<Pdoc>>(domainId: string, pid: number, key: ArrayKeys<Pdoc>, values: Pdoc[T][0][]) {
return document.pull(domainId, document.TYPE_PROBLEM, pid, key, values.map((_id) => ({ _id }))); return document.deleteSub(domainId, document.TYPE_PROBLEM, pid, key, values);
} }
export function inc(domainId: string, _id: number, field: NumberKeys<Pdoc>, n: number): Promise<Pdoc> { export function inc(domainId: string, _id: number, field: NumberKeys<Pdoc>, n: number): Promise<Pdoc> {
@@ -147,29 +147,35 @@ export function del(domainId: string, docId: number) {
} }
export async function addTestdata(domainId: string, pid: number, name: string, f: Readable | Buffer | string) { export async function addTestdata(domainId: string, pid: number, name: string, f: Readable | Buffer | string) {
await storage.put(`problem/${domainId}/${pid}/testdata/${name}`, f); const [current] = await Promise.all([
document.getSub(domainId, document.TYPE_PROBLEM, pid, 'data', name),
storage.put(`problem/${domainId}/${pid}/testdata/${name}`, f),
]);
const meta = await storage.getMeta(`problem/${domainId}/${pid}/testdata/${name}`); const meta = await storage.getMeta(`problem/${domainId}/${pid}/testdata/${name}`);
return await push(domainId, pid, 'data', { const payload = { name, ...pick(meta, ['size', 'lastModified', 'etag']) };
_id: name, name, size: meta.size, lastModified: meta.lastModified, etag: meta.etag, if (!current) await push(domainId, pid, 'data', { _id: name, ...payload });
}); else await document.setSub(domainId, document.TYPE_PROBLEM, pid, 'data', name, payload);
} }
export async function delTestdata(domainId: string, pid: number, name: string | string[]) { export async function delTestdata(domainId: string, pid: number, name: string | string[]) {
const names = name instanceof Array ? name : [name]; const names = (name instanceof Array) ? name : [name];
await storage.del(names.map((t) => `problem/${domainId}/${pid}/testdata/${t}`)); await storage.del(names.map((t) => `problem/${domainId}/${pid}/testdata/${t}`));
await pull(domainId, pid, 'data', names); await pull(domainId, pid, 'data', names);
} }
export async function addAdditionalFile(domainId: string, pid: number, name: string, f: Readable | Buffer | string) { export async function addAdditionalFile(domainId: string, pid: number, name: string, f: Readable | Buffer | string) {
await storage.put(`problem/${domainId}/${pid}/additional_file/${name}`, f); const [[, fileinfo]] = await Promise.all([
document.getSub(domainId, document.TYPE_PROBLEM, pid, 'additional_file', name),
storage.put(`problem/${domainId}/${pid}/additional_file/${name}`, f),
]);
const meta = await storage.getMeta(`problem/${domainId}/${pid}/additional_file/${name}`); const meta = await storage.getMeta(`problem/${domainId}/${pid}/additional_file/${name}`);
return await push(domainId, pid, 'additional_file', { const payload = { name, ...pick(meta, ['size', 'lastModified', 'etag']) };
_id: name, name, size: meta.size, lastModified: meta.lastModified, etag: meta.etag, if (!fileinfo) await push(domainId, pid, 'additional_file', { _id: name, ...payload });
}); else await document.setSub(domainId, document.TYPE_PROBLEM, pid, 'additional_file', name, payload);
} }
export async function delAdditionalFile(domainId: string, pid: number, name: string | string[]) { export async function delAdditionalFile(domainId: string, pid: number, name: string | string[]) {
const names = name instanceof Array ? name : [name]; const names = (name instanceof Array) ? name : [name];
await storage.del(names.map((t) => `problem/${domainId}/${pid}/additional_file/${t}`)); await storage.del(names.map((t) => `problem/${domainId}/${pid}/additional_file/${t}`));
await pull(domainId, pid, 'additional_file', names); await pull(domainId, pid, 'additional_file', names);
} }