mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 17:36:08 +08:00
比赛举办者可给用户推送通知
This commit is contained in:
1 parent
0f1f5f26e1
commit
bfc2e95ef5
5 files changed
+48
-11
No files matched your search
@@ -2,7 +2,6 @@
|
||||
discussion前端权限节点显示异常?
|
||||
web端运行脚本异常?
|
||||
讨论回复通知
|
||||
比赛举办者发布通知
|
||||
举报功能
|
||||
SETTINGS_PRIVACY.allowRegisteredUsers
|
||||
model.setting.ui.name
|
||||
|
||||
@@ -4,7 +4,7 @@ import AdmZip from 'adm-zip';
|
||||
import { isSafeInteger } from 'lodash';
|
||||
import {
|
||||
ContestNotLiveError, ValidationError, ProblemNotFoundError,
|
||||
ContestNotAttendedError,
|
||||
ContestNotAttendedError, PermissionError,
|
||||
} from '../error';
|
||||
import { isContent, isTitle } from '../lib/validator';
|
||||
import paginate from '../lib/paginate';
|
||||
@@ -14,6 +14,7 @@ import * as document from '../model/document';
|
||||
import * as problem from '../model/problem';
|
||||
import * as record from '../model/record';
|
||||
import * as user from '../model/user';
|
||||
import * as message from '../model/message';
|
||||
import * as system from '../model/system';
|
||||
import {
|
||||
Route, Handler, Types, param,
|
||||
@@ -65,7 +66,7 @@ class ContestDetailHandler extends ContestHandler {
|
||||
]);
|
||||
const psdict = {};
|
||||
let rdict = {};
|
||||
let attended;
|
||||
let attended: boolean;
|
||||
if (tsdoc) {
|
||||
attended = tsdoc.attend === 1;
|
||||
for (const pdetail of tsdoc.journal || []) psdict[pdetail.pid] = pdetail;
|
||||
@@ -97,6 +98,35 @@ class ContestDetailHandler extends ContestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
class ContestBoardcastHandler extends ContestHandler {
|
||||
@param('tid', Types.ObjectID)
|
||||
async get(domainId: string, tid: ObjectID) {
|
||||
const tdoc = await contest.get(domainId, tid);
|
||||
if (tdoc.owner !== this.user._id) throw new PermissionError('Boardcast Message');
|
||||
const path = [
|
||||
['Hydro', 'homepage'],
|
||||
['contest_main', 'contest_main'],
|
||||
[tdoc.title, 'contest_detail', { tid }, true],
|
||||
['contest_boardcast'],
|
||||
];
|
||||
this.response.template = 'contest_boardcast.html';
|
||||
this.response.body = path;
|
||||
}
|
||||
|
||||
@param('tid', Types.ObjectID)
|
||||
@param('content', Types.String, isContent)
|
||||
async post(domainId: string, tid: ObjectID, content: string) {
|
||||
const tdoc = await contest.get(domainId, tid);
|
||||
if (tdoc.owner !== this.user._id) throw new PermissionError('Boardcast Message');
|
||||
const tsdocs = await contest.getMultiStatus(domainId, { docId: tid }).toArray();
|
||||
const uids = Array.from(new Set(tsdocs.map((tsdoc) => tsdoc.uid)));
|
||||
await Promise.all(
|
||||
uids.map((uid) => message.send(this.user._id, uid, content, message.FLAG_ALERT)),
|
||||
);
|
||||
this.response.redirect = this.url('contest_detail', { tid });
|
||||
}
|
||||
}
|
||||
|
||||
class ContestScoreboardHandler extends ContestHandler {
|
||||
@param('tid', Types.ObjectID)
|
||||
async get(domainId: string, tid: ObjectID) {
|
||||
@@ -383,6 +413,7 @@ export async function apply() {
|
||||
Route('contest_create', '/contest/create', ContestCreateHandler, PERM.PERM_CREATE_CONTEST);
|
||||
Route('contest_main', '/contest', ContestListHandler, PERM.PERM_VIEW_CONTEST);
|
||||
Route('contest_detail', '/contest/:tid', ContestDetailHandler, PERM.PERM_VIEW_CONTEST);
|
||||
Route('contest_boardcast', '/contest/:tid/boardcast', ContestBoardcastHandler);
|
||||
Route('contest_edit', '/contest/:tid/edit', ContestEditHandler, PERM.PERM_VIEW_CONTEST);
|
||||
Route('contest_scoreboard', '/contest/:tid/scoreboard', ContestScoreboardHandler, PERM.PERM_VIEW_CONTEST);
|
||||
Route('contest_scoreboard_download', '/contest/:tid/export/:ext', ContestScoreboardDownloadHandler, PERM.PERM_VIEW_CONTEST);
|
||||
|
||||
@@ -321,10 +321,7 @@ class HomeMessagesHandler extends Handler {
|
||||
if (!udoc) throw new UserNotFoundError(uid);
|
||||
if (udoc.gravatar) udoc.gravatar = misc.gravatar(udoc.gravatar);
|
||||
const mdoc = await message.send(this.user._id, uid, content, message.FLAG_UNREAD);
|
||||
// TODO(twd2): improve here: projection
|
||||
if (this.user._id !== uid) {
|
||||
bus.publish(`user_message-${uid}`, { mdoc, udoc });
|
||||
}
|
||||
// TODO(twd2): improve here: projection\
|
||||
this.back({ mdoc, udoc });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { ObjectID } from 'mongodb';
|
||||
import * as user from './user';
|
||||
import { Mdoc } from '../interface';
|
||||
import * as db from '../service/db';
|
||||
import * as bus from '../service/bus';
|
||||
|
||||
const coll = db.collection('message');
|
||||
|
||||
@@ -14,9 +16,15 @@ export async function send(
|
||||
const res = await coll.insertOne({
|
||||
from, to, content, flag,
|
||||
});
|
||||
return {
|
||||
const mdoc = {
|
||||
from, to, content, _id: res.insertedId, flag,
|
||||
};
|
||||
if (from !== to) {
|
||||
// ENHANCE domainId?
|
||||
const udoc = await user.getById('system', to);
|
||||
bus.publish(`user_message-${to}`, { mdoc, udoc });
|
||||
}
|
||||
return mdoc;
|
||||
}
|
||||
|
||||
export async function get(_id: ObjectID): Promise<Mdoc> {
|
||||
|
||||
@@ -59,7 +59,8 @@ const Tools: Array<[Converter, Validator, boolean?]> = [
|
||||
[(v) => parseInt(v, 10), (v) => parseInt(v, 10) > 0],
|
||||
[(v) => parseFloat(v), (v) => {
|
||||
const t = parseFloat(v);
|
||||
return t && !Number.isNaN(t) && !Number.isFinite(t);
|
||||
console.log(t);
|
||||
return t && !Number.isNaN(t) && Number.isFinite(t);
|
||||
}],
|
||||
[(v) => new ObjectID(v), ObjectID.isValid],
|
||||
[(v) => !!v, null, true],
|
||||
@@ -72,7 +73,8 @@ const Tools: Array<[Converter, Validator, boolean?]> = [
|
||||
(v) => {
|
||||
const d = v.split('-');
|
||||
assert(d.length === 3);
|
||||
return moment(`${d[0]}-${d[1].length === 1 ? '0' : ''}${d[1]}-${d[2].length === 1 ? '0' : ''}${d[2]}`).isValid();
|
||||
const st = `${d[0]}-${d[1].length === 1 ? '0' : ''}${d[1]}-${d[2].length === 1 ? '0' : ''}${d[2]}`;
|
||||
return moment(st).isValid();
|
||||
}],
|
||||
[
|
||||
(v) => {
|
||||
@@ -83,7 +85,7 @@ const Tools: Array<[Converter, Validator, boolean?]> = [
|
||||
(v) => {
|
||||
const t = v.split(':');
|
||||
assert(t.length === 2);
|
||||
return moment(`${(t[0].length === 1 ? '0' : '') + t[0]}:${t[1].length === 1 ? '0' : ''}${t[1]}`).isValid();
|
||||
return moment(`2020-01-01 ${(t[0].length === 1 ? '0' : '') + t[0]}:${t[1].length === 1 ? '0' : ''}${t[1]}`).isValid();
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
Reference in new issue
Block a user