Files
JMuseum/models/renderModels/showcase.js
2018-02-26 14:09:18 +08:00

166 lines
7.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const User = require("../mongooseSchemas/User");
const Painting = require("../mongooseSchemas/Painting");
const ParticipantInfo = require("../mongooseSchemas/ParticipantInfo");
/**
* 以主使用者與被檢查的使用者之間的關係,取得觀看權限數值。
* @param {User} mainUser 主要使用者的資料。
* @param {string} otherUser_id 目標要查詢的使用者_id。
* @return {number} 觀看權限數值。
*/
function GetAuthorityNumber(mainUser, otherUser_id) {
if (mainUser._id.equals(otherUser_id)) { // 若mainUser與otherUser為同一人則回傳2。
return 2;
}
else if (mainUser.IsUsersFriend(otherUser_id)) { // 若otherUser為mainUser的好友則回傳1。
return 1;
}
else { // 若不為好友則回傳0。
return 0;
}
}
/**
* @typedef PaintingRange
* @prop {number} n 表示第n個區間。
* @prop {string[]} range_id 表示在第n個區間中的圖畫Id。
*/
/**
* 取得目標要尋找的圖畫Id座落的區間與該區間中第一個圖畫Id。
* @param {Painting[]} list 全域的資料。為圖畫陣列。
* @param {string} id 要尋找座落在哪區間的資料。為圖畫Id。
* @param {number} viewAutho 觀看權限數值。
* @return {PaintingRange} 回傳第N個區間整數與該區間中的第一個圖畫Id。為 {n, range_id}。
*/
function GetRangeIndex(list, id, viewAutho) {
let viewList = list.filter((docs => docs.viewAuthority <= viewAutho)); // 用「訪問權限」與觀看權限數值,過濾原本的畫作清單,成新的畫作清單。
let length = viewList.length; // 取得清單內容長度
// 尋找目標畫作在清單中的索引位置
for (let i = 0; i < length; i++) {
if (list[i].id == id) {
// 以十個畫作為一組取得目前在第n組
let n = Math.floor(i / 10);
// 回傳n與第n組中 (n * 10) ~ (n * 10 + 9) 之間的畫作_id清單。
return { n: n, range_id: list.slice(n * 10, n * 10 + 10).filter(docs => docs._id) };
}
}
// 若沒找到則回傳null。
return null;
}
/**
* 為「個人藝廊」模式下的插值方法。
* @param {BasicLayout} renderData 基本差值物件。
* @param {string[]} params 路由路徑中的每項參數。
* @param {Express.Session} session Express的Session物件。
* @param {CallbackFunction} callback 回呼函式。
*/
function PersonalShowcaseRender(renderData, params, session, callback) {
let username = params[2]; // 此個人藝廊的使用者
let paintingId = params[3]; // 指定要瀏覽的畫作Id
let tag = params[4]; // 指定畫作的標籤群組(可有可無)
let datas = renderData.datas;
datas.isActivity = false;
datas.themeTitle = null;
datas.themeOriginator = null;
datas.artist = username;
datas.tag = tag;
datas.paintings = []; // 建立畫作清單欄位
// 建立 Populate Query
let populateQuery = {
path: "paintings",
select: { "id": 1, "viewAuthority": 1 },
match: { "isLocked": false }
};
// 如果有指定tag則將其加入到populateQuery之中作為條件
// 比對每個畫作的標籤中是否有包含tag。
if (tag)
populateQuery.match.tags = tag;
// 以username尋找目標使用者的資料其中選取paintings欄位然後再以populateQuery做畫作連結
User.findOne({"username": username})
.select("personalInfo.photo paintings friendList")
.populate(populateQuery)
.exec((err, userDocs) => {
if (err) callback(err, null);
if (!userDocs) callback(User.Error_UserNotExist(), null); // 若找不到使用者,則帶著相對應的錯誤回呼
let ownersPhotoURL = userDocs.personalInfo.photo; // 擁有此展示藝廊的人的頭像照片
let paintingList = userDocs.paintings; // 取得畫作Id清單
let viewAuth = GetAuthorityNumber(userDocs, session.passport.user); // 取得觀看權限數值
let rangeInfo = GetRangeIndex(paintingList, paintingId, viewAuth); // 取得區間資料
// 如果目標畫作不在清單之中的話,則回呼錯誤 **仍要再改
if (!rangeInfo) return callback(new Error("找不到對應的畫作。"), null);
// 以區間尋找畫作資訊
Painting.find({ "_id": { $in: rangeInfo.range_id } })
.populate([{path: "ratings"}, {path: "comments"}])
.exec((err, paintingDocs) => {
if (err) callback(err, null);
// 循每一個畫作資料,取其中的欄位資料加入至 datas.paintings 中
paintingDocs.forEach((docs) => {
datas.paintings.push({
id: docs.id,
links: docs.links,
name: docs.name,
description: docs.description,
artistInfo: { name: username, photoURL: ownersPhotoURL},
totalScore: docs.totalScore,
userScore: docs.FindRatingScoreByUsername(renderData.username),
comments: docs.comments
});
});
// 最後,取得當前使用者的個人照片
User.findOne({"_id": session.passport.user}, "personalInfo.photo", (err, guestUserDocs) => {
if (err) return callback(err, null);
if (!guestUserDocs) return callback(User.Error_UserNotExist(), null);
datas.photoURL = guestUserDocs.personalInfo.photo; // 取得當前使用者的個人照片
callback(null, true);
});
}
);
}
);
}
/**
* 為「活動藝廊」模式下的差值方法。
* @param {BasicLayout} renderData 基本插值物件。
* @param {string[]} params 路由路徑中的每項參數。
* @param {Express.Session} session Express的Session物件。
* @param {CallbackFunction} callback 回呼函式。
*/
function ActivityShowcaseRender(renderData, params, session, callback) {
}
/**
*
* @param {BasicLayout} renderData 基本插值物件。
* @param {string} route 路由路徑。
* @param {Express.Session} session Express的Session物件。
* @param {CallbackFunction} callback 回呼函式。
*/
function ShowcaseRender(renderData, route, session, callback) {
let params = route.split("/").slice(1);
switch(params[1]) {
case "personal":
PersonalShowcaseRender(renderData, params, session, callback);
break;
case "activity":
ActivityShowcaseRender(renderData, params, session, callback);
break;
default:
callback(new Error("未定義的展示藝廊模式。"), null);
}
}
module.exports.Render = ShowcaseRender;