From 2055a27edf584f545278c9d44382b3b76608152b Mon Sep 17 00:00:00 2001 From: zjz1993 <1429595365@qq.com> Date: Tue, 13 Aug 2019 18:27:37 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E8=AF=84=E8=AE=BA=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E6=94=B9=E7=89=88=E5=88=9D=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models-built/new_reply.js | 144 ++++++++++++++++++++++++++++++++++ models-built/new_reply.js.map | 1 + models/new_reply.ts | 51 ++++++++++++ modules/discussion.js | 96 +++++++++++++++++------ views/article.ejs | 36 --------- 5 files changed, 269 insertions(+), 59 deletions(-) create mode 100644 models-built/new_reply.js create mode 100644 models-built/new_reply.js.map create mode 100644 models/new_reply.ts diff --git a/models-built/new_reply.js b/models-built/new_reply.js new file mode 100644 index 0000000..f22355d --- /dev/null +++ b/models-built/new_reply.js @@ -0,0 +1,144 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var TypeORM = require("typeorm"); +var common_1 = require("./common"); +var user_1 = require("./user"); +var article_1 = require("./article"); +var NewReply = /** @class */ (function (_super) { + __extends(NewReply, _super); + function NewReply() { + return _super !== null && _super.apply(this, arguments) || this; + } + NewReply.prototype.loadRelationships = function () { + return __awaiter(this, void 0, void 0, function () { + var _a, _b; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + _a = this; + return [4 /*yield*/, user_1["default"].findById(this.from_user_id)]; + case 1: + _a.user = _c.sent(); + _b = this; + return [4 /*yield*/, article_1["default"].findById(this.article_id)]; + case 2: + _b.article = _c.sent(); + return [2 /*return*/]; + } + }); + }); + }; + NewReply.prototype.isAllowedEditBy = function (user) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.loadRelationships()]; + case 1: + _a.sent(); + return [2 /*return*/, user && (user.is_admin || this.from_user_id === user.id || user.id === this.article.user_id)]; + } + }); + }); + }; + NewReply.cache = false; + __decorate([ + TypeORM.PrimaryGeneratedColumn(), + __metadata("design:type", Number) + ], NewReply.prototype, "id"); + __decorate([ + TypeORM.Column({ nullable: true, type: "mediumtext" }), + __metadata("design:type", String) + ], NewReply.prototype, "content"); + __decorate([ + TypeORM.Column({ nullable: true, type: "integer" }), + __metadata("design:type", Number) + ], NewReply.prototype, "article_id"); + __decorate([ + TypeORM.Column({ nullable: true, type: "integer" }), + __metadata("design:type", Number) + ], NewReply.prototype, "from_user_id"); + __decorate([ + TypeORM.Column({ nullable: true, type: "integer" }), + __metadata("design:type", Number) + ], NewReply.prototype, "to_user_id"); + __decorate([ + TypeORM.Column({ nullable: true, type: "integer" }), + __metadata("design:type", Number) + ], NewReply.prototype, "parent_id"); + __decorate([ + TypeORM.Column({ nullable: true, type: "integer" }), + __metadata("design:type", Number) + ], NewReply.prototype, "public_time"); + __decorate([ + TypeORM.Column({ nullable: true, type: "integer" }), + __metadata("design:type", Number) + ], NewReply.prototype, "update_time"); + __decorate([ + TypeORM.Column({ "default": 0, type: "integer" }), + __metadata("design:type", Number) + ], NewReply.prototype, "comments_num"); + NewReply = __decorate([ + TypeORM.Entity() + ], NewReply); + return NewReply; +}(common_1["default"])); +exports["default"] = NewReply; +; +//# sourceMappingURL=new_reply.js.map \ No newline at end of file diff --git a/models-built/new_reply.js.map b/models-built/new_reply.js.map new file mode 100644 index 0000000..0e03d58 --- /dev/null +++ b/models-built/new_reply.js.map @@ -0,0 +1 @@ +{"version":3,"file":"new_reply.js","sourceRoot":"","sources":["../models/new_reply.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iCAAmC;AACnC,mCAA6B;AAC7B,+BAA0B;AAC1B,qCAAgC;AAIhC;IAAsC,4BAAK;IAA3C;;IA2CA,CAAC;IAVS,oCAAiB,GAAvB;;;;;;wBACI,KAAA,IAAI,CAAA;wBAAQ,qBAAM,iBAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,EAAA;;wBAAlD,GAAK,IAAI,GAAG,SAAsC,CAAC;wBACnD,KAAA,IAAI,CAAA;wBAAW,qBAAM,oBAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAA;;wBAAtD,GAAK,OAAO,GAAG,SAAuC,CAAC;;;;;KAC1D;IAEK,kCAAe,GAArB,UAAsB,IAAI;;;;4BACtB,qBAAM,IAAI,CAAC,iBAAiB,EAAE,EAAA;;wBAA9B,SAA8B,CAAC;wBAC/B,sBAAO,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAC;;;;KACvG;IAxCM,cAAK,GAAG,KAAK,CAAC;IAGrB;QADC,OAAO,CAAC,sBAAsB,EAAE;;gCACtB;IAGX;QADC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;;qCACvC;IAGhB;QADC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;wCACjC;IAGnB;QADC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;0CAC/B;IAGrB;QADC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;wCACjC;IAGnB;QADC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;uCAClC;IAGlB;QADC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;yCAChC;IAGpB;QADC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;yCAChC;IAGpB;QADC,OAAO,CAAC,MAAM,CAAC,EAAE,SAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;0CAC3B;IA5BJ,QAAQ;QAD5B,OAAO,CAAC,MAAM,EAAE;OACI,QAAQ,CA2C5B;IAAD,eAAC;CAAA,AA3CD,CAAsC,mBAAK,GA2C1C;qBA3CoB,QAAQ;AA2C5B,CAAC"} \ No newline at end of file diff --git a/models/new_reply.ts b/models/new_reply.ts new file mode 100644 index 0000000..ebfc763 --- /dev/null +++ b/models/new_reply.ts @@ -0,0 +1,51 @@ +import * as TypeORM from "typeorm"; +import Model from "./common"; +import User from "./user"; +import Article from "./article"; +declare var syzoj: any; + +@TypeORM.Entity() +export default class NewReply extends Model { + static cache = false; + + @TypeORM.PrimaryGeneratedColumn() + id: number; + + @TypeORM.Column({ nullable: true, type: "mediumtext" }) + content: string; + + @TypeORM.Column({ nullable: true, type: "integer" }) + article_id: number; + + @TypeORM.Column({ nullable: true, type: "integer" }) + from_user_id: number; + + @TypeORM.Column({ nullable: true, type: "integer" }) + to_user_id: number; + + @TypeORM.Column({ nullable: true, type: "integer" }) + parent_id: number; + + @TypeORM.Column({ nullable: true, type: "integer" }) + public_time: number; + + @TypeORM.Column({ nullable: true, type: "integer" }) + update_time: number; + + @TypeORM.Column({ default: 0, type: "integer" }) + comments_num: number; + + user?: User; + article?: Article; + + async loadRelationships() { + this.user = await User.findById(this.from_user_id); + this.article = await Article.findById(this.article_id); + } + + async isAllowedEditBy(user) { + await this.loadRelationships(); + return user && (user.is_admin || this.from_user_id === user.id || user.id === this.article.user_id); + } + +}; diff --git a/modules/discussion.js b/modules/discussion.js index 028d25d..2284c45 100644 --- a/modules/discussion.js +++ b/modules/discussion.js @@ -3,6 +3,7 @@ let Article = syzoj.model('article'); let ArticleComment = syzoj.model('article-comment'); let User = syzoj.model('user'); let Reply = syzoj.model('reply'); +let NewReply = syzoj.model('new_reply'); app.get('/discussion/:type?', async (req, res) => { try { @@ -75,42 +76,88 @@ app.get('/discussion/problem/:pid', async (req, res) => { }); app.get('/article/:id', async (req, res) => { + // try { + // let id = parseInt(req.params.id); + // let replyQuery = await Reply.createQueryBuilder(); + // let article = await Article.findById(id); + // if (!article) throw new ErrorMessage('无此帖子。'); + // + // await article.loadRelationships(); + // article.allowedEdit = await article.isAllowedEditBy(res.locals.user); + // article.allowedComment = await article.isAllowedCommentBy(res.locals.user); + // article.content = await syzoj.utils.markdown(article.content); + // + // let where = { article_id: id }; + // let commentsCount = await ArticleComment.countForPagination(where); + // let paginate = syzoj.utils.paginate(commentsCount, req.query.page, syzoj.config.page.article_comment); + // + // let comments = await ArticleComment.queryPage(paginate, where, { + // public_time: 'DESC' + // }); + // + // for (let comment of comments) { + // const commentId = comment.id; + // const reply = await replyQuery.where("comment_id = :commentId", { commentId }).getMany(); + // if (reply.length === 0) { + // comment.reply = []; + // } else { + // comment.reply = await reply.mapAsync(async (item) => { + // const replyUserId = item.user_id; + // item.reply_user = await User.findById(replyUserId); + // return item + // }); + // } + // comment.content = await syzoj.utils.markdown(comment.content); + // comment.allowedEdit = await comment.isAllowedEditBy(res.locals.user); + // await comment.loadRelationships(); + // } + // + // let problem = null; + // if (article.problem_id) { + // problem = await Problem.findById(article.problem_id); + // if (!await problem.isAllowedUseBy(res.locals.user)) { + // throw new ErrorMessage('您没有权限进行此操作。'); + // } + // } + // res.render('article', { + // user: res.locals.user, + // article: article, + // comments: comments, + // paginate: paginate, + // problem: problem, + // commentsCount: commentsCount + // }); + // } catch (e) { + // syzoj.log(e); + // res.render('error', { + // err: e + // }); + // } try { let id = parseInt(req.params.id); - let replyQuery = await Reply.createQueryBuilder(); let article = await Article.findById(id); if (!article) throw new ErrorMessage('无此帖子。'); - + await article.loadRelationships(); article.allowedEdit = await article.isAllowedEditBy(res.locals.user); article.allowedComment = await article.isAllowedCommentBy(res.locals.user); article.content = await syzoj.utils.markdown(article.content); - + let where = { article_id: id }; - let commentsCount = await ArticleComment.countForPagination(where); + let commentsCount = await NewReply.countForPagination(where); let paginate = syzoj.utils.paginate(commentsCount, req.query.page, syzoj.config.page.article_comment); - - let comments = await ArticleComment.queryPage(paginate, where, { + + let comments = await NewReply.queryPage(paginate, where, { public_time: 'DESC' }); - + console.log(comments); + for (let comment of comments) { - const commentId = comment.id; - const reply = await replyQuery.where("comment_id = :commentId", { commentId }).getMany(); - if (reply.length === 0) { - comment.reply = []; - } else { - comment.reply = await reply.mapAsync(async (item) => { - const replyUserId = item.user_id; - item.reply_user = await User.findById(replyUserId); - return item - }); - } comment.content = await syzoj.utils.markdown(comment.content); comment.allowedEdit = await comment.isAllowedEditBy(res.locals.user); await comment.loadRelationships(); } - + let problem = null; if (article.problem_id) { problem = await Problem.findById(article.problem_id); @@ -239,18 +286,21 @@ app.post('/article/:id/comment', async (req, res) => { let id = parseInt(req.params.id); let article = await Article.findById(id); - + let to_id = article.user_id; if (!article) { throw new ErrorMessage('无此帖子。'); } else { if (!await article.isAllowedCommentBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。'); } - let comment = await ArticleComment.create({ + let comment = await NewReply.create({ content: req.body.comment, article_id: id, - user_id: res.locals.user.id, - public_time: syzoj.utils.getCurrentDate() + from_user_id: res.locals.user.id, + to_user_id: to_id, + public_time: syzoj.utils.getCurrentDate(), + update_time: syzoj.utils.getCurrentDate(), + comments_num: 1, }); await comment.save(); diff --git a/views/article.ejs b/views/article.ejs index 2b2a7a3..4c0c655 100644 --- a/views/article.ejs +++ b/views/article.ejs @@ -110,42 +110,6 @@ <%}%> - <% for (let reply of comment.reply) { %> -
- - - -
- <%= reply.reply_user.username %><% if (reply.reply_user.nameplate) { %><%- reply.reply_user.nameplate %><% } %> - -
<%- reply.content %>
- <% if (comment.allowedEdit) { %> - - - <% } %> -
-
- <% } %> <% } %>